> 技术文档 > python通过调用海康SDK打开工业相机(全流程)_海康工业相机sdk

python通过调用海康SDK打开工业相机(全流程)_海康工业相机sdk

首先打开海康机器人-机器视觉-下载中心

下载最新版的 MVS

安装后打开目录找到

...\\MVS\\Development\\Samples\\Python

将MvImport内所有文件拷贝至工作目录

然后到

C:\\Program Files (x86)\\Common Files\\MVS\\Runtime

找到适合自己系统的版本,将整个文件夹拷贝至工作目录,并重命名为lib,方便后期移植

完成上述操作后,工作目录是这样的:

打开MvCameraControl_class.py 找到

由于python3.8往后的版本导入动态链接库的机制发生了改变,因此这里时常会导入失败(2025-4-5)

因此需要更改为

*动态链接库的位置在刚刚更改名字的lib文件夹内,需根据实际情况做更改*

创建一个新的py文件(我的叫HKCamera.py)用于创建相机类,方便进行相机任务

在这个新的py文件中,创建一个类,用于创建句柄、开启流等操作

class Camera: #初始化 def __init__(self): ... #打开相机 def _open(self): ... #关闭相机 def _close(self): ... #获取图像数据 def get_img(self): ...

初始化中,可以选择是否查看设备信息,并打开相机,方便取流

 def __init__(self,camera_index): \"\"\" 初始化参数 :param camera_index:相机索引,未装驱动电脑索引从0开始,装了驱动的从1开始 \"\"\" #设备信息表初始化 self._deviceList = MV_CC_DEVICE_INFO_LIST() #设备类型 self._tlayerType = MV_USB_DEVICE #相机实例 self._cam = MvCamera() #相机参数 self._stParam = None #数据包大小 self._nPayloadSize = None #数据流 self._data_buf = None #相机索引 self._camera_index = camera_index #相机型号等打印 self._Show_info = True #获取设备信息 MvCamera.MV_CC_EnumDevices(self._tlayerType, self._deviceList) #打印设备信息 if self._Show_info: self._print_debug_info() #打开相机流 self._open()

设备型号打印函数:

 def _print_debug_info(self): mvcc_dev_info = cast(self._deviceList.pDeviceInfo[self._camera_index], POINTER(MV_CC_DEVICE_INFO)).contents if mvcc_dev_info.nTLayerType == MV_USB_DEVICE: print(\"\\n设备列表: [%d]\" % self._camera_index) strModeName = \"\" for per in mvcc_dev_info.SpecialInfo.stUsb3VInfo.chModelName: if per == 0:  break strModeName = strModeName + chr(per) print(\"设备名称: %s\" % strModeName) strSerialNumber = \"\" for per in mvcc_dev_info.SpecialInfo.stUsb3VInfo.chSerialNumber: if per == 0:  break strSerialNumber = strSerialNumber + chr(per) print(\"串行代号: %s\" % strSerialNumber)

成功打开后会看到(先注释掉_open函数,再运行):

然后完善open函数,打开相机流

 def _open(self): \"\"\" 打开设备 :return: \"\"\" if int(self._camera_index) >= self._deviceList.nDeviceNum: print(\"索引相机失败!\") sys.exit() #创建相机实例 stDeviceList = cast(self._deviceList.pDeviceInfo[int(self._camera_index)], POINTER(MV_CC_DEVICE_INFO)).contents ret = self._cam.MV_CC_CreateHandle(stDeviceList) if ret != 0: print(\"相机打开错误: 相机索引创建句柄失败! 错误码:[0x%x]\" % ret) sys.exit() #打开设备 ret = self._cam.MV_CC_OpenDevice(MV_ACCESS_Exclusive, 0) if ret != 0: print(\"相机打开错误: 设备打开失败! 错误码:[0x%x]\" % ret) sys.exit() ret = self._cam.MV_CC_SetEnumValue(\"TriggerMode\", MV_TRIGGER_MODE_OFF) if ret != 0: print(\"相机打开错误: 触发模式设置失败! 错误码:[0x%x] ret[0x%x]\" % ret) sys.exit() #获取数据包大小 self._stParam = MVCC_INTVALUE() memset(byref(self._stParam), 0, sizeof(MVCC_INTVALUE)) ret = self._cam.MV_CC_GetIntValue(\"PayloadSize\", self._stParam) if ret != 0: print(\"相机打开错误: 数据包大小获取失败! 错误码:[0x%x]\" % ret) sys.exit() self._nPayloadSize = self._stParam.nCurValue # ch:开始取流 | en:Start grab image ret = self._cam.MV_CC_StartGrabbing() if ret != 0: print(\"取流失败: 开始取流失败! 错误码:[0x%x]\" % ret) sys.exit()

打开相机可以看作是一个流程,一个流程过完才能过下一个流程

分别是   

创建相机实例   ->  打开设备  ->  获取数据包大小  ->  开始取流

然后就是get_img函数了,这个函数是获取相机图像的

将相机的图像buffer转化成opencv能够识别的图像数据

 def get_img(self): \"\"\" 获取一帧图像 :return: \"\"\" #创建图像信息表 stDeviceList = MV_FRAME_OUT_INFO_EX() #初始化图像信息表 memset(byref(stDeviceList), 0, sizeof(stDeviceList)) #创建原始图像信息表 self._data_buf = (c_ubyte * self._nPayloadSize)() #采用超时机制获取一帧图片,SDK内部等待直到有数据时返回 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 = 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() #获取图像信息 img_buff = (c_ubyte * stConvertParam.nImageLen)() cdll.msvcrt.memcpy(byref(img_buff), stConvertParam.pImageBuffer, stConvertParam.nImageLen) # 将 ctypes 数组转换为 NumPy 数组 _img_array = np.frombuffer(img_buff, dtype=np.uint8) # 使用 cv2.imdecode 解码图像 _image = cv2.imdecode(_img_array, cv2.IMREAD_COLOR) return _image

(可选)

最后是关闭相机函数

 def _close(self): ret = self._cam.MV_CC_StopGrabbing() if ret != 0: print(\"相机关闭失败: 停止取流失败! 错误码:[0x%x]\" % ret) del self._data_buf sys.exit() ret = self._cam.MV_CC_CloseDevice() if ret != 0: print(\"相机关闭失败: 设别关闭失败! 错误码:[0x%x]\" % ret) del self._data_buf sys.exit() ret = self._cam.MV_CC_DestroyHandle() if ret != 0: print(\"相机关闭失败: 句柄销毁失败! 错误码:[0x%x]\" % ret) del self._data_buf sys.exit() del self._data_buf

至此相机已经可以调用并使用啦

#实例def main(): camera = Camera(0) while True: img = camera.get_img() cv2.imshow(\'img\', img) if cv2.waitKey(1) & 0xff == 27: breakif __name__ == \'__main__\': main()

感谢:

Python海康相机api---超简单入坑学习必看_python海康相机连接教程-CSDN博客

Python 实现海康机器人工业相机 MV-CU060-10GM 的实时显示视频流及拍照功能 - 龙凌云端 - 博客园

win11 python调用dll问题:FileNotFoundError: Could not find module ‘xxx.dll‘ (or one of its dependencies)_filenotfounderror: could not find module \'nvcuda.d-CSDN博客