Image Processing14(Hough Line Transform)

Goal

In this tutorial you will learn how to:

  • Use the OpenCV functions HoughLines() and HoughLinesP() to detect lines in an image.
  • 使用OpenCV库函数HoughLines() and HoughLinesP() 检测图像中的直线。

Theory

Note

The explanation below belongs to the book Learning OpenCV by Bradski and Kaehler.

       理论来源于《 Learning OpenCV》这本书。

Hough Line Transform

  1. The Hough Line Transform is a transform used to detect straight lines.
  2. 霍夫线变换用于检测直线
  3. To apply the Transform, first an edge detection pre-processing is desirable.
  4. 在进行霍夫变换之前,首先需要进行边缘检测预处理。

How does it work?

As you know, a line in the image space can be expressed with two variables. For example:

  1. In the Cartesian coordinate system: Parameters: (m,b).。笛卡尔坐标下,直线的两个参数。
  2. In the Polar coordinate system: Parameters:(r,θ)极坐标笛卡尔坐标下,直线的二个参数。。极坐标下,直线的两个参数。

                                                             Hough_Lines_Tutorial_Theory_0.jpg

For Hough Transforms, we will express lines in the Polar system. Hence, a line equation can be written as:

y=(cosθsinθ)x+(rsinθ)
在霍夫线变换中,通常在极坐标下表示。因此,线性方式如上。
Arranging the terms: r=xcosθ+ysinθ
对上个方程进行整理为: r=xcosθ+ysinθ

1.In general for each point (x0,y0), we can define the family of lines that goes through that point as:

rθ=x0cosθ+y0sinθ
可以定义通过该点的线条族为上式。
2.If for a given (x0,y0) we plot the family of lines that goes through it, we get a sinusoid. For instance, for x0=8 and y0=6 we get the following plot (in a plane θ - r):
对于给定点,它的线条族其实是一个正弦曲线。
 

                                                                Hough_Lines_Tutorial_Theory_1.jpg

We consider only points such that r>0 and 0<θ<2π.(只考虑这个情况)

3.We can do the same operation above for all the points in an image. If the curves of two different points intersect in the plane θ - r, that means that both points belong to a same line. For instance, following with the example above and drawing the plot for two more points: x1=4, y1=9 and x2=12, y2=3, we get:

                                                       Hough_Lines_Tutorial_Theory_2.jpg

对于图像上的所有点进行相同的操作,如果不同点的曲线在平面相交,那也叫意味着这两个点属于同一条直线。例如,这三个点交于一点。

4.What does all the stuff above mean? It means that in general, a line can be detected by finding the number of intersections between curves.The more curves intersecting means that the line represented by that intersection have more points. In general, we can define a threshold of the minimum number of intersections needed to detect a line.

上面的材料意味着什么呢?意味着,一条直线可以通过检测交点的数量检测处理啊。越多的曲线相交,则就以为这条直线有很多的点。通过可以设置一个最小的阀值作为检测点的数量来检测直线。

5.This is what the Hough Line Transform does. It keeps track of the intersection between curves of every point in the image. If the number of intersections is above some threshold, then it declares it as a line with the parameters (θ,rθ) of the intersection point.

这也就是霍夫线变换要做的内容。它跟中每个点曲线之间的交际。如果交点的数量高于阀值,则认为其是一条曲线,并且参数为 (θ,rθ)
 

Standard and Probabilistic Hough Line Transform

OpenCV implements two kind of Hough Line Transforms:

a. The Standard Hough Transform(标准变换)

  • It consists in pretty much what we just explained in the previous section. It gives you as result a vector of couples(包含了前面所讲的内容,最后给出结果(θ,rθ)()
  • In OpenCV it is implemented with the function HoughLines()(使用这个函数)

b. The Probabilistic Hough Line Transform(概率霍夫变换)

  • A more efficient implementation of the Hough Line Transform. It gives as output the extremes of the detected lines (更有效的方法,并给出结果)(x0,y0,x1,y1)()
  • In OpenCV it is implemented with the function HoughLinesP()(使用这个函数)

What does this program do?

  • Loads an image(加载图像)
  • Applies a Standard Hough Line Transform and a Probabilistic Line Transform.(进行两种变换)
  • Display the original image and the detected line in three windows.(展示原图像和结果)

Code

#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
    // Declare the output variables
    Mat dst, cdst, cdstP;
    const char* default_file = "lena.jpg";
    const char* filename = argc >=2 ? argv[1] : default_file;
    // Loads an image
    Mat src = imread( filename, IMREAD_GRAYSCALE );
    // Check if image is loaded fine
    if(src.empty()){
        printf(" Error opening image\n");
        printf(" Program Arguments: [image_name -- default %s] \n", default_file);
        return -1;
    }
    // Edge detection
    Canny(src, dst, 50, 200, 3); //输入,输出,小,大,大小
    // Copy edges to the images that will display the results in BGR
    cvtColor(dst, cdst, COLOR_GRAY2BGR); //灰度图
    cdstP = cdst.clone();
    // Standard Hough Line Transform
    vector<Vec2f> lines; // will hold the results of the detection,两个浮点数
    HoughLines(dst, lines, 1, CV_PI/180, 150, 0, 0 ); // runs the actual detection
    //输入,输出,搜索直线时的步长,同上一个弧度,阀值,默认参数均为零
    // Draw the lines

    for( size_t i = 0; i < lines.size(); i++ )
    {
        float rho = lines[i][0], theta = lines[i][1];
        Point pt1, pt2;
        double a = cos(theta), b = sin(theta);
        double x0 = a*rho, y0 = b*rho;
        pt1.x = cvRound(x0 + 1000*(-b)); //4舍5入
        pt1.y = cvRound(y0 + 1000*(a));
        pt2.x = cvRound(x0 - 1000*(-b));
        pt2.y = cvRound(y0 - 1000*(a));
        line( cdst, pt1, pt2, Scalar(0,0,255), 3, LINE_AA); //图像,第一点,第二点,颜色,厚度,线型
    }
    // Probabilistic Line Transform
    vector<Vec4i> linesP; // will hold the results of the detection,4个整数
    HoughLinesP(dst, linesP, 1, CV_PI/180, 50, 50, 10 ); // runs the actual detection
    //输入,结果,分辨率,分辨率,阀值,显示一条直线的最短距离,允许两个点相连接的最大距离。
    // Draw the lines

    for( size_t i = 0; i < linesP.size(); i++ )
    {
        Vec4i l = linesP[i];
        line( cdstP, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0,0,255), 3, LINE_AA);
    }
    // Show results
    imshow("Source", src);
    imshow("Detected Lines (in red) - Standard Hough Line Transform", cdst);
    imshow("Detected Lines (in red) - Probabilistic Line Transform", cdstP);
    // Wait and Exit
    waitKey();
    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 2.8)

set(CMAKE_CXX_FLAGS "-std=c++11")
project( DisplayImage )
find_package( OpenCV REQUIRED )
include_directories( ${OpenCV_INCLUDE_DIRS} )
add_executable( DisplayImage main.cpp )
target_link_libraries( DisplayImage ${OpenCV_LIBS} )


install(TARGETS DisplayImage RUNTIME DESTINATION bin

Results



猜你喜欢

转载自blog.csdn.net/qq_27806947/article/details/80302109