0
$\begingroup$

Rosanswers logo

Hi!

What's te best way to solely stream an image from disk? How do I convert from cv::Mat to proper ROS image message?

The relevant snippet would be:

cv_bridge::CvImagePtr cv_ptr;
cv_ptr->image = cv::imread(this->filename_);
image_pub_.publish(cv_ptr->toImageMsg());

How can the cv_bridge::CvImagePtr be initialized? The command above aborts at runtime as one would expect if the constructor requires something else. The error:

iri_simple_perception: /usr/include/boost/smart_ptr/shared_ptr.hpp:418: T* boost::shared_ptr< <template-parameter-1-1> >::operator->() const [with T = cv_bridge::CvImage]: Assertion `px != 0' failed.

Having a look at toCvCopyImpl seems a bit of an overkill ( http://www.ros.org/doc/api/cv_bridge/html/c++/cv__bridge_8cpp_source.html#l00200 ). So, any suggestions?


Originally posted by quimnuss on ROS Answers with karma: 169 on 2011-10-14

Post score: 5

$\endgroup$

3 Answers 3

0
$\begingroup$

Rosanswers logo

cv_bridge::CvImagePtr is a pointer type that points to NULL by default. You have to allocate storage before you can actually use it, and the boost assertion catches the null pointer dereference.

Correct would be either something like

cv_bridge::CvImagePtr cv_ptr(new cv_bridge::CvImage);

or

cv_bridge::CvImagePtr cv_ptr;
cv_ptr.reset (new cv_bridge::CvImage);

As a rule of thumb, every ROS type xxxPtr is a pointer type for xxx.


Originally posted by roehling with karma: 1951 on 2011-10-14

This answer was ACCEPTED on the original site

Post score: 4


Original comments

Comment by quimnuss on 2011-10-24:
There was a bug, it perfectly works now.

Comment by quimnuss on 2011-10-18:
Yes, I did. image_transport::Publisher pub = imgtransport_.advertise("disk/image", 1);

Comment by roehling on 2011-10-17:
Did you advertise the publisher properly? It is not sufficient just to declare a Publisher image_pub_, you must call ImageTransport::advertise() or something similar to get a valid Publisher object.

Comment by quimnuss on 2011-10-16:
I'll mark the question as unresolved, in case somebody steps up to this alternative approach.

Comment by quimnuss on 2011-10-14:
Yes, that looks more like what I was thinking of. There's, however, something I'm still missing: a fatal is reported by the publish(cv_ptr->toImageMsg()). 'Call to publish() on an invalid image_transport::Publisher'. I've tried both filling the header and encoding as well as leaving them blank.

$\endgroup$
0
$\begingroup$

Rosanswers logo

I've used the gscam driver to publish saved video files as a camera, and you can also use it to do snapshots, or really anything that gstreamer supports. You would be able to do what you want using this driver.


Originally posted by John Hoare with karma: 765 on 2011-10-14

This answer was NOT ACCEPTED on the original site

Post score: 1


Original comments

Comment by quimnuss on 2011-10-14:
Indeed it works! Thanks!

Comment by John Hoare on 2011-10-14:
It will be the same syntax as the gst-launch command. Store the command you used to the gst-launch (without the sink) to the environment variable GSCAM_CONFIG. See the wiki for details.

Comment by quimnuss on 2011-10-14:
Looks good. Although I am not familiar with the syntax, I've managed to publish the image through gst-launch. I'll look into it to port it to the gscam config export definition. Or you do know what that would be?

Comment by John Hoare on 2011-10-14:
Sure, however you'll have to adjust the gstreamer pipeline to constantly publish the same image.

Comment by quimnuss on 2011-10-14:
Would it work with a single still jpg image?

$\endgroup$
0
$\begingroup$

Rosanswers logo

Here is my example that I got working in Hydro

#include <ros/ros.h>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>

int main(int argc, char** argv)
{
  ros::init(argc, argv, "image_publisher");
  ros::NodeHandle nh;

    cv_bridge::CvImage cv_image;
    cv_image.image = cv::imread("/home/taylor/Pictures/face.jpg",CV_LOAD_IMAGE_COLOR);
    cv_image.encoding = "bgr8";
    sensor_msgs::Image ros_image;
    cv_image.toImageMsg(ros_image);

  ros::Publisher pub = nh.advertise<sensor_msgs::Image>("/static_image", 1);
  ros::Rate loop_rate(5);

  while (nh.ok()) 
  {
    pub.publish(ros_image);
    loop_rate.sleep();
  }
}

Originally posted by TFinleyosu with karma: 385 on 2014-02-13

This answer was NOT ACCEPTED on the original site

Post score: 2


Original comments

Comment by sam on 2015-07-13:
Thank you very much! This code is excellent!

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.