海康Camera MVS Linux SDK二次开发封装ROS packge过程记录(c++)

本文介绍了如何通过自定义驱动和二次开发,将海康威视工业相机与大疆固态激光雷达结合,实现实时彩色点云生成与三维重建,重点分享了SDK封装及ROS包开发的过程。

Livox Lidar  + HIKROBOT Camera系列

最近在开发相机和激光雷达融合的slam算法,主要用于三维重建,想实时的得到彩色点云地图,传感器选择了海康威视的工业相机和大疆的固态激光雷达。

海康Camera MVS Linux SDK二次开发封装ROS packge过程记录(c++)

Livox Lidar+海康Camera实时生成彩色点云

Livox Lidar+海康Camera实时三维重建生成RGB彩色点云地图


前言

海康的相机没有ros驱动,而且对linux开发不太用好(windows的支持还是不错的),就重写了sdk接口,并创建了ros节点封装成ros包,方便linux环境下ros的调用,用于开发后面的算法,完整版ros驱动:https://github.com/luckyluckydadada/HIKROBOT-MVS-ROS-package,请自取。

本文主要是对sdk的封装过程,和创建ros驱动包的开发过程记录。

虽然海康的相机是usb传输数据,但是不同于其他usb设备的调用,海康的相机并不会在/dev/目录下映射ttyUSB或video1这样的设备,所以不能用open/read/write这样的system call的方式打开设备,所以https://github.com/ros-drivers/usb_cam这样的usb ros驱动无法支持。基于此,就只能自己开发ros驱动包。

海康的打开设备的方式在MvUsb3VDevice.h和MvGigEDevice.h中实现(分别对应usb3.0相机和以太网相机),具体过程并没有开源,只提供了相应的so文件,海康提供了统一的接口MV_CC_EnumDevices实现对两种设备(usb3.0接口和以太网接口)的调用,因此开发一个ros驱动包是两种相机都适用的

如果你的相机在/dev/下有映射(比如笔记本自带的摄像头一般是/dev/video1),可以使用https://github.com/ros-drivers/usb_cam这个驱动包,如果是海康这样的方式,请使用我的ros驱动包https://github.com/luckyluckydadada/HIKROBOT-MVS-ROS-package

海康的相机sdk虽然不开源,但是提供了armhf和aarch64架构编译的so文件,之后我会移植到jetson上。

环境

  • Ubuntu 18.04
  • 机器视觉工业相机客户端MVS V2.1.0(Linux)

  • 相机型号:MV-CE060-10UC

适用于海康机器视觉工业相机系列(以太网传输和usb传输同样适用),相机接入pc或开发板的usb3.0接口或网口。

下载海康mvs sdk

https://www.hikrobotics.com/machinevision/service/download?module=0,选linux的最新版:机器视觉工业相机客户端MVS V2.1.0(Linux)

解压

MVS_Linux_STD_V2.1.0_201228.zip解压后,目录中含有多种架构已经编译好并打包的*.dpkg包,另外还有tar.gz(也含编译好的so和bin文件)。

MVS-2.1.0_aarch64_20201228.deb      MVS-2.1.0_i386_20201228.deb

MVS-2.1.0_aarch64_20201228.tar.gz   MVS-2

### 1. 环境准备 在开始封装之前,确保已经安装以下环境: - **ROS**:建议使用 ROS Noetic 或 Melodic(适用于 Ubuntu 20.04 或 18.04)[^1]。 - **C++ 编译器**:g++ 或 clang++。 - **海康威视 MVS SDK**:从官网下载 Linux 版本的 SDK 并解压到指定路径。 - **构建工具**:`catkin` 是 ROS 的构建系统,用于管理包依赖和编译。 ```bash # 创建 ROS 工作空间 mkdir -p ~/my_ros_ws/src cd ~/my_ros_ws catkin_make source devel/setup.bash ``` ### 2. 创建 ROS 包 进入 `src` 目录并创建一个新的 ROS 包。假设包名为 `hikvision_camera_sdk_wrapper`,其依赖项包括 `roscpp`, `sensor_msgs`, 和 `image_transport`。 ```bash cd ~/my_ros_ws/src catkin_create_pkg hikvision_camera_sdk_wrapper roscpp sensor_msgs image_transport ``` ### 3. 集成海康 Camera MVS SDK 将下载的 MVS SDK 解压到 `hikvision_camera_sdk_wrapper` 包目录下的 `third_party/MVS` 文件夹中。 #### 3.1 修改 CMakeLists.txt 编辑 `CMakeLists.txt` 文件以包含头文件路径、链接库以及编译选项: ```cmake cmake_minimum_required(VERSION 3.0.2) project(hikvision_camera_sdk_wrapper) find_package(catkin REQUIRED COMPONENTS roscpp sensor_msgs image_transport ) include_directories( ${catkin_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}/third_party/MVS/include ) link_directories(${PROJECT_SOURCE_DIR}/third_party/MVS/lib) add_executable(camera_node src/camera_node.cpp) target_link_libraries(camera_node ${catkin_LIBRARIES} CameraSDK # 根据实际 SDK 名称调整 ) ``` ### 4. 编写封装代码 #### 4.1 定义相机接口类 创建 `include/hikvision_camera.h` 头文件,定义相机控制接口: ```cpp #ifndef HIKVISION_CAMERA_H #define HIKVISION_CAMERA_H #include <string> #include <memory> class HikvisionCamera { public: virtual ~HikvisionCamera() = default; virtual bool connect(const std::string& device_id) = 0; virtual bool start_streaming() = 0; virtual bool stop_streaming() = 0; virtual void set_exposure_time(double time_ms) = 0; virtual void grab_image(cv::Mat& image) = 0; }; using HikvisionCameraPtr = std::shared_ptr<HikvisionCamera>; HikvisionCameraPtr create_hikvision_camera(); #endif // HIKVISION_CAMERA_H ``` #### 4.2 实现 SDK 封装类 创建 `src/mvs_camera.cpp` 文件,实现基于 MVS SDK 的具体逻辑: ```cpp #include "hikvision_camera.h" #include <mv_camera_control_api.h> // 引入 SDK 头文件 class MvsCamera : public HikvisionCamera { public: MvsCamera() : handle_(nullptr), is_connected_(false) {} ~MvsCamera() override { if (is_connected_) disconnect(); } bool connect(const std::string& device_id) override { MV_CC_DEVICE_INFO info = {}; info.nDeviceID = const_cast<char*>(device_id.c_str()); int status = MV_CC_CreateCamera(&handle_, &info); if (status != MV_OK) return false; status = MV_CC_OpenDevice(handle_); if (status != MV_OK) return false; is_connected_ = true; return true; } bool start_streaming() override { if (!is_connected_) return false; int status = MV_CC_StartGrabbing(handle_); return status == MV_OK; } bool stop_streaming() override { if (!is_connected_) return false; int status = MV_CC_StopGrabbing(handle_); return status == MV_OK; } void set_exposure_time(double time_ms) override { MVCC_FLOATVALUE stParam; stParam.fCurValue = static_cast<float>(time_ms); MV_CC_SetFloatValue(handle_, "ExposureTime", &stParam); } void grab_image(cv::Mat& image) override { MV_FRAME_OUT frame_out = {0}; int status = MV_CC_GetImageBuffer(handle_, &frame_out, 1000); if (status == MV_OK) { // 假设图像格式为 BGR8 cv::Mat raw(frame_out.stFrameInfo.nHeight, frame_out.stFrameInfo.nWidth, CV_8UC3, frame_out.pBufAddr); image = raw.clone(); // 拷贝数据 MV_CC_FreeImageBuffer(handle_, &frame_out); } } private: void disconnect() { MV_CC_CloseDevice(handle_); MV_CC_DestroyCamera(handle_); is_connected_ = false; } private: void* handle_; bool is_connected_; }; HikvisionCameraPtr create_hikvision_camera() { return std::make_shared<MvsCamera>(); } ``` #### 4.3 创建 ROS 节点 创建 `src/camera_node.cpp` 文件,实现 ROS 节点与封装类的集成: ```cpp #include <ros/ros.h> #include <image_transport/image_transport.h> #include <cv_bridge/cv_bridge.h> #include <opencv2/opencv.hpp> #include "hikvision_camera.h" int main(int argc, char** argv) { ros::init(argc, argv, "hikvision_camera_node"); ros::NodeHandle nh; image_transport::ImageTransport it(nh); image_transport::Publisher pub = it.advertise("camera/image_raw", 1); HikvisionCameraPtr camera = create_hikvision_camera(); if (!camera->connect("CAMERA_SERIAL_NUMBER")) { ROS_ERROR("Failed to connect to camera."); return -1; } if (!camera->start_streaming()) { ROS_ERROR("Failed to start streaming."); return -1; } ros::Rate loop_rate(30); // 30 Hz while (ros::ok()) { cv::Mat image; camera->grab_image(image); if (!image.empty()) { sensor_msgs::ImagePtr msg = cv_bridge::CvImage(std_msgs::Header(), "bgr8", image).toImageMsg(); pub.publish(msg); } ros::spinOnce(); loop_rate.sleep(); } camera->stop_streaming(); return 0; } ``` ### 5. 编译与运行 返回工作空间根目录并编译整个项目: ```bash cd ~/my_ros_ws catkin_make source devel/setup.bash ``` 启动节点: ```bash rosrun hikvision_camera_sdk_wrapper camera_node ``` ### 6. 调试与测试 使用 `rqt_image_view` 查看实时图像: ```bash rosrun rqt_image_view rqt_image_view ``` 选择 `/hikvision_camera_node/camera/image_raw` 主题进行查看。 --- ###
评论 60
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值