PyQt5+OpenCV多线程显示摄像头数据
pyqt5是一套Python绑定Digia QT5应用的框架。它可用于Python 2和3。Qt库是最强大的GUI库之一。pyqt5很大的优势就是跨平台,而且使用起来非常的方便,编写的代码比较精简,又能实现比较复杂的界面。在很多视觉程序中都需要GUI, 搭配OpenCV, pyqt5可方便的实现各种视觉类应用。下面的代码相当相当于一个框架,实现了摄像头采集到处理的一个框架,摄像头采集的代码放在单独的线程中,这样就避免了因为图像处理算法耗时较多而导致摄像头数据采集的不及时。
import sys
from PyQt5.QtWidgets import (QWidget, QPushButton, QApplication, QLabel)
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtCore import QCoreApplication
import cv2
import threading
import copy
class demo_window(QWidget):
def __init__(self):
super().__init__()
self.cap = cv2.VideoCapture()
self.init_ui()
def init_ui(self):
self.image = QLabel(self)
self.image.setGeometry(0, 0, 400, 300)
self.image.setStyleSheet("background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0.0284091, "
+ "stop:0 rgba(67, 88, 89, 177), stop:1 rgba(110, 161, 164, 195));")
self.didou = QLabel(self)
self.didou.setGeometry(300+140, 30, 60, 120)
self.didou.setStyleSheet("background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0.034091, "
+ "stop:0 rgba(210, 88, 89, 177), stop:1 rgba(210, 161, 164, 195));")
self.label = QLabel(self)
self.label.setText("<B>液面高度:</B>")
self.label.move(500, 80)
self.btn = QPushButton('打开摄像头', self)
self.btn.move(410, 200)
self.btn.clicked.connect(self.open_camera)
self.btn = QPushButton('拍摄并识别', self)
self.btn.move(510, 200)
self.btn.clicked.connect(self.capture_and_rec)
self.btn = QPushButton('关闭摄像头', self)
self.btn.move(600, 200)
self.btn.clicked.connect(self.close_camera)
self.setGeometry(300, 300, 700, 300)
self.setWindowTitle('Demo')
self.stopEvent = threading.Event()
self.stopEvent.clear()
self.R = threading.Lock()
def open_camera(self):
if self.cap.isOpened():
print("is opened!")
return
self.cap = cv2.VideoCapture("Capture00000.avi")
if self.cap.isOpened():
th = threading.Thread(target=self.Display)
th.start()
pass
def close_camera(self):
self.stopEvent.set()
pass
def capture_and_rec(self):
self.R.acquire()
frame = self.src_image
self.R.release()
# 处理图像的过程可以在这里完成
img = QImage(frame.data, frame.shape[1], frame.shape[0], QImage.Format_RGB888)
self.didou.setPixmap(QPixmap.fromImage(img))
def Display(self):
while self.cap.isOpened():
success, frame = self.cap.read()
if success is False:
continue
self.R.acquire()
self.src_image = copy.deepcopy(frame)
self.R.release()
frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR) # RGB转BGR
frame = cv2.resize(frame, (400, 300))
img = QImage(frame.data, frame.shape[1], frame.shape[0], QImage.Format_RGB888)
self.image.setPixmap(QPixmap.fromImage(img))
cv2.waitKey(1)
# 判断关闭事件是否已触发
if self.stopEvent.is_set():
self.stopEvent.clear()
self.image.clear()
self.cap.release()
break
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = demo_window()
ex.show()
sys.exit(app.exec_())
- 原文作者:Binean
- 原文链接:https://bzhou830.github.io/post/20160515python_opencv_camera/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。