Hikvision Robotics: Secondary Development of Industrial Camera SDK
introduction
Hikrobotics official website link: https://www.hikrobotics.com/cn
Download the user manual according to the model of the purchased device
The author's laboratory purchased two models, one with GigE network interface and one with USB interface.
1 Software installation steps
1.1 SDK installation
Download the MVS client installation package and SDK development package from "Service Support" > "Download Center" > "Machine Vision".
Download and install the compressed package, and decompress it
to view the README as follows:
安装包对应的操作系统
arm架构64位系统:
MVS-2.1.2_aarch64_20221024.deb
MVS-2.1.2_aarch64_20221024.tar.gz
arm架构32位系统:
MVS-2.1.2_armhf_20221024.deb
MVS-2.1.2_armhf_20221024.tar.gz
MVS-2.1.2_arm-none_20221024.tar.gz
x86架构64位系统:
MVS-2.1.2_i386_20221024.deb
MVS-2.1.2_i386_20221024.tar.gz
x86架构32位系统:
MVS-2.1.2_x86_64_20221024.deb
MVS-2.1.2_x86_64_20221024.tar.gz
1. 根据系统名称选择相对应的安装包:在终端中输入“uname -a”命令,根据输出的信息选择安装包,例如:输出的信息包含aarch64就选择aarch64的安装包;
2. .deb安装包通过dpkg命令安装,主要应用于ubuntu等系统;
3. .tar.gz安装包是一个压缩包,通tar命令解压后,再执行setup.sh脚本进行安装。
Actual installation:
Choose to decompress the corresponding compressed package according to your own system, open INSTALL to view the installation steps
To install the MVS Camera Software Suite in /opt/MVS # 软件安装目录
follow these steps:
1. Gaining root privileges and input password:
sudo su or su root # 进入root权限进行安装
2. Change to the directory which contains this INSTALL file, e.g.:
cd ~/MVS-1.0.0_x86_64 # 进入文件夹
3. Running the configuration scripts source
./setup.sh # 执行安装
Or use the deb way to install, easy to uninstall. Both tar and deb installations are ok
sudo dpkg -i MVS-2.1.2_x86_64_20221208.deb
# 删除用以下命令
sudo dpkg -r mvs
As shown below:
1.2 Running examples
source ~/.bashrc
cd /opt/MVS/Samples/64/GrabImage
make
./GrabImage
Enable network jumbo frames
# 查看网卡名
ifconfig
# 开启网络巨帧
sudo ifconfig enp0s31f6 mtu 9000
# 再次使用ifconfig查看,mtu等于9000,即设置成功
ifconfig
# 永久设置网卡开启巨帧
sudo vim /etc/network/interfaces
# 将sudo ifconfig enp0s31f6 mtu 9000写入文件
1.3 Open the software
4. Execute /opt/MVS/bin/MVSPlayer to test your cameras.
sudo su # 须进入root权限才能打开软件
cd /opt/MVS/bin # 进入软件安装目录
./MVS # 执行软件
1.3 Software function description
2 python+opencv: secondary development SDK
Project directory structure Copy it
from MVImport
the installation directory, as shown in the figure below, GrabImage_opencv.py
: Custom code (based on python+OpenCV to achieve streaming, display, save video, etc.), util
used to put in other custom functional scripts
2.1 Camera Control Steps
Camera control is divided into five steps: enumeration, opening, parameter setting, closing, and destroying the handle
2.1 Main code 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