opencv3学习之霍夫变换
霍夫变换分为霍夫线变换和霍夫圆变换。
1.霍夫线变换分为三种:标准霍夫变换、多尺度霍夫变换、累计概率霍夫变换。前两个由HoughLines调用,第三个 由HoughLinesP调用。
霍夫线变换的原理:其实就是笛卡尔坐标和极坐标之间的转换,公式:r=x*cosθ+y*sinθ
对于给定的x,y一点,对于笛卡尔坐标中的任意一点x,y都可以根据公式作出一个图像,也就是一条曲线,如果两个点(x1,y1),(x2,y2)的图像能够交于一点,那么说明这两点在同一条直线上。可以通过设置阈值,来限定多少点交于一点则认为它们在一条直线上。
代码如下:
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;
int main(){
Mat srcImage,midImage,dstImage;
srcImage=imread("/Users/oumoemoe/Downloads/timg-2.jpeg");
Canny(srcImage, midImage, 50, 200,3);
cvtColor(midImage, dstImage, CV_GRAY2BGR);
vector<Vec2f> lines;
HoughLines(midImage, lines, 1, CV_PI/180, 150,0,0);
for(size_t i=0;i<lines.size();i++){
float rho=lines[i][0],theta=lines[i][1];//lines是一个矢量,它有两个参数,第一个参数是rho也就是当前点到坐标原点的距离,第二个参数是角度。用i做变量是因为我们要获取每个点的信息,对每个点进行处理。
double a=cos(theta),b=sin(theta);
double x0=rho*a,y0=rho*b;
Point pt1,pt2;
pt1.x=cvRound(x0+1000*(-b));
pt1.y=cvRound(y0+1000*a);
pt2.x=cvRound(x0-1000*(-b));
pt2.y=cvRound(y0+1000*(-a));
//上面这些式子,可以用下面这个图来解释,其中这个1000,是随意取得,就是说上下到(x0,y0)这个点各1000
//pt1,pt2两点的坐标就是通过下面的几何变换推倒出来的,这个图是我自己画的
line(dstImage, pt1, pt2, Scalar(55, 10,195),1,LINE_AA);//pt1,pt2分为代表直线的起点和终点,毕竟两个点就能确定一条直线
}
imshow("1", midImage);
imshow("2", dstImage);
waitKey(0);
return 0;
}