【Python动画设计教程】系列文章目录
【第一讲】软件准备
【第二讲】搭建界面,Excel读取,图片读取
【第三讲】图像绘制
【第四讲】制作动画
文章目录
- 计划
讲义在2020年1月11日初步完成
2小时课时,完成界面搭建、excel和图片基本操作
- 码云代码库
参考我的代码,码云的主页:https://gitee.com/bigearrabbit/kevinpython/tree/master/kevinanimation
- 软件准备
下文中的SVN代码仓,地址为:svn://gitee.com/bigearrabbit/kevinpython/kevinanimation
1 搭建Qt界面
使用QT来搭建界面,快速方便,和C++的QT一样的用法。方便进行C++的迁移。
详细步骤请参考网友文章《opencv 结合pyqt5 编写简单的图像处理GUI程序》
1.1 搭建界面
创建2个label和4个按钮。
文件 | 用途 |
---|---|
KevinAnimationUI.ui | 通过qt designer 自动生成的ui界面文件 |
resource.qrc | qt资源文件 |
KevinAnimationDlg.py | 手工创建的界面处理类(包括main函数) |
KevinAnimationUI.bat | 转换ui和qrc的批处理 |
KevinAnimationUI.ui | 通过 KevinAnimationUI.bat 自动生成的python界面文件 |
resource_rc.py | 通过 KevinAnimationUI.bat 自动生成的资源文件 |
KevinAnimationDlg.py文件:
import sys
import cv2 as cv
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import QFileDialog, QMainWindow
from KevinAnimationUI import Ui_MainWindow
class KevinAnimationDlg(QMainWindow, Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
self.FileExcel = ''
self.FileImage = ''
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
dlg = KevinAnimationDlg()
dlg.show()
sys.exit(app.exec_())
bat语句,调用pyuic5进行转换
pyuic5 -o KevinAnimationUI.py KevinAnimationUI.ui
pyrcc5 -o resource_rc.py resource.qrc
pause
运行 KevinAnimationDlg.py文件,效果:
如果学员没有调试出来,可以把SVN代码仓切换到版本3,查看效果。
1.2 信号槽建立
SVN代码仓切换到版本3。
在界面上创建曹函数,关联到界面按钮
添加的曹函数,在KevinAnimationUI.ui文件的最后,可以看到曹函数如下:
<slots>
<slot>OnOpenImage()</slot>
<slot>OnOpenExcel()</slot>
<slot>OnDrawImage()</slot>
<slot>OnNextImage()</slot>
</slots>
运行后输出,逐个点击文件,输出下面信息,说明信号槽创建正确:
I am in OnOpenExcel().
I am in OnOpenImage().
I am in OnDrawImage().
I am in OnNextImage().
如果学员没有调试出来,可以把SVN代码仓切换到版本5,查看效果。
2 读取Excel
SVN代码仓切换到版本4。
设计一个表格,保存为hello.xlsx
id | contents |
---|---|
1 | Hello Python |
2 | Kevin is a good man. |
3 | kevin is a handsome man. |
4 | Kevin is lazy. |
6 | kevin is sleeping. |
创建一个helloexcel.py,如下:
import xlrd # Excel 读取
# 打开文件:
wb = xlrd.open_workbook("hello.xlsx")
sheet = wb.sheet_by_index(0) # sheet索引从0开始
contents = [] # 定义一个行数组
# 逐行读取
for i in range(sheet.nrows): # i从0开始
tmp = [] # 定义一个空数组变量
# 逐列读取
for j in range(sheet.ncols):
value = sheet.cell_value(i, j)
tmp.append(value) # add one value
contents.append(tmp) # first row
# 逐行输出
for i in range(len(contents)):
print(contents[i][-1]) # 逐个输出最后一列
按F5运行,输出效果:
Contents
Hello Python
Kevin is a good man.
kevin is a handsome man.
Kevin is lazy.
kevin is sleeping.
如果学员没有调试出来,可以把SVN代码仓切换到版本5,查看效果。
3 图片的读取和显示
(SVN代码仓保持版本4不动)
利用Opencv读取,利用QT显示
3.1 OpenCV打开图片显示测试
下面的图片另存为orange.jpg,放到vscode的工程目录下。
检出地址:svn://gitee.com/bigearrabbit/kevinpython/kevinanimation/orange.jpg
在Vscode里面建立一个文件: helloopencv2.py
检出地址: svn://gitee.com/bigearrabbit/kevinpython/kevinanimation/helloopencv2.py
import cv2 as cv # 导入opencv,命名为cv
img = cv.imread("orange.jpg") # 读取当前文件夹下的图片
cv.namedWindow("orange", cv.WINDOW_AUTOSIZE) # 创建一个名称为orange的窗口,自动缩放
cv.imshow("orange", img) # 显示读入的图片
cv.waitKey(0) # 进入事件循环,按任意键后关闭窗口
cv.destroyAllWindows() # 销毁窗口
按F5运行:
3.2 在QT程序内使用OpenCV打开图片
在构造函数内,添加变量imgInput 初始化:
self.imgInput = None
修改OnOpenImage()函数,添加打开图片
def OnOpenImage(self):
print('I am in OnOpenImage().')
self.imgInput = cv.imread("orange.jpg") # 读取当前文件夹下的图片
return 0
3.3 在Qt界面上显示图片
- 添加一个函数 ShowCVImage():
def ShowCVImage(self, iCVImg, iLabel):
QtImg = QtGui.QImage(iCVImg.data,
iCVImg.shape[1],
iCVImg.shape[0],
iCVImg.shape[1] * 3,
QtGui.QImage.Format_RGB888)
iLabel.setPixmap(QtGui.QPixmap.fromImage(QtImg))
iLabel.show()
return 0
- 修改OnOpenImage()函数,添加显示图片语句
def OnOpenImage(self):
print('I am in OnOpenImage().')
self.imgInput = cv.imread("orange.jpg") # 读取当前文件夹下的图片
self.ShowCVImage(self.imgInput,self.labelInput) #显示到InputLabel上
return 0
效果:
发现颜色反了
- 增加颜色转换语句:
openCV 读取的图片是BGR格式,Qt上是RGB格式,需要转换
def ShowCVImage(self, iCVImg, iLabel):
# 颜色转换语句:
if iCVImg.ndim == 2: # 2维度表示长宽
channels = 1 # 单通道(grayscale)
img = cv.cvtColor(iCVImg, cv.COLOR_GRAY2RGB)
elif iCVImg.ndim == 3:
channels = iCVImg.shape[-1] # 第三维度表示通道,应为3
if(channels != 3): # 应该是三才对
return -1
img = cv.cvtColor(iCVImg, cv.COLOR_BGR2RGB)
else: # 异常维度,不是图片了
return 1
QtImg = QtGui.QImage(img.data,
img.shape[1],
img.shape[0],
img.shape[1] * 3,
QtGui.QImage.Format_RGB888)
iLabel.setPixmap(QtGui.QPixmap.fromImage(QtImg))
iLabel.show()
return 0
显示正确:
如果学员没有调试出来,可以把SVN代码仓切换到版本5,查看效果。