00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <iostream>
00019 #include <vector>
00020 #include <opencv2/core/core.hpp>
00021 #include <opencv2/imgproc/imgproc.hpp>
00022 #include <opencv2/highgui/highgui.hpp>
00023
00024 #include <ros/ros.h>
00025 #include <image_transport/image_transport.h>
00026 #include <cv_bridge/cv_bridge.h>
00027 #include <sensor_msgs/image_encodings.h>
00028
00029 #include "linefinder.h"
00030 #include "edgedetector.h"
00031
00032 #define PI 3.1415926
00033 namespace enc = sensor_msgs::image_encodings;
00034
00035
00036 static const char WINDOW1[] = "Image Processed";
00037 static const char WINDOW0[] = "Image Raw";
00038
00039
00040 image_transport::Publisher pub;
00041
00042 int imageCallback(const sensor_msgs::ImageConstPtr& original_image)
00043 {
00044 int x=0 , y=0;
00045
00046 cv_bridge::CvImagePtr cv_ptr;
00047 cv::Mat im_gray;
00048 cv::Mat YCbCr;
00049 cv::Mat subImg;
00050 cv::Mat cv_clone;
00051
00052 try
00053 {
00054
00055
00056 cv_ptr = cv_bridge::toCvCopy(original_image, enc::BGR8);
00057 cv_clone = cv_ptr->image.clone();
00058
00059 }
00060 catch (cv_bridge::Exception& e)
00061 {
00062
00063 ROS_ERROR("tutorialROSOpenCV::main.cpp::cv_bridge exception: %s", e.what());
00064 return 0;
00065 }
00066
00067
00068 cv::Mat image;
00069 cv_clone.copyTo(image);
00070 if (!image.data)
00071 return 0;
00072
00073
00074
00075
00076
00077
00078
00079 EdgeDetector ed;
00080 ed.computeSobel(image);
00081
00082
00083 cv::namedWindow("Sobel (orientation)");
00084 cv::imshow("Sobel (orientation)",ed.getSobelOrientationImage());
00085 cv::waitKey(3);
00086 cv::imwrite("ori.bmp",ed.getSobelOrientationImage());
00087
00088
00089 cv::namedWindow("Sobel (low threshold)");
00090 cv::imshow("Sobel (low threshold)",ed.getBinaryMap(125));
00091 cv::waitKey(3);
00092
00093 cv::namedWindow("Sobel (high threshold)");
00094 cv::imshow("Sobel (high threshold)",ed.getBinaryMap(350));
00095 cv::waitKey(3);
00096
00097 cv::Mat contours;
00098 cv::Canny(image,contours,125,350);
00099 cv::Mat contoursInv;
00100 cv::threshold(contours,contoursInv,128,255,cv::THRESH_BINARY_INV);
00101
00102
00103 cv::namedWindow("Canny Contours");
00104 cv::imshow("Canny Contours",contoursInv);
00105 cv::waitKey(3);
00106
00107
00108 std::vector<cv::Vec2f> lines;
00109 cv::HoughLines(contours,lines,1,(75*PI)/180,60);
00110
00111
00112 cv::Mat result(contours.rows,contours.cols,CV_8U,cv::Scalar(255));
00113 image.copyTo(result);
00114
00115 std::cout << "Lines detected: " << lines.size() << std::endl;
00116
00117 std::vector<cv::Vec2f>::const_iterator it= lines.begin();
00118 while (it!=lines.end()) {
00119
00120 float rho= (*it)[0];
00121 float theta= (*it)[1];
00122
00123 if (theta < PI/4. || theta > 3.*PI/4.) {
00124
00125
00126 cv::Point pt1(rho/cos(theta),0);
00127
00128 cv::Point pt2((rho-result.rows*sin(theta))/cos(theta),result.rows);
00129
00130 cv::line( result, pt1, pt2, cv::Scalar(255), 1);
00131
00132 } else {
00133
00134
00135 cv::Point pt1(0,rho/sin(theta));
00136
00137 cv::Point pt2(result.cols,(rho-result.cols*cos(theta))/sin(theta));
00138
00139 cv::line( result, pt1, pt2, cv::Scalar(255), 1);
00140 }
00141
00142 std::cout << "line: (" << rho << "," << theta << ")\n";
00143
00144 ++it;
00145 }
00146
00147
00148 cv::namedWindow("Detected Lines with Hough");
00149 cv::imshow("Detected Lines with Hough",result);
00150 cv::waitKey(3);
00151
00152 LineFinder ld;
00153
00154
00155 ld.setLineLengthAndGap(15,40);
00156 ld.setMinVote(50);
00157
00158
00159 std::vector<cv::Vec4i> li= ld.findLines(contours);
00160 ld.drawDetectedLines(image);
00161 cv::namedWindow("Detected Lines with HoughP");
00162 cv::imshow("Detected Lines with HoughP",image);
00163
00164
00165 std::vector<cv::Vec4i>::const_iterator it2= li.begin();
00166 while (it2!=li.end()) {
00167
00168 std::cout << "(" << (*it2)[0] << ","<< (*it2)[1]<< ")-("
00169 << (*it2)[2]<< "," << (*it2)[3] << ")" <<std::endl;
00170
00171 ++it2;
00172 }
00173
00174
00175
00176 int n=0;
00177 cv::line(image, cv::Point(li[n][0],li[n][1]),cv::Point(li[n][2],li[n][3]),cv::Scalar(255),5);
00178 cv::namedWindow("One line of the Image");
00179 cv::imshow("One line of the Image",image);
00180
00181
00182 cv::Mat oneline(image.size(),CV_8U,cv::Scalar(0));
00183 cv::line(oneline, cv::Point(li[n][0],li[n][1]),cv::Point(li[n][2],li[n][3]),cv::Scalar(255),5);
00184 cv::bitwise_and(contours,oneline,oneline);
00185 cv::line(oneline, cv::Point(li[n+1][0],li[n+1][1]),cv::Point(li[n+1][2],li[n+1][3]),cv::Scalar(255),5);
00186 cv::bitwise_and(contours,oneline,oneline);
00187
00188 cv::Mat onelineInv;
00189
00190 cv::adaptiveThreshold(oneline, onelineInv, 128, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY_INV, 3, 5);
00191 cv::namedWindow("One line");
00192 cv::imshow("One line",onelineInv);
00193
00194 std::vector<cv::Point> points;
00195
00196
00197 for( int y = 0; y < oneline.rows; y++ ) {
00198
00199 uchar* rowPtr = oneline.ptr<uchar>(y);
00200
00201 for( int x = 0; x < oneline.cols; x++ ) {
00202
00203
00204 if (rowPtr[x]) {
00205
00206 points.push_back(cv::Point(x,y));
00207 }
00208 }
00209 }
00210
00211
00212 cv::Vec4f line;
00213 cv::fitLine(cv::Mat(points),line,CV_DIST_L2,0,0.01,0.01);
00214
00215 std::cout << "line: (" << line[0] << "," << line[1] << ")(" << line[2] << "," << line[3] << ")\n";
00216
00217 int x0= line[2];
00218 int y0= line[3];
00219 int x1= x0-200*line[0];
00220 int y1= y0-200*line[1];
00221
00222 cv::line(image,cv::Point(x0,y0),cv::Point(x1,y1),cv::Scalar(0),3);
00223 cv::namedWindow("Estimated line");
00224 cv::imshow("Estimated line",image);
00225
00226
00227 ld.removeLinesOfInconsistentOrientations(ed.getOrientation(),0.4,0.1);
00228
00229
00230
00231 ld.drawDetectedLines(image);
00232 cv::namedWindow("Detected Lines (2)");
00233 cv::imshow("Detected Lines (2)",image);
00234
00235
00236 cv::Mat acc(200,180,CV_8U,cv::Scalar(0));
00237
00238
00239 x=50, y=30;
00240
00241
00242 for (int i=0; i<180; i++) {
00243
00244 double theta= i*PI/180.;
00245
00246
00247 double rho= x*cos(theta)+y*sin(theta);
00248 int j= static_cast<int>(rho+100.5);
00249
00250 std::cout << i << "," << j << std::endl;
00251
00252
00253 acc.at<uchar>(j,i)++;
00254 }
00255
00256
00257
00258
00259 x=30, y=10;
00260
00261
00262 for (int i=0; i<180; i++) {
00263
00264 double theta= i*PI/180.;
00265 double rho= x*cos(theta)+y*sin(theta);
00266 int j= static_cast<int>(rho+100.5);
00267
00268 acc.at<uchar>(j,i)++;
00269 }
00270
00271 cv::namedWindow("Hough Accumulator");
00272 cv::imshow("Hough Accumulator",acc*100);
00273 ROS_ERROR("-------ERROR -----");
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309 cv::waitKey(3);
00310 return 0;
00311 }
00312
00313
00317 int main(int argc, char **argv)
00318 {
00319 ros::init(argc, argv, "test");
00320
00321 ros::NodeHandle nh;
00322
00323 image_transport::ImageTransport it(nh);
00324
00325 cv::namedWindow(WINDOW0, CV_WINDOW_AUTOSIZE);
00326 cv::namedWindow(WINDOW1, CV_WINDOW_AUTOSIZE);
00327
00328 image_transport::Subscriber sub = it.subscribe("image", 1, imageCallback);
00329
00330 cv::destroyWindow(WINDOW0);
00331 cv::destroyWindow(WINDOW1);
00332
00333 pub = it.advertise("image_processed", 1);
00334
00335 ros::spin();
00336 ROS_INFO("tutorialROSOpenCV::main.cpp::No error.");
00337 }