使用图像处理库OpenCV从摄像头获取数据并在PyQt5上显示出来

opencv能够处理图像、视频、深度图像等各种类型的视觉数据,在某些情况下,尽管opencv可以显示窗口,但pyqt5可能更适合用于创建复杂的交互式应用程序,而自带gpu的h618就成为了这些图像显示的最佳载体。
本文将实现的功能是使用图像处理库opencv从摄像头获取数据,缩放后从pyqt5的窗口中显示出来。
创建pyqt5窗口
这里在电脑上使用designer软件,创建一个main window类型窗体。从左边组件栏中拖出一个label放到窗口中间。
点一下放在窗口中的label,在软件右下角的属性编辑器里可以设置很多东西,这里就不细介绍了。这里我是设置了qframe启用了边框,qlabel中的texte属性控制显示的文本,qlabel中的alignment属性控制文本对齐方式。
然后保存为.ui结尾的文件:
随后将designer绘制的ui文件转化为py文件
python3 -m pyqt5.uic.pyuic ui_main.ui -o ui_main.py  
接下来编写main.py程序,调用刚刚画的窗口进行显示,先把刚刚的ui_main.py以及一些qt库给import进来:
from  ui_main import ui_mainwindowimport pyqt5from pyqt5 import qtcore, qtgui, qtwidgetsfrom pyqt5.qtcore import *from pyqt5.qtgui import *# 修正qt的plugin路径,因为某些程序(cv2)会将其改到其他路径import osos.environ['qt_qpa_platform_plugin_path'] = os.path.dirname(pyqt5.__file__)  
放入一点辅助代码,一个是为了实现从远程命令行运行qt程序显示到桌面上,一个是为了在命令行下可以按ctrl+c快捷键来强制退出qt程序
#【可选代码】允许远程运行import osos.environ[display] = :0.0#【建议代码】允许终端通过ctrl+c中断窗口,方便调试import signalsignal.signal(signal.sigint, signal.sig_dfl)timer = qtcore.qtimer()timer.start(100)  # you may change this if you wish.timer.timeout.connect(lambda: none)  # let the interpreter run each 100 ms  
加上调用函数进行显示的部分,这个显示pyqt5窗口的基本程序就完成了
# 初始化窗口import sysapp = qtwidgets.qapplication(sys.argv)window = window()ui = ui_mainwindow()ui.setupui(window)window.showfullscreen() #全屏显示# window.show() #按绘制时的尺寸显示sys.exit(app.exec_()) 在核桃派lcd屏上的效果展示
opencv图像读取及显示
调用头文件,opencv的头文件只需要这一个
import cv2  
打开摄像头,其中传入的参数1是摄像头编号,一般是从0开始往后排
cap = cv2.videocapture(1)  
从摄像头读取一帧图像,ret是读取状态,frame是图像数据
ret, frame = cap.read()  
cap.read函数读到的是bgr格式的,为了把opencv的图像数据显示到qt的label,需要先转为rgb格式,并将图像转为qt中用来表示图像的qimage。
rgbimage = cv2.cvtcolor(frame, cv2.color_bgr2rgb)h, w, ch = rgbimage.shapeqtimage = qimage(rgbimage.data, h, w, ch*w, qtgui.qimage.format_rgb888)  
label的setpixmap方法可以图像数据覆盖label
label.setpixmap(qpixmap.fromimage(qtimage)) 显示效果
线程,信号与槽
原代码为了简单,没有使用信号槽机制,不够线程安全,我们这里使用qt自带的多线程功能,他的使用很简单,只需要创建一个类并继承自qthread, 然后将要运行的东西写到类里的run方法下面。实例化一个对象后,调用start方法即可创建新线程
class work(qthread):    def run(self):        passwork = work()work.start()  
直接在线程内调用函数去修改qt窗口的内容,不能满足线程安全。
我们需要创建一个信号,把修改qt窗口的语句写到一个槽内,连接他们,在想修改窗口时发出信号,让qt内部去调度,防止跟其他qt内部的线程发生冲突。
因为我们这个线程类继承自qthread,所以可以在类内定义信号。只需要实例化一个pyqtsignal对象即可,调用时括号内的参数决定了槽函数必须有什么类型的参数,以及发送信号时需要传入什么参数。
signal_update_label = pyqtsignal( qpixmap)  
槽函数就是随便定义一个函数,只要函数参数跟信号一样就行。
label:qlabel    def sloat_update_label( self, pixmap:qpixmap):        self.label.setpixmap(pixmap)  
使用emit方法即可发送信号,qt内部会进行调度,将所有连接到本信号的函数都调出来运行,并将参数传给他们。这是qt实现线程安全的重要机制。
self.signal_update_label.emit(qpixmap.fromimage(qtimage))  
本文转载自:https://forum.walnutpi.com/t/topic/84


努比亚Z17、一加5区别对比评测:努比亚Z17线上全平台开售,跟一加5相比谁更值得入手?
国内外独立服务器的区别是什么
Adobe已经这么厉害了,为何还要帮助创意设计人才实现数字化转型?
中国前沿专利技术表现抢眼
具有过流保护的电子变压器电路图
使用图像处理库OpenCV从摄像头获取数据并在PyQt5上显示出来
吉利爆胎监测与安全控制系统(BMBS)
iOS10.3.1越狱盘古出,iOS10.2越狱由卢卡斯出!万事俱备只欠东风,iOS10.2越狱、iOS10.3越狱发布的契机是什么?
长安逸动纯电动汽车故障维修方案
嵌入式语音芯片系统的重要特性
主动红外入侵探测器的安装环境_主动红外探测器的安装注意事项
联通上线5G升级包 9.9元即可畅享5G流量
嵌入式状态监测与故障诊断装置设计
智能硬件创新设计行业走势及战略布局
基于LINUX的嵌入式浏览器的设计与实现
华为史上最好看手机今天发布 叫板iPhone7
带鱼屏+升降镜头?颜值超高,但看到处理器?再见?
适用于传输少量数据的蓝牙低能耗技术
IBM助力客户斩获多项IDC中国未来企业大奖
三种write mode,你真的理解吗?