OpenCV (36): Hough line detection

1. Hough transform principle for detecting straight lines

2. Detect the straight line function HoughLines()

Detect straight line process:

Step1: Discretize the coordinate axes of the parameter space.

Step2: Use each non-zero pixel in the image to obtain the square grid passing through the parameter space through the mapping relationship.

Step3: Count the number of occurrences of each square in the parameter space, and select the square whose number is greater than a certain value as the square representing the straight line.

Step4: Use the parameters of the square grid representing the straight line in the parameter space as the parameters of the straight line in the image

void cv::HoughLines ( InputArray image

OutputArray lines,

double   rho,

double   theta,

int          threshold.

double   srn = 0,

double    stn =0,

double   min_theta = 0,

double    max_theta = CV_PI

)

Parameter Description:

  • image: The input binary image, usually the image after edge detection.
  • lines: Output parameter, vector containing detected straight lines.
  • rho: The accuracy of the polar diameter parameter ρ, in pixels.
  • theta: The accuracy of the angle parameter θ, in radians.
  • threshold: voting threshold in parameter space, used to determine detected straight lines.
  • srn, stn, min_theta, max_theta: These parameters are optional and are used to further refine the accuracy and range of line detection.

Sample code:

void drawLine(Mat &img,//要标记直线的图像
              vector<Vec2f> lines,//检测的直线数据
              double rows,//原图像的行数(高)
              double cols,//原图像的列数(宽)
              Scalar scalar,//绘制直线的颜色
              int n//绘制直线的线宽
              ){
    Point pt1,pt2;
    for(size_t i=0;i<lines.size();i++){
        float rho=lines[i][0];//直线距离坐标原点的距离
        float theta=lines[i][1];//直线过坐标原点垂线
        double a=cos(theta);//夹角的余弦值
        double b=sin(theta);//夹角的正弦值
        double x0=a*rho,y0=b*rho;//直线与坐标原点的垂线的交点
        double length=max(rows,cols);//图像高宽的最大值
        //计算直线上的一点
        pt1.x= cvRound(x0+length*(-b));
        pt1.y= cvRound(y0+length*(a));
        //计算直线上的另一点
        pt2.x= cvRound(x0-length*(-b));
        pt2.y= cvRound(y0-length*(a));
        //两点绘制一条直线
        line(img,pt1,pt2,scalar,n);
    }
}
//霍夫直线检测
void Hough_linear_detection(Mat image){
    Mat gray;
    cvtColor(image,gray,COLOR_BGR2GRAY);
    Mat edge;
    //检测边缘图像,并二值化
    Canny(gray,edge,80,180,3, false);
    //用不同的累加器进行检测直线
    vector<Vec2f> lines1,lines2;
    HoughLines(edge, lines1,1,CV_PI/180,50,0,0);
    HoughLines(edge, lines2,1,CV_PI/180,150,0,0);
    //在原图像中绘制直线
    Mat img1,img2;
    image.copyTo(img1);
    image.copyTo(img2);
    drawLine(img1,lines1,edge.rows,edge.cols,Scalar(255),2);
    drawLine(img2,lines2,edge.rows,edge.cols,Scalar(255),2);
    //显示图像
    imwrite("/sdcard/DCIM/edge.png",edge);
    imwrite("/sdcard/DCIM/img1.png",img1);
    imwrite("/sdcard/DCIM/img2.png",img2);
}

Picture after Canny operator edge detection:

Use the accumulator to be 50 to detect a straight line:

Use the accumulator to be 150 to detect a straight line:

3. Detect straight line function HoughLinesP()

void cv::HoughLinesP ( InputArray   image,

OutputArray lines,

double     rho,

double    theta,

int        threshold,

double   minLineLength =0,

double   maxLineGap = 0

)

  • image: The original image of the straight line to be detected must be a single-channel binary image of CV_8C
  • Lines: The straight line output detected by the Hough transform. Each straight line is described by 4 parameters, which are the coordinates of the two endpoints of the straight line.
  • rho: distance resolution in pixels.
  • theta: angular resolution in radians
  • threshold: the threshold of the accumulator
  • minLineLength: The minimum length of the straight line. When the length of the detected straight line is less than this value, it will be eliminated.
  • maxLineGap: The maximum distance allowed to connect two points on the same line.

Sample code:

//霍夫直线检测
void Hough_linearP_detection(Mat image){
    Mat gray;
    cvtColor(image,gray,COLOR_BGR2GRAY);
    Mat edge;
    //检测边缘图像,并二值化
    Canny(gray,edge,80,180,3, false);
    //利用渐进概率式霍夫变换提取直线
    vector<Vec4i> linesP1,linesP2;
    HoughLinesP(edge, linesP1,1,CV_PI/180,150,30,10);//两个点连接最大距离10
    HoughLinesP(edge, linesP2,1,CV_PI/180,150,30,30);//两个点连接最大距离30
    //绘制两个点连接最大距离10直线检测结果
    Mat img1;
    image.copyTo(img1);
    for(size_t i=0;i<linesP1.size();i++){
        line(img1,Point(linesP1[i][0],linesP1[i][1]),
             Point(linesP1[i][2],linesP1[i][3]),Scalar(255),3);
    }
    //绘制两个点连接最大距离30直线检测结果
    Mat img2;
    image.copyTo(img2);
    for(size_t i=0;i<linesP2.size();i++){
        line(img2,Point(linesP2[i][0],linesP2[i][1]),
             Point(linesP2[i][2],linesP2[i][3]),Scalar(255),3);
    }

    //显示图像
    imwrite("/sdcard/DCIM/img10.png",img1);
    imwrite("/sdcard/DCIM/img20.png",img2);
}

Draw a straight line connecting two points with a maximum distance of 10 detection results:

Draw a straight line connecting two points with a maximum distance of 30. Detection results:

Guess you like

Origin blog.csdn.net/weixin_63357306/article/details/132796740