python 调用海康工业相机图像获取方式之主动取流(getoneframetimeout )并用 opencv 显示

系列文章目录

第一章 python调用海康工业相机并用opencv显示(整体实现)

第二章 python 调用海康工业相机图像获取方式之回调取流并用 opencv 显示

第三章 python 调用海康工业相机图像获取方式之主动取流(getoneframetimeout )并用 opencv 显示

第四章 python 调用海康工业相机图像获取方式之主动取流( getimagebuffer )并用 opencv 显示

第五章 python 调用海康工业相机调试后出现被占用问题


 


前言

海康工业相机的底层SDK中提供了两种不同方式的图像数据获取方式,一种是回调方式,一种是主动取流方式。但是官方示例中,只提供了相关数据获取到之后的打印信息,对于图像数据的解析并没有给出,基于以上情况,本文对主动取流方式(getoneframetimeout )获取到的图像数据进行解析。


一、使用前提

需要先安装海康工业相机的底层SDK,在安装之后,会有相关例程在安装目录下,本文的代码调用需要在该目录下调用(未作移植使用);

基于第一章(python调用海康工业相机并用opencv显示)对于海康工业相机连接的内容,本文对于海康工业相机的主动取流方式(getoneframetimeout )取到的图像解析进行说明。

二、主动取流(官方例程说明)

1.接口说明

在海康提供的底层SDK中,有相关主动取流之 getoneframetimeout 取流的接口,并且在安装目录下的工业相机SDK开发指南中,有对该接口的具体介绍,具体如下:

接口:MV_CC_GetOneFrameTimeout()

对应于 C 语言接口如下:

MV_CAMCTRL_API int __stdcall MV_CC_GetOneFrameTimeout  ( IN void *  handle,  
                                                         IN OUT unsigned char *  pData,  
                                                         IN unsigned int  nDataSize,  
                                                         IN OUT MV_FRAME_OUT_INFO_EX *  pstFrameInfo,  
                                                         unsigned int  nMsec  
                                                       ) 

参数:

。handle :设备句柄

。pData :图像数据接收指针

。nDataSize :接收缓存大小

。pstFrameInfo : 图像信息结构体

。nMsec :等待超时时间

返回:

。调用成功,返回 MV_OK

。调用失败,返回错误码

注: 

     1、通过该接口可以设置图像数据回调函数,需要在 MV_CC_StarGrabbing() 接口之后设置使用,该接口为主动式获取帧数据,上层应用程序需要根据帧率,控制好调用该接口的频率。该接口支持设置超时时间,SDK内部等待直到有数据时返回,可以增加取流平稳性,适合用于对平稳性要求较高的场合。

     2、该接口不支持 Cameralink 设备,仅支持 GigE 、USB 设备;

    3、该接口的图像缓存是由我们自己去申请;

2.python 下接口实现

(1) 根据以上说明可知,MV_CC_GetOneFrameTimeout()接口需要在开始采集图像接口调用之后使用,即官方历程中的该接口调用,如下:

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:
                break

(2)在开启取流之后,通过该接口主动去抓取 SDK 底层的 buffer 中的图像数据和信息,通过该接口,可以将图像数据给到我们,但是官方例程中,并没有提供相关数据解析和显示的相关内容,这样就导致我们在此环节需要重新开发,本文第三部分将对图像数据的解析和显示做相关的代码实现;

三、主动取流( getoneframetimeout )对黑白图像数据解析并用 opencv 显示

1.主动取流( getoneframetimeout )数据获取并解析 mono 格式的图像数据

def work_thread(cam=0, pData=0, nDataSize=0 , name = 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))
            image = np.asarray(pData).reshape((stFrameInfo.nHeight, stFrameInfo.nWidth))
            cv2.imshow("show", image)
            k = cv2.waitKey(1) & 0xff
        else:
            print ("no data[0x%x]" % ret)
        if g_bExit == True:
                break

通过对官方例程中回调获取图像数据的代码修改,获取到相关图像的数据,如上代码中 data 即为该接口获取到的图像数据,并通过对图像数据进行 reshape 操作,最终实现显示;

四、主动取流( getoneframetimeout )获取多种像素格式的图像数据解析并用 opencv 显示

1.主动取流( getoneframetimeout )数据获取并解析多种像素格式的数据

基于第一章(python调用海康工业相机并用opencv显示)中,对于常用接口的封装,getoneframetimeout 也进行相关内容的封装,将该接口获取的图像数据解析部分封装为一体,获取图像部分具体代码如下所示:

    elif active_way == "getoneframetimeout":
        stParam = MVCC_INTVALUE_EX()
        memset(byref(stParam), 0, sizeof(MVCC_INTVALUE_EX))
        ret = cam.MV_CC_GetIntValueEx("PayloadSize", stParam)
        if ret != 0:
            print("get payload size fail! ret[0x%x]" % ret)
            sys.exit()
        nDataSize = stParam.nCurValue
        pData = (c_ubyte * nDataSize)()
        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))
                image = np.asarray(pData)
                image_control(data=image, stFrameInfo=stFrameInfo)
            else:
                print("no data[0x%x]" % ret)

通过以上方式,将获取到的图像数据整块的获取到,获取到之后通过自定义韩式 image_control() 函数,将不同格式的图像数据分别进行通道转换,转换为可以被 opencv 显示的格式;

2.图像数据显示

有以上内容可知,获取到的图像数据块可能是多种像素格式类型的,不同的像素格式类型图像通道不同,不同的通道转换成 opencv 可以显示的格式转换方式不同,以下内容是对不同像素格式类型的图像数据的显示,代码如下:

# 显示图像
def image_show(image):
    image = cv2.resize(image, (600, 400), interpolation=cv2.INTER_AREA)
    cv2.imshow('fgmask', image)
    k = cv2.waitKey(1) & 0xff

# 需要显示的图像数据转换
def image_control(data , stFrameInfo):
    if stFrameInfo.enPixelType == 17301505:
        image = data.reshape((stFrameInfo.nHeight, stFrameInfo.nWidth))
        image_show(image=image)
    elif stFrameInfo.enPixelType == 17301514:
        data = data.reshape(stFrameInfo.nHeight, stFrameInfo.nWidth, -1)
        image = cv2.cvtColor(data, cv2.COLOR_BAYER_GB2RGB)
        image_show(image=image)
    elif stFrameInfo.enPixelType == 35127316:
        data = data.reshape(stFrameInfo.nHeight, stFrameInfo.nWidth, -1)
        image = cv2.cvtColor(data, cv2.COLOR_RGB2BGR)
        image_show(image=image)
    elif stFrameInfo.enPixelType == 34603039:
        data = data.reshape(stFrameInfo.nHeight, stFrameInfo.nWidth, -1)
        image = cv2.cvtColor(data, cv2.COLOR_YUV2BGR_Y422)
        image_show(image = image)

可以看到不同的通道数,对应不同的数据转换,最终将图像显示在桌面上;


总结

在工业相机的使用中,getoneframetimeout 获取到的图像数据如何解析,相对比较重要,以上是对海康工业相机 python 下调用 getoneframetimeout 接口获取到的图像数据的解析;由于现阶段大部分工业相机的SDK底层是以 C 语言和 C# 为主要语言,所以 python 的调用,就选择了使用 C 语言为基础的接口转换后的 python 接口来调用相机,而这种方式在工业界相对比较常见。

  • 13
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
以下是使用PythonOpenCV调用海康工业相机显示的步骤: 1.安装海康SDK并配置环境变量。 2.安装PythonOpenCV。 3.导入必要的库和模块。 ```python import sys from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QVBoxLayout import cv2 from HCNetSDK import * ``` 4.创建一个Qt窗口并在其中添加一个标签。 ```python class Video(QWidget): def __init__(self): super().__init__() self.label = QLabel(self) self.layout = QVBoxLayout() self.layout.addWidget(self.label) self.setLayout(self.layout) ``` 5.初始化海康SDK并登录相机。 ```python def init_camera(): # 初始化SDK if not NET_DVR_Init(): print("SDK初始化失败") sys.exit() # 登录相机 device_info = NET_DVR_DEVICEINFO_V30() device_ip = "192.168.1.64" device_port = 8000 device_username = "admin" device_password = "12345" device_id = NET_DVR_Login_V30(device_ip, device_port, device_username, device_password, device_info) if device_id < 0: print("登录相机失败") sys.exit() return device_id ``` 6.获取相机数据并将其转换为OpenCV支持的格式。 ```python def get_frame(device_id): # 获取相机数据 frame = NET_DVR_GetRealPlayImage(device_id) # 将相机数据转换为OpenCV支持的格式 frame_data = frame.contents.pBuffer frame_size = frame.contents.dwSize frame_image = np.frombuffer(frame_data, dtype=np.uint8) frame_image = frame_image.reshape((frame_size[1], frame_size[0], 4)) frame_image = cv2.cvtColor(frame_image, cv2.COLOR_BGRA2BGR) return frame_image ``` 7.在Qt窗口中显示相机数据。 ```python def show_camera(): app = QApplication(sys.argv) video = Video() video.show() device_id = init_camera() while True: frame_image = get_frame(device_id) frame_image = cv2.resize(frame_image, (640, 480)) frame_image = cv2.cvtColor(frame_image, cv2.COLOR_BGR2RGB) video.label.setPixmap(QPixmap.fromImage(QImage(frame_image.data, frame_image.shape[1], frame_image.shape[0], QImage.Format_RGB888))) if cv2.waitKey(1) & 0xFF == ord('q'): break NET_DVR_Logout(device_id) NET_DVR_Cleanup() sys.exit(app.exec_()) ``` 8.运行程序并显示相机数据。 ```python if __name__ == '__main__': show_camera() ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值