ROS学习——读取摄像头数据image

在ROS工作空间的src文件夹下创建read_camera功能包,并在包内创建include、launch、src、cfg四个文件夹。
在cfg文件夹中创建param.yaml文件,并写入以下内容:

image_dev: /dev/video0
save_path: /home/huanyu/datasets/camera

save: false
visualization: true

在include文件夹中创建camera_manager.h文件,并写入以下内容:

#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<cv_bridge/cv_bridge.h> 
#include <image_transport/image_transport.h>
#include<ros/ros.h>
#include<string>
#include<iostream>
#include<sensor_msgs/Image.h>
#include<sensor_msgs/image_encodings.h>
#include<std_msgs/Header.h>
#include<sys/stat.h>
class CameraManager
{
public:
    CameraManager(ros::NodeHandle nh,std::string name,int hz,std::string path="./");
    cv::Mat* read_image(bool save);
 const cv::Mat& getRGB() const{return RGB_;}
    const cv::Mat& getGRY() const{return GRAY_;}
    const double get_delay() const{return delay_;}
bool save_image(std::string name,cv::Mat& image)
    {
         //std::cout << path_+name << std::endl;
         return cv::imwrite(path_+name,image);
    }
  void spin(bool ros_send = true ,bool save = false,bool visualization = false);
private:
 image_transport::ImageTransport nh_;
    image_transport::Publisher image_pub;
   //for visualization
    cv::Mat GRAY_;
    cv::Mat RGB_;
   cv::VideoCapture capture_;
   int size_[3];
   int hz_;
    double delay_;
    std::string device_name_;
    std::string path_;
};
在src文件夹中创建camera_manager.cpp文件,并写入以下内容:
#include"camera_manager.h"
using namespace std;
CameraManager::CameraManager(ros::NodeHandle nh,std::string name,int hz,std::string path):
nh_(nh),device_name_(name),hz_(hz),path_(path)
{
    delay_ = 1000.0/hz_;
   cout<<"delay: "<<delay_<<endl;
   capture_ = cv::VideoCapture(0);
    
    if(!capture_.isOpened())
        return;
 cv::Mat frame;
    capture_ >> frame;
    size_[0] = frame.size[0];
    size_[1] = frame.size[1];
    size_[2] = frame.size[2];
    image_pub = nh_.advertise("/sensor_msgs/image_gray",5);
}
cv::Mat* CameraManager::read_image(bool save)
{
    cv::Mat frame,gray;
    capture_ >> frame;
    ros::Time timestamp = ros::Time::now();
    std::string time_second = std::to_string(timestamp.toSec()*1e9);
    std::string image_name(time_second);
    image_name.erase(19);
    image_name.append(".png");
    if(frame.empty())
    {
        //std::cout << "frequency is too high"<<std::endl;
        return nullptr;
    }
    cv::cvtColor(frame, gray, CV_BGR2GRAY);
    RGB_ = frame;
    GRAY_ = gray;
    if(save)
    {
        save_image(image_name, gray);
    }
    return &RGB_;
}
void CameraManager::spin(bool ros_send ,bool save,bool visualization)
{    
    sensor_msgs::ImagePtr msg;
    while(ros::ok())
    {
        cv::Mat* imagePtr = read_image(save);
        if(visualization) imshow("image_gray",*imagePtr);
        if(imagePtr&&ros_send)
        {
            msg = cv_bridge::CvImage(std_msgs::Header(), "bgr8", *imagePtr).toImageMsg();
            image_pub.publish(msg);
        }
        cv::waitKey(delay_);
    }
}

在launch文件夹中创建read_image.launch文件,并写入以下内容:

<launch>
    <node pkg = "read_camera" type="read_image" name="read_image" output="screen">
        <rosparam file="$(find read_camera)/cfg/param.yaml" command="load"/>
    </node>

    <node pkg="rviz" type="rviz" name="rviz"/>
</launch>

下面还提供了保存照片的函数,需要的人自行编译save_image.cpp

#include<ros/ros.h>
#include<sensor_msgs/CameraInfo.h>
#include<opencv2/opencv.hpp>
#include"camera_manager.h"
using namespace cv;
int main(int argc,char** argv)
{
    ros::init(argc,argv,"save_images");
    ros::NodeHandle nh;
    std::string device_name,save_path;
    bool save,visualization;
    ros::param::get("~/image_dev",device_name);
    ros::param::get("~/save_path",save_path);
    ros::param::get("~/visualization",visualization);
    CameraManager cm(nh,device_name,20,save_path);
    cm.spin(true,visualization,save);
}

需要注意的一点是,在读取摄像头数据的时候用到了OpenCV,所以在CMakeLists.txt文件find_package中加入OpenCV。
重新打开终端,输入rviz,运行rviz,然后修改image Topic为/sensor_msgs/image_gray,在rviz左下角就会显示摄像头的图像了。

  • 3
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值