00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00038
00039 #include <ros/ros.h>
00040 #include <cv_bridge/cv_bridge.h>
00041 #include <sensor_msgs/image_encodings.h>
00042 #include <sensor_msgs/Image.h>
00043 #include <image_transport/image_transport.h>
00044
00045
00046 #include <opencv2/objdetect/objdetect.hpp>
00047 #include <opencv2/imgproc/imgproc.hpp>
00048 #include <opencv2/highgui/highgui.hpp>
00049
00050 class TrackSequential
00051 {
00052 public:
00053 TrackSequential(ros::NodeHandle nh_);
00054 ~TrackSequential();
00055 image_transport::ImageTransport _imageTransport;
00056 image_transport::Subscriber image_sub;
00057
00058 protected:
00059 void imageCB(const sensor_msgs::ImageConstPtr& msg);
00060 void ImageProcessing();
00061 void ContourDetection(cv::Mat thresh_in, cv::Mat &output_);
00062
00063 private:
00064 std::string win1, win2;
00065 cv::Mat img_bgr, img1, img2, thresh, diff;
00066 int i;
00067 };
00068
00069
00070 TrackSequential::TrackSequential(ros::NodeHandle nh_): _imageTransport(nh_)
00071 {
00072 win1 = "orig";
00073 win2 = "thresh diff";
00074 image_sub = _imageTransport.subscribe("xtion/rgb/image_raw", 1, &TrackSequential::imageCB, this, image_transport::TransportHints("compressed"));
00075 cv::namedWindow(win1, CV_WINDOW_AUTOSIZE);
00076 cv::namedWindow(win2, CV_WINDOW_AUTOSIZE);
00077 i=0;
00078 }
00079
00080 TrackSequential::~TrackSequential()
00081 {
00082 cv::destroyWindow(win1);
00083 cv::destroyWindow(win2);
00084 }
00085
00086 void TrackSequential::imageCB(const sensor_msgs::ImageConstPtr& msg)
00087 {
00088 cv_bridge::CvImagePtr cvPtr;
00089 try
00090 {
00091 cvPtr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
00092 }
00093 catch (cv_bridge::Exception& e)
00094 {
00095 ROS_ERROR("cv_bridge exception: %s", e.what());
00096 return;
00097 }
00098 cvPtr->image.copyTo(img_bgr);
00099 cv::cvtColor(cvPtr->image, img1, cv::COLOR_BGR2GRAY);
00100 this->ImageProcessing();
00101
00102 img1.copyTo(img2);
00103 }
00104
00105 void TrackSequential::ImageProcessing()
00106 {
00107 if(i!=0)
00108 {
00109 cv::absdiff(img1,img2,diff);
00110 cv::threshold(diff, thresh, 20, 255, cv::THRESH_BINARY);
00111 cv::morphologyEx(thresh, thresh, 2, cv::getStructuringElement( 2, cv::Size(3, 3)));
00112 this->ContourDetection(thresh, img_bgr);
00113 cv::imshow(win1, img_bgr);
00114 cv::imshow(win2, thresh);
00115 }
00116 ++i;
00117 cv::waitKey(1);
00118 }
00119
00120 void TrackSequential::ContourDetection(cv::Mat thresh_in, cv::Mat &output_)
00121 {
00122 cv::Mat temp;
00123 cv::Rect objectBoundingRectangle = cv::Rect(0,0,0,0);
00124 thresh_in.copyTo(temp);
00125 std::vector<std::vector<cv::Point> > contours;
00126 std::vector<cv::Vec4i> hierarchy;
00127 cv::findContours(temp, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
00128 if(contours.size()>0)
00129 {
00130 std::vector<std::vector<cv::Point> > largest_contour;
00131 largest_contour.push_back(contours.at(contours.size()-1));
00132 objectBoundingRectangle = cv::boundingRect(largest_contour.at(0));
00133 int x = objectBoundingRectangle.x+objectBoundingRectangle.width/2;
00134 int y = objectBoundingRectangle.y+objectBoundingRectangle.height/2;
00135 cv::circle(output_,cv::Point(x,y),20,cv::Scalar(0,255,0),2);
00136 }
00137 }
00138
00139
00140 int main(int argc, char** argv)
00141 {
00142 ros::init(argc, argv, "TrackSequential");
00143 ros::NodeHandle nh;
00144 TrackSequential ts(nh);
00145 ros::spin();
00146 }