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
00037 #include <ros/ros.h>
00038 #include <cv_bridge/cv_bridge.h>
00039 #include <sensor_msgs/image_encodings.h>
00040 #include <sensor_msgs/Image.h>
00041 #include <image_transport/image_transport.h>
00042
00043 #include <opencv2/highgui/highgui.hpp>
00044 #include <opencv2/imgproc/imgproc.hpp>
00045
00046 #include <iostream>
00047 #include <stdio.h>
00048 #include <stdlib.h>
00049
00050
00051 class CornerDetection
00052 {
00053 public:
00054 CornerDetection(ros::NodeHandle nh_);
00055 ~CornerDetection();
00056
00057 protected:
00058 void myShiTomasi_function(cv::Mat img, cv::Mat img_gray, cv::Mat myShiTomasi_dst);
00059 void myHarris_function(cv::Mat img, cv::Mat img_gray);
00060 void imageCB(const sensor_msgs::ImageConstPtr& msg);
00061
00062 image_transport::ImageTransport _imageTransport;
00063 image_transport::Subscriber image_sub;
00064
00065 int myShiTomasi_qualityLevel = 50;
00066 int myHarris_qualityLevel = 50;
00067 int max_qualityLevel = 100;
00068 int blockSize_shi = 3;
00069 int blockSize_harris = 3;
00070 int apertureSize = 3;
00071 cv::Mat myHarris_copy, myShiTomasi_copy, Mc;
00072 double myHarris_minVal, myHarris_maxVal, myShiTomasi_minVal, myShiTomasi_maxVal;
00073 };
00074
00075 const std::string shiTomasi_win = "My ShiTomasi window";
00076 const std::string harris_win = "My Harris window";
00077 cv::RNG rng(12345);
00078
00079 CornerDetection::CornerDetection(ros::NodeHandle nh_): _imageTransport(nh_)
00080 {
00081 image_sub = _imageTransport.subscribe("xtion/rgb/image_raw", 1, &CornerDetection::imageCB, this, image_transport::TransportHints("compressed"));
00082
00083 cv::namedWindow(shiTomasi_win, CV_WINDOW_FREERATIO);
00084 cv::createTrackbar( " Quality Level:", shiTomasi_win, &myShiTomasi_qualityLevel, max_qualityLevel);
00085 cv::createTrackbar( " Block Size:", shiTomasi_win, &blockSize_shi, 25);
00086 cv::namedWindow(harris_win, CV_WINDOW_FREERATIO);
00087 cv::createTrackbar( " Quality Level:", harris_win, &myHarris_qualityLevel, max_qualityLevel);
00088 cv::createTrackbar( " Block Size:", harris_win, &blockSize_harris, 25);
00089 }
00090
00091 CornerDetection::~CornerDetection()
00092 {
00093 cv::destroyAllWindows();
00094 }
00095
00096 void CornerDetection::imageCB(const sensor_msgs::ImageConstPtr& msg)
00097 {
00098 if(blockSize_harris == 0)
00099 blockSize_harris = 1;
00100 if(blockSize_shi == 0)
00101 blockSize_shi = 1;
00102
00103 cv::Mat img, img_gray, myHarris_dst, myShiTomasi_dst;
00104 cv_bridge::CvImagePtr cvPtr;
00105
00106 try
00107 {
00108 cvPtr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
00109 }
00110 catch (cv_bridge::Exception& e)
00111 {
00112 ROS_ERROR("cv_bridge exception: %s", e.what());
00113 return;
00114 }
00115 cvPtr->image.copyTo(img);
00116 cv::cvtColor(img, img_gray, cv::COLOR_BGR2GRAY);
00117
00118 myHarris_dst = cv::Mat::zeros( img_gray.size(), CV_32FC(6) );
00119 Mc = cv::Mat::zeros( img_gray.size(), CV_32FC1 );
00120
00121 cv::cornerEigenValsAndVecs( img_gray, myHarris_dst, blockSize_harris, apertureSize, cv::BORDER_DEFAULT );
00122
00123 for( int j = 0; j < img_gray.rows; j++ )
00124 for( int i = 0; i < img_gray.cols; i++ )
00125 {
00126 float lambda_1 = myHarris_dst.at<cv::Vec6f>(j, i)[0];
00127 float lambda_2 = myHarris_dst.at<cv::Vec6f>(j, i)[1];
00128 Mc.at<float>(j,i) = lambda_1*lambda_2 - 0.04f*pow( ( lambda_1 + lambda_2 ), 2 );
00129 }
00130
00131 cv::minMaxLoc( Mc, &myHarris_minVal, &myHarris_maxVal, 0, 0, cv::Mat() );
00132
00133 this->myHarris_function(img, img_gray);
00134
00135 myShiTomasi_dst = cv::Mat::zeros( img_gray.size(), CV_32FC1 );
00136 cv::cornerMinEigenVal( img_gray, myShiTomasi_dst, blockSize_shi, apertureSize, cv::BORDER_DEFAULT );
00137 cv::minMaxLoc( myShiTomasi_dst, &myShiTomasi_minVal, &myShiTomasi_maxVal, 0, 0, cv::Mat() );
00138
00139 this->myShiTomasi_function(img, img_gray, myShiTomasi_dst);
00140
00141 cv::waitKey(2);
00142 }
00143
00144
00145 void CornerDetection::myHarris_function(cv::Mat img, cv::Mat img_gray)
00146 {
00147 myHarris_copy = img.clone();
00148
00149 if( myHarris_qualityLevel < 1 )
00150 myHarris_qualityLevel = 1;
00151
00152 for( int j = 0; j < img_gray.rows; j++ )
00153 for( int i = 0; i < img_gray.cols; i++ )
00154 if( Mc.at<float>(j,i) > myHarris_minVal + ( myHarris_maxVal - myHarris_minVal )*myHarris_qualityLevel/max_qualityLevel )
00155 cv::circle( myHarris_copy, cv::Point(i,j), 4, cv::Scalar( rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255) ), -1, 8, 0 );
00156
00157 cv::imshow( harris_win, myHarris_copy );
00158 }
00159
00160 void CornerDetection::myShiTomasi_function(cv::Mat img, cv::Mat img_gray, cv::Mat myShiTomasi_dst)
00161 {
00162 myShiTomasi_copy = img.clone();
00163
00164 if( myShiTomasi_qualityLevel < 1 )
00165 myShiTomasi_qualityLevel = 1;
00166
00167 for( int j = 0; j < img_gray.rows; j++ )
00168 for( int i = 0; i < img_gray.cols; i++ )
00169 if( myShiTomasi_dst.at<float>(j,i) > myShiTomasi_minVal + ( myShiTomasi_maxVal - myShiTomasi_minVal )*myShiTomasi_qualityLevel/max_qualityLevel )
00170 cv::circle( myShiTomasi_copy, cv::Point(i,j), 4, cv::Scalar( rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255) ), -1, 8, 0 );
00171
00172 cv::imshow( shiTomasi_win, myShiTomasi_copy );
00173 }
00174
00175
00176 int main(int argc, char** argv)
00177 {
00178 ros::init(argc, argv, "FindKeypoints");
00179
00180 ros::NodeHandle nh;
00181
00182 CornerDetection cd(nh);
00183
00184 ros::spin();
00185 }