Opencv(C++)笔记--霍夫变换检测直线、霍夫变换检测圆

目录

1--原理

2--Opencv API

3--实例代码

4--霍夫变换检测圆


1--原理

        具体原理可参考 博客1 和 视频讲解1;

        霍夫变换检测直线的核心思想是:在笛卡尔坐标系下,一条直线(两个点(x1, y1)和(x2, y2)确定一条直线)可以变换为霍夫空间中的一个点(r, θ),由霍夫空间的一个点表示笛卡尔坐标系的一条直线

Opencv(C++)笔记--霍夫变换检测直线、霍夫变换检测圆_第1张图片

        对于图像中的直线而言,其由许多个像素点组成;而笛卡尔坐标系中的像素点可以映射为霍夫空间中的一条直线(因为一个像素点可以组成无数条直线,每一条直线对应霍夫空间的一个点),即霍夫空间的一条直线,对应笛卡尔坐标系的一个点

        对于霍夫空间中的每一条直线,其存在交点,霍夫空间的多条直线相交于一个交点,这个交点对应于笛卡尔坐标系下的一条直线,通过在霍夫空间中检测交点的个数确定交点的坐标(r, θ),可以检测笛卡尔坐标系下的直线。

2--Opencv API

Opencv(C++)笔记--霍夫变换检测直线、霍夫变换检测圆_第2张图片

3--实例代码

         进行霍夫变换直线检测时,通常配合 Canny边缘检测算法 进行,先对图片进行边缘检测,再进行直线检测;

# include 
# include 
# include 

int main(int argc, char** argv){
    cv::Mat src;
    src = cv::imread("C:/Users/Liujinfu/Desktop/opencv_bilibili/test_1218.jpg");
    if (src.empty()){
        printf("could not load image..\n");
        return -1;
    }
    cv::imshow("input", src);
    
    cv::Mat canny, dst;
    cv::Canny(src, canny, 150, 200); // 配合canny算法使用
    cv::cvtColor(canny, dst, cv::COLOR_GRAY2BGR); //灰度图转换为彩色图
    cv::imshow("edge", canny);

    std::vector plines;
    cv::HoughLinesP(canny, plines, 1, CV_PI / 180.0, 5, 0, 10);
    cv::Scalar color = cv::Scalar(0, 0, 255);
    for(size_t i = 0; i < plines.size(); i++){
        cv::Vec4f hline = plines[i];
        cv::line(dst, cv::Point(hline[0], hline[1]), cv::Point(hline[2], hline[3]), color, 3, cv::LINE_AA);
    }
    cv::imshow("output", dst);
    
    cv::waitKey(0);
    return 0;
}

Opencv(C++)笔记--霍夫变换检测直线、霍夫变换检测圆_第3张图片

4--霍夫变换检测圆

① 原理建议参考视频讲解2;

② Opencv API

Opencv(C++)笔记--霍夫变换检测直线、霍夫变换检测圆_第4张图片

参数说明:

cv::InputArray image:表示输入图像;

cv::OutputArray circles:圆的参数,包含圆心坐标和圆的半径;

int method:采用的检测方法,默认使用霍夫梯度法;

double dp:累加器分辨率与图像分辨率的反比。dp=1表示累加器具有与输入图像相同的分辨率。

double minDist:标新两个圆心之间的最小距离;

double param1 = (100.0):表示边缘检测对应的参数。对于霍夫梯度法而言,表示为传递给canny边缘检测算子的高阈值,而低阈值则为高阈值的一半;

double param2 = (100.0):表示检测方法对应的参数。对于霍夫梯度法而言,表示在检测阶段圆心的累加器阈值。参数值越小就越可以检测出更多不存在的圆;反之,检测出的圆一般都很完美;

int minRadius = 0:表示半径的最小值;

int maxRadius = 0:表示半径的最大值;

③ 代码实例

# include 
# include 
# include 

int main(int argc, char** argv){
    cv::Mat src;
    src = cv::imread("C:/Users/Liujinfu/Desktop/opencv_bilibili/test_1221.jpg");
    if (src.empty()){
        printf("could not load image..\n");
        return -1;
    }
    cv::imshow("input", src);
    
    cv::Mat temp, gray, dst;
    
    cv::medianBlur(src, temp, 3); // 中值滤波去除噪声
    cv::cvtColor(temp, gray, cv::COLOR_BGR2GRAY); // 灰度化

    // 霍夫圆检测
    std::vector pcircles;
    cv::HoughCircles(gray, pcircles, cv::HOUGH_GRADIENT, 1, 20, 100, 100, 1, 100);

    src.copyTo(dst);
    for(size_t i = 0; i < pcircles.size(); i++){
        cv::Vec3f cc = pcircles[i]; // cc[0] -> x  cc[1] -> y  cc[2] -> r
        cv::circle(dst, cv::Point(cc[0], cc[1]), cc[2], cv::Scalar(0, 0, 255), 2, cv::LINE_AA); // 可视化圆弧 
        cv::circle(dst, cv::Point(cc[0], cc[1]), 1, cv::Scalar(255, 0, 0), 2, cv::LINE_AA); // 可视化圆心
    }
    cv::imshow("output", dst);

    cv::waitKey(0);
    return 0;
}

Opencv(C++)笔记--霍夫变换检测直线、霍夫变换检测圆_第5张图片

 

你可能感兴趣的:(Opencv(C++)学习笔记,opencv,人工智能,计算机视觉)