pyqt5使用cv2打开相机并在视频流中绘制一个矩形框

pyqt5使用cv2打开相机并在视频流中绘制一个矩形框


前言

实现

  1. 打开摄像头
    • 将QLable的大小设置为相机支持的比例
    • 使用QTimer定期刷新Label中的Pixmap
  2. 重载QLabel的鼠标事件方法
    • 重载mousePressEvent方法,点击鼠标时记录起点坐标(此时终点坐标与起点坐标一致),并将is_drawing置为True
    • 重载mouseMoveEvent方法,鼠标移动时记录终点坐标,并通过is_drawing判断是否正在移动,通过调用update更新Label内容
  3. 重载QLabel绘制方法paintEvent,在Label上绘制框图
import sys
from PyQt5 import QtGui  
from PyQt5.QtWidgets import QApplication, QLabel, QMainWindow,QWidget  
from PyQt5.QtGui import QPainter, QPen, QColor  
from PyQt5.QtCore import Qt, QRect  
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt, QTimer  
from PyQt5.QtGui import QImage, QPixmap  

import cv2
class MyLabel(QLabel):  
    def __init__(self, parent=None):  
        super(MyLabel, self).__init__(parent)  
        self.rect = QRect()  
        self.is_drawing = False
        self.is_update_frame = False
        self.x0 =0
        self.y0 =0
        self.x1 =0
        self.y1 =0
    
    def mousePressEvent(self, event):  
        if event.button() == Qt.LeftButton: 
            self.is_drawing =True
            self.x0 = event.x()
            self.y0 = event.y()
            self.x1 = event.x()
            self.y1 = event.y()
    def mouseMoveEvent(self, event) -> None:
        if self.is_drawing:
            self.x1 = event.x()
            self.y1 = event.y()
            self.update()
                    
    def paintEvent(self, event):  
        super().paintEvent(event)  
        x0 ,y0 = min(self.x0,self.x1),min(self.y0,self.y1)  #左顶点坐标
        x1 ,y1 =max(self.x0,self.x1),max(self.y0,self.y1) #右底部坐标
        self.rect = QRect(x0, y0, abs(x1-x0), abs(y1-y0))
        painter = QPainter(self)  
        pen = QPen(QColor(255, 0, 0))  # 蓝色  
        pen.setWidth(3)  # 线条宽度  
        painter.setPen(pen)  
        painter.drawRect(self.rect)  # 绘制矩形框 
  
class MainWindow(QMainWindow):  
    def __init__(self):  
        super().__init__()  
        self.setWindowTitle("Draw Rectangle on QLabel")  
        self.setGeometry(100, 100, 800, 600)  
        self.centralwidget = QWidget(self)
        self.centralwidget.setMaximumSize(QtCore.QSize(800, 600))
        self.centralwidget.setObjectName("centralwidget")
        self.setCentralWidget(self.centralwidget)  
        self.label = MyLabel(self.centralwidget)  
        self.label.setGeometry(QtCore.QRect(0, 0, 400, 300))
        self.label.setCursor(Qt.CrossCursor)

        self.timer = QTimer()  
        self.timer.timeout.connect(self.update_frame)  
        self.timer.start(33)  # 更新频率为每秒30帧  
        self.cap = cv2.VideoCapture(0)  # 使用默认摄像头  
        if not self.cap.isOpened():  
            print("无法打开摄像头")  
            sys.exit()  
        self.update_frame() 
         
    def update_frame(self):
        self.label.is_update_frame = True
        self.ret, self.frame = self.cap.read()  
        if not self.ret:  
            return  
        self.frame = cv2.cvtColor(self.frame, cv2.COLOR_BGR2RGB)  
        h, w, ch = self.frame.shape  
        bytes_per_line = 3 * w  
        qt_image = QImage(self.frame.data, w, h, bytes_per_line, QImage.Format_RGB888)  
        pixmap = QPixmap.fromImage(qt_image)  
        self.label.setPixmap(pixmap)  
        self.label.setScaledContents(True) 
              
if __name__ == "__main__":  
    app = QApplication(sys.argv)  
    window = MainWindow()  
    window.show()  
    sys.exit(app.exec_())

效果

在这里插入图片描述

总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值