1.准备工作
准备一个海康相机
下载MVS 和SDK
2.python MVS示例
(说明:MVS里有很多python示例,可以直接运行,但没有用opencv)
下载完MVS后,我们打开路径安装路径
我的:
D:\soft\MVS\MVS\Development\Samples\Python\BasicDemo
D:\soft\MVS\MVS\Development\Samples\Python\MvImport
可以看到有很多现成的示例。
我们借用一下"D:\soft\MVS\MVS\Development\Samples\Python\BasicDemo\BasicDemo.py"
创建 python项目test_HKcamera
复制BasicDemo.py
发现一片红,
我们把
D:\soft\MVS\MVS\Development\Samples\Python\BasicDemo
D:\soft\MVS\MVS\Development\Samples\Python\MvImport
里面的文件都复制过来
复制后,如图所示:
运行后:
成功输出画面。
3. python opencv 调用
创建test_HKcamera_opencv文件夹
创建test_hk_opecv.py文件
把第二节的文件复制进来
如图:
test_hk_opecv.py完整代码如下:
import cv2
import numpy as np
from MvCameraControl_class import *
from CameraParams_header import *
#-------------------opencv操作部分--------------------------------------
def opencv_action(img):
#自己定义操作
result_img = img
return result_img
#-----------------------海康相机设置部分---------------------------------------
ret = MvCamera.MV_CC_Initialize()
if ret != 0:
print(f"初始化SDK失败,错误码: {ret}")
exit()
# 枚举设备
deviceList = MV_CC_DEVICE_INFO_LIST()
n_layer_type = MV_GIGE_DEVICE | MV_USB_DEVICE | MV_GENTL_CAMERALINK_DEVICE
ret = MvCamera.MV_CC_EnumDevices(n_layer_type, deviceList)
if ret != 0:
print("枚举设备失败")
exit()
print(f"找到 {deviceList.nDeviceNum} 台设备")
if deviceList.nDeviceNum == 0:
exit()
stDeviceList = cast(deviceList.pDeviceInfo[0], POINTER(MV_CC_DEVICE_INFO)).contents
camera = MvCamera()
ret = camera.MV_CC_CreateHandle(stDeviceList)
# 打开设备(使用已创建的句柄)
ret = camera.MV_CC_OpenDevice()
if ret != 0:
print(f"打开设备失败,错误码: {ret}")
exit()
# 获取相机参数
width = c_uint()
height = c_uint()
pixel_format = c_uint()
payload_size = c_uint()
stParam = MVCC_INTVALUE()
ret = camera.MV_CC_GetIntValue("PayloadSize", stParam)
if ret != 0:
print(f"获取PayloadSize失败,错误码: {ret}")
exit()
payload_size.value = stParam.nCurValue
# 获取宽度
ret = camera.MV_CC_GetIntValue("Width", stParam)
if ret != 0:
print(f"获取宽度失败,错误码: {ret}")
exit()
width.value = stParam.nCurValue
# 获取高度
ret = camera.MV_CC_GetIntValue("Height", stParam)
if ret != 0:
print(f"获取高度失败,错误码: {ret}")
exit()
height.value = stParam.nCurValue
print(width.value,height.value)
pixel_format.value = 17301505 # RGB8
# 或
#pixel_format.value = 17301514 # Mono8
#曝光时间
exposure_time = 15000 # 单位:微秒
ret = camera.MV_CC_SetFloatValue("ExposureTime", exposure_time)
# 开始抓图
ret = camera.MV_CC_StartGrabbing()
if ret != 0:
print(f"开始抓图失败,错误码: {ret}")
exit()
# 分配缓冲区
data_buf = (c_ubyte * payload_size.value)()
data_size = c_uint(payload_size.value)
stFrameInfo = MV_FRAME_OUT_INFO_EX()
#-----------------------------------------------运行部分---------------------------
# 创建OpenCV窗口
cv2.namedWindow("Camera", cv2.WINDOW_NORMAL)
try:
while True:
data_buf = (c_ubyte * payload_size.value)()
ret = camera.MV_CC_GetOneFrameTimeout(
byref(data_buf),
payload_size.value,
stFrameInfo,
1000
)
if ret == 0:
#print(f"获取到帧: 宽度={stFrameInfo.nWidth}, 高度={stFrameInfo.nHeight}, "f"像素格式={stFrameInfo.enPixelType}, 帧大小={stFrameInfo.nFrameLen}")
frame = np.frombuffer(data_buf, dtype=np.uint8)
actual_width = stFrameInfo.nWidth
actual_height = stFrameInfo.nHeight
if stFrameInfo.enPixelType == 17301505: # RGB8
expected_size = actual_width * actual_height * 3
if len(frame) != expected_size:
print(f"数据大小不匹配: 期望 {expected_size}, 实际 {len(frame)}")
continue
frame = frame.reshape((actual_height, actual_width, 3))
frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
elif stFrameInfo.enPixelType == 17301514: # Mono8
expected_size = actual_width * actual_height
if len(frame) != expected_size:
print(f"数据大小不匹配: 期望 {expected_size}, 实际 {len(frame)}")
continue
frame = frame.reshape((actual_height, actual_width))
elif stFrameInfo.enPixelType == 17301513: # 可能是 Bayer 格式
expected_size = actual_width * actual_height
if len(frame) != expected_size:
print(f"数据大小不匹配: 期望 {expected_size}, 实际 {len(frame)}")
continue
frame = frame.reshape((actual_height, actual_width))
frame = cv2.cvtColor(frame, cv2.COLOR_BayerGB2BGR)
frame = opencv_action(frame)
else:
print(f"不支持的像素格式: {stFrameInfo.enPixelType}")
break
cv2.imshow("Camera", frame)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
else:
print(f"获取图像失败,错误码: {ret}")
break
finally:
# 停止抓图
camera.MV_CC_StopGrabbing()
# 关闭设备
camera.MV_CC_CloseDevice()
# 销毁句柄
camera.MV_CC_DestroyHandle()
# 销毁窗口
cv2.destroyAllWindows()
完整代码如下:
通过网盘分享的文件:py_opencv_HK
链接:https://pan.baidu.com/s/1DmrVSV1LT9zGBCRx3nIKAQ
提取码: usii
4.花絮
不知道哪个教程教的=-=
# 创建设备句柄 handle = c_void_p() stDeviceList = cast(deviceList.pDeviceInfo[0], POINTER(MV_CC_DEVICE_INFO)).contents # 创建相机实例并调用方法(关键修正点) camera = MvCamera() # 实例化 MvCamera 类 #方法一: ret = camera.MV_CC_CreateHandle(stDeviceList) #报错:TypeError: MvCamera.MV_CC_GetIntValue() takes 3 positional arguments but 4 were given #方法二: #ret = MvCamera.MV_CC_CreateHandle(byref(handle), stDeviceList) #报错AttributeError: '_ctypes.CArgObject' object has no attribute 'handle' #方法三: #ret = MvCamera.MV_CC_CreateHandle(byref(stDeviceList)) #报错TypeError: MvCamera.MV_CC_CreateHandle() missing 1 required positional argument: 'stDevInfo' #方法四: #ret = camera.MV_CC_OpenDevice(byref(handle),byref(stDeviceList)) #报错TypeError: MvCamera.MV_CC_CreateHandle() missing 1 required positional argument: 'stDevInfo' # 打开设备(使用已创建的句柄) ret = MvCamera.MV_CC_OpenDevice(handle) if ret != 0: print(f"打开设备失败,错误码: {ret}") exit()
创建
handle = c_void_p()
就疯狂报错。