0
$\begingroup$

Rosanswers logo

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 into an OpenCV Matrix

    //Convert cv::Mat stitched to ROS image
    
    
    image_pub.publish(stitching_output);

    ros::spinOnce();

    loop_rate.sleep();
    ++count;
  }


  return 0;
}

Originally posted by soulfutterer on ROS Answers with karma: 13 on 2015-05-30

Post score: 1


Original comments

Comment by frankb on 2015-05-31:
are you following the turtorial here? http://wiki.ros.org/cv_bridge/Tutorials/UsingCvBridgeToConvertBetweenROSImagesAndOpenCVImages calling cv_bridge::toCvCopy with the correct image encoding?

Comment by soulfutterer on 2015-06-01:
Yes, I was working with the tutorial. I added my code to the post.

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

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;
  }

Originally posted by Wolf with karma: 7555 on 2015-06-02

This answer was ACCEPTED on the original site

Post score: 2


Original comments

Comment by soulfutterer on 2015-06-02:
Thank you very much for your explanation! It's working now. :)

$\endgroup$

Your Answer

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