我需要在视频流顶部显示十字线。
现在视频流与瞄准标记和视频场景重叠。
mainUI.py
# Form implementation generated from reading ui file 'PyUICBasicDemo.ui'
#
# Created by: PyQt6 UI code generator 6.6.1
#
# WARNING: Any manual changes made to this file will be lost when pyuic6 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt6 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(869, 636)
self.centralWidget = QtWidgets.QWidget(parent=MainWindow)
self.centralWidget.setObjectName("centralWidget")
self.ComboDevices = QtWidgets.QComboBox(parent=self.centralWidget)
self.ComboDevices.setGeometry(QtCore.QRect(10, 20, 511, 22))
self.ComboDevices.setObjectName("ComboDevices")
**************************************************************************************
self.widgetDisplay = QtWidgets.QGraphicsView(parent=self.centralWidget)
self.widgetDisplay.setGeometry(QtCore.QRect(10, 60, 511, 401))
self.widgetDisplay.setAcceptDrops(False)
self.widgetDisplay.setObjectName("widgetDisplay")
***************************************************************************************
self.gridLayoutWidget_4 = QtWidgets.QWidget(parent=self.widgetDisplay)
self.gridLayoutWidget_4.setGeometry(QtCore.QRect(0, -1, 511, 401))
self.gridLayoutWidget_4.setObjectName("gridLayoutWidget_4")
self.gridLayout_3 = QtWidgets.QGridLayout(self.gridLayoutWidget_4)
self.gridLayout_3.setContentsMargins(11, 11, 11, 11)
self.gridLayout_3.setSpacing(6)
self.gridLayout_3.setObjectName("gridLayout_3")
self.groupInit = QtWidgets.QGroupBox(parent=self.centralWidget)
self.groupInit.setGeometry(QtCore.QRect(530, 20, 211, 101))
self.groupInit.setObjectName("groupInit")
self.gridLayoutWidget = QtWidgets.QWidget(parent=self.groupInit)
self.gridLayoutWidget.setGeometry(QtCore.QRect(9, 19, 201, 81))
self.gridLayoutWidget.setObjectName("gridLayoutWidget")
self.gridLayout = QtWidgets.QGridLayout(self.gridLayoutWidget)
self.gridLayout.setContentsMargins(11, 11, 11, 11)
self.gridLayout.setSpacing(6)
self.gridLayout.setObjectName("gridLayout")
self.bnClose = QtWidgets.QPushButton(parent=self.gridLayoutWidget)
self.bnClose.setEnabled(False)
self.bnClose.setObjectName("bnClose")
self.gridLayout.addWidget(self.bnClose, 2, 2, 1, 1)
self.bnOpen = QtWidgets.QPushButton(parent=self.gridLayoutWidget)
self.bnOpen.setObjectName("bnOpen")
self.gridLayout.addWidget(self.bnOpen, 2, 1, 1, 1)
self.bnEnum = QtWidgets.QPushButton(parent=self.gridLayoutWidget)
self.bnEnum.setObjectName("bnEnum")
self.gridLayout.addWidget(self.bnEnum, 1, 1, 1, 2)
self.groupGrab = QtWidgets.QGroupBox(parent=self.centralWidget)
self.groupGrab.setEnabled(False)
self.groupGrab.setGeometry(QtCore.QRect(530, 130, 241, 171))
self.groupGrab.setObjectName("groupGrab")
self.gridLayoutWidget_2 = QtWidgets.QWidget(parent=self.groupGrab)
self.gridLayoutWidget_2.setGeometry(QtCore.QRect(9, 19, 222, 141))
self.gridLayoutWidget_2.setObjectName("gridLayoutWidget_2")
self.gridLayout_2 = QtWidgets.QGridLayout(self.gridLayoutWidget_2)
self.gridLayout_2.setContentsMargins(11, 11, 11, 11)
self.gridLayout_2.setSpacing(6)
self.gridLayout_2.setObjectName("gridLayout_2")
self.bnSaveImage = QtWidgets.QPushButton(parent=self.gridLayoutWidget_2)
self.bnSaveImage.setEnabled(False)
self.bnSaveImage.setObjectName("bnSaveImage")
self.gridLayout_2.addWidget(self.bnSaveImage, 4, 0, 1, 2)
self.radioContinueMode = QtWidgets.QRadioButton(parent=self.gridLayoutWidget_2)
self.radioContinueMode.setObjectName("radioContinueMode")
self.gridLayout_2.addWidget(self.radioContinueMode, 0, 0, 1, 1)
self.radioTriggerMode = QtWidgets.QRadioButton(parent=self.gridLayoutWidget_2)
self.radioTriggerMode.setObjectName("radioTriggerMode")
self.gridLayout_2.addWidget(self.radioTriggerMode, 0, 1, 1, 1)
self.bnStop = QtWidgets.QPushButton(parent=self.gridLayoutWidget_2)
self.bnStop.setEnabled(False)
self.bnStop.setObjectName("bnStop")
self.gridLayout_2.addWidget(self.bnStop, 2, 1, 1, 1)
self.bnStart = QtWidgets.QPushButton(parent=self.gridLayoutWidget_2)
self.bnStart.setEnabled(False)
self.bnStart.setObjectName("bnStart")
self.gridLayout_2.addWidget(self.bnStart, 2, 0, 1, 1)
self.bnSoftwareTrigger = QtWidgets.QPushButton(parent=self.gridLayoutWidget_2)
self.bnSoftwareTrigger.setEnabled(False)
self.bnSoftwareTrigger.setObjectName("bnSoftwareTrigger")
self.gridLayout_2.addWidget(self.bnSoftwareTrigger, 3, 0, 1, 2)
self.groupParam = QtWidgets.QGroupBox(parent=self.centralWidget)
self.groupParam.setEnabled(False)
self.groupParam.setGeometry(QtCore.QRect(530, 310, 211, 151))
self.groupParam.setObjectName("groupParam")
self.gridLayoutWidget_3 = QtWidgets.QWidget(parent=self.groupParam)
self.gridLayoutWidget_3.setGeometry(QtCore.QRect(10, 20, 201, 131))
self.gridLayoutWidget_3.setObjectName("gridLayoutWidget_3")
self.gridLayoutParam = QtWidgets.QGridLayout(self.gridLayoutWidget_3)
self.gridLayoutParam.setContentsMargins(11, 11, 11, 11)
self.gridLayoutParam.setSpacing(6)
self.gridLayoutParam.setObjectName("gridLayoutParam")
self.label_6 = QtWidgets.QLabel(parent=self.gridLayoutWidget_3)
self.label_6.setObjectName("label_6")
self.gridLayoutParam.addWidget(self.label_6, 3, 0, 1, 1)
self.edtGain = QtWidgets.QLineEdit(parent=self.gridLayoutWidget_3)
self.edtGain.setObjectName("edtGain")
self.gridLayoutParam.addWidget(self.edtGain, 1, 1, 1, 1)
self.label_5 = QtWidgets.QLabel(parent=self.gridLayoutWidget_3)
self.label_5.setObjectName("label_5")
self.gridLayoutParam.addWidget(self.label_5, 1, 0, 1, 1)
self.label_4 = QtWidgets.QLabel(parent=self.gridLayoutWidget_3)
self.label_4.setObjectName("label_4")
self.gridLayoutParam.addWidget(self.label_4, 0, 0, 1, 1)
self.edtExposureTime = QtWidgets.QLineEdit(parent=self.gridLayoutWidget_3)
self.edtExposureTime.setObjectName("edtExposureTime")
self.gridLayoutParam.addWidget(self.edtExposureTime, 0, 1, 1, 1)
self.bnGetParam = QtWidgets.QPushButton(parent=self.gridLayoutWidget_3)
self.bnGetParam.setObjectName("bnGetParam")
self.gridLayoutParam.addWidget(self.bnGetParam, 4, 0, 1, 1)
self.bnSetParam = QtWidgets.QPushButton(parent=self.gridLayoutWidget_3)
self.bnSetParam.setObjectName("bnSetParam")
self.gridLayoutParam.addWidget(self.bnSetParam, 4, 1, 1, 1)
self.edtFrameRate = QtWidgets.QLineEdit(parent=self.gridLayoutWidget_3)
self.edtFrameRate.setObjectName("edtFrameRate")
self.gridLayoutParam.addWidget(self.edtFrameRate, 3, 1, 1, 1)
self.gridLayoutParam.setColumnStretch(0, 2)
self.gridLayoutParam.setColumnStretch(1, 3)
self.groupBox = QtWidgets.QGroupBox(parent=self.centralWidget)
self.groupBox.setGeometry(QtCore.QRect(530, 470, 211, 71))
self.groupBox.setObjectName("groupBox")
self.bnStart_focus = QtWidgets.QPushButton(parent=self.groupBox)
self.bnStart_focus.setGeometry(QtCore.QRect(10, 30, 75, 24))
self.bnStart_focus.setCursor(QtGui.QCursor(QtCore.Qt.CursorShape.ArrowCursor))
self.bnStart_focus.setObjectName("bnStart_focus")
self.bntest = QtWidgets.QPushButton(parent=self.groupBox)
self.bntest.setGeometry(QtCore.QRect(100, 30, 97, 24))
self.bntest.setObjectName("bntest")
self.groupBox_2 = QtWidgets.QGroupBox(parent=self.centralWidget)
self.groupBox_2.setGeometry(QtCore.QRect(10, 500, 120, 80))
self.groupBox_2.setWhatsThis("")
self.groupBox_2.setObjectName("groupBox_2")
self.lcdNumber = QtWidgets.QLCDNumber(parent=self.groupBox_2)
self.lcdNumber.setGeometry(QtCore.QRect(10, 30, 101, 41))
self.lcdNumber.setCursor(QtGui.QCursor(QtCore.Qt.CursorShape.ArrowCursor))
self.lcdNumber.setWhatsThis("")
self.lcdNumber.setAccessibleName("")
self.lcdNumber.setAccessibleDescription("")
self.lcdNumber.setObjectName("lcdNumber")
self.widgetDisplay.raise_()
self.ComboDevices.raise_()
self.groupInit.raise_()
self.groupGrab.raise_()
self.groupParam.raise_()
self.groupBox.raise_()
self.groupBox_2.raise_()
MainWindow.setCentralWidget(self.centralWidget)
self.statusBar = QtWidgets.QStatusBar(parent=MainWindow)
self.statusBar.setObjectName("statusBar")
MainWindow.setStatusBar(self.statusBar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.groupInit.setTitle(_translate("MainWindow", "Initialization"))
self.bnClose.setText(_translate("MainWindow", "Close Device"))
self.bnOpen.setText(_translate("MainWindow", "Open Device"))
self.bnEnum.setText(_translate("MainWindow", "Find Devices"))
self.groupGrab.setTitle(_translate("MainWindow", "Acquisition"))
self.bnSaveImage.setText(_translate("MainWindow", "Save Image"))
self.radioContinueMode.setText(_translate("MainWindow", "Continuous Mode"))
self.radioTriggerMode.setText(_translate("MainWindow", "Trigger Mode"))
self.bnStop.setText(_translate("MainWindow", "Stop Acquisition"))
self.bnStart.setText(_translate("MainWindow", "Start Acquisition"))
self.bnSoftwareTrigger.setText(_translate("MainWindow", "Software Trigger Once"))
self.groupParam.setTitle(_translate("MainWindow", "Parameters"))
self.label_6.setText(_translate("MainWindow", "Frame Rate"))
self.edtGain.setText(_translate("MainWindow", "0"))
self.label_5.setText(_translate("MainWindow", "Gain"))
self.label_4.setText(_translate("MainWindow", "Exposure"))
self.edtExposureTime.setText(_translate("MainWindow", "0"))
self.bnGetParam.setText(_translate("MainWindow", "Get Parameters"))
self.bnSetParam.setText(_translate("MainWindow", "Set Parameters"))
self.edtFrameRate.setText(_translate("MainWindow", "0"))
self.groupBox.setTitle(_translate("MainWindow", "Автофокус"))
self.bnStart_focus.setText(_translate("MainWindow", "Start"))
self.bntest.setText(_translate("MainWindow", "test"))
self.groupBox_2.setTitle(_translate("MainWindow", "Резкость"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec())
主窗口.py
# -- coding: utf-8 --
from PyQt6 import QtWidgets, QtGui, QtCore, QtMultimediaWidgets
from PyQt6.QtCore import QThreadPool, Qt
from PyQt6.QtWidgets import QApplication, QMainWindow, QMessageBox
from PyQt6.QtGui import QBrush, QPen, QColor
from Camera_net.BasicDemo.CamOperation_class import CameraOperation
from Camera_net.MvImport.MvCameraControl_class import *
from Camera_net.MvImport.MvErrorDefine_const import *
from Camera_net.MvImport.CameraParams_header import *
from GUI.thread_process_worker import RobotClientWorker
from GUI.mainUI import Ui_MainWindow
class CameraApplication(QMainWindow):
def __init__(self):
super().__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.deviceList = MV_CC_DEVICE_INFO_LIST()
self.cam = MvCamera()
self.nSelCamIndex = 0
self.obj_cam_operation = None
self.isOpen = False
self.isGrabbing = False
self.init_ui()
def init_ui(self):
self.ui.bnEnum.clicked.connect(self.enum_devices)
self.ui.bnOpen.clicked.connect(self.open_device)
self.ui.bnClose.clicked.connect(self.close_device)
self.ui.bnStart.clicked.connect(self.start_grabbing)
self.ui.bnStop.clicked.connect(self.stop_grabbing)
self.ui.bnSoftwareTrigger.clicked.connect(self.trigger_once)
self.ui.radioTriggerMode.clicked.connect(self.set_software_trigger_mode)
self.ui.radioContinueMode.clicked.connect(self.set_continue_mode)
self.ui.bnGetParam.clicked.connect(self.get_param)
self.ui.bnSetParam.clicked.connect(self.set_param)
self.ui.bnSaveImage.clicked.connect(self.save_bmp)
self.ui.bnStart_focus.clicked.connect(self.start_focus)
self.ui.bntest.clicked.connect(lambda: (None, None))
***************************************************************************************
# Create a QGraphicsScene and set it as the scene for the display widget
self._scene = QtWidgets.QGraphicsScene(self)
self.ui.widgetDisplay.setScene(self._scene)
# Create a video item and add it to the scene
self._videoitem = QtMultimediaWidgets.QGraphicsVideoItem()
self._videoitem.setSize(QtCore.QSizeF(500, 400))
# Define a rectangle for the ellipse
self._circle_item_rect = QtCore.QRectF(-20, -20, 40, 40)
# Create an ellipse and add it to the scene (should be added after the video item)
self._circle_item = QtWidgets.QGraphicsEllipseItem(self._circle_item_rect, parent=None)
self._circle_item.setBrush(QBrush(QColor(0, 0, 255)))
self._circle_item.setPen(QPen(QColor(255, 0, 0)))
# Set the position of the ellipse
self._circle_item.setPos(100, 100)
# Stack the ellipse behind the video item
self._circle_item.stackBefore(self._videoitem)
# Set the Z-values to control the layering of items
self._videoitem.setZValue(0)
self._circle_item.setZValue(1)
# Add items to the scene
self._scene.addItem(self._videoitem)
self._scene.addItem(self._circle_item)
# Make the ellipse the active panel
self._scene.setActivePanel(self._circle_item)
*********************************************************************
def TxtWrapBy(self, start_str, end, all):
start = all.find(start_str)
if start >= 0:
start += len(start_str)
end = all.find(end, start)
if end >= 0:
return all[start:end].strip()
# Converts the returned error code to hexadecimal display
def ToHexStr(self, num):
chaDic = {10: 'a', 11: 'b', 12: 'c', 13: 'd', 14: 'e', 15: 'f'}
hexStr = ""
if num < 0:
num = num + 2 ** 32
while num >= 16:
digit = num % 16
hexStr = chaDic.get(digit, str(digit)) + hexStr
num //= 16
hexStr = chaDic.get(num, str(num)) + hexStr
return hexStr
def enum_devices(self):
self.deviceList = MV_CC_DEVICE_INFO_LIST()
ret = MvCamera.MV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, self.deviceList)
if ret != 0:
strError = "Enum devices fail! ret = :" + ToHexStr(ret)
QMessageBox.warning(self, "Error", strError, QMessageBox.StandardButton.Ok)
return ret
if self.deviceList.nDeviceNum == 0:
QMessageBox.warning(self, "Info", "Find no device", QMessageBox.StandardButton.Ok)
return ret
print("Find %d devices!" % self.deviceList.nDeviceNum)
devList = []
for i in range(0, self.deviceList.nDeviceNum):
mvcc_dev_info = cast(self.deviceList.pDeviceInfo[i], POINTER(MV_CC_DEVICE_INFO)).contents
if mvcc_dev_info.nTLayerType == MV_GIGE_DEVICE:
print("\ngige device: [%d]" % i)
chUserDefinedName = ""
for per in mvcc_dev_info.SpecialInfo.stGigEInfo.chUserDefinedName:
if 0 == per:
break
chUserDefinedName = chUserDefinedName + chr(per)
print("device user define name: %s" % chUserDefinedName)
chModelName = ""
for per in mvcc_dev_info.SpecialInfo.stGigEInfo.chModelName:
if 0 == per:
break
chModelName = chModelName + chr(per)
print("device model name: %s" % chModelName)
nip1 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0xff000000) >> 24)
nip2 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x00ff0000) >> 16)
nip3 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x0000ff00) >> 8)
nip4 = (mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x000000ff)
print("current ip: %d.%d.%d.%d\n" % (nip1, nip2, nip3, nip4))
devList.append(
"[" + str(i) + "]GigE: " + chUserDefinedName + " " + chModelName + "(" + str(nip1) + "." + str(
nip2) + "." + str(nip3) + "." + str(nip4) + ")")
elif mvcc_dev_info.nTLayerType == MV_USB_DEVICE:
print("\nu3v device: [%d]" % i)
chUserDefinedName = ""
for per in mvcc_dev_info.SpecialInfo.stUsb3VInfo.chUserDefinedName:
if per == 0:
break
chUserDefinedName = chUserDefinedName + chr(per)
print("device user define name: %s" % chUserDefinedName)
chModelName = ""
for per in mvcc_dev_info.SpecialInfo.stUsb3VInfo.chModelName:
if 0 == per:
break
chModelName = chModelName + chr(per)
print("device model name: %s" % chModelName)
strSerialNumber = ""
for per in mvcc_dev_info.SpecialInfo.stUsb3VInfo.chSerialNumber:
if per == 0:
break
strSerialNumber = strSerialNumber + chr(per)
print("user serial number: %s" % strSerialNumber)
devList.append("[" + str(i) + "]USB: " + chUserDefinedName + " " + chModelName
+ "(" + str(strSerialNumber) + ")")
self.ui.ComboDevices.clear()
self.ui.ComboDevices.addItems(devList)
self.ui.ComboDevices.setCurrentIndex(0)
def open_device(self):
if self.isOpen:
QMessageBox.warning(self, "Error", 'Camera is Running!', QMessageBox.StandardButton.Ok)
return MV_E_CALLORDER
self.nSelCamIndex = self.ui.ComboDevices.currentIndex()
if self.nSelCamIndex < 0:
QMessageBox.warning(self, "Error", 'Please select a camera!', QMessageBox.StandardButton.Ok)
return MV_E_CALLORDER
self.obj_cam_operation = CameraOperation(self.cam, self.deviceList, self.nSelCamIndex)
ret = self.obj_cam_operation.Open_device()
if 0 != ret:
strError = "Open device failed ret:" + ToHexStr(ret)
QMessageBox.warning(self, "Error", strError, QMessageBox.StandardButton.Ok)
self.isOpen = False
else:
self.set_continue_mode()
self.get_param()
self.isOpen = True
self.enable_controls()
def update_sharpness_lcd(self, sharpness):
print(sharpness)
self.ui.lcdNumber.display(sharpness)
def start_grabbing(self):
ret = self.obj_cam_operation.Start_grabbing(self.ui.widgetDisplay.winId())
self.obj_cam_operation.sharpness_signal.connect(self.update_sharpness_lcd)
if ret != 0:
strError = "Start grabbing failed ret:" + ToHexStr(ret)
QMessageBox.warning(self, "Error", strError, QMessageBox.StandardButton.Ok)
else:
self.isGrabbing = True
self.enable_controls()
def stop_grabbing(self):
ret = self.obj_cam_operation.Stop_grabbing()
if ret != 0:
strError = "Stop grabbing failed ret:" + ToHexStr(ret)
QMessageBox.warning(self, "Error", strError, QMessageBox.StandardButton.Ok)
else:
self.isGrabbing = False
self.enable_controls()
def close_device(self):
if self.isOpen:
self.obj_cam_operation.Close_device()
self.isOpen = False
self.isGrabbing = False
self.enable_controls()
def set_continue_mode(self):
ret = self.obj_cam_operation.Set_trigger_mode(False)
if ret != 0:
strError = "Set continue mode failed ret:" + ToHexStr(ret)
QMessageBox.warning(self, "Error", strError, QMessageBox.StandardButton.Ok)
else:
self.ui.radioContinueMode.setChecked(True)
self.ui.radioTriggerMode.setChecked(False)
self.ui.bnSoftwareTrigger.setEnabled(False)
def set_software_trigger_mode(self):
ret = self.obj_cam_operation.Set_trigger_mode(True)
if ret != 0:
strError = "Set trigger mode failed ret:" + ToHexStr(ret)
QMessageBox.warning(self, "Error", strError, QMessageBox.StandardButton.Ok)
else:
self.ui.radioContinueMode.setChecked(False)
self.ui.radioTriggerMode.setChecked(True)
self.ui.bnSoftwareTrigger.setEnabled(self.isGrabbing)
def trigger_once(self):
ret = self.obj_cam_operation.Trigger_once()
if ret != 0:
strError = "TriggerSoftware failed ret:" + ToHexStr(ret)
QMessageBox.warning(self, "Error", strError, QMessageBox.StandardButton.Ok)
def save_bmp(self):
ret = self.obj_cam_operation.Save_Bmp()
if ret != MV_OK:
strError = "Save BMP failed ret:" + ToHexStr(ret)
QMessageBox.warning(self, "Error", strError, QMessageBox.StandardButton.Ok)
else:
print("Save image success")
def get_param(self):
ret = self.obj_cam_operation.Get_parameter()
if ret != MV_OK:
strError = "Get param failed ret:" + ToHexStr(ret)
QMessageBox.warning(self, "Error", strError, QMessageBox.StandardButton.Ok)
else:
self.ui.edtExposureTime.setText("{0:.2f}".format(self.obj_cam_operation.exposure_time))
self.ui.edtGain.setText("{0:.2f}".format(self.obj_cam_operation.gain))
self.ui.edtFrameRate.setText("{0:.2f}".format(self.obj_cam_operation.frame_rate))
def set_param(self):
frame_rate = self.ui.edtFrameRate.text()
exposure = self.ui.edtExposureTime.text()
gain = self.ui.edtGain.text()
ret = self.obj_cam_operation.Set_parameter(frame_rate, exposure, gain)
if ret != MV_OK:
strError = "Set param failed ret:" + ToHexStr(ret)
QMessageBox.warning(self, "Error", strError, QMessageBox.StandardButton.Ok)
return MV_OK
def start_focus(self):
robot_client_worker = RobotClientWorker(self.obj_cam_operation)
thread_pool = QThreadPool.globalInstance()
thread_pool.start(robot_client_worker)
def enable_controls(self):
self.ui.groupGrab.setEnabled(self.isOpen)
self.ui.groupParam.setEnabled(self.isOpen)
self.ui.bnOpen.setEnabled(not self.isOpen)
self.ui.bnClose.setEnabled(self.isOpen)
self.ui.bnStart.setEnabled(self.isOpen and (not self.isGrabbing))
self.ui.bnStop.setEnabled(self.isOpen and self.isGrabbing)
self.ui.bnSoftwareTrigger.setEnabled(self.isGrabbing and self.ui.radioTriggerMode.isChecked())
self.ui.bnSaveImage.setEnabled(self.isOpen and self.isGrabbing)
if __name__ == "__main__":
app = QApplication(sys.argv)
main_window = CameraApplication()
main_window.show()
sys.exit(app.exec())
我认为我的代码中存在某种结构错误。
有必要以某种方式在视频顶部画一个圆圈或在场景中正确显示视频。
为了完成这些任务,我使用 OpenCV 进行了解决。当您执行视频捕获时,它会返回一个 numpy 矩阵 B、G、R。我没有特别快的计算机,但例如,如果您在标签中显示图像,则延迟最小。 (我通过用 Blackmagic 卡捕获秒表来测试它,并设法实时捕获和重放)。当然,需要进行优化,但它很方便,特别是当您使用视图和场景时。 ellyanesc 有一个关于如何在场景上绘制网格的教程;我建议查找它以将视频集成到场景中。 PyQt6 中最简单的方法是将 numpy 数组转换为像素图(您需要以 24/30/50/60 fps 创建循环)并将其作为 QGraphicPixmap 对象插入。如果你在顶部设置像-1这样的深度,你就可以在上面绘图。我在 GitHub 上编写了一个小型视频混合器,网址为 https://github.com/AlessioMichelassi/openPyVision_013/。它仍在进行中,但您可以在那里找到很多代码。当然,我能写出来这要归功于musicamante和ellyanesc的学习! :)