20 #include <opencv2/core/core.hpp>
21 #include <opencv2/imgproc/imgproc.hpp>
22 #include <opencv2/highgui/highgui.hpp>
25 #include <image_transport/image_transport.h>
26 #include <cv_bridge/cv_bridge.h>
27 #include <sensor_msgs/image_encodings.h>
33 namespace enc = sensor_msgs::image_encodings;
36 static const char WINDOW1[] =
"Image Processed";
37 static const char WINDOW0[] =
"Image Raw";
40 image_transport::Publisher
pub;
46 cv_bridge::CvImagePtr cv_ptr;
56 cv_ptr = cv_bridge::toCvCopy(original_image, enc::BGR8);
57 cv_clone = cv_ptr->image.clone();
60 catch (cv_bridge::Exception& e)
63 ROS_ERROR(
"tutorialROSOpenCV::main.cpp::cv_bridge exception: %s", e.what());
69 cv_clone.copyTo(image);
83 cv::namedWindow(
"Sobel (orientation)");
89 cv::namedWindow(
"Sobel (low threshold)");
90 cv::imshow(
"Sobel (low threshold)",ed.
getBinaryMap(125));
93 cv::namedWindow(
"Sobel (high threshold)");
94 cv::imshow(
"Sobel (high threshold)",ed.
getBinaryMap(350));
98 cv::Canny(image,contours,125,350);
100 cv::threshold(contours,contoursInv,128,255,cv::THRESH_BINARY_INV);
103 cv::namedWindow(
"Canny Contours");
104 cv::imshow(
"Canny Contours",contoursInv);
108 std::vector<cv::Vec2f> lines;
109 cv::HoughLines(contours,lines,1,(75*
PI)/180,60);
112 cv::Mat result(contours.rows,contours.cols,CV_8U,cv::Scalar(255));
113 image.copyTo(result);
115 std::cout <<
"Lines detected: " << lines.size() << std::endl;
117 std::vector<cv::Vec2f>::const_iterator it= lines.begin();
118 while (it!=lines.end()) {
121 float theta= (*it)[1];
123 if (theta < PI/4. || theta > 3.*
PI/4.) {
126 cv::Point pt1(rho/cos(theta),0);
128 cv::Point pt2((rho-result.rows*sin(theta))/cos(theta),result.rows);
130 cv::line( result, pt1, pt2, cv::Scalar(255), 1);
135 cv::Point pt1(0,rho/sin(theta));
137 cv::Point pt2(result.cols,(rho-result.cols*cos(theta))/sin(theta));
139 cv::line( result, pt1, pt2, cv::Scalar(255), 1);
142 std::cout <<
"line: (" << rho <<
"," << theta <<
")\n";
148 cv::namedWindow(
"Detected Lines with Hough");
149 cv::imshow(
"Detected Lines with Hough",result);
159 std::vector<cv::Vec4i> li= ld.
findLines(contours);
161 cv::namedWindow(
"Detected Lines with HoughP");
162 cv::imshow(
"Detected Lines with HoughP",image);
165 std::vector<cv::Vec4i>::const_iterator it2= li.begin();
166 while (it2!=li.end()) {
168 std::cout <<
"(" << (*it2)[0] <<
","<< (*it2)[1]<<
")-("
169 << (*it2)[2]<<
"," << (*it2)[3] <<
")" <<std::endl;
177 cv::line(image, cv::Point(li[n][0],li[n][1]),cv::Point(li[n][2],li[n][3]),cv::Scalar(255),5);
178 cv::namedWindow(
"One line of the Image");
179 cv::imshow(
"One line of the Image",image);
182 cv::Mat oneline(image.size(),CV_8U,cv::Scalar(0));
183 cv::line(oneline, cv::Point(li[n][0],li[n][1]),cv::Point(li[n][2],li[n][3]),cv::Scalar(255),5);
184 cv::bitwise_and(contours,oneline,oneline);
185 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);
186 cv::bitwise_and(contours,oneline,oneline);
190 cv::adaptiveThreshold(oneline, onelineInv, 128, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY_INV, 3, 5);
191 cv::namedWindow(
"One line");
192 cv::imshow(
"One line",onelineInv);
194 std::vector<cv::Point> points;
197 for(
int y = 0; y < oneline.rows; y++ ) {
199 uchar* rowPtr = oneline.ptr<uchar>(y);
201 for(
int x = 0; x < oneline.cols; x++ ) {
206 points.push_back(cv::Point(x,y));
213 cv::fitLine(cv::Mat(points),line,CV_DIST_L2,0,0.01,0.01);
215 std::cout <<
"line: (" << line[0] <<
"," << line[1] <<
")(" << line[2] <<
"," << line[3] <<
")\n";
219 int x1= x0-200*line[0];
220 int y1= y0-200*line[1];
222 cv::line(image,cv::Point(x0,y0),cv::Point(x1,y1),cv::Scalar(0),3);
223 cv::namedWindow(
"Estimated line");
224 cv::imshow(
"Estimated line",image);
232 cv::namedWindow(
"Detected Lines (2)");
233 cv::imshow(
"Detected Lines (2)",image);
236 cv::Mat acc(200,180,CV_8U,cv::Scalar(0));
242 for (
int i=0; i<180; i++) {
244 double theta= i*
PI/180.;
247 double rho= x*cos(theta)+y*sin(theta);
248 int j=
static_cast<int>(rho+100.5);
250 std::cout << i <<
"," << j << std::endl;
253 acc.at<uchar>(j,i)++;
262 for (
int i=0; i<180; i++) {
264 double theta= i*
PI/180.;
265 double rho= x*cos(theta)+y*sin(theta);
266 int j=
static_cast<int>(rho+100.5);
268 acc.at<uchar>(j,i)++;
271 cv::namedWindow(
"Hough Accumulator");
272 cv::imshow(
"Hough Accumulator",acc*100);
273 ROS_ERROR(
"-------ERROR -----");
317 int main(
int argc,
char **argv)
319 ros::init(argc, argv,
"test");
323 image_transport::ImageTransport it(nh);
325 cv::namedWindow(
WINDOW0, CV_WINDOW_AUTOSIZE);
326 cv::namedWindow(
WINDOW1, CV_WINDOW_AUTOSIZE);
328 image_transport::Subscriber sub = it.subscribe(
"image", 1,
imageCallback);
333 pub = it.advertise(
"image_processed", 1);
336 ROS_INFO(
"tutorialROSOpenCV::main.cpp::No error.");
std::vector< cv::Vec4i > findLines(cv::Mat &binary)
static const char WINDOW1[]
void drawDetectedLines(cv::Mat &image, cv::Scalar color=cv::Scalar(255, 255, 255))
void setMinVote(int minv)
cv::Mat getSobelOrientationImage()
int main(int argc, char **argv)
image_transport::Publisher pub
void setLineLengthAndGap(double length, double gap)
std::vector< cv::Vec4i > removeLinesOfInconsistentOrientations(const cv::Mat &orientations, double percentage, double delta)
static const char WINDOW0[]
void computeSobel(const cv::Mat image, cv::Mat sobelX=cv::Mat(), cv::Mat sobelY=cv::Mat())
int imageCallback(const sensor_msgs::ImageConstPtr &original_image)
cv::Mat getBinaryMap(double threshold)