海康工业相机Python调用实现连续实时拍照
前言:
海康的相机调用简直太复杂了。当然相比point gray fly的相机无法python调用要好很多。
为了将照片调用打包成类,我竟然花了两天时间?
这里做一个简单的记录。希望能给大伙儿一个分享。
参考链接:
海康工业相机Python调用实现拍照
通过python调用海康威视工业摄像头并进行图像存储(数据流获取问题未能解决)
提前设置:
- 先安装MVS,下载地址
- 条件:Python+海康官方的mvs文件下的development/samples下的python文件夹
- 注意:相机连接后不要用官方app打开相机,不然python代码检测不到设备,代码在pycharm会提示报错,亲测能跑并能截取到图片
- 需要添加模块MvImport的路径:
这是整个代码的核心,文件里面内容如下,具体可以下载MVS里面例程里面有:
import sys
sys.path.append("C:\Program Files (x86)\MVS\Development\Samples\Python\MvImport")
图片数据流的获取:
save_image2local
函数部分,主要是将C程序给过来的数据流进行了一个转换,仔细看保存的路径不难看出,img_buff就是我们想要的图像数据流。
但是我把它print出来的时候它仍然是一个C*ubyte的数据类型,所以没法直接用python-opencv进行直接读取,即不能直接转成numpy array的形式。
只能先将其存储下来然后再通过cv2进行读取来进行一系列图片操作。
file_path是我们图片存储的路径,可以自己更改。原本下面有一个输入a退出的按钮但没有反应,所以我删掉了它。
再到之后就是关闭数据流,关闭摄像头操作。因为博主没法直接读取数据流不能直接视频显示,没法得知这个数据是实时更新图像还是一次整体运行获取一次图像信息,所以我的方法是整体运行关闭一次采集一次数据,非常麻烦。
代码:
# -- coding: utf-8 --
from os import times
import cv2
import sys
import numpy as np
import time
from ctypes import *
sys.path.append("C:\Program Files (x86)\MVS\Development\Samples\Python\MvImport")
from MvCameraControl_class import *
class HHV:
def __init__(self,):
self.init_cam()
for i in range(10):
st = time.time()
img = self.get_image_array()
print(img.shape)
# cv2.imshow("img", img)
# cv2.waitKey(0)
# cv2.destroyAllWindows()
print("st:", time.time()-st)
self.exit_cam()
def get_image_array(self):
self.save_image2local(index=0)
img = cv2.imread("AfterConvert_RGB0.jpg")
return img
def init_cam(self,):
deviceList = MV_CC_DEVICE_INFO_LIST()
tlayerType = MV_GIGE_DEVICE | MV_USB_DEVICE
ret = MvCamera.MV_CC_EnumDevices(tlayerType, deviceList)
nConnectionNum = 0
# ch:创建相机实例 | en:Creat Camera Object
self.cam = MvCamera()
# ch:选择设备并创建句柄 | en:Select device and create handle
stDeviceList = cast(deviceList.pDeviceInfo[int(nConnectionNum)],
POINTER(MV_CC_DEVICE_INFO)).contents
ret = self.cam.MV_CC_CreateHandle(stDeviceList)
# ch:打开设备 | en:Open device
ret = self.cam.MV_CC_OpenDevice(MV_ACCESS_Exclusive, 0)
# ch:设置触发模式为off | en:Set trigger mode as off
ret = self.cam.MV_CC_SetEnumValue("TriggerMode", MV_TRIGGER_MODE_OFF)
# ch:获取数据包大小 | en:Get payload size
stParam = MVCC_INTVALUE()
memset(byref(stParam), 0, sizeof(MVCC_INTVALUE))
ret = self.cam.MV_CC_GetIntValue("PayloadSize", stParam)
self.nPayloadSize = stParam.nCurValue
def save_image2local(self, index=0):
# ch:开始取流 | en:Start grab image
ret = self.cam.MV_CC_StartGrabbing()
stDeviceList = MV_FRAME_OUT_INFO_EX()
memset(byref(stDeviceList), 0, sizeof(stDeviceList))
self.data_buf = (c_ubyte * self.nPayloadSize)()
ret = self.cam.MV_CC_GetOneFrameTimeout(byref(self.data_buf), self.nPayloadSize, stDeviceList, 1000)
if ret == 0:
# print ("get one frame: Width[%d], Height[%d], nFrameNum[%d]" % (stDeviceList.nWidth, stDeviceList.nHeight, stDeviceList.nFrameNum))
nRGBSize = stDeviceList.nWidth * stDeviceList.nHeight * 3
stConvertParam=MV_SAVE_IMAGE_PARAM_EX()
stConvertParam.nWidth = stDeviceList.nWidth
stConvertParam.nHeight = stDeviceList.nHeight
stConvertParam.pData = self.data_buf
stConvertParam.nDataLen = stDeviceList.nFrameLen
stConvertParam.enPixelType = stDeviceList.enPixelType
stConvertParam.nImageLen = stConvertParam.nDataLen
stConvertParam.nJpgQuality = 70
stConvertParam.enImageType = MV_Image_Jpeg
stConvertParam.pImageBuffer = (c_ubyte * nRGBSize)()
stConvertParam.nBufferSize = nRGBSize
# ret = self.cam.MV_CC_ConvertPixelType(stConvertParam)
# print(stConvertParam.nImageLen)
ret = self.cam.MV_CC_SaveImageEx2(stConvertParam)
if ret != 0:
print ("convert pixel fail ! ret[0x%x]" % ret)
del self.data_buf
sys.exit()
file_path = "AfterConvert_RGB"+str(index)+".jpg"
file_open = open(file_path.encode('ascii'), 'wb+')
img_buff = (c_ubyte * stConvertParam.nImageLen)()
cdll.msvcrt.memcpy(byref(img_buff), stConvertParam.pImageBuffer, stConvertParam.nImageLen)
file_open.write(img_buff)
# print ("Save Image succeed!")
def exit_cam(self,):
# ch:停止取流 | en:Stop grab image
ret = self.cam.MV_CC_StopGrabbing()
if ret != 0:
print ("stop grabbing fail! ret[0x%x]" % ret)
del self.data_buf
sys.exit()
# ch:关闭设备 | Close device
ret = self.cam.MV_CC_CloseDevice()
if ret != 0:
print ("close deivce fail! ret[0x%x]" % ret)
del self.data_buf
sys.exit()
# ch:销毁句柄 | Destroy handle
ret = self.cam.MV_CC_DestroyHandle()
if ret != 0:
print ("destroy handle fail! ret[0x%x]" % ret)
del self.data_buf
sys.exit()
del self.data_buf
if __name__ == "__main__":
hhv = HHV()