Nvidia Jetson Agx Xavier 在Ros中调用GMSL2相机

在ros中调用GMSL2摄像头,刚开始是通过修改官方驱动包ros-meloidc-usb-cam,可能是修改的地方不对,一直报错,调用失败,要是有大佬修改成功,希望能交流一下。

后来借鉴了一下别人关于这方面的博客,成功拿到了图像数据。理论上jetson orin/nanotx2等也可以用。

1、设备 Nvidia Jetson Agx Xavier

2、jetpack 4.6.1

3、opencv 4.1.1

4、ros-melodic

5、python3.6.9

6、GMSL2相机+相机采集板

1、编译python3版cv_bridge

参考我的上篇博客,此步不可省略,因为opencv4.1.1是python3版本的,所以就得使用python3版本的cv_bridge,而官方默认版本为python2版,如不自己构建cv_bridge,必须安装python2版本的opencv版本,使用默认cv_bridge。

2、创建ROS工作空间

mkdir -p ~/ros_camera_ws/src
cd ~/ros_camera_ws/
catkin_make
source devel/setup.bash

3、创建ROS功能包learning_image_transport

cd ~/ros_camera_ws/src
catkin_create_pkg learning_image_transport roscpp std_msgs cv_bridge image_transport sensor_msgs

4、编写发布订阅节点C++文件

在功能包learning_image_transport下的src目录中建立两个cpp文件。

cd ~/ros_camera_ws/src/learning_image_transport/src/
gedit my_publisher.cpp

写入以下代码:

#include <ros ros.h>
#include <image_transport image_transport.h>
#include <opencv2 highgui highgui.hpp>
#include <cv_bridge cv_bridge.h>
#include <sstream> // for converting the command line parameter to integer

int main(int argc, char** argv)
{
    // Check if video source has been passed as a parameter
    if(argv[1] == NULL)
    {
        ROS_INFO("argv[1]=NULL\n");
        return 1;
    }

    ros::init(argc, argv, "image_publisher");
    ros::NodeHandle nh;
    image_transport::ImageTransport it(nh);
    image_transport::Publisher pub = it.advertise("camera/image", 1);

    // Convert the passed as command line parameter index for the video device to an integer
    std::istringstream video_sourceCmd(argv[1]);
    int video_source;
    // Check if it is indeed a number
    if(!(video_sourceCmd >> video_source))
    {
        ROS_INFO("video_sourceCmd is %d\n",video_source);
        return 1;
    }

    cv::VideoCapture cap(video_source);
    // Check if video device can be opened with the given index
    if(!cap.isOpened())
    {
        ROS_INFO("can not opencv video device\n");
        return 1;
    }
    cv::Mat frame;
    sensor_msgs::ImagePtr msg;

    ros::Rate loop_rate(5);
    while (nh.ok())
    {
        cap >> frame;
        // Check if grabbed frame is actually full with some content
        if(!frame.empty())
        {
            msg = cv_bridge::CvImage(std_msgs::Header(), "bgr8", frame).toImageMsg();
            pub.publish(msg);
            //cv::Wait(1);
        }
    }

    ros::spinOnce();
    loop_rate.sleep();
}  </sstream></cv_bridge></opencv2></image_transport></ros>
gedit my_subscriber.cpp

写入以下代码:

#include <ros ros.h>
#include <image_transport image_transport.h>
#include <opencv2 highgui highgui.hpp>
#include <cv_bridge cv_bridge.h>

void imageCallback(const sensor_msgs::ImageConstPtr& msg)
{
    try
    {
        cv::imshow("view", cv_bridge::toCvShare(msg, "bgr8")->image);
        // cv::waitKey(30);
    }
    catch (cv_bridge::Exception& e)
    {
        ROS_ERROR("Could not convert from '%s' to 'bgr8'.", msg->encoding.c_str());
    }
}

int main(int argc, char **argv)
{
    ros::init(argc, argv, "image_listener");
    ros::NodeHandle nh;
    cv::namedWindow("view");
    cv::startWindowThread();
    image_transport::ImageTransport it(nh);
    image_transport::Subscriber sub = it.subscribe("camera/image", 1,imageCallback);
    ros::spin();
    cv::destroyWindow("view");
}  </cv_bridge></opencv2></image_transport></ros>

5、配置文件修改

cd ~/ros_camera_ws/src/learning_image_transport/
gedit CMakeLists.txt

填入以下内容:

find_package(OpenCV REQUIRED)
add the publisher example
add_executable(my_publisher src/my_publisher.cpp)

target_link_libraries(my_publisher ${catkin_LIBRARIES} ${OpenCV_LIBRARIES})

add the subscriber example
add_executable(my_subscriber src/my_subscriber.cpp)
target_link_libraries(my_subscriber ${catkin_LIBRARIES} ${OpenCV_LIBRARIES})

6、编译ROS包

cd ~/ros_camera_ws/
catkin_make

7、测试

roscore
cd ~/ros_camera_ws/
source devel/setup.bash
rosrun learning_image_transport my_publisher 0

0代表默认摄像头,如果有多个摄像头,则第二个是1,依次类推。

cd ~/ros_camera_ws/
source devel/setup.bash
rosrun learning_image_transport my_subscriber

8、其他节点订阅图像

在对应功能包scripts文件夹下新建image_view.py

#!/usr/bin/env python3
#coding:utf-8

import rospy
import cv2
from sensor_msgs.msg import Image
from cv_bridge import CvBridge,CvBridgeError

def callback(data):
    cv_image=CvBridge().imgmsg_to_cv2(data,"bgr8")
    cv2.imshow("view",cv_image)
    cv2.waitKey(1)

if __name__ == '__main__':
    rospy.init_node('image_acquistion')
    rospy.Subscriber('camera/image', Image, callback)
    rospy.spin()
    cv2.destoryAllWindows()
rosrun &#x4F60;&#x7684;&#x5305;&#x540D; image_view.py

参考博客

Original: https://blog.csdn.net/qq_41426807/article/details/125618650
Author: Ponnyao
Title: Nvidia Jetson Agx Xavier 在Ros中调用GMSL2相机

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/702313/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球