Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Object detection using OpenCV

Hello everyone,

I'm trying to do pattern recognition from some images and it's not working. I have my drone with a bottom camera, and the camera is connected to a ROS node. Using cv_bridge I converted the image from a ROS format to an OpenCV format, but what I have to do now is to detect if a determined pattern (learned previously) is in the image.

In the ROS node it appears a different image each 0.02 second (I can change the frequency). The pattern will stay on the floor, so what can be done is to detect the variance of the image (for example, the floor or the sea will have low variance, and the pattern that I set on the floor will have high variance (for example, a pattern like a chess table)).

This is the code that I'm using (http://wiki.ros.org/cv_bridge/Tutorials/UsingCvBridgeToConvertBetweenROSImagesAndOpenCVImages):

#include <ros/ros.h>
#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>

static const std::string OPENCV_WINDOW = "Image window";

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

public:
  ImageConverter()
    : it_(nh_)
  {
    // Subscrive to input video feed and publish output video feed
    image_sub_ = it_.subscribe("/camera/image_raw", 1,
      &ImageConverter::imageCb, this);
    image_pub_ = it_.advertise("/image_converter/output_video", 1);

    cv::namedWindow(OPENCV_WINDOW);
  }

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

  void imageCb(const sensor_msgs::ImageConstPtr& msg)
  {
    cv_bridge::CvImagePtr cv_ptr;
    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 > 60 && cv_ptr->image.cols > 60)
      cv::circle(cv_ptr->image, cv::Point(50, 50), 10, CV_RGB(255,0,0));

    // Update GUI Window
    cv::imshow(OPENCV_WINDOW, cv_ptr->image);
    cv::waitKey(3);

    // Output modified video stream
    image_pub_.publish(cv_ptr->toImageMsg());
  }
};

int main(int argc, char** argv)
{
  ros::init(argc, argv, "image_converter");
  ImageConverter ic;
  ros::spin();
  return 0;
}

but that code just prints the image and puts a red circle on the upper left corner, so what has to be modified is this part:

// Draw an example circle on the video stream
    if (cv_ptr->image.rows > 60 && cv_ptr->image.cols > 60)
      cv::circle(cv_ptr->image, cv::Point(50, 50), 10, CV_RGB(255,0,0));

I would like if you can help me. This is just the beginning of the project, then I have to take decisions in order to what is seen, and so on. If you don't have a code that does what I need, please provide me some links or books or whatever that can help me (I've been 2 days trying to make this work and I couldn't).

Thanks!

Object detection using OpenCV

Hello everyone,

I'm trying to do pattern recognition from some images and it's not working. I have my drone with a bottom camera, and the camera is connected to a ROS node. Using cv_bridge I converted the image from a ROS format to an OpenCV format, but what I have to do now is to detect if a determined pattern (learned previously) is in the image.

In the ROS node it appears a different image each 0.02 second (I can change the frequency). The pattern will stay on the floor, so what can be done is to detect the variance of the image (for example, the floor or the sea will have low variance, and the pattern that I set on the floor will have high variance (for example, a pattern like a chess table)).

This is the code that I'm using (http://wiki.ros.org/cv_bridge/Tutorials/UsingCvBridgeToConvertBetweenROSImagesAndOpenCVImages):

#include <ros/ros.h>
#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>

static const std::string OPENCV_WINDOW = "Image window";

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

public:
  ImageConverter()
    : it_(nh_)
  {
    // Subscrive to input video feed and publish output video feed
    image_sub_ = it_.subscribe("/camera/image_raw", 1,
      &ImageConverter::imageCb, this);
    image_pub_ = it_.advertise("/image_converter/output_video", 1);

    cv::namedWindow(OPENCV_WINDOW);
  }

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

  void imageCb(const sensor_msgs::ImageConstPtr& msg)
  {
    cv_bridge::CvImagePtr cv_ptr;
    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 > 60 && cv_ptr->image.cols > 60)
      cv::circle(cv_ptr->image, cv::Point(50, 50), 10, CV_RGB(255,0,0));

    // Update GUI Window
    cv::imshow(OPENCV_WINDOW, cv_ptr->image);
    cv::waitKey(3);

    // Output modified video stream
    image_pub_.publish(cv_ptr->toImageMsg());
  }
};

int main(int argc, char** argv)
{
  ros::init(argc, argv, "image_converter");
  ImageConverter ic;
  ros::spin();
  return 0;
}

but that code just prints the image and puts a red circle on the upper left corner, so what has to be modified is this part:

// Draw an example circle on the video stream
    if (cv_ptr->image.rows > 60 && cv_ptr->image.cols > 60)
      cv::circle(cv_ptr->image, cv::Point(50, 50), 10, CV_RGB(255,0,0));

I would like if you can help me. This is just the beginning of the project, then I have to take decisions in order to what is seen, and so on. If you don't have a code that does what I need, please provide me some links or books or whatever that can help me (I've been 2 days trying to make this work and I couldn't).

EDIT:

So I need your help in the OpenCV part (if you know about ROS it would be much better, but I can try to do the translation between OpenCV and ROS): imagine that a different image come to your program each 0.02 seconds and you have that time to see if in that image a predefined pattern appears. The pattern that I would like to recognize should be something that is not easy to find in nature, for example:

image description (without the blue arrow)

or this:

image description

or something similar

Thanks!