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

python通过调用海康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) for per in mvcc_dev_info.SpecialInfo.stUsb3VInfo.chModelName: if per == 0: break strModeName = strModeName + chr(per) print("设备名称: %s" % strModeName) 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: break if __name__ == '__main__': main()

感谢:

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

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-ZEEKLOG博客

Read more

超全 MySQL 学习笔记(3 万字):操作、约束、范式、连接查询全解析

超全 MySQL 学习笔记(3 万字):操作、约束、范式、连接查询全解析

文章目录 * 一、数据库操作 * 1.1 登录 MySQL 数据库 * 1.2 查看当前服务器中的所有数据库 * 1.3 创建数据库 * 1.3.1 创建数据库的标准语法 * ⚠️ 注意:数据库名是否可以使用关键字? * 1.3.2 utf8 与 utf8mb4 的区别(高频面试题) * 1.4 查看 MySQL 服务的默认字符集 * 1.5 查看当前正在使用的数据库 * 1.6 删除数据库(慎用) * 1.7 查看 MySQL 帮助 * 1.8 创建数据表 * 1.8.

By Ne0inhk

X86、ARM与C86架构全面对比分析:性能、功耗、成本与生态系统

目录标题 * X86、ARM与C86架构全面对比分析:性能、功耗、成本与生态系统 * 一、架构概述与发展背景 * 1.1 X86架构:PC与服务器市场的传统霸主 * 1.2 ARM架构:移动领域的王者与新兴服务器力量 * 1.3 C86架构:国产x86兼容的创新尝试 * 二、性能表现对比分析 * 2.1 运算速度与数据处理能力 * 2.2 不同场景下的性能表现 * 2.3 性能优化与未来趋势 * 三、功耗与能效比分析 * 3.1 不同架构的功耗特性 * 3.2 不同应用场景下的能耗分析 * 3.3 能效优化技术与未来趋势 * 四、成本分析与经济性比较 * 4.1 芯片制造成本对比 * 4.2 不同应用场景的总体拥有成本(

By Ne0inhk
从SQL Server到KingbaseES:一步到位的跨平台迁移与性能优化指南

从SQL Server到KingbaseES:一步到位的跨平台迁移与性能优化指南

摘要:信创背景下,国产数据库正以惊人的兼容性和更优的成本效益赢得市场。本文详细介绍了国产数据库KingbaseES V9R4C12作为SQL Server替代方案的实战应用。通过代码示例展示了其在语法兼容性(95%以上T-SQL兼容)、数据类型支持、存储过程迁移等方面的优异表现。文章包含Windows/Linux安装指南、基础操作对比、高级特性实现(如分页查询、事务控制)以及TPCH100G性能测试结果(部分场景性能优于SQL Server)。特别强调了KingbaseES在信创背景下的合规优势,提供了迁移验证脚本和注意事项,证明其能实现低风险平滑迁移,同时大幅降低License成本。 一、为什么选择KingbaseES替代SQL Server? 在信创窗口期,许多使用SQL Server作为核心数据库的企业面临着合规性风险和高昂的License费用。经过多轮PoC验证, 金仓KingbaseES V9R4C12(SQL Server兼容版) 展现出强大的兼容能力,官方宣称"数据库平替用金仓",为背负2000+存储过程的系统提供了低风险迁移方案。 先来看一个直观的兼容性对比:

By Ne0inhk
数据库 SQL 防火墙:内核级防护,筑牢 SQL 注入安全防线

数据库 SQL 防火墙:内核级防护,筑牢 SQL 注入安全防线

在数字化转型持续深化的今天,数据早已从辅助资源升级为企业的核心生产要素。无论是政务系统、金融交易,还是工业控制、能源调度,数据库作为数据的最终载体,其安全直接关系到业务连续性与数据资产完整性。 在各类数据库安全威胁中,SQL注入凭借门槛低、隐蔽性强、破坏力大的特点,长期位居OWASP Top 10 Web应用安全风险前列。它就像潜伏在业务链路中的隐秘入侵者,利用应用逻辑漏洞,将恶意指令伪装成正常参数传入数据库,进而实现越权访问、数据窃取甚至删库破坏。 尽管行业内早已形成共识——通过预编译语句、参数化查询、输入校验等方式可以有效防范SQL注入,但在真实业务环境中,风险依然无处不在:老旧系统的遗留代码难以全面改造、第三方组件存在未知漏洞、多团队协作中难免出现编码疏漏、动态SQL拼接场景难以完全规范化……只要存在一处薄弱环节,就可能被攻击者利用,引发连锁安全事故。 面对这种“处处设防仍可能百密一疏”的困境,单纯依赖应用层加固显然不够。能否从数据库自身出发,构建一层独立、可靠、主动的防御体系?金仓数据库(KingbaseES)V009R002C014版本内置的SQL防火墙能力,正是从这一

By Ne0inhk