ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
1

Working with cv_bridge and OpenCV correctly

asked 2015-05-30 09:01:44 -0500

soulfutterer gravatar image

updated 2015-06-01 10:49:55 -0500

Hello, I am struggling to use cv_bridge correctly. Do I have to convert the cv_bridge to a cv::Mat, before I can use OpenCV's functions? My situation is the following: I wrote a simple OpenCV application and now want to use it as a ros-node. So I changed my code for all relevant parts from

cvtColor( image, gray_image, CV_BGR2GRAY );

to

cvtColor( cv_ptr->image, gray_cv_ptr->image, CV_BGR2GRAY );

(with cv::Mat image and cv_bridge::CvImagePtr cv_ptr).

However I get the same error every time I run the node:

/usr/include/boost/smart_ptr/shared_ptr.hpp:653: typename boost::detail::sp_member_access<T>::type boost::shared_ptr<T>::operator->() const [with T = cv_bridge::CvImage; typename boost::detail::sp_member_access<T>::type = cv_bridge::CvImage*]: Assertion `px != 0' failed. Aborted (core dumped)

I already figured out, that I am somehow not using cv_bridge correctly. I get the same error, once I try Mat image= cv_ptr->image or interact with cv_bridge variables and OpenCV otherwise.

Where is the fallacy?

EDIT: This is my code:

#include "ros/ros.h"            //ROS
#include <stdio.h>
#include <iostream>
#include <sensor_msgs/Image.h> 
#include <sensor_msgs/image_encodings.h>    //Converting ROS to OpenCV images
#include <cv_bridge/cv_bridge.h>            //Converting ROS to OpenCV images
#include <image_transport/image_transport.h>//Publishing and subscribing to images in ROS
#include <opencv2/imgproc/imgproc.hpp>      //Converting ROS to OpenCV images
#include "opencv2/core/core.hpp"            //OpenCV Stitching
#include "opencv2/features2d/features2d.hpp"//OpenCV Stitching
#include "opencv2/highgui/highgui.hpp"      //OpenCV Stitching 
#include "opencv2/nonfree/nonfree.hpp"      //OpenCV Stitching
#include "opencv2/calib3d/calib3d.hpp"      //OpenCV Stitching
#include "opencv2/imgproc/imgproc.hpp"      //OpenCV Stitching

using namespace cv;

// Create a container for the data.
sensor_msgs::Image cam1;
sensor_msgs::Image cam2;
sensor_msgs::Image output;
cv_bridge::CvImagePtr cv_ptr1;          //ROS and OpenCV suitable image for cam1
cv_bridge::CvImagePtr cv_ptr2;          //ROS and OpenCV suitable image for cam1
cv_bridge::CvImagePtr stitching_output; //ROS and OpenCV suitable output
Mat image1;
Mat image2; 

//Callback Funktionen
//If an image is published load it into the global variable
void cam1_cb (const sensor_msgs::ImageConstPtr& input)
{
  cam1=*input;
  ROS_INFO("Input from cam1");

  //Convert ROS image message to CvImage suitable for OpenCV
  try
  {
        cv_ptr1 = cv_bridge::toCvCopy(input, sensor_msgs::image_encodings::BGR8);
  }
  catch (cv_bridge::Exception& e)
  {
        ROS_ERROR("cv_bridge exception: %s", e.what());
        return;
  }
}

void cam2_cb (const sensor_msgs::ImageConstPtr& input)
{
  cam2=*input;
  ROS_INFO("Input from cam2");
  //Convert ROS image message to CvImage suitable for OpenCV
  try
  {
        cv_ptr2 = cv_bridge::toCvCopy(input, sensor_msgs::image_encodings::BGR8);
  }
  catch (cv_bridge::Exception& e)
  {
        ROS_ERROR("cv_bridge exception: %s", e.what());
        return;
  }
}

int main(int argc, char **argv)
{

  ros::init(argc, argv, "img_stitch");

  ros::NodeHandle n;

  //Create a publisher for the stitched images
  ros::Publisher image_pub = n.advertise<sensor_msgs::Image>("stitched", 1);

  //Publish-rate [Hz]
  ros::Rate loop_rate(1);

  //Create ROS subscribers for the input images
  ros::Subscriber sub1 = n.subscribe ("topicname", 1, cam1_cb);
  ros::Subscriber sub2 = n.subscribe ("topicname", 1, cam2_cb);

  int count = 0;
  while (ros::ok())
  {
    //Here is usually my stitching-routine. 
    //I left it out for visibility as nothing should be wrong with it.         
    // Error occurs for example in this line:
     image1 = cv_ptr1->image;     //Load the cv_bridge image ...
(more)
edit retag flag offensive close merge delete

Comments

are you following the turtorial here? http://wiki.ros.org/cv_bridge/Tutoria... calling cv_bridge::toCvCopy with the correct image encoding?

frankb gravatar image frankb  ( 2015-05-31 01:56:44 -0500 )edit

Yes, I was working with the tutorial. I added my code to the post.

soulfutterer gravatar image soulfutterer  ( 2015-06-01 10:41:18 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted
2

answered 2015-06-02 04:50:49 -0500

Wolf gravatar image

In the while loop you have to wait for the images to arrive. By default your ptrs will be initialized to NULL, so accessing them before the call backs are called will fail; and you are guaranteed to do so at least in your first loop iteration of your while loop. Try something like:

 int count = 0;
  while (ros::ok())
  {
    if ( cv_ptr1 && cv_ptr2 )
    {
        //Here is usually your stitching-routine. 
       // Error won't occur here:
       image1 = cv_ptr1->image;     //Load the cv_bridge image into an OpenCV Matrix

       //Convert cv::Mat stitched to ROS image


       image_pub.publish(stitching_output);

       // after you have processed the image your might want to release them
       // so your node does not process the same images multiple times
       // reset the ptrs and wait for the callbacks to fill them again
       cv_ptr1.reset();
       cv_ptr2.reset();
    }
    else
    {
       // nothing can be done here; we have to spin and wait for images to arrive
    }


    ros::spinOnce();

    loop_rate.sleep();
    ++count;
  }
edit flag offensive delete link more

Comments

Thank you very much for your explanation! It's working now. :)

soulfutterer gravatar image soulfutterer  ( 2015-06-02 13:43:05 -0500 )edit

Question Tools

1 follower

Stats

Asked: 2015-05-30 09:01:44 -0500

Seen: 3,594 times

Last updated: Jun 02 '15