opencv 读取 海康GIGE相机视频流

新项目中我们需要使用opencv读取海康威视的工业相机 MV-CA060-10GM 的视频流进行处理。那么首先我们要读取到相机的视频流,总所周知 opencv 读取视频流的办法就是使用  VideoCapture 函数 来读取。 但是经过多次测试,读取了文档和源代码 发现 opencv没有公版驱动可以和GIGE 协议的相机直接对接。那么怎么办呢?

然后我想到了海康威视提供的SDK 开发包。在sdk里面翻找了一下 终于发现一批python的例程,所以说大公司就是周到。那么我们来看一下如何把 海康的sdk连接到 opencv吧。

经过筛选我们选个了海康sdk python 例子中 的GrabImage.py 这个例子,来改造加入opencv 元素。

这个是 安装了海康威视最新的相机驱动之后都带的 sdk开发包中 就有 这个文件

下面是这个例子的源代码

# -- coding: utf-8 --import sys
import threading
import msvcrtfrom ctypes import *sys.path.append("../MvImport")
from MvCameraControl_class import *g_bExit = False# 为线程定义一个函数
def work_thread(cam=0, pData=0, nDataSize=0):stFrameInfo = MV_FRAME_OUT_INFO_EX()memset(byref(stFrameInfo), 0, sizeof(stFrameInfo))while True:ret = cam.MV_CC_GetOneFrameTimeout(pData, nDataSize, stFrameInfo, 1000)if ret == 0:print ("get one frame: Width[%d], Height[%d], nFrameNum[%d]"  % (stFrameInfo.nWidth, stFrameInfo.nHeight, stFrameInfo.nFrameNum))else:print ("no data[0x%x]" % ret)if g_bExit == True:breakif __name__ == "__main__":deviceList = MV_CC_DEVICE_INFO_LIST()tlayerType = MV_GIGE_DEVICE | MV_USB_DEVICE# ch:枚举设备 | en:Enum deviceret = MvCamera.MV_CC_EnumDevices(tlayerType, deviceList)if ret != 0:print ("enum devices fail! ret[0x%x]" % ret)sys.exit()if deviceList.nDeviceNum == 0:print ("find no device!")sys.exit()print ("Find %d devices!" % deviceList.nDeviceNum)for i in range(0, deviceList.nDeviceNum):mvcc_dev_info = cast(deviceList.pDeviceInfo[i], POINTER(MV_CC_DEVICE_INFO)).contentsif mvcc_dev_info.nTLayerType == MV_GIGE_DEVICE:print ("\ngige device: [%d]" % i)strModeName = ""for per in mvcc_dev_info.SpecialInfo.stGigEInfo.chModelName:strModeName = strModeName + chr(per)print ("device model name: %s" % strModeName)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))elif mvcc_dev_info.nTLayerType == MV_USB_DEVICE:print ("\nu3v device: [%d]" % i)strModeName = ""for per in mvcc_dev_info.SpecialInfo.stUsb3VInfo.chModelName:if per == 0:breakstrModeName = strModeName + chr(per)print ("device model name: %s" % strModeName)strSerialNumber = ""for per in mvcc_dev_info.SpecialInfo.stUsb3VInfo.chSerialNumber:if per == 0:breakstrSerialNumber = strSerialNumber + chr(per)print ("user serial number: %s" % strSerialNumber)nConnectionNum = input("please input the number of the device to connect:")if int(nConnectionNum) >= deviceList.nDeviceNum:print ("intput error!")sys.exit()# ch:创建相机实例 | en:Creat Camera Objectcam = MvCamera()# ch:选择设备并创建句柄 | en:Select device and create handlestDeviceList = cast(deviceList.pDeviceInfo[int(nConnectionNum)], POINTER(MV_CC_DEVICE_INFO)).contentsret = cam.MV_CC_CreateHandle(stDeviceList)if ret != 0:print ("create handle fail! ret[0x%x]" % ret)sys.exit()# ch:打开设备 | en:Open deviceret = cam.MV_CC_OpenDevice(MV_ACCESS_Exclusive, 0)if ret != 0:print ("open device fail! ret[0x%x]" % ret)sys.exit()# ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal package size(It only works for the GigE camera)if stDeviceList.nTLayerType == MV_GIGE_DEVICE:nPacketSize = cam.MV_CC_GetOptimalPacketSize()if int(nPacketSize) > 0:ret = cam.MV_CC_SetIntValue("GevSCPSPacketSize",nPacketSize)if ret != 0:print ("Warning: Set Packet Size fail! ret[0x%x]" % ret)else:print ("Warning: Get Packet Size fail! ret[0x%x]" % nPacketSize)# ch:设置触发模式为off | en:Set trigger mode as offret = cam.MV_CC_SetEnumValue("TriggerMode", MV_TRIGGER_MODE_OFF)if ret != 0:print ("set trigger mode fail! ret[0x%x]" % ret)sys.exit()# ch:获取数据包大小 | en:Get payload sizestParam =  MVCC_INTVALUE()memset(byref(stParam), 0, sizeof(MVCC_INTVALUE))ret = cam.MV_CC_GetIntValue("PayloadSize", stParam)if ret != 0:print ("get payload size fail! ret[0x%x]" % ret)sys.exit()nPayloadSize = stParam.nCurValue# ch:开始取流 | en:Start grab imageret = cam.MV_CC_StartGrabbing()if ret != 0:print ("start grabbing fail! ret[0x%x]" % ret)sys.exit()data_buf = (c_ubyte * nPayloadSize)()try:hThreadHandle = threading.Thread(target=work_thread, args=(cam, byref(data_buf), nPayloadSize))hThreadHandle.start()except:print ("error: unable to start thread")print ("press a key to stop grabbing.")msvcrt.getch()g_bExit = TruehThreadHandle.join()# ch:停止取流 | en:Stop grab imageret = cam.MV_CC_StopGrabbing()if ret != 0:print ("stop grabbing fail! ret[0x%x]" % ret)del data_bufsys.exit()# ch:关闭设备 | Close deviceret = cam.MV_CC_CloseDevice()if ret != 0:print ("close deivce fail! ret[0x%x]" % ret)del data_bufsys.exit()# ch:销毁句柄 | Destroy handleret = cam.MV_CC_DestroyHandle()if ret != 0:print ("destroy handle fail! ret[0x%x]" % ret)del data_bufsys.exit()del data_buf

我们看到程序中主要程序里面的功能就是 读取电脑中GIGE 的相机列表 让你选择相机,然后打开设备,再然后读取视屏流数据

我们看到运行结果是读取了一帧画面。

那么我们要做的就是把这一帧画面转换成 opencv的图像格式并显示。

所以我们要在线程函数work_thread中去修改。

# 为线程定义一个函数
def work_thread(cam=0, pData=0, nDataSize=0):stFrameInfo = MV_FRAME_OUT_INFO_EX()memset(byref(stFrameInfo), 0, sizeof(stFrameInfo))while True:temp = np.asarray(pData)  # 将c_ubyte_Array转化成ndarray得到(3686400,)temp = temp.reshape((2048, 3072, 1))  # 根据自己分辨率进行转化# print(temp)# print(temp.shape)temp = cv2.cvtColor(temp, cv2.COLOR_BGR2RGB)  # 这一步获取到的颜色不对,因为默认是BRG,要转化成RGB,颜色才正常cv2.namedWindow("result", cv2.WINDOW_AUTOSIZE)cv2.imshow("result", temp)if cv2.waitKey(1) & 0xFF == ord('q'):breakret = cam.MV_CC_GetOneFrameTimeout(pData, nDataSize, stFrameInfo, 1000)if ret == 0:print("get one frame: Width[%d], Height[%d], nFrameNum[%d]" % (stFrameInfo.nWidth, stFrameInfo.nHeight, stFrameInfo.nFrameNum))else:print("no data[0x%x]" % ret)if g_bExit == True:break

我们看到在 这个 函数中 pdata 这个参数就是我们需要的 数据流块,nDataSize就是 数据大小。

我们需要把pdata 格式化一下,因为目前数据是线性的一维数据,所以 我们根据图像格式将数据数组重新构建。

temp.reshape((2048, 3072, 1)) 这里我们根据相机 来确定维度。图像的高和宽,颜色通道。这里相机是灰度的 所以使用单通道 参数惨设置为1.

然后的到的temp 图像数据 还需要转换成 opencv格式, opencv格式是 RGB  而 海康 取到的数据是BGR的

temp = cv2.cvtColor(temp, cv2.COLOR_BGR2RGB)

其实到了这一步大家都看到了。后面就是循环显示了。只是对sdk 稍作改动就行了。

哦对了这里还有个坑。就是

try:hThreadHandle = threading.Thread(target=work_thread, args=(cam, byref(data_buf), nPayloadSize))hThreadHandle.start()

这句代码里面 byref(data_buf) 这个参数 如果直接使用会让opencv程序报错。 应为opencv 的数据格式 是 int 型的不是 浮点型。所以我们只要把 byref()去掉就不会报错了。

效果图。

图不太好看 没上镜头。好了 言归正传。解决了 opencv读取相机的问题 那么我们就要把视频流在pyqt 中去实时显示了

pyqt5 opencv 动态显示相机视频流

下面我们用Qt Designer 创建一个ui界面,界面包括相机选取列表,显示label,打开相机按钮,关闭相机按钮,界面如下:

然后我们在程序启动的时候就必须读取所有 海康gigie 的相机列表。所以我们需要从上面的 sdk sample里面找出相机列表的相关代码 编辑成一个函数SelectDevice()

    #获得所有相机的列表存入cmbSelectDevice中def SelectDevice(self):'''选择所有能用的相机到列表中,gige相机需要配合 sdk 得到。'''#得到相机列表tlayerType = MV_GIGE_DEVICE | MV_USB_DEVICE# ch:枚举设备 | en:Enum deviceret = MvCamera.MV_CC_EnumDevices(tlayerType, self.deviceList)if ret != 0:print("enum devices fail! ret[0x%x]" % ret)sys.exit()if self.deviceList.nDeviceNum == 0:print("find no device!")sys.exit()print("Find %d devices!" % self.deviceList.nDeviceNum)for i in range(0, self.deviceList.nDeviceNum):mvcc_dev_info = cast(self.deviceList.pDeviceInfo[i], POINTER(MV_CC_DEVICE_INFO)).contentsif mvcc_dev_info.nTLayerType == MV_GIGE_DEVICE:print("\ngige device: [%d]" % i)strModeName = ""for per in mvcc_dev_info.SpecialInfo.stGigEInfo.chModelName:strModeName = strModeName + chr(per)print("device model name: %s" % strModeName)self.camSelect.addItem(strModeName,i) #写入设备列表。

然后在ui初始化的时候 创建一个自定义信号连接槽函数。执行读取相机列表。

    sendAddDeviceName = pyqtSignal() #定义一个添加设备列表的信号。def connect_and_emit_sendAddDeviceName(self):# Connect the sendAddDeviceName signal to a slot.self.sendAddDeviceName.connect(self.SelectDevice)# Emit the signal.self.sendAddDeviceName.emit()def __init__(self):super(mywindow, self).__init__()self.setupUi(self)self.connect_and_emit_sendAddDeviceName()

这样就读取了系统已连接的所有gige相机的列表。

然后给打开按钮和关闭相机按钮点击事件信号连接曹函数。

    def __init__(self):super(mywindow, self).__init__()self.setupUi(self)self.connect_and_emit_sendAddDeviceName()self.butopenCam.clicked.connect(lambda:self.openCam(self.camSelect.currentData()))self.butcloseCam.clicked.connect(self.closeCam)

然后通过更改SDK 编辑 openCam 和 closeCam 两个曹函数

    #打开摄像头。def openCam(self,camid):self.g_bExit = False# ch:选择设备并创建句柄 | en:Select device and create handlestDeviceList = cast(self.deviceList.pDeviceInfo[int(camid)], POINTER(MV_CC_DEVICE_INFO)).contentsret = self.cam.MV_CC_CreateHandle(stDeviceList)if ret != 0:print("create handle fail! ret[0x%x]" % ret)sys.exit()# ch:打开设备 | en:Open deviceret = self.cam.MV_CC_OpenDevice(MV_ACCESS_Exclusive, 0)if ret != 0:print("open device fail! ret[0x%x]" % ret)sys.exit()# ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal package size(It only works for the GigE camera)if stDeviceList.nTLayerType == MV_GIGE_DEVICE:nPacketSize = self.cam.MV_CC_GetOptimalPacketSize()if int(nPacketSize) > 0:ret = self.cam.MV_CC_SetIntValue("GevSCPSPacketSize", nPacketSize)if ret != 0:print("Warning: Set Packet Size fail! ret[0x%x]" % ret)else:print("Warning: Get Packet Size fail! ret[0x%x]" % nPacketSize)# ch:设置触发模式为off | en:Set trigger mode as offret = self.cam.MV_CC_SetEnumValue("TriggerMode", MV_TRIGGER_MODE_OFF)if ret != 0:print("set trigger mode fail! ret[0x%x]" % ret)sys.exit()# ch:获取数据包大小 | en:Get payload sizestParam = MVCC_INTVALUE()memset(byref(stParam), 0, sizeof(MVCC_INTVALUE))ret = self.cam.MV_CC_GetIntValue("PayloadSize", stParam)if ret != 0:print("get payload size fail! ret[0x%x]" % ret)sys.exit()nPayloadSize = stParam.nCurValue# ch:开始取流 | en:Start grab imageret = self.cam.MV_CC_StartGrabbing()if ret != 0:print("start grabbing fail! ret[0x%x]" % ret)sys.exit()data_buf = (c_ubyte * nPayloadSize)()try:hThreadHandle = threading.Thread(target=self.work_thread, args=(self.cam, data_buf, nPayloadSize))hThreadHandle.start()except:print("error: unable to start thread")

函数的参数 camid 是选择的相机的编号。通过读取 UI控件camSelect来得到。

self.camSelect.currentData()

这个我在编辑的时候遇到了一个问题困扰了半天。就是在pyqt5里面 带参数传入的曹函数连接 一定需要使用lambda语句所以连接曹函数的语句就需要写成

self.butopenCam.clicked.connect(lambda:self.openCam(self.camSelect.currentData()))

下面是关闭相机的曹函数。

    #关闭相机def closeCam(self):self.g_bExit=True# ch:停止取流 | en:Stop grab imageret = self.cam.MV_CC_StopGrabbing()if ret != 0:print("stop grabbing fail! ret[0x%x]" % ret)sys.exit()# ch:关闭设备 | Close deviceret = self.cam.MV_CC_CloseDevice()if ret != 0:print("close deivce fail! ret[0x%x]" % ret)# ch:销毁句柄 | Destroy handleret = self.cam.MV_CC_DestroyHandle()if ret != 0:print("destroy handle fail! ret[0x%x]" % ret)

实现了相机的打开与关闭那么我们就要实现 最重要的 主体图像显示线程函数了。

   def work_thread(self,cam=0, pData=0, nDataSize=0):stFrameInfo = MV_FRAME_OUT_INFO_EX()memset(byref(stFrameInfo), 0, sizeof(stFrameInfo))while True:QIm = np.asarray(pData)  # 将c_ubyte_Array转化成ndarray得到(3686400,)QIm = QIm.reshape((2048, 3072, 1))  # 根据自己分辨率进行转化# print(temp)# print(temp.shape)QIm = cv2.cvtColor(QIm, cv2.COLOR_BGR2RGB)  # 这一步获取到的颜色不对,因为默认是BRG,要转化成RGB,颜色才正常pyrD1=cv2.pyrDown(QIm) #向下取样pyrD2 = cv2.pyrDown(pyrD1)  # 向下取样image_height, image_width, image_depth = pyrD2.shape  # 读取图像高宽深度#QIm = cv2.cvtColor(QIm, cv2.COLOR_BGR2RGB)pyrD3 = QImage(pyrD2, image_width, image_height,  image_width * image_depth,QImage.Format_RGB888)self.label.setPixmap(QPixmap.fromImage(pyrD3))#cv2.namedWindow("result", cv2.WINDOW_AUTOSIZE)#cv2.imshow("result", temp)#if cv2.waitKey(1) & 0xFF == ord('q'):#    breakret = cam.MV_CC_GetOneFrameTimeout(pData, nDataSize, stFrameInfo, 1000)if ret == 0:print("get one frame: Width[%d], Height[%d], nFrameNum[%d]" % (stFrameInfo.nWidth, stFrameInfo.nHeight, stFrameInfo.nFrameNum))else:print("no data[0x%x]" % ret)if self.g_bExit == True:del pDatabreak

在前文中我们已经学习了如何在pyqt5的窗口中显示 opencv 图像。那么我们要把显示图像的功能中加入 相机sdk读取数据流后显示到ui的功能。前文中已经读取了数据流并显示在了 opencv的窗口中,而这里我们只要把数据作为窗体控件label 的背景显示出来就行了

            QIm = cv2.cvtColor(QIm, cv2.COLOR_BGR2RGB)  # 这一步获取到的颜色不对,因为默认是BRG,要转化成RGB,颜色才正常pyrD1=cv2.pyrDown(QIm) #向下取样pyrD2 = cv2.pyrDown(pyrD1)  # 向下取样image_height, image_width, image_depth = pyrD2.shape  # 读取图像高宽深度pyrD3 = QImage(pyrD2, image_width, image_height,  image_width * image_depth,QImage.Format_RGB888)self.label.setPixmap(QPixmap.fromImage(pyrD3))

这些代码里由于取得的图样太大所有我们对其进行了缩小,使用的是 金字塔向下取样。

这样我们整个程序就完成了。可以在pyqt5 中实现海康Gige相机的实时视频了

全部源码:

# -*- coding: utf-8 -*-# Form implementation generated from reading ui file 'mainWindow.ui'
#
# Created by: PyQt5 UI code generator 5.15.0
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_MainWindow(object):def setupUi(self, MainWindow):MainWindow.setObjectName("MainWindow")MainWindow.resize(589, 530)self.centralwidget = QtWidgets.QWidget(MainWindow)self.centralwidget.setObjectName("centralwidget")self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)self.verticalLayout.setObjectName("verticalLayout")self.camSelect = QtWidgets.QComboBox(self.centralwidget)self.camSelect.setObjectName("camSelect")self.verticalLayout.addWidget(self.camSelect)self.label = QtWidgets.QLabel(self.centralwidget)self.label.setObjectName("label")self.verticalLayout.addWidget(self.label)self.butopenCam = QtWidgets.QPushButton(self.centralwidget)self.butopenCam.setObjectName("butopenCam")self.verticalLayout.addWidget(self.butopenCam)self.butcloseCam = QtWidgets.QPushButton(self.centralwidget)self.butcloseCam.setObjectName("butcloseCam")self.verticalLayout.addWidget(self.butcloseCam)MainWindow.setCentralWidget(self.centralwidget)self.menubar = QtWidgets.QMenuBar(MainWindow)self.menubar.setGeometry(QtCore.QRect(0, 0, 589, 23))self.menubar.setObjectName("menubar")MainWindow.setMenuBar(self.menubar)self.statusbar = QtWidgets.QStatusBar(MainWindow)self.statusbar.setObjectName("statusbar")MainWindow.setStatusBar(self.statusbar)self.retranslateUi(MainWindow)QtCore.QMetaObject.connectSlotsByName(MainWindow)def retranslateUi(self, MainWindow):_translate = QtCore.QCoreApplication.translateMainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))self.label.setText(_translate("MainWindow", "TextLabel"))self.butopenCam.setText(_translate("MainWindow", "打开相机"))self.butcloseCam.setText(_translate("MainWindow", "关闭相机"))

这是UI窗口类

# -- coding: utf-8 --
import cv2
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtGui import *
import numpy as npfrom MvImport.MvCameraControl_header import MV_CC_DEVICE_INFO_LIST
from mainWindow import Ui_MainWindow  # 导入创建的GUI类
import sys
import threading
import msvcrt
from ctypes import *
sys.path.append("./MvImport")
from MvCameraControl_class import *class mywindow(QtWidgets.QMainWindow, Ui_MainWindow):sendAddDeviceName = pyqtSignal() #定义一个添加设备列表的信号。deviceList = MV_CC_DEVICE_INFO_LIST()g_bExit = False# ch:创建相机实例 | en:Creat Camera Objectcam = MvCamera()def connect_and_emit_sendAddDeviceName(self):# Connect the sendAddDeviceName signal to a slot.self.sendAddDeviceName.connect(self.SelectDevice)# Emit the signal.self.sendAddDeviceName.emit()def __init__(self):super(mywindow, self).__init__()self.setupUi(self)self.connect_and_emit_sendAddDeviceName()self.butopenCam.clicked.connect(lambda:self.openCam(self.camSelect.currentData()))self.butcloseCam.clicked.connect(self.closeCam)# setting main window geometrydesktop_geometry = QtWidgets.QApplication.desktop()  # 获取屏幕大小main_window_width = desktop_geometry.width()  # 屏幕的宽main_window_height = desktop_geometry.height()  # 屏幕的高rect = self.geometry()  # 获取窗口界面大小window_width = rect.width()  # 窗口界面的宽window_height = rect.height()  # 窗口界面的高x = (main_window_width - window_width) // 2  # 计算窗口左上角点横坐标y = (main_window_height - window_height) // 2  # 计算窗口左上角点纵坐标self.setGeometry(x, y, window_width, window_height)  # 设置窗口界面在屏幕上的位置# 无边框以及背景透明一般不会在主窗口中用到,一般使用在子窗口中,例如在子窗口中显示gif提示载入信息等等# self.setWindowFlags(Qt.FramelessWindowHint)# self.setAttribute(Qt.WA_TranslucentBackground)#打开摄像头。def openCam(self,camid):self.g_bExit = False# ch:选择设备并创建句柄 | en:Select device and create handlestDeviceList = cast(self.deviceList.pDeviceInfo[int(camid)], POINTER(MV_CC_DEVICE_INFO)).contentsret = self.cam.MV_CC_CreateHandle(stDeviceList)if ret != 0:print("create handle fail! ret[0x%x]" % ret)sys.exit()# ch:打开设备 | en:Open deviceret = self.cam.MV_CC_OpenDevice(MV_ACCESS_Exclusive, 0)if ret != 0:print("open device fail! ret[0x%x]" % ret)sys.exit()# ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal package size(It only works for the GigE camera)if stDeviceList.nTLayerType == MV_GIGE_DEVICE:nPacketSize = self.cam.MV_CC_GetOptimalPacketSize()if int(nPacketSize) > 0:ret = self.cam.MV_CC_SetIntValue("GevSCPSPacketSize", nPacketSize)if ret != 0:print("Warning: Set Packet Size fail! ret[0x%x]" % ret)else:print("Warning: Get Packet Size fail! ret[0x%x]" % nPacketSize)# ch:设置触发模式为off | en:Set trigger mode as offret = self.cam.MV_CC_SetEnumValue("TriggerMode", MV_TRIGGER_MODE_OFF)if ret != 0:print("set trigger mode fail! ret[0x%x]" % ret)sys.exit()# ch:获取数据包大小 | en:Get payload sizestParam = MVCC_INTVALUE()memset(byref(stParam), 0, sizeof(MVCC_INTVALUE))ret = self.cam.MV_CC_GetIntValue("PayloadSize", stParam)if ret != 0:print("get payload size fail! ret[0x%x]" % ret)sys.exit()nPayloadSize = stParam.nCurValue# ch:开始取流 | en:Start grab imageret = self.cam.MV_CC_StartGrabbing()if ret != 0:print("start grabbing fail! ret[0x%x]" % ret)sys.exit()data_buf = (c_ubyte * nPayloadSize)()try:hThreadHandle = threading.Thread(target=self.work_thread, args=(self.cam, data_buf, nPayloadSize))hThreadHandle.start()except:print("error: unable to start thread")#关闭相机def closeCam(self):self.g_bExit=True# ch:停止取流 | en:Stop grab imageret = self.cam.MV_CC_StopGrabbing()if ret != 0:print("stop grabbing fail! ret[0x%x]" % ret)sys.exit()# ch:关闭设备 | Close deviceret = self.cam.MV_CC_CloseDevice()if ret != 0:print("close deivce fail! ret[0x%x]" % ret)# ch:销毁句柄 | Destroy handleret = self.cam.MV_CC_DestroyHandle()if ret != 0:print("destroy handle fail! ret[0x%x]" % ret)def work_thread(self,cam=0, pData=0, nDataSize=0):stFrameInfo = MV_FRAME_OUT_INFO_EX()memset(byref(stFrameInfo), 0, sizeof(stFrameInfo))while True:QIm = np.asarray(pData)  # 将c_ubyte_Array转化成ndarray得到(3686400,)QIm = QIm.reshape((2048, 3072, 1))  # 根据自己分辨率进行转化# print(temp)# print(temp.shape)QIm = cv2.cvtColor(QIm, cv2.COLOR_BGR2RGB)  # 这一步获取到的颜色不对,因为默认是BRG,要转化成RGB,颜色才正常pyrD1=cv2.pyrDown(QIm) #向下取样pyrD2 = cv2.pyrDown(pyrD1)  # 向下取样image_height, image_width, image_depth = pyrD2.shape  # 读取图像高宽深度pyrD3 = QImage(pyrD2, image_width, image_height,  image_width * image_depth,QImage.Format_RGB888)self.label.setPixmap(QPixmap.fromImage(pyrD3))#cv2.namedWindow("result", cv2.WINDOW_AUTOSIZE)#cv2.imshow("result", temp)#if cv2.waitKey(1) & 0xFF == ord('q'):#    breakret = cam.MV_CC_GetOneFrameTimeout(pData, nDataSize, stFrameInfo, 1000)if ret == 0:print("get one frame: Width[%d], Height[%d], nFrameNum[%d]" % (stFrameInfo.nWidth, stFrameInfo.nHeight, stFrameInfo.nFrameNum))else:print("no data[0x%x]" % ret)if self.g_bExit == True:del pDatabreak#获得所有相机的列表存入cmbSelectDevice中def SelectDevice(self):'''选择所有能用的相机到列表中,gige相机需要配合 sdk 得到。'''#得到相机列表tlayerType = MV_GIGE_DEVICE | MV_USB_DEVICE# ch:枚举设备 | en:Enum deviceret = MvCamera.MV_CC_EnumDevices(tlayerType, self.deviceList)if ret != 0:print("enum devices fail! ret[0x%x]" % ret)sys.exit()if self.deviceList.nDeviceNum == 0:print("find no device!")sys.exit()print("Find %d devices!" % self.deviceList.nDeviceNum)for i in range(0, self.deviceList.nDeviceNum):mvcc_dev_info = cast(self.deviceList.pDeviceInfo[i], POINTER(MV_CC_DEVICE_INFO)).contentsif mvcc_dev_info.nTLayerType == MV_GIGE_DEVICE:print("\ngige device: [%d]" % i)strModeName = ""for per in mvcc_dev_info.SpecialInfo.stGigEInfo.chModelName:strModeName = strModeName + chr(per)print("device model name: %s" % strModeName)self.camSelect.addItem(strModeName,i) #写入设备列表。def pushbutton_function(self):#do some thingsImg=cv2.imread('JP1.JPG') #通过opencv读入一张图片image_height, image_width, image_depth=Img.shape #读取图像高宽深度QIm=cv2.cvtColor(Img,cv2.COLOR_BGR2RGB)QIm=QImage(QIm.data, image_width, image_height,  image_width * image_depth,QImage.Format_RGB888)self.label.setPixmap(QPixmap.fromImage(QIm))if __name__ == '__main__':app = QtWidgets.QApplication(sys.argv)window = mywindow()window.show()sys.exit(app.exec_())

以上是主程序。

pyQT5 学习使用 笔记 六 pyQt5+opencv 显示海康GIGE相机动态视频流相关推荐

  1. ubuntu 使用opencv 获取海康网络摄像头视频流

    1. 前言 之前在windows平台下使用opencv获取海康网络摄像头的视频流,但是不管怎么设置都无法登录摄像头,导致无法获取摄像头的视频流,但是换到ubuntu又正常了,主要是设置rtsp的格式, ...

  2. (一)Qt+OpenCV调用海康工业相机SDK示例开发

    系列文章目录 提示:这里是该系列文章的所有文章的目录 第一章: (一)Qt+OpenCV调用海康工业相机SDK示例开发 第二章: (二)Qt多线程实现海康工业相机图像实时采集 文章目录 系列文章目录 ...

  3. 浏览器显示海康摄像头实时预览画面纯前端解决方案

    浏览器显示海康摄像头实时预览画面纯前端解决方案 将海康设备的 rtsp 协议视频流通过 ffmpeg 转码为 flv 实时视频流,并将实时视频流通过 express 服务生成 http 长链接或 ws ...

  4. C++下OPENCV驱动调用海康GigE工业相机

    系列文章目录 第一章 Ubuntu22下OpenCV4.6.0+contrib模块编译安装 第二章 ubuntu22下C++ kdevelop环境搭建:OpenCV示例 第三章 C++下OPENCV驱 ...

  5. QT+opencv调用海康工业相机

    这里写自定义目录标题 QT+opencv调用海康工业相机 开发环境 引用海康开发文件 直接上代码 QT+opencv调用海康工业相机 最近在使用Opencv调用海康工业相机的程序,从网上查了好多资料, ...

  6. 海康威视工业相机SDK二次开发(VS+Opencv+QT+海康SDK+C++)(一)

    最近在做一个项目,涉及到工业相机,需要对其进行二次开发.相机方面选择了海康威视,网上关于海康威视工业相机SDK的开发资料很少,官方文档里面虽然写的是支持C++开发的,但其实是C.自己也摸索了一段时间, ...

  7. Emgucv不完整图像分割试验(十八)——Emgucv或opencv连接海康/萤石网络4G摄像头

    项目需要远程连摄像头,之前也一直觉得这事挺简单的,opencv有教程也平时很多地方见过这样的操作,没想到实践起来蛮多坑的. 1.首先确定摄像头支不支持4G或WIFI,尽量选海康萤石这种大厂,资料较多. ...

  8. Python下Opencv尝试调用海康GIGE工业相机

    环境 一.相机型号(海康): HIKVison MV-CE013-50GC 二.win10 x86_64 三.Python3.6.5.OpenCV3.4 四.需要结合海康SDK 拿到的童鞋,估计要慌了 ...

  9. 学习笔记:使用opencv做双目测距(相机标定+立体匹配+测距).

    装载:https://www.cnblogs.com/daihengchen/p/5492729.html 最近在做双目测距,觉得有必要记录点东西,所以我的第一篇博客就这么诞生啦~ 双目测距属于立体视 ...

最新文章

  1. OpenCV cv::split用法的实例(附完整代码)
  2. 克隆可序列化和不可序列化的Java对象
  3. html5 内嵌网页_如何分析并优化网页的性能?新梦想软件测试
  4. oracle静默文件建库,【配置上线】Oracle静默建库 for 11g
  5. Qt文档阅读笔记-数据驱动测试
  6. 亚信java在线测评题库_校招秋招,网申在线测评如何训练才能通过?
  7. 中级联选择中多级选择方法使用_PCB加工中,使用选择性波峰焊的优缺点是什么?...
  8. Android开发笔记(十)常用的图片加工操作
  9. php持续交付,持续交付概述
  10. 什么是平板电脑的杀手锏?
  11. 【纪念】我的大学同学名单
  12. python3.4.3如何获取文件的路径
  13. 7.Kong入门与实战 基于Nginx和OpenResty的云原生微服务网关 --- 日志收集与分析
  14. 学习webpack系列之三 ---- (输出管理)
  15. mysql后台数据库学习报告
  16. php模拟QQ登录获得skey码,PHP模拟QQ网页版授权登陆
  17. 数据库应用——MySQL集群
  18. 零基础学习资料(建议收藏)
  19. java实现掌阅Ireader签到领取阅饼
  20. 希尔伯特曲线的绘制c语言,[转载]希尔伯特曲线及其matlab画法

热门文章

  1. 微信公众号 授权死循环 问题解决
  2. “50份简历没获得面试”也正常
  3. 小程序SetTimeOut的一个坑
  4. 网络IO Socket
  5. ios 界面开发_iOS开发新手指南:界面-第一部分
  6. Excel常用函数记录
  7. 解决锐捷客户端登陆时网卡网关配置有误的方法
  8. MYSQL获取当前时间、前一天时间,前一个月时间
  9. 动态改变UITableView中的Cell高度
  10. 怎样吸引零售行业客流?