opencv4 学习 13 直线和圆形的检测

1、直线检测

HoughLines函数:保存到输出的是直线的极坐标公式参数

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 );
HoughLinesP:保存到输出的是直线的端点
HoughLinesP( 
InputArray image,
OutputArray lines,
double rho, double theta,
int threshold,
double minLineLength = 0,
double maxLineGap = 0
);

算法原理和参数含义请参考:https://docs.opencv.org/3.4/d9/db0/tutorial_hough_lines.html

#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>

using namespace cv;
using namespace std;


int main(int argc, char* argv[])
{
    Mat dst, cdst, cdstP;

    const char* filename = "sudoku.png";
    Mat src = imread(filename, IMREAD_GRAYSCALE);
    Canny(src,dst,50,200,3);
    cvtColor(dst,cdst,COLOR_GRAY2BGR);
    cdstP = cdst.clone();

    vector<Vec2f> lines;
    HoughLines(dst, 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];
        Point pt1, pt2;
        double a = cos(theta), b = sin(theta);
        double x0 = a * rho, y0 = b * rho;
        pt1.x = cvRound(x0 + 1000 * (-b));
        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);
    }

    vector<Vec4i> linesP;
    HoughLinesP(dst, linesP, 1, CV_PI/180, 50, 50, 10);
    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);
    }

    imshow("Source", src);
    imshow("Strandard Hough Line Transform", cdst);
    imshow("Probabilistic Line Transform", cdstP);


    waitKey();
    return EXIT_SUCCESS;
}

 

2、圆形检测

HoughCircles( 
InputArray image,
OutputArray circles,
int method, \\ 目前只实现了,CV_HOUGH_GRADIENT
double dp,
double minDist, \\ 圆心之间的最小距离,值设太小,误检的圆会增多;值设太大,漏检的圆会增多
double param1 = 100, \\ 对应canny算子中的2个阈值,该阈值对应是upper,lower参数upper的 1/2
double param2 = 100, \\ 被检测为圆心的阈值
int minRadius = 0, \\ 最小的圆半径
int maxRadius = 0 \\ 最大的圆半径
);
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>

using namespace cv;
using namespace std;


int main(int argc, char* argv[])
{
    Mat src = imread("smarties.png", IMREAD_COLOR);

    Mat gray;
    cvtColor(src, gray, COLOR_BGR2GRAY);
    medianBlur(gray, gray, 5);

    vector<Vec3f> circles;
    HoughCircles(gray, circles, HOUGH_GRADIENT, 1, gray.rows/16, 100, 30, 1, 30);

    for(size_t i = 0; i < circles.size(); i++){
        Vec3i c = circles[i];
        Point center = Point(c[0], c[1]);
        circle(src, center, 1, Scalar(0, 100, 100), 3, LINE_AA);
        int radius = c[2];
        circle(src, center, radius, Scalar(255, 0, 255), 3, LINE_AA);

    }

    imshow("detected circles", src);
    waitKey();
    return EXIT_SUCCESS;
}

具体算法原理参考:https://docs.opencv.org/3.4/d4/d70/tutorial_hough_circle.html

posted @ 2020-08-13 09:40  blackx  阅读(190)  评论(0编辑  收藏  举报