OpenCV2 Study Notes (eight): Using Hough Transform to detect lines and circles

Source: Internet
Author: User

In the study of an image, there are often planar or linear problems, and the lines are frequently visible in the image. These meaningful features play an important role in the process of image processing such as object recognition. This section mainly records a classical detection line algorithm-Hough transform (Hough Transform), using Hough transform to detect the line and circle in the image, the development platform is qt5.3.2+opencv2.4.9.

One: Hough transform to detect the line of the image

1. Basic Hough Transformation

In the Hough transform, the line is represented by the following equation:

Where the parameter represents the distance from a straight line to the original point of the image (upper-left corner), which represents the angle perpendicular to the line. As shown, the angle of the vertical line of line 1 is equal to 0, and the Horizon 5 equals two π. At the same time, the angle of the line 3 equals four π, while the angle of the line 4 is approximately 0.7π. In order to be able to get all possible straight lines between the interval [0,π], the radius value is preferable to a negative number, which is exactly the case of Line 2.

OPENCV provides two kinds of Hough transform implementations, the basic version is: Cv::houghlines. Its input is a two-value image containing a set of points, some of which form a straight line, usually an edge image, such as from the Sobel operator or the canny operator. The output of the Cv::houghlines function is a cv::vec2f vector, and each element is a pair of floating-point numbers (p, r0) that represent the detected line. When designing the program, we first find the polar coordinate equation of each point in the image, and if the number of polar curves that intersect at a point is greater than the minimum number of votes, then the corresponding (p, r0) of that point is placed in the vector, that is, a straight line is obtained. The Cv::houghlines function is called as follows:

    // 基础版本的Hough变换    // 首先应用Canny算子获取图像的轮廓    cv::Mat image = cv::imread("c:/031.jpg"0);    cv::Mat contours;    cv::Canny(image,contours,125,350);    // Hough变换检测直线    std::vector<cv::Vec2f> lines;    cv::HoughLines(contours,lines,                   1,PI/180,  // 步进尺寸                   80);       // 最小投票数

The complete code to implement the underlying Hough transformation is as follows, which is added directly to the main function:

#include <QCoreApplication>#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>#include <opencv2/imgproc/imgproc.hpp>#include <QDebug>#define PI 3.1415926intMainintargcChar*argv[]) {qcoreapplication A (argc, argv);//Basic version of the Hough transform    //Apply canny operator first to get the contour of the imageCv::mat image = Cv::imread ("C:/031.jpg",0);    Cv::mat contours; Cv::canny (Image,contours, the, -);//Hough Transform detection line    STD:: vector<cv::Vec2f>Lines Cv::houghlines (Contours,lines,1, pi/ the,//Step size                    the);//Minimum number of votes    //The following steps draw a lineCv::mat Result (Contours.rows,contours.cols,cv_8u,cv::scalar (255)); Image.copyto (result);//The following traverse the image to draw each line    STD:: vector<cv::Vec2f>:: Const_iterator it= lines.begin (); while(It!=lines.end ()) {//The following two parameters are used to detect whether a line is a vertical or horizontal line        floatrho= (*it) [0];//indicates distance        floatTheta= (*it) [1];//Indication Angle        if(Theta < pi/4.|| Theta >3.*pi/4.)//If detected as vertical line{//Get the intersection of the line and the first lineCV::P oint pt1 (rho/Cos(Theta),0);//Get the intersection of the line and the last lineCV::P oint pt2 (rho-result.rows*Sin(theta)) /Cos(theta), result.rows);//Call line function to draw linesCv::line (result, pt1, Pt2, Cv::scalar (255),1); }Else //If detected as a horizontal line{//Get the intersection of the line and the first columnCV::P oint PT1 (0, rho/Sin(theta));//Get the intersection of the line and the last columnCV::P oint pt2 (Result.cols, rho-result.cols*Cos(theta)) /Sin(theta));//Call line function to draw linesCv::line (result, pt1, Pt2, Cv::scalar (255),1);    } ++it; }//Display resultsCv::namedwindow ("detected Lines with Hough"); Cv::imshow ("detected Lines with Hough", result);returnA.exec ();}

Changing the minimum number of votes in the cv::houghlines can result in different detection results, so it is important to know the number of votes for straight line judgments. When the minimum number of votes is 100:

The minimum number of votes is 60 o'clock:

Note that the Hough transformation requires that you enter a two-value image that contains a set of points.

2. Probability Hough Transformation

It is shown from the output that the basic Hough transform detects the straight line in the image, but in many applications we need a local segment rather than an entire line. As is the case in the code, the intersection of the line and the image boundary needs to be determined to determine a segment, otherwise the drawn line will pass through the entire image. Second, the Hough transform only finds an arrangement of edge points, which is likely to lead to false detection due to unexpected pixel permutations or multiple lines passing through the same set of pixels.

In order to overcome these difficulties, people put forward the improved algorithm, that is, probabilistic Hough transform, the corresponding function Cv::houghlinep in OpenCV, the following gives the implementation of the algorithm, first encapsulated in the class Linefinder, Linefinder.h added:

#ifndef Linefinder_h#define LINEFINDER_H#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>#include <opencv2/imgproc/imgproc.hpp>#include <QDebug>#define PI 3.1415926classlinefinder{Private://Store original imageCv::mat img;//vector contains the endpoint of the detected line    STD:: vector<cv::Vec4i>Lines//Accumulator resolution parameters    DoubleDeltarho;//Distance    DoubleDeltatheta;//Angle    //The number of votes required to be judged as a straight line    intMinvote;//Minimum length of straight line    DoubleMinLength;//maximum notch along a straight line direction    DoubleMaxgap; Public://Default accumulator resolution is a single pixel with an angle of 1 degrees    //Do not set notch and minimum length valuesLinefinder (): Deltarho (1), Deltatheta (pi/ the), Minvote (Ten), MinLength (0.), Maxgap (0.) {}//Set the resolution of the accumulator    voidSetaccresolution (DoubleDrho,DoubleDtheta);//Set minimum number of votes    voidSetminvote (intMINV);//Set notch and minimum length    voidSetlinelengthandgap (DoubleLengthDoubleGAP);//Use probability Hough transform    STD:: vector<cv::Vec4i>Findlines (cv::mat& binary);//Draw a detected line    voidDrawdetectedlines (Cv::mat &image, Cv::scalar color=cv::scalar (255,255,255));};#endif //Linefinder_h 

The functions are then defined and added in Linefinder.cpp:

#include "linefinder.h"#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>#include <opencv2/imgproc/imgproc.hpp>#include <QDebug>#define PI 3.1415926//Set the resolution of the accumulatorvoidLinefinder::setaccresolution (DoubleDrho,DoubleDtheta) {deltarho= Drho; Deltatheta= Dtheta;}//Set minimum number of votesvoidLinefinder::setminvote (intMINV) {minvote= MINV;}//Set notch and minimum lengthvoidLinefinder::setlinelengthandgap (DoubleLengthDoubleGAP) {minlength= length; Maxgap= Gap;}//Use probability Hough transformSTD:: vector<cv::Vec4i>Linefinder::findlines (cv::mat& binary) {lines.clear ();//Call probability Hough transform functionCv::houghlinesp (Binary,lines,deltarho,deltatheta,minvote, MinLength, maxgap);returnLines;}//Draw a detected linevoidLinefinder::d rawdetectedlines (Cv::mat &image, cv::scalar color) {STD:: vector<cv::Vec4i>:: Const_iterator it2= lines.begin (); while(It2!=lines.end ()) {CV::P oint pt1 ((*it2) [0], (*IT2) [1]); CV::P oint pt2 ((*it2) [2], (*IT2) [3]);        Cv::line (image, PT1, pt2, color);    ++it2; }}

Finally, simply modify the main function to:

#include <QCoreApplication>#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>#include <opencv2/imgproc/imgproc.hpp>#include <QDebug>#include "linefinder.h"intMainintargcChar*argv[]) {qcoreapplication A (argc, argv); Cv::mat image = Cv::imread ("C:/031.jpg",0);if(!image.data) {Qdebug () <<"No Input Image";return 0; }///First use the canny algorithm to detect the edge part of the imageCv::mat contours; Cv::canny (image, contours, the, -); Linefinder Finder;//Create an object    //Set probability hough parameterFinder.setlinelengthandgap ( -, -); Finder.setminvote ( the);//Minimum number of votes    //The following steps to detect and draw a line    STD:: vector<cv::Vec4i>lines = Finder.findlines (contours);    Finder.drawdetectedlines (image); Cv::namedwindow ("Detected Lines"); Cv::imshow ("Detected Lines", image);returnA.exec ();}

The results are as follows:

In short, the purpose of the Hough transform is to find all the lines in a two-value image that pass through a sufficient number of points, analyze each individual pixel, and identify all the straight lines that might pass through it. When the same line passes through many points, it means that the presence of the line is obvious enough.

And the probabilistic Hough transform is based on the original algorithm to add a little change, these changes are mainly reflected in:

    1. Instead of systematically scanning the image, the pixels are randomly picked, and once an item in the accumulator reaches the given minimum, the pixels along the corresponding line are scanned and all the passing points are removed (even if they have not voted);

    2. The probabilistic Hough transform defines two additional parameters: one is the minimum length of the acceptable segment, and the other is the maximum pixel interval that allows continuous segments to be formed, although these additional steps inevitably increase the complexity of the algorithm, but because the number of points participating in the poll has decreased, some compensation has been obtained.

Second: Hough transform to detect the circle in the image

The Hough transform can be used to detect other geometries, and in fact, the geometry that can be represented by the parametric equation can be tested using Hough transforms, such as a circle, which corresponds to a parametric equation:

The function contains three parameters, namely the coordinates of the center and the radius of the circle, which means that three-dimensional accumulators are required. The Hough Circle detection algorithm implemented in OPENCV is usually detected using two steps:

    1. Two-dimensional accumulators are used to look for positions that may be round. Since the gradient of the points on the circumference should point to the direction of the radius, for each point only the items along the gradient direction are increased (this requires a predetermined maximum and minimum radius);

    2. If a center is found, a histogram of the radius of one dimension is constructed, and the peak of the histogram corresponds to the radius of the detected circle.

The following gives the realization method of the Hough Transform detection circle, mainly using the function cv::houghcircles, it integrates the canny detection and the Huo transformation, at the same time, before the Huffman transformation, it is recommended to smooth the operation image to reduce the noise points that may cause false detection:

 //smooth the image before calling the Cv::houghcircles function, Reduce error  Cv::gaussianblur (image,image,cv::size (7 , ), 1.5 ); std :: vector     <cv::vec3f>  circles; Cv::houghcircles (image, Circles, cv_hough_gradient, 2 , 50 , //the minimum distance between two circles  200 , //canny high threshold  100 , //min votes  20 , 80 ); //the minimum and maximum effective radius   

The complete code is as follows, just add it in the main function:

    //Detect the circle in the imageImage= Cv::imread ("C:/44.png",0);if(!image.data) {Qdebug () <<"No Input Image";return 0; }//Smoothing the image before calling the Cv::houghcircles function to reduce errorsCv::gaussianblur (Image,image,cv::size (7,7),1.5);STD:: vector<cv::Vec3f>Circles Cv::houghcircles (image, circles, cv_hough_gradient,2,//accumulator Resolution (image size/2)         -,minimum distance between//two circles         $,high threshold value in//canny         -,//Minimum number of votes         -, the);min and max value of the effective RADIUS    //Draw CircleImage= Cv::imread ("C:/44.png",0);if(!image.data) {Qdebug () <<"No Input Image";return 0; }//Once a circle vector is detected, traverse the vector and draw a circle    //The method returns a cv::vec3f type vector    //contains the Circle's center coordinate and radius three information    STD:: vector<cv::Vec3f>:: Const_iterator itc= circles.begin (); while(Itc!=circles.end ()) {cv::circle (image, CV::P oint ((*ITC) [0], (*ITC) [1]),//Center(*ITC) [2],//radius of the circleCv::scalar (255),//Painted colors          6);//thickness of the circle++ITC; } Cv::namedwindow ("Detected Circles"); Cv::imshow ("Detected Circles", image);

Effect:

Three: Generalized hough transformations

For some shapes, their function expressions are more complex, such as triangles, polygons, etc., but it is possible to use Hough transform to locate these shapes, the principle of which is the same as the above detection. Create a two-dimensional accumulator that represents all the positions that may exist for the target shape. Therefore, a reference point must be defined, and each feature point on the image will vote on the coordinates of the possible reference points. Since a point may be anywhere within the shape's outline, all possible reference locations will depict a shape in the accumulator that will mirror the target shape.

OpenCV2 Study Notes (eight): Using Hough Transform to detect lines and circles

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.