Ask Your Question
0

Using image callback and videocallback OpenCV Kinetic

asked 2017-08-12 21:30:43 -0600

DAC31415 gravatar image

updated 2017-08-12 23:19:39 -0600

Hi all! First question in the site!

Hope you guys can help me out, I've got a problem by trying to use an image inside a function. In this function I got an example of edge detector from the camera. I want to use SIFT Feature Detector but I can't manage to use the information of the image. I think it is because in some way I haven't made the callback properly.

I have a node that publishes image and in an other node I want to subscribe to that image and compare it with the video frame. The only way I got to read that image is putting the subscriber in the main function.

#include <ros/ros.h>
#include <iostream>
#include <sstream>
#include <math.h>
#include <string>
#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 <opencv2/core/types_c.h>
#include <opencv2/core/core_c.h>
#include <opencv2/xfeatures2d/nonfree.hpp>
#include <opencv2/features2d/features2d.hpp>

using namespace cv;
using namespace std;
using namespace xfeatures2d;

Mat train, train_g;
Mat train_desc;
vector<KeyPoint> train_kp;
static const std::string OPENCV_WINDOW = "Raw Image window";
static const std::string OPENCV_WINDOW_1 = "Edge Detection";
static const std::string OPENCV_WINDOW_2 = "TEST_G";

void imageCallback(const sensor_msgs::ImageConstPtr& msg) {
   try {

        train=cv_bridge::toCvShare(msg, "bgr8")->image;
    cvtColor(train,train_g,CV_BGR2GRAY);    
    cv::imshow("Original", train);
    cv::imshow("Gray", train_g);
    cv::waitKey(30);
 }
  catch (cv_bridge::Exception& e) {
    ROS_ERROR("Could not convert from '%s' to 'bgr8'.", msg->encoding.c_str());
  }
}

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

public:
 Edge_Detector():it_(nh_)
 {
   // Subscribe to input video feed and publish output video feed
   image_sub_ = it_.subscribe("/cv_camera/image_raw", 1, &Edge_Detector::imageCb, this); //usb_cam
   image_pub_ = it_.advertise("/edge_detector/raw_image", 1); ///edge_detector/raw_image
   //createTrackbars();
 }

 ~Edge_Detector()
 {
  cv::destroyWindow(OPENCV_WINDOW);
 }

 void imageCb(const sensor_msgs::ImageConstPtr& msg)
 {

   cv_bridge::CvImagePtr cv_ptr;
   namespace enc = sensor_msgs::image_encodings;

   try
       {
       cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
       }
       catch (cv_bridge::Exception& e)
       {
       ROS_ERROR("cv_bridge exception: %s", e.what());
       return;
       }

// Draw an example circle on the video stream
//if (cv_ptr->image.rows > 400 && cv_ptr->image.cols > 600){

detect_edges(cv_ptr->image); // sth tells me here is the problem, I'm not caling the image but I have tried many things and still doesn't work.
    image_pub_.publish(cv_ptr->toImageMsg());

//}
    }


 void detect_edges(cv::Mat img) {

     cv::Mat src, src_gray;
 cv::Mat dst, detected_edges;

     int edgeThresh = 1;
 int lowThreshold = 200;
 int highThreshold =300;
 int kernel_size = 5;

 img.copyTo(src);

 cv::cvtColor( img, src_gray, CV_BGR2GRAY );
     cv::blur( src_gray, detected_edges, cv::Size(5,5) );
 cv::Canny( detected_edges, detected_edges, lowThreshold, highThreshold, kernel_size );

 dst = cv::Scalar::all(0);
 img.copyTo( dst, detected_edges);
 dst.copyTo(img);

     Mat test, test_g;

    cv::cvtColor(img, test_g, CV_BGR2GRAY);


 //detect SIFT keypoints and extract descriptors in the test image
vector<KeyPoint> test_kp;
Mat test_desc;
Ptr<SiftFeatureDetector> featureDetector=SiftFeatureDetector::create();//SiftFeatureDetector featureDetector;
featureDetector->detect(test_g, test_kp);//featureDetector.detect(test_g, test_kp);
Ptr<SiftDescriptorExtractor> featureExtractor=SiftDescriptorExtractor::create(); //SiftDescriptorExtractor featureExtractor;
featureExtractor->compute(test_g, test_kp, test_desc);//featureExtractor.compute(test_g, test_kp, test_desc ...
(more)
edit retag flag offensive close merge delete

Comments

What do you mean by "I can't manage to use the information of the image" and "I think it is because in some way I haven't made the callback properly"? Why do you believe this? Is there any terminal output that you can copy and paste such as errors/warnings?

jayess gravatar imagejayess ( 2017-08-12 22:34:13 -0600 )edit

Yes, I got this: OpenCV Error: Assertion failed (!outImage.empty()) in drawKeypoints, file /tmp/binarydeb/ros-kinetic-opencv3-3.2.0/modules/features2d/src/draw.cpp, line 115 terminate called after throwing an instance of 'cv::Exception' what(): /tmp/binarydeb/ros-kinetic-opencv3-3.2.0/modul....

DAC31415 gravatar imageDAC31415 ( 2017-08-12 22:58:43 -0600 )edit

/modules/features2d/src/draw.cpp:115: error: (-215) !outImage.empty() in function drawKeypoints

Aborted (core dumped)

As far as I know and investigated it is because I have and empty mat and I guess is the image.

DAC31415 gravatar imageDAC31415 ( 2017-08-12 22:59:55 -0600 )edit

Please update your question with any errors (such as the one you just mentioned) and warnings.

jayess gravatar imagejayess ( 2017-08-12 23:01:02 -0600 )edit

Ok, that's the only one. thx

DAC31415 gravatar imageDAC31415 ( 2017-08-12 23:20:13 -0600 )edit

1 Answer

Sort by ยป oldest newest most voted
0

answered 2017-08-12 23:44:26 -0600

jayess gravatar image

updated 2017-08-13 00:08:11 -0600

According to this answer on Stack Overflow, it may be from these lines:

Mat img_show;
drawMatches(test, test_kp, train, train_kp, good_matches, img_show);

The error message hints that it's not expecting an empty() image. You can try to initialize the image with black pixels first:

img_show = Mat::zeros(img_1.size(), CV_8UC3 );

Notice I'm using the first image dimensions/size, assuming both images have the same size. Be sure double check your setup and use the appropriate size. Additionally you can put the block in a try...catch block to see the details:

try {  //your drawKeyPoints code here
} catch (cv::Exception &e) { 
  cerr <<  e.msg << endl;  
}
edit flag offensive delete link more

Comments

I noticed a copy and paste error on my part so I updated the answer with img_show instead of img_matches

jayess gravatar imagejayess ( 2017-08-13 00:08:59 -0600 )edit

I added that lines and the same error message. I will try to separate the program in different nodes. THX

DAC31415 gravatar imageDAC31415 ( 2017-08-16 15:03:35 -0600 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2017-08-12 21:30:43 -0600

Seen: 296 times

Last updated: Aug 13 '17