一、在树莓派上安装海康工业机器人的MVS软件(Linux版本)

海康工业机器人软件下载地址: [https://www.hikrobotics.com/cn/machinevision/service/download?module=0] ,打开后如下图所示,找到所需要的的版本。
在这里插入图片描述
找到Linux下载安装包,我这里下载的是MVS V2.1.0(Linux)版本。
在这里插入图片描述
点击下载,开始下载安装包,下载完成将安装包移到u盘上,再插入到树莓派上(这里我用的VNC软件去操控树莓派)。新建了一个文件linux-mvs,将下载好后的安装包放入此文件夹下 在这里插入图片描述

下载好的解压文件
将下载好的文件解压后得到下列文件,这其中,树莓派选择文件名中armfhf的两个文件,如果是linux-PC端可以选择x86_84,jetson选择aarch64,i386是32位的linux-PC.在linux安装MVS软件,有两种方式使用一种即可,这里我只介绍我使用的安装方法。
打开终端,通过cd 命令进入到当前文件夹,准备解压文件。
在这里插入图片描述
通过dpkg包安装
打开终端,通过cd 命令进入到当前文件夹,运行如下命令:sudo dpkg –i MVS-2.1.0_armhf_20201228.deb,此时将MVS软件安装在了/opt/MVS路径下:
安装完成后的文件
到这一步,在树莓派上安装MVS就安装成功了!

二、使用python-Opencv打开海康工业相机

使用python程序打开海康工业相机,需要调用MVS软件中的.py文件,具体路径在在/opt/MVS/Samples/armhf/Python/MvImport,打开这个文件中的MvCameraControl_class.py文件,查看这个语句,MvCamCtrldll,这是打开工业相机的关键,是调用了动态链接库
在这里插入图片描述
这个语句它默认调用的是/opt/MVS/lib/armhf中的文件,实际程序运行中最大的问题也在这里,树莓派与Linux系统的调用不同之处也在这里,树莓派并不会自动添加MVS调用的动态链接路径,需要我们手动添加动态链接的路径。为了防止调用失败,出现文件无法查询 比如如下的错误:
OSError:libGCBase_gcc46_v3_0.so:cannot open shared object file:No such file or directory。
有则我们需要对树莓派的/etc/ld.so.conf.d 目录下的文件进行修改,添加我们想要路径。
在这里插入图片描述
可以新建文件,或者在已有的文件中,添加我们需要的路径即可。如图所示:
在这里插入图片描述
添加完成后,保存文件。在修改文件时或者查询文件时,若出现权限不够问题,利用“chmod 777 /文件名”命令去修改文件权限。即可改为权限为任何人,这样就可以任意修改文件了:
在这里插入图片描述
在保存完成后,打开终端,输入sudo ldconfig 命令,这样就完成配置了。
最后运行程序,可以看到成功打开了相机。
在这里插入图片描述

三、在jetson nano 下打开海康工业相机

在jetson nano 下打开此相机,安装MVS安装包顺序与在树莓派下安装的流程不变,但安装包变为安装sudo dpkg –i MVS-2.1.0_aarch64_20201228.deb。
程序中也要修改这条语句sys.path.append("/opt/MVS/Samples/armhf/Python/MvImport “)将其改为sys.path.append(”/opt/MVS/Samples/aarch/Python/MvImport ")( 具体以实际文件名称为主! )
然后检查/etc/ld.so.conf.d 目录下的文件,是否有aarch64的相关文件,有则无需修改,没有则参照树莓派手动添加动态链接的路径的方法。
之后便可以运行程序了,若在运行程序中出现 Failed to load modile “Canberra-get-module”
解决方案:打开终端,输入sudo apt-get install libcanberra-gtk-module。相机打开运行如下:
在这里插入图片描述
程序主要代码如下:

import sys 
from ctypes import *
import os
import numpy as np
import time
#from Camera import Camera
#from FTPService import FTPService 
#from GPIO_set import GPIO_set
import cv2
#import configparser
sys.path.append("/opt/MVS/Samples/armhf/Python/MvImport") #打开MVS中的MvImport文件,对于不同系统打开的文件路径跟随实际文件路径变化即可
from MvCameraControl_class import * #调用了MvCameraControl_class.py文件
class HKCamera()def __init__(self, CameraIdx=0, log_path=None):
        # enumerate all the camera devices
        deviceList = self.enum_devices()
        # generate a camera instance
        self.camera = self.open_camera(deviceList, CameraIdx, log_path)
        self.start_camera()
    def __del__(self):
        if self.camera is None:
            return
        # 停止取流
        ret = self.camera.MV_CC_StopGrabbing()
        if ret != 0:
            raise Exception("stop grabbing fail! ret[0x%x]" % ret)
        # 关闭设备
        ret = self.camera.MV_CC_CloseDevice()
        if ret != 0:
            raise Exception("close deivce fail! ret[0x%x]" % ret)
        # 销毁句柄
        ret = self.camera.MV_CC_DestroyHandle()
        if ret != 0:
            raise Exception("destroy handle fail! ret[0x%x]" % ret)
    @staticmethod
    def enum_devices(device=0, device_way=False):
        device = 0  枚举网口、USB口、未知设备、cameralink 设备
        device = 1 枚举GenTL设备
        if device_way == False:
            if device == 0:
                cameraType = MV_GIGE_DEVICE | MV_USB_DEVICE | MV_UNKNOW_DEVICE | MV_1394_DEVICE | MV_CAMERALINK_DEVICE
                deviceList = MV_CC_DEVICE_INFO_LIST()
                # 枚举设备
                ret = MvCamera.MV_CC_EnumDevices(cameraType, deviceList)
                if ret != 0:
                    raise Exception("enum devices fail! ret[0x%x]" % ret)
                return deviceList
            else:
        elif device_way == True:
    def open_camera(self, deviceList, CameraIdx, log_path):
        # generate a camera instance
        camera = MvCamera()
        # 选择设备并创建句柄
        stDeviceList = cast(deviceList.pDeviceInfo[CameraIdx], POINTER(MV_CC_DEVICE_INFO)).contents
        if log_path is not None:
            ret = self.camera.MV_CC_SetSDKLogPath(log_path)
            if ret != 0:
                raise Exception("set Log path  fail! ret[0x%x]" % ret)
            # 创建句柄,生成日志
            ret = camera.MV_CC_CreateHandle(stDeviceList)
            if ret != 0:
                raise Exception("create handle fail! ret[0x%x]" % ret)
        else:
            # 创建句柄,不生成日志
            ret = camera.MV_CC_CreateHandleWithoutLog(stDeviceList)
            if ret != 0:
                raise Exception("create handle fail! ret[0x%x]" % ret)
        # 打开相机
        ret = camera.MV_CC_OpenDevice(MV_ACCESS_Exclusive, 0)
        if ret != 0:
            raise Exception("open device fail! ret[0x%x]" % ret)
        return camera
    def start_camera(self):
        stParam = MVCC_INTVALUE()
        memset(byref(stParam), 0, sizeof(MVCC_INTVALUE))
        ret = self.camera.MV_CC_GetIntValue("PayloadSize", stParam)
        if ret != 0:
            raise Exception("get payload size fail! ret[0x%x]" % ret)
        self.nDataSize = stParam.




    
nCurValue
        self.pData = (c_ubyte * self.nDataSize)()
        self.stFrameInfo = MV_FRAME_OUT_INFO_EX()
        memset(byref(self.stFrameInfo), 0, sizeof(self.stFrameInfo))
        self.camera.MV_CC_StartGrabbing()
    def get_Value(self, param_type, node_name):
        :param cam:            相机实例
        :param_type:           获取节点值得类型
        :param node_name:      节点名 可选 int 、float 、enum 、bool 、string 型节点
        :return:               节点值
        if param_type == "int_value":
            stParam = MVCC_INTVALUE_EX()
            memset(byref(stParam), 0, sizeof(MVCC_INTVALUE_EX))
            ret = self.camera.MV_CC_GetIntValueEx(node_name, stParam)
            if ret != 0:
                raise Exception("获取 int 型数据 %s 失败 ! 报错码 ret[0x%x]" % (node_name, ret))
            return stParam.nCurValue
        elif param_type == "float_value":
            stFloatValue = MVCC_FLOATVALUE()
            memset(byref(stFloatValue), 0, sizeof(MVCC_FLOATVALUE))
            ret = self.camera.MV_CC_GetFloatValue(node_name, stFloatValue)
            if ret != 0:
                raise Exception("获取 float 型数据 %s 失败 ! 报错码 ret[0x%x]" % (node_name, ret))
            return stFloatValue.fCurValue
        elif param_type == "enum_value":
            stEnumValue = MVCC_ENUMVALUE()
            memset(byref(stEnumValue), 0, sizeof(MVCC_ENUMVALUE))
            ret = self.camera.MV_CC_GetEnumValue(node_name, stEnumValue)
            if ret != 0:
                raise Exception("获取 enum 型数据 %s 失败 ! 报错码 ret[0x%x]" % (node_name, ret))
            return stEnumValue.nCurValue
        elif param_type == "bool_value":
            stBool = c_bool(False)
            ret = self.camera.MV_CC_GetBoolValue(node_name, stBool)
            if ret != 0:
                raise Exception("获取 bool 型数据 %s 失败 ! 报错码 ret[0x%x]" % (node_name, ret))
            return stBool.value
        elif param_type == "string_value":
            stStringValue = MVCC_STRINGVALUE()
            memset(byref(stStringValue), 0, sizeof(MVCC_STRINGVALUE))
            ret = self.camera.MV_CC_GetStringValue(node_name, stStringValue)
            if ret != 0:
                raise Exception("获取 string 型数据 %s 失败 ! 报错码 ret[0x%x]" % (node_name, ret))
            return stStringValue.chCurValue
        else:
            return None
    def set_Value(self, param_type, node_name, node_value):
        :param cam:               相机实例
        :param param_type:        需要设置的节点值得类型
            float:
            enum:     参考于客户端中该选项的 Enum Entry Value 值即可
            bool:     对应 0 为关,1 为开
            string:   输入值为数字或者英文字符,不能为汉字
        :param node_name:         需要设置的节点名
        :param node_value:        设置给节点的值
        :return:
        if param_type == "int_value":
            ret = self.camera.MV_CC_SetIntValueEx(node_name, int(node_value))
            if ret != 0:
                raise Exception("设置 int 型数据节点 %s 失败 ! 报错码 ret[0x%x]" % (node_name, ret))
        elif param_type == "float_value":
            ret = self.camera.MV_CC_SetFloatValue(node_name, float(node_value))
            if ret != 0:
                raise Exception("设置 float 型数据节点 %s 失败 ! 报错码 ret[0x%x]" % (node_name, ret))
        elif param_type == "enum_value":
            ret = self.camera.MV_CC_SetEnumValue(node_name, node_value)
            if ret != 0:
                raise Exception("设置 enum 型数据节点 %s 失败 ! 报错码 ret[0x%x]" % (node_name, ret))
        elif param_type == "bool_value":
            ret = self.camera.MV_CC_SetBoolValue(node_name, node_value)
            if ret != 0:
                raise Exception("设置 bool 型数据节点 %s 失败 ! 报错码 ret[0x%x]" % (node_name, ret))
        elif param_type == "string_value":
            ret = self.camera.MV_CC_SetStringValue(node_name, str(node_value))
            if ret != 0:
                raise Exception("设置 string 型数据节点 %s 失败 ! 报错码 ret[0x%x]" % (node_name, ret))
    def set_exposure_time(self, exp_time):
        self.set_Value(param_type="float_value", node_name="ExposureTime", node_value=exp_time)
    def get_exposure_time(self):
        return self.get_Value(param_type="float_value", node_name="ExposureTime")
    def get_image(self, width=None):
        :param cam:     相机实例
        :active_way:主动取流方式的不同方法 分别是(getImagebuffer)(getoneframetimeout)
        :return:
        ret = self.camera.MV_CC_GetOneFrameTimeout(self.pData, self.nDataSize, self.stFrameInfo, 1000)
        if ret == 0:
            image = np.asarray(self.pData).reshape((self.stFrameInfo.nHeight, self.stFrameInfo.nWidth))
            if width is not None:
                image = cv2.resize(image, (width, int(self.stFrameInfo.nHeight * width / self.stFrameInfo.nWidth)))
            return image
        else:
            return None
    def show_runtime_info(self, image):
        exp_time = self.get_exposure_time()
        cv2.putText(image, ("exposure time = %1.1fms" % (exp_time * 0.001)), (20, 50), cv2.FONT_HERSHEY_SIMPLEX, 0.5, 255, 1)
if __name__ == '__main__':
    camera = HKCamera()
    try:
        while True:
         image = camera.get_image(width=800)
         if image is not None:
             camera.show_runtime_info(image)
             cv2.imshow("", image)
         key = cv2.waitKey(50) & 0xFF
         if key == ord('e') or key == ord('E'):
             cv2.destroyAllWindows()
             break
    except Exception as e:
        print(e)

参考大神文章:

linux下添加动态链接库路径的方法:https://www.cnblogs.com/ostin/p/9193029.html
海康Camera MVS Linux SDK二次开发封装ROS packge过程记录(c++):https://blog.csdn.net/weixin_41965898/article/details/116801491
python调用海康工业相机并用opencv显示(整体实现,在windows下):https://blog.csdn.net/qq_39570716/article/details/114066097?spm=1001.2014.3001.5501

该系统是官方Raspbian-buster-full,安装的OpenCV版本为3.4.3,系统镜像4.86G,压缩后2.09G,直接烧录到TF卡中就可以使用OpenCV,系统已设置好,上手就能用,有详细的使用文档,包括密码和各类软件的说明使用,能够马上上手使用,兼容4及4以下的树莓派设备。 将该系统镜像写入TF卡中,TF卡的大小可以为8G、16G等,只有大于4G的都可以。文件中有系统的详细说明和使用方法,包括用户密码、软件的使用、和windows系统的交互方法等,能够让你很快地上手。 里面包含5个wheel: opencv_python-3.4.3.18-cp37-cp37m-linux_armv7l.whl opencv_python-4.1.1.26-cp37-cp37m-linux_armv7l.whl opencv_python-4.1.1.26-cp35-cp35m-linux_armv7l.whl opencv_python-4.1.1.26-cp37-cp37m-linux_armv6l.whl opencv_python-4.1.1.26-cp37-cp37m-linux_armv7l.whl 下载之后选择里面的 MVS-1.0.0_aarch64_20190708.tar.gz 这个是64位架构的 ARMHF是32位架构上使用的 解压之后 如果直接安装的话因为ubuntu18.04删除了 /etc/rc.local 直接安装的话会报错 首先新建一个rc.local文件 root用户下 to... 环境:树莓派 Ubuntu系统 编程环境:Python3.7 Node(忘了版本了,都可以,最好稳定版本) 需要安装的模块:Python端:cv2 websockets fastapi等;Node端:主要是ws(用来传输视频流) 安装可以看网上的文章,很多有写,不过树莓派这里避坑:树莓派进入是pi用户,需要才能切换为root用户,安装Python模块时如果在用户下安装,用用户运行是是没有的,会报错误。另外,安装模块时似乎不能用安装,需要用它自带的安装,不过不知道是不是只有我这里才是这样的。...... 2.2.1 使用海康威视官方软件SDK(Ubuntu版安装失败,遂使用Winows版)查相机IP及账号密码 2.2.2 Windows 中在网络适配器设置IPV4与摄像头同一个网络,IE浏览器192.168.xxx.xxx,输入账号密码登录,安装插件即可得到视频 不想再安装庞大的MVS,先下载Linux runtime包 机器视觉工业相机SDK V3.2.0版本Runtime组件包(Linux).zip: 海康机器人-机器视觉-下载中心 然后解压出来 接着执行下面命令安装Lib: sudo dpkg -i MvCamCtrlSDK_Runtime-3.2.0_armhf_20210915.deb 第一次安装会让设置一个基础路径,我设置的是 : /opt/MVS 可能是我不懂啊,安装后找不到include文件夹,无奈,还是得下载MVS,. 我们知道Linux内存管理是以页为单位进行的,对内存的管理是通过伙伴系统进行。 从Linux内存管理框架图可知,页面分配器是其他林林总总内存操作的基础。 这也是为什么在介绍了《Linux内存管理 (1)物理内存初始化》、《Linux内存管理 (2)页表的映射过程》、《Linux内存管理 (3... ffplay rtsp://xxxx:xxxxxxxx@192.168.1.200:554/h264/ch1/sub/av_stream xxxx:xxxxxxxxx是账户名和密码,@后面是摄像仪的IP地址,后面那个:554是端口号,可以不用,默认就是554,不用改。 sub可以换成main,一个是主码流,一个子码流,分辨率和带宽不一样。 另外,经常出现 Invalid data found when processing input authorization failed 等..