Haikang industrial camera Python+OpenCV call to achieve streaming

foreword

With the continuous in-depth development of the language python, it has become a popular demand for python to call industrial cameras;
this article will simply sort out the use of python for Hikvision industrial cameras

reference link

I moved some well-written articles for reference.
Introduction to Hikrobotics Industrial Camera SDK.
Python language calls Hikrobotics industrial cameras.
Use python plus opencv to interact with Hikrobotics industrial cameras.
Hikvision industrial camera parameter setting and acquisition

environment settings

  1. Install MVS first, the download address is the official website of Haikang Robotics , you can also see the reference blog above for the introduction of SDK
  2. Condition: Python+ the python folder under development/samples under the official mvs file of Haikang
  3. Note: Do not use the official app to open the camera after the camera is connected, otherwise the python code will not detect the device, and the code will prompt an error in pycharm, and the personal test can run and capture pictures (this means that the camera should not be occupied by other software links, At the same time, a camera can only be linked by one software)
  4. The path of the module MvImport needs to be added: This is the core of the entire code. The contents of the file are as follows. For details, you can download the routines in MVS:
import sys
sys.path.append("C:\Program Files (x86)\MVS\Development\Samples\Python\MvImport")

insert image description here

Camera Control and Data Acquisition

We can divide the industrial camera sdk call into two parts, camera control and image data acquisition
1. Camera control
Refer to the flow chart provided by its SDK, we can see that camera control is divided into enumeration, opening, parameter setting, closing, and destroying the handle Five steps
insert image description here
, then call the corresponding python interface to achieve

  • enumerate cameras
# ch:枚举设备 | en:Enum device
    ret = MvCamera.MV_CC_EnumDevices(tlayerType, deviceList)
    if ret != 0:
        print ("enum devices fail! ret[0x%x]" % ret)
        sys.exit()
  • Turn on the camera
	ret = cam.MV_CC_CreateHandle(stDeviceList)
    if ret != 0:
        print ("create handle fail! ret[0x%x]" % ret)
        sys.exit()
    # ch:打开设备 | en:Open device
    ret = cam.MV_CC_OpenDevice(MV_ACCESS_Exclusive, 0)
    if ret != 0:
        print ("open device fail! ret[0x%x]" % ret)
        sys.exit()
  # ch:设置触发模式为off | en:Set trigger mode as off
    ret = cam.MV_CC_SetEnumValue("TriggerMode", MV_TRIGGER_MODE_OFF)
    if ret != 0:
        print ("set trigger mode fail! ret[0x%x]" % ret)
        sys.exit()
  • turn off the camera
   # ch:停止取流 | en:Stop grab image
    ret = cam.MV_CC_StopGrabbing()
    if ret != 0:
        print ("stop grabbing fail! ret[0x%x]" % ret)
        sys.exit()

    # ch:关闭设备 | Close device
    ret = cam.MV_CC_CloseDevice()
    if ret != 0:
        print ("close deivce fail! ret[0x%x]" % ret)
        sys.exit()
  • destroy handle
    # ch:销毁句柄 | Destroy handle
    ret = cam.MV_CC_DestroyHandle()
    if ret != 0:
        print ("destroy handle fail! ret[0x%x]" % ret)
        sys.exit()

2. Image data acquisition
There are two ways to acquire image data. One is to refer to Grab_Callback.py and use the callback function to obtain it. The other is to refer to GrabImage and use the active streaming interface to obtain it. The two methods have different usage scenarios;
Take its official sample program Grab_Callback.py as an example. Its main purpose is in the callback function, the function interface data address pData, pData is a C*ubyte data type, there is no way to directly read it directly with python-opencv Take, that is, it cannot be directly converted into the form of numpy array

  • Callback
def image_callback(pData, pFrameInfo, pUser):
        stFrameInfo = cast(pFrameInfo, POINTER(MV_FRAME_OUT_INFO_EX)).contents
        if stFrameInfo:
            print ("get one frame: Width[%d], Height[%d], nFrameNum[%d]" % (stFrameInfo.nWidth, stFrameInfo.nHeight, stFrameInfo.nFrameNum))
CALL_BACK_FUN = FrameInfoCallBack(image_callback)
  • Active fetch function
	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))

Data format conversion

How to convert pdata to opencv data format?
The first step is to obtain image data. We can get the pdata pointer through the two different stream fetching functions introduced above, but pdata is a POINTER(c_ubyte)) type pointer, we need to convert it into asarray. The second step is to judge and convert the image format
. We need to know what image format the camera outputs pdata, and what format opencv can handle Haikang color industrial camera image format conversion method (Bayer to RGB)
black and white single channel is okay, color needs to be converted into BGR three-channel data
. Three steps, opencv display

 #实现GetImagebuffer函数取流,HIK格式转换函数
def work_thread_1(cam=0, pData=0, nDataSize=0):
    stFrameInfo = MV_FRAME_OUT_INFO_EX()
    memset(byref(stFrameInfo), 0, sizeof(stFrameInfo))
    print("work_thread_1!\n")
    img_buff = None
    while True:
        ret = cam.MV_CC_GetOneFrameTimeout(pData, nDataSize, stFrameInfo, 1000)
        if ret == 0:
            print ("MV_CC_GetOneFrameTimeout: Width[%d], Height[%d], nFrameNum[%d]"  % (stFrameInfo.nWidth, stFrameInfo.nHeight, stFrameInfo.nFrameNum))
            time_start = time.time()
            stConvertParam = MV_CC_PIXEL_CONVERT_PARAM()
            memset(byref(stConvertParam), 0, sizeof(stConvertParam))
            if IsImageColor(stFrameInfo.enPixelType) == 'mono':
                print("mono!")
                stConvertParam.enDstPixelType = PixelType_Gvsp_Mono8
                nConvertSize = stFrameInfo.nWidth * stFrameInfo.nHeight
            elif IsImageColor(stFrameInfo.enPixelType) == 'color':
                print("color!")
                stConvertParam.enDstPixelType = PixelType_Gvsp_BGR8_Packed  # opecv要用BGR,不能使用RGB
                nConvertSize = stFrameInfo.nWidth * stFrameInfo.nHeight* 3
            else:
                print("not support!!!")
            if img_buff is None:
                img_buff = (c_ubyte * stFrameInfo.nFrameLen)()
            # ---
            stConvertParam.nWidth = stFrameInfo.nWidth
            stConvertParam.nHeight = stFrameInfo.nHeight
            stConvertParam.pSrcData = cast(pData, POINTER(c_ubyte))
            stConvertParam.nSrcDataLen = stFrameInfo.nFrameLen
            stConvertParam.enSrcPixelType = stFrameInfo.enPixelType
            stConvertParam.pDstBuffer = (c_ubyte * nConvertSize)()
            stConvertParam.nDstBufferSize = nConvertSize
            ret = cam.MV_CC_ConvertPixelType(stConvertParam)
            if ret != 0:
                print("convert pixel fail! ret[0x%x]" % ret)
                del stConvertParam.pSrcData
                sys.exit()
            else:
                print("convert ok!!")
                # 转OpenCV
                # 黑白处理
                if IsImageColor(stFrameInfo.enPixelType) == 'mono':
                    img_buff = (c_ubyte * stConvertParam.nDstLen)()
                    cdll.msvcrt.memcpy(byref(img_buff), stConvertParam.pDstBuffer, stConvertParam.nDstLen)
                    img_buff = np.frombuffer(img_buff,count=int(stConvertParam.nDstLen), dtype=np.uint8)
                    img_buff = img_buff.reshape((stFrameInfo.nHeight, stFrameInfo.nWidth))
                    print("mono ok!!")
                    image_show(image=img_buff)  # 显示图像函数
                # 彩色处理
                if IsImageColor(stFrameInfo.enPixelType) == 'color':
                    img_buff = (c_ubyte * stConvertParam.nDstLen)()
                    cdll.msvcrt.memcpy(byref(img_buff), stConvertParam.pDstBuffer, stConvertParam.nDstLen)
                    img_buff = np.frombuffer(img_buff, count=int(stConvertParam.nDstBufferSize), dtype=np.uint8)
                    img_buff = img_buff.reshape(stFrameInfo.nHeight,stFrameInfo.nWidth,3)
                    print("color ok!!")
                    image_show(image=img_buff)  # 显示图像函数
                time_end = time.time()
                print('time cos:', time_end - time_start, 's') 
        else:
            print ("no data[0x%x]" % ret)
        if g_bExit == True:
                break
# 显示图像
def image_show(image):
    image = cv2.resize(image, (600, 400), interpolation=cv2.INTER_AREA)
    cv2.imshow('test', image)
    k = cv2.waitKey(1) & 0xff
# 判读图像格式是彩色还是黑白
def IsImageColor(enType):
    dates = {
    
    
        PixelType_Gvsp_RGB8_Packed: 'color',
        PixelType_Gvsp_BGR8_Packed: 'color',
        PixelType_Gvsp_YUV422_Packed: 'color',
        PixelType_Gvsp_YUV422_YUYV_Packed: 'color',
        PixelType_Gvsp_BayerGR8: 'color',
        PixelType_Gvsp_BayerRG8: 'color',
        PixelType_Gvsp_BayerGB8: 'color',
        PixelType_Gvsp_BayerBG8: 'color',
        PixelType_Gvsp_BayerGB10: 'color',
        PixelType_Gvsp_BayerGB10_Packed: 'color',
        PixelType_Gvsp_BayerBG10: 'color',
        PixelType_Gvsp_BayerBG10_Packed: 'color',
        PixelType_Gvsp_BayerRG10: 'color',
        PixelType_Gvsp_BayerRG10_Packed: 'color',
        PixelType_Gvsp_BayerGR10: 'color',
        PixelType_Gvsp_BayerGR10_Packed: 'color',
        PixelType_Gvsp_BayerGB12: 'color',
        PixelType_Gvsp_BayerGB12_Packed: 'color',
        PixelType_Gvsp_BayerBG12: 'color',
        PixelType_Gvsp_BayerBG12_Packed: 'color',
        PixelType_Gvsp_BayerRG12: 'color',
        PixelType_Gvsp_BayerRG12_Packed: 'color',
        PixelType_Gvsp_BayerGR12: 'color',
        PixelType_Gvsp_BayerGR12_Packed: 'color',
        PixelType_Gvsp_Mono8: 'mono',
        PixelType_Gvsp_Mono10: 'mono',
        PixelType_Gvsp_Mono10_Packed: 'mono',
        PixelType_Gvsp_Mono12: 'mono',
        PixelType_Gvsp_Mono12_Packed: 'mono'}
    return dates.get(enType, '未知')

Effect display:
color:
insert image description here
black and white:
insert image description here
sample program download: GrabImage.py

Guess you like

Origin blog.csdn.net/qq_23107577/article/details/113984935