Article directory
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
- 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
- Condition: Python+ the python folder under development/samples under the official mvs file of Haikang
- 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)
- 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")
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
, 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()
- Parameter settings For
more parameter settings, you can go to see how the general interface is used Hikvision industrial camera parameter setting and acquisition
# 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:
black and white:
sample program download: GrabImage.py