mkuse
mkuse

Reputation: 2488

ROS custom message with sensor_msgs/Image issue with subscriber

I have a custom message -

sensor_msgs/Image im
float32 age
string name

I could successfully write a publisher for this message and it seem to run ok. However, I have an issue with the subscriber.

#include <ros/ros.h>

#include <custom_msg/MyString.h>
#include <custom_msg/MyImage.h>

#include <image_transport/image_transport.h>
#include <sensor_msgs/Image.h>

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>
#include <cv_bridge/cv_bridge.h>


void custom_image_rcvd( const custom_msg::MyImage& msg )
{
    ROS_INFO_STREAM( "msg::: Name:"<< msg.name << " Age:"<< msg.age );

    cv::Mat im =  cv_bridge::toCvShare(  msg.im, "bgr8" )->image ;
    cv::imshow("viewz", im );
    cv::waitKey(30);
}

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

    ros::Subscriber sub2 = nh.subscribe( "custom_image", 2, custom_image_rcvd );

    ros::spin();
}

When I try to catkin_make this I get the following error.

/home/eeuser/ros_workspaces/HeloRosProject/src/custom_msg/subsc.cpp: In function ‘void custom_image_rcvd(const MyImage&)’:
/home/eeuser/ros_workspaces/HeloRosProject/src/custom_msg/subsc.cpp:22:57: error: no matching function for call to ‘toCvShare(const _im_type&, const char [5])’
/home/eeuser/ros_workspaces/HeloRosProject/src/custom_msg/subsc.cpp:22:57: note: candidates are:
/opt/ros/hydro/include/cv_bridge/cv_bridge.h:198:17: note: cv_bridge::CvImageConstPtr cv_bridge::toCvShare(const Image&, const boost::shared_ptr<const void>&, const string&)
/opt/ros/hydro/include/cv_bridge/cv_bridge.h:198:17: note:   no known conversion for argument 2 from ‘const char [5]’ to ‘const boost::shared_ptr<const void>&’
/opt/ros/hydro/include/cv_bridge/cv_bridge.h:171:17: note: cv_bridge::CvImageConstPtr cv_bridge::toCvShare(const ImageConstPtr&, const string&)
/opt/ros/hydro/include/cv_bridge/cv_bridge.h:171:17: note:   no known conversion for argument 1 from ‘const _im_type {aka const sensor_msgs::Image_<std::allocator<void> >}’ to ‘const ImageConstPtr& {aka const boost::shared_ptr<const sensor_msgs::Image_<std::allocator<void> > >&}’
make[2]: *** [custom_msg/CMakeFiles/subscribe.dir/subsc.cpp.o] Error 1
make[1]: *** [custom_msg/CMakeFiles/subscribe.dir/all] Error 2
make: *** [all] Error 2
Invoking "make" failed

What I can make out is that msg.im is of the type _im_type aka. sensor_msgs::Image_<ContainerAllocator>. I cannot seem to understand this part.

How can I retrieve my image correctly from this custom message?

Upvotes: 2

Views: 3225

Answers (1)

luator
luator

Reputation: 5019

You have to take a closer look on the signature of toCvShare. It can be read from the error message, that this function has two overloads:

cv_bridge::CvImageConstPtr cv_bridge::toCvShare(const Image&, const boost::shared_ptr<const void>&, const string&)

and

cv_bridge::CvImageConstPtr cv_bridge::toCvShare(const ImageConstPtr&, const string&)

So the function either expects an Image plus a pointer to some object (first case) or a ImageConstPtr (second case). You are, however, only passing a Image, so this matches neither of the two options.

If I understand the API documentation correctly, the second argument in the first case is expected to be a pointer to the message that contains the image. Try the following code:

void custom_image_rcvd(const custom_msg::MyImageConstPtr& msg)
{
    ROS_INFO_STREAM("msg::: Name:" << msg->name << " Age:" << msg->age);

    cv::Mat im =  cv_bridge::toCvShare(msg->im, msg, "bgr8")->image;
    cv::imshow("viewz", im);
    cv::waitKey(30);
}

Note that I changed the call of toCvShare as well as the signature of the callback.

Upvotes: 3

Related Questions