霍夫变换(Hough Transform)

霍夫变换的主要作用是从图像中检测出具有某种相同特征的几何形状,如直线、圆等。

霍夫变换的基本原理:
例如检测情景为直线检测。我们知道,在直角坐标系下,直线方程表示为 y=kx+b ,其中 k,b 为参数,表示直线的斜率和截距。

那么,对于直角坐标系下的某个特定点 (x0,y0) ,过该点的任意直线方程为 y0=kx0+b ,也就是说点 (x0,y0) 确定了一个直线簇,直线簇由参数 k,b 变量决定。由此可以理解为直角坐标系下的一个点 (x0,y0) 对应于 kb 参数空间的一条直线 y0=kx0+b

在以上理论的基础上,我们考虑,在图像中,如果有多个像素点位于一条直线上,而每个像素点对应于参数空间 kb 的一条直线,而这些直线的共性是相交于一点,该点 (k0,b0) 就是图像空间中像素所对应直线的斜率和截距。

因此,我们可以把图像空间中的像素点转换为参数空间表示,并通过统计参数空间上的峰值(交点)点来检测图像空间上的直线,此时每个峰值点对应于图像空间中的一条直线。

实际中, y0=kx0+b 的直线方程无法表示 x=c 这种形式的直线,因为直线的斜率为无穷大。所以通常参数空间表示采用 ρ=xcosθ+ysinθ 的形式,参数为 ρ θ ,这样图像空间中的一个像素点对应于 ρθ 空间的一条曲线。

这里列举一个实验例子,左图为霍夫变换检测的直线,右图为canny检测的边缘。
霍夫变换(Hough Transform)_第1张图片

基本代码如下,

Mat img = imread("road.jpg");
if (img.empty())
    return -1;

int height = img.rows;
int width = img.cols;

Mat Gray_img;
cvtColor(img, Gray_img, CV_BGRA2GRAY);//RGB to Gray image

Mat Coutours;
Canny(Gray_img, Coutours,125, 500);// canny edge

double rho = 1;
double theta = PI / 180;
int threshold = 160;//peak above the threshold will be returned

vector lines;
HoughLines(Coutours, lines, rho, theta, threshold);//hough transform

printf("lines number = %d\n", lines.size());

vector::const_iterator it;
for (it = lines.begin(); it != lines.end(); it++){
    Vec2f data = *it;

    //each (rho, theta) in hough space corrsponds to a line
    float rho = data[0];
    float theta = data[1];

    //rho = x*cos(theta) + y*sin(theta)
    float y1 = rho / sin(theta);
    float y2 = (rho - width*cos(theta)) / sin(theta);

    Point pt1(0, y1);
    Point pt2(width, y2);

    line(img, pt1, pt2, Scalar(0, 0, 255));
}

imshow("img", img);
imshow("coutours", Coutours);

你可能感兴趣的:(计算机视觉)