|
|
#include <cv.h> #include <highgui.h> #include <math.h> using namespace cv; int main(int argc, char** argv) { Mat src, dst, color_dst; if( argc != 2 || !(src=imread(argv[1], 0)).data) return -1; Canny( src, dst, 50, 200, 3 ); cvtColor( dst, color_dst, CV_GRAY2BGR ); #if 0 vector<Vec2f> lines; HoughLines( dst, lines, 1, CV_PI/180, 100 ); for( size_t i = 0; i < lines.size(); i++ ) { float rho = lines[i][0]; float theta = lines[i][1]; double a = cos(theta), b = sin(theta); double x0 = a*rho, y0 = b*rho; Point pt1(cvRound(x0 + 1000*(-b)), cvRound(y0 + 1000*(a))); Point pt2(cvRound(x0 - 1000*(-b)), cvRound(y0 - 1000*(a))); line( color_dst, pt1, pt2, Scalar(0,0,255), 3, 8 ); } #else vector<Vec4i> lines; HoughLinesP( dst, lines, 1, CV_PI/180, 80, 30, 10 ); for( size_t i = 0; i < lines.size(); i++ ) { line( color_dst, Point(lines[i][0], lines[i][1]), Point(lines[i][2], lines[i][3]), Scalar(0,0,255), 3, 8 ); } #endif namedWindow( "Source", 1 ); imshow( "Source", src ); namedWindow( "Detected Lines", 1 ); imshow( "Detected Lines", color_dst ); waitKey(0); return 0; }
const double pi = 3.1415926f; const double RADIAN = 180.0/pi; struct line { int theta; int r; };
vector<struct line> houghLine(Mat &img, int threshold) { vector<struct line> lines; int diagonal = floor(sqrt(img.rows*img.rows + img.cols*img.cols)); vector< vector<int> >p(360 ,vector<int>(diagonal)); for( int j = 0; j < img.rows ; j++ ) { for( int i = 0; i < img.cols; i++ ) { if( img.at<unsigned char>(j,i) > 0) { for(int theta = 0;theta < 360;theta++) { int r = floor(i*cos(theta/RADIAN) + j*sin(theta/RADIAN)); if(r < 0) continue; p[theta][r]++; } } } } //get local maximum for( int theta = 0;theta < 360;theta++) { for( int r = 0;r < diagonal;r++) { int thetaLeft = max(0,theta-1); int thetaRight = min(359,theta+1); int rLeft = max(0,r-1); int rRight = min(diagonal-1,r+1); int tmp = p[theta][r]; if( tmp > threshold && tmp > p[thetaLeft][rLeft] && tmp > p[thetaLeft][r] && tmp > p[thetaLeft][rRight] && tmp > p[theta][rLeft] && tmp > p[theta][rRight] && tmp > p[thetaRight][rLeft] && tmp > p[thetaRight][r] && tmp > p[thetaRight][rRight]) { struct line newline; newline.theta = theta; newline.r = r; lines.push_back(newline); } } } return lines; }
void drawLines(Mat &img, const vector<struct line> &lines) { for(int i = 0;i < lines.size();i++) { vector<Point> points; int theta = lines[i].theta; int r = lines[i].r; double ct = cos(theta/RADIAN); double st = sin(theta/RADIAN); //r = x*ct + y*st //left int y = int(r/st); if(y >= 0 && y < img.rows){ Point p(0, y); points.push_back(p); } //right y = int((r-ct*(img.cols-1))/st); if(y >= 0 && y < img.rows){ Point p(img.cols-1, y); points.push_back(p); } //top int x = int(r/ct); if(x >= 0 && x < img.cols){ Point p(x, 0); points.push_back(p); } //down x = int((r-st*(img.rows-1))/ct); if(x >= 0 && x < img.cols){ Point p(x, img.rows-1); points.push_back(p); } cv::line( img, points[0], points[1], Scalar(0,0,255), 1, CV_AA); } }
#include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include <iostream> #include <vector> #include <cmath> using namespace cv; using namespace std; const double pi = 3.1415926f; const double RADIAN = 180.0/pi; struct line { int theta; int r; }; /* * r = xcos(theta) + ysin(theta) */ vector<struct line> houghLine(Mat &img, int threshold) { vector<struct line> lines; int diagonal = floor(sqrt(img.rows*img.rows + img.cols*img.cols)); vector< vector<int> >p(360 ,vector<int>(diagonal)); for( int j = 0; j < img.rows ; j++ ) { for( int i = 0; i < img.cols; i++ ) { if( img.at<unsigned char>(j,i) > 0) { for(int theta = 0;theta < 360;theta++) { int r = floor(i*cos(theta/RADIAN) + j*sin(theta/RADIAN)); if(r < 0) continue; p[theta][r]++; } } } } //get local maximum for( int theta = 0;theta < 360;theta++) { for( int r = 0;r < diagonal;r++) { int thetaLeft = max(0,theta-1); int thetaRight = min(359,theta+1); int rLeft = max(0,r-1); int rRight = min(diagonal-1,r+1); int tmp = p[theta][r]; if( tmp > threshold && tmp > p[thetaLeft][rLeft] && tmp > p[thetaLeft][r] && tmp > p[thetaLeft][rRight] && tmp > p[theta][rLeft] && tmp > p[theta][rRight] && tmp > p[thetaRight][rLeft] && tmp > p[thetaRight][r] && tmp > p[thetaRight][rRight]) { struct line newline; newline.theta = theta; newline.r = r; lines.push_back(newline); } } } return lines; } void drawLines(Mat &img, const vector<struct line> &lines) { for(int i = 0;i < lines.size();i++) { vector<Point> points; int theta = lines[i].theta; int r = lines[i].r; double ct = cos(theta/RADIAN); double st = sin(theta/RADIAN); //r = x*ct + y*st //left int y = int(r/st); if(y >= 0 && y < img.rows){ Point p(0, y); points.push_back(p); } //right y = int((r-ct*(img.cols-1))/st); if(y >= 0 && y < img.rows){ Point p(img.cols-1, y); points.push_back(p); } //top int x = int(r/ct); if(x >= 0 && x < img.cols){ Point p(x, 0); points.push_back(p); } //down x = int((r-st*(img.rows-1))/ct); if(x >= 0 && x < img.cols){ Point p(x, img.rows-1); points.push_back(p); } cv::line( img, points[0], points[1], Scalar(0,0,255), 1, CV_AA); } } int main( int, char** argv ) { Mat src,src_gray,edge; src = imread( argv[1] ); cvtColor( src, src_gray, CV_BGR2GRAY ); blur( src_gray, src_gray, Size(3,3) ); Canny( src_gray, edge, 50, 200); vector<struct line> lines = houghLine(edge, 90); drawLines(src, lines); namedWindow("result", 1); imshow("result", src); waitKey(); return 0; }
OpenCV2马拉松第22圈——Hough变换直线检测原理与实现,布布扣,bubuko.com
OpenCV2马拉松第22圈——Hough变换直线检测原理与实现
原文地址:http://blog.csdn.net/abcd1992719g/article/details/27220445