1

I'm using ROS and OpenCV in C++ environment in order to acquire a video (gray-scale) from a ROS node, convert the data through cv_bridge (in order to elaborate it through OpenCV), extract some data and publish them on a topic as ROS messages.

My problem is that I don't know how to send the array frame to the main function in order to elaborate it! I cannot elaborate out of it, because I need to distinguish between different data of different frames. This is my code:

#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <vector>
#include "rd_ctrl/proc_data.h"
#include <cv.h>

using namespace std;
namespace enc = sensor_msgs::image_encodings;


rd_ctrl::proc_data points;

ros::Publisher data_pub_; 

static const char WINDOW[] = "Image window";

class ImageConverter
{
  ros::NodeHandle nh_;
  image_transport::ImageTransport it_;
  image_transport::Subscriber image_sub_;
  image_transport::Publisher image_pub_;

public:
  ImageConverter()
    : it_(nh_)
  {
    image_pub_ = it_.advertise("out", 1);
    image_sub_ = it_.subscribe("/vrep/visionSensorData", 1, &ImageConverter::imageCb, this);


    cv::namedWindow(WINDOW);
  }

  ~ImageConverter()
  {
    cv::destroyWindow(WINDOW);
  }

  void imageCb(const sensor_msgs::ImageConstPtr& msg)
  {
    cv_bridge::CvImagePtr cv_ptr;
    try
    {
      cv_ptr = cv_bridge::toCvCopy(msg, enc::BGR8);
    }
    catch (cv_bridge::Exception& e)
    {
      ROS_ERROR("cv_bridge exception: %s", e.what());
      return;
    }

 CvMat frame= cv_ptr->image;     //definition of "frame"
cvSmooth(&frame, &frame, CV_MEDIAN);
 cvThreshold(&frame, &frame,200, 255,CV_THRESH_BINARY);

    cv::imshow(WINDOW, cv_ptr->image);
    cv::waitKey(3);

    image_pub_.publish(cv_ptr->toImageMsg());
  }
};


int main(int argc, char** argv)
{
  ros::init(argc, argv, "image_proc");
  ImageConverter ic;
ros::NodeHandle n;

//....elaboration of "frame" and production of the data "points"

data_pub_.publish(points);

data_pub_ = n.advertise<rd_ctrl::proc_data>("/data_im", 1);

 ros::spin();
  return 0;
}

I hope that the question is clear enough. Can you help me please?

Tom Walters
  • 15,366
  • 7
  • 57
  • 74
Matteo
  • 51
  • 1
  • 1
  • 5

1 Answers1

1

Now if I understand you correctly you want to call imageCb and have the frame it creates passed back to main. If that is indeed the case then you can modify imageCb as follows:

void imageCb(const sensor_msgs::ImageConstPtr& msg, cv::Mat frame )

You will need to create the frame in main and pass it imageCb:

cv::Mat frame ;
ic.imageCb( ..., frame ) ;

This will use the copy constructor, it will just copy the header and use a pointer to the actual data, so it won't be very expensive.

This previous thread has a much more detailed elaboration on cv::Mat copy constructor.

Community
  • 1
  • 1
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740