【发布时间】:2020-02-01 23:19:23
【问题描述】:
我想在按下鼠标时在光标位置的视频上绘制一个圆圈。视频在 MainWindow 中的 QLabel 对象中播放。我正在使用 OpenCV 以 10 fps 从网络摄像头读取帧。我将帧转换为 QPixmap 并在 QLabel 对象中显示它们 (self.vidWindow)。
在下面的代码中,当 MainWindow 启动时立即绘制圆圈(不是我想要的),然后被视频流覆盖。文本显示在掩码 Qlabel 对象中,并在按下鼠标按钮时在 MainWindow 中打印一条消息。
我可以在 QLabel 对象中画一个圆吗?如果是这样,我应该使用掩码 QLabel 对象还是有办法直接覆盖self.vidWindow 中的视频?
在代码的最小化版本中,视频显示,但是当我尝试绘制椭圆时触发错误。
import sys, cv2
from PyQt5.QtWidgets import QMainWindow, QApplication, QLabel
from PyQt5.QtGui import QImage, QPixmap, QPainter, QPen, QFont
from PyQt5.QtCore import QTimer, Qt, QCoreApplication
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.statusBar().showMessage('Ready')
self.setGeometry(50, 50, 800, 600)
self.setWindowTitle('Statusbar')
self.vidWindow = QLabel(self)
self.vidWindow.setGeometry(20, 20, 640, 480)
self.maskWindow = QLabel(self)
self.maskWindow.setGeometry(20, 20, 640, 480)
self.maskWindow.setStyleSheet('background-color: rgba(0,0,0,0%)')
font = QFont()
font.setPointSize(18)
font.setBold(True)
font.setWeight(75)
self.maskWindow.setFont(font)
self.maskWindow.setText('Message is on the mask Qlabel object')
self.msgLabel = QLabel(self)
self.msgLabel.setGeometry(675, 300, 100, 20)
self.cap = cv2.VideoCapture(0)
self.pix = QImage()
self.timer = QTimer()
self.frame_rate = 5
self.show()
self.start()
def nextFrameSlot(self):
ret, frame = self.cap.read()
if ret == True:
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
img = QImage(frame,frame.shape[1], frame.shape[0], QImage.Format_RGB888)
img = img.scaled(640, 480, Qt.KeepAspectRatio)
self.pix = QPixmap.fromImage(img)
self.vidWindow.setPixmap(self.pix)
def mousePressEvent(self, QMouseEvent):
self.msgLabel.setText('Mouse Clicked!')
def paintEvent(self, QMouseEvent):
e = QMouseEvent
painter = QPainter(self)
painter.setPen(QPen(Qt.green, 4, Qt.SolidLine))
painter.drawEllipse(e.x(), e.y(), 100)
def start(self):
rate = int(1000.0 / self.frame_rate)
self.timer.setTimerType(Qt.PreciseTimer)
self.timer.timeout.connect(self.nextFrameSlot)
self.timer.start(rate)
def closeEvent(self, event):
if self.cap.isOpened():
self.cap.release()
self.vidWindow.clear()
QCoreApplication.quit()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = MainWindow()
sys.exit(app.exec_())
【问题讨论】:
标签: python video pyqt qpainter qlabel