介绍
海康机器人官网链接:海康机器人-让机器更智能,让智能更普惠
根据购买设备的型号下载用户说明书
本人使用的是一款USB接口的M12工业相机
功能特性
-
支持自动或手动调节增益、曝光时间、白平衡、Gamma、LUT校正等
-
彩色相机植入优异的图像插值算法,更好的颜色还原
-
通过USB3.0接口供电并传输数据
-
兼容USB3 Vision协议和GenlCam标准,可接入第三方软件平台
订货型号
MV-CB060-10UC-S
外形尺寸
产品参数
型号 | 型号 | MV-CB060-10UC-S |
名称 | 600万像素USB 3.0板级相机,IMX178, 彩色, M12口, V4 | |
性能 | 传感器类型 | CMOS,卷帘快门 |
传感器型号 | IMX178 | |
像元尺寸 | 2.4 µm×2.4 µm | |
靶面尺寸 | 1/1.8" | |
分辨率 | 3072 × 2048 | |
最大帧率 | 60.9 fps @ 3072 × 2048 Bayer RG 8 | |
动态范围 | 66 dB | |
信噪比 | 41.5 dB | |
增益 | 0 dB ~ 24 dB | |
曝光时间 | 8 μs ~ 1 sec | |
快门模式 | 支持自动曝光、手动曝光、一键曝光以及 Global Reset、 Trigger Rolling | |
黑白/彩色 | 彩色 | |
像素格式 | Mono 8/10/12 Bayer RG 8/10/10Packed/12/12Packed YUV422Packed, YUV422_YUYV_Packed RGB 8,BGR 8 | |
Binning | 支持1 × 1,2 × 2 | |
下采样 | 支持1 × 1,2 × 2,4 × 4 | |
镜像 | 支持水平镜像、垂直镜像 | |
电气特性 | 数据接口 | USB 3.0 |
数字I/O | 2路双向可配置非隔离IO(Line2,Line5) | |
供电 | 支持USB 3.0供电 | |
典型功耗 | 1.8 W@5 VDC | |
结构 | 镜头接口 | M12-Mount |
外形尺寸 | 35 mm × 35 mm × 8.6 mm | |
重量 | 约 43.5 g | |
温度 | 工作温度0~50℃,储藏温度-30~70℃ | |
湿度 | 20%~80%RH无冷凝 | |
一般规范 | 软件 | MVS或者兼容USB3 Vision协议的第三方软件 |
操作系统 | Windows XP/7/10/11 32/64bits,Linux 32/64bits | |
协议/标准 | USB3 Vision,GenlCam | |
认证 | CE,RoHS,KC |
软件安装步骤
SDK安装
服务支持”>“下载中心”>“机器视觉”中下载MVS客户端安装包及SDK开发包。
Ubuntu18.04系统安装
下载安装压缩包,并解压
查看README如下
说明:
树莓派 选armhf架构,jetson 选aarch64,pc 机选x86_64,i386是32位pc。
armhf和aarch64区别就是armhf是armv7架构,如树莓派。aarch64是armv8架构,如jetson nano。
arm-none只有Samples,没有编译好的bin,也没有dpkg包,海康也没有提供源码,所以用不上。
实际安装:
方法1:
根据自己的系统选择解压相应的压缩包,打开INSTALL查看安装步骤
方法2:
或者使用deb的方式安装,方便卸载。tar和deb安装都可以
sudo dpkg -i MVS-2.1.2_x86_64_20221208.deb
# 删除用以下命令
sudo dpkg -r mvs
如下图所示:
编译demo1
source ~/.bashrc
cd /opt/MVS/Samples/64/GrabImage
make
./GrabImage
python+opencv:二次开发SDK
项目目录结构
其中MVImport
从安装目录中拷贝,如下图所示,GrabImage_opencv.py
:自定义代码(基于python+OpenCV实现取流,显示、保存视频等),util
用于放入自定义的其他功能性脚本
相机控制步骤
相机控制分成枚举、打开、参数设置、关闭,销毁句柄五个步骤
主代码GrabImage_opencv.py
# -- coding: utf-8 --
"""
2023.03.14
author:alian
function 海康威视摄像头取流
总结海康相机的取流步骤如下:
1 枚举
2 打开
3 参数设置
4 取流
5 关闭
6 销毁句柄
"""
import sys
import threading
import os
import termios
import time
import cv2
import numpy as np
from ctypes import *
sys.path.append("/opt/MVS/Samples/64/Python/MvImport") # 导入相应SDK的库,实际安装位置绝对路径
from MvImport.MvCameraControl_class import *
def creat_video(): # 创建视频
time_stamp = time.time()
video_name = time.strftime("%Y%m%d%H%M%S", time.localtime(time_stamp))
writer = cv2.VideoWriter("%s.mp4" % video_name, cv2.VideoWriter_fourcc(*"mp4v"), 30, (img_w, img_h))
return writer,time_stamp
# opencv转换显示
def work_thread_opencv(cam=0, pData=0, nDataSize=0,video_length=None):
img_w = 1920
img_h = 1080
stFrameInfo = MV_FRAME_OUT_INFO_EX()
memset(byref(stFrameInfo), 0, sizeof(stFrameInfo))
# 定义视频对象输出,自定义一段时间后新建视频文件,时间间隔设置为video_length
writer, time_stamp = creat_video()
while True:
ret = cam.MV_CC_GetOneFrameTimeout(pData, nDataSize, stFrameInfo, 1000)
if ret == 0:
print("get one frame: Width[%d], Height[%d], PixelType[0x%x], nFrameNum[%d]" % (
stFrameInfo.nWidth, stFrameInfo.nHeight, stFrameInfo.enPixelType, stFrameInfo.nFrameNum))
print(time.time()-time_stamp)
# 设置视频采集时长不大于video_length(以小时为单位)
if video_length!=None and time.time()-time_stamp > video_length*3600:
writer.release()
writer, time_stamp = creat_video()
# 设置相机输出像素格式,用OpenCV显示和保存视频数据
img = np.asarray(pData) # 读取帧
img = img.reshape(stFrameInfo.nHeight, stFrameInfo.nWidth, -1)
img = cv2.resize(img,(img_w,img_h))
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
import tkinter as tk # 获取屏幕尺寸,用于随屏幕分辨率自适应显示
root = tk.Tk()
width = root.winfo_screenwidth()
height = root.winfo_screenheight()
root.destroy()
cv2.imshow('View', cv2.resize(img, (width, height)))
writer.write(img) # 写入视频数据
# 按Q退出
if cv2.waitKey(24) & 0xFF == ord('q'):
break
else:
print("no data[0x%x]" % ret)
cv2.destroyAllWindows() # 释放所有显示图像窗口
sys.exit()
def press_any_key_exit(): # 任意按键退出程序
fd = sys.stdin.fileno()
old_ttyinfo = termios.tcgetattr(fd)
new_ttyinfo = old_ttyinfo[:]
new_ttyinfo[3] &= ~termios.ICANON
new_ttyinfo[3] &= ~termios.ECHO
termios.tcsetattr(fd, termios.TCSANOW, new_ttyinfo)
try:
os.read(fd, 7)
except:
pass
finally:
termios.tcsetattr(fd, termios.TCSANOW, old_ttyinfo)
if __name__ == "__main__":
deviceList = MV_CC_DEVICE_INFO_LIST()
tlayerType = MV_GIGE_DEVICE | MV_USB_DEVICE
# 1 枚举设备 | en:Enum device
ret = MvCamera.MV_CC_EnumDevices(tlayerType, deviceList)
if ret != 0:
print("enum devices fail! ret[0x%x]" % ret)
sys.exit()
if deviceList.nDeviceNum == 0:
print("find no device!")
sys.exit()
print("Find %d devices!" % deviceList.nDeviceNum)
nConnectionNum = 0
# 2 打开
# 2.1 创建相机实例 | en:Creat Camera Object
cam = MvCamera()
# ch:选择设备并创建句柄| en:Select device and create handle
stDeviceList = cast(deviceList.pDeviceInfo[int(nConnectionNum)], POINTER(MV_CC_DEVICE_INFO)).contents
ret = cam.MV_CC_CreateHandle(stDeviceList)
if ret != 0:
print("create handle fail! ret[0x%x]" % ret)
sys.exit()
# 2.2 打开设备 | 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()
# 3 参数设置
# 3.1 设置触发模式为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()
# 3.2 获取数据包大小 | en:Get payload size
stParam = MVCC_INTVALUE()
memset(byref(stParam), 0, sizeof(MVCC_INTVALUE))
ret = cam.MV_CC_GetIntValue("PayloadSize", stParam)
if ret != 0:
print("get payload size fail! ret[0x%x]" % ret)
sys.exit()
nPayloadSize = stParam.nCurValue
# 4 开始取流 | en:Start grab image
ret = cam.MV_CC_StartGrabbing()
if ret != 0:
print("start grabbing fail! ret[0x%x]" % ret)
sys.exit()
# 将PayloadSize的uint数据转为可供numpy处理的数据,后面就可以用numpy将其转化为numpy数组格式。
data_buf = (c_ubyte * nPayloadSize)()
try:
hThreadHandle = threading.Thread(target=work_thread_opencv, args=(cam, data_buf, nPayloadSize))
hThreadHandle.start()
hThreadHandle.join()
except:
print("error: unable to start thread")
# 5 关闭
# 5.1 停止取流 | en:Stop grab image
ret = cam.MV_CC_StopGrabbing()
if ret != 0:
print("stop grabbing fail! ret[0x%x]" % ret)
del data_buf
sys.exit()
# 5.2 关闭设备 | Close device
ret = cam.MV_CC_CloseDevice()
if ret != 0:
print("close deivce fail! ret[0x%x]" % ret)
del data_buf
sys.exit()
# 6 销毁句柄 | Destroy handle
ret = cam.MV_CC_DestroyHandle()
if ret != 0:
print("destroy handle fail! ret[0x%x]" % ret)
del data_buf
sys.exit()
del data_buf