OpenCV特征检测(8)检测图像中圆形的函数HoughCircles()的使用

news/2024/9/23 7:06:15 标签: opencv, 人工智能, 计算机视觉
  • 操作系统:ubuntu22.04
  • OpenCV版本:OpenCV4.9
  • IDE:Visual Studio Code
  • 编程语言:C++11

算法描述

在灰度图像中使用霍夫变换查找圆形。

该函数使用霍夫变换的一种修改版本在灰度图像中查找圆形。
例子:

#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <math.h>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
    Mat img, gray;
    if( argc != 2 || !(img=imread(argv[1], IMREAD_COLOR)).data)
        return -1;
    cvtColor(img, gray, COLOR_BGR2GRAY);
    // smooth it, otherwise a lot of false circles may be detected
    GaussianBlur( gray, gray, Size(9, 9), 2, 2 );
    vector<Vec3f> circles;
    HoughCircles(gray, circles, HOUGH_GRADIENT,
                 2, gray.rows/4, 200, 100 );
    for( size_t i = 0; i < circles.size(); i++ )
    {
         Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
         int radius = cvRound(circles[i][2]);
         // draw the circle center
         circle( img, center, 3, Scalar(0,255,0), -1, 8, 0 );
         // draw the circle outline
         circle( img, center, radius, Scalar(0,0,255), 3, 8, 0 );
    }
    namedWindow( "circles", 1 );
    imshow( "circles", img );
    waitKey(0);
    return 0;
}

注意:

通常该函数能够很好地检测圆形的中心。然而,它可能无法正确找到半径。如果你知道半径范围,可以通过指定 minRadius 和 maxRadius 来帮助函数。或者,在使用 HOUGH_GRADIENT 方法的情况下,你可以将 maxRadius 设置为一个负数,以仅返回中心而不进行半径搜索,并使用额外的过程来找到正确的半径。
对图像进行轻微的平滑处理也有帮助,除非图像本身已经很平滑。例如,使用大小为 7x7 的高斯核和 1.5x1.5 的 sigma 进行 GaussianBlur() 或类似的模糊处理可能会有帮助。

HoughCircles 是 OpenCV 中用于检测图像中圆形的一个函数。Hough 变换是一种用于检测图像中特定形状的技术,尤其是直线和圆形。HoughCircles 实现了 Hough 变换的一个变种,专门用于检测圆形。

函数原型

void cv::HoughCircles
(
	InputArray 	image,
	OutputArray 	circles,
	int 	method,
	double 	dp,
	double 	minDist,
	double 	param1 = 100,
	double 	param2 = 100,
	int 	minRadius = 0,
	int 	maxRadius = 0 
)		

参数

  • 参数image: 8 位单通道灰度输入图像。

  • 参数circles: 输出的检测到的圆形向量。每个向量编码为包含 3 或 4 个元素的浮点数向量(x, y, 半径)或(x, y, 半径, 投票数)。

  • 参数method: 检测方法,参见 HoughModes。可用的方法包括 HOUGH_GRADIENT 和 HOUGH_GRADIENT_ALT。

  • 参数dp: 累加器分辨率与图像分辨率的逆比。例如,如果 dp=1,累加器具有与输入图像相同的分辨率。如果 dp=2,累加器的宽度和高度各为输入图像的一半。对于 HOUGH_GRADIENT_ALT,推荐的值是 dp=1.5,除非需要检测一些非常小的圆形。

  • 参数minDist: 检测到的圆形中心之间的最小距离。如果该参数太小,可能会错误地检测到多个相邻的圆形。如果太大,某些圆形可能会被遗漏。

  • 参数param1: 第一个特定于方法的参数。在 HOUGH_GRADIENT 和 HOUGH_GRADIENT_ALT 的情况下,它是传递给 Canny 边缘检测器的较高阈值(较低的阈值是较高阈值的一半)。注意 HOUGH_GRADIENT_ALT 使用 Scharr 算法来计算图像的导数,所以阈值通常应该更高,例如 300 或者适用于正常曝光和对比度较高的图像。

  • 参数param2: 第二个特定于方法的参数。在 HOUGH_GRADIENT 的情况下,它是检测阶段的累加器阈值,用于圆心。该值越小,可能检测到的虚假圆形越多。对应的累加器值较大的圆形将优先返回。在 HOUGH_GRADIENT_ALT 算法中,这是圆形的“完美度”度量。该值越接近 1,算法选择的圆形形状越好。大多数情况下 0.9 应该是合适的。如果你想更好地检测小圆形,可以将其减小到 0.85、0.8 或甚至更小。但同时也要尝试限制搜索范围 [minRadius, maxRadius] 以避免出现许多虚假圆形。

  • 参数minRadius: 最小圆形半径。

  • 参数maxRadius: 最大圆形半径。如果 <= 0,使用最大图像尺寸。如果 < 0,HOUGH_GRADIENT 返回中心而不查找半径。HOUGH_GRADIENT_ALT 总是计算圆形的半径。

代码示例


#include <iostream>
#include <opencv2/opencv.hpp>

int main( int argc, char** argv )
{
    // 加载图像

    cv::Mat img = cv::imread("/media/dingxin/data/study/OpenCV/sources/images/qiu.jpg", cv::IMREAD_COLOR );

    if ( !img.data )
    {
        std::cout << "No image data" << std::endl;
        return -1;
    }

    cv::imshow( "Original Image", img );

    // 转换为灰度图
    cv::Mat gray;
    cvtColor( img, gray, cv::COLOR_BGR2GRAY );

    // 高斯模糊减少噪声
    cv::GaussianBlur( gray, gray, cv::Size( 9, 9 ), 2, 2 );

    std::vector< cv::Vec3f > circles;  // 存储检测到的圆形信息

    // 设置参数
    double dp      = 1;             // 累加器分辨率
    double minDist = img.rows / 8;  // 圆心之间的最小距离
    double param1  = 100;           // 边缘检测的高阈值
    double param2  = 30;            // 累加器阈值
    int minRadius  = 0;             // 最小半径
    int maxRadius  = 0;             // 最大半径

    // 使用 HoughCircles 检测圆形
    cv::HoughCircles( gray, circles, cv::HOUGH_GRADIENT, dp, minDist, param1, param2, minRadius, maxRadius );

    // 绘制检测到的圆形
    for ( size_t i = 0; i < circles.size(); i++ )
    {
        cv::Vec3i c = circles[ i ];
        cv::Point center( cvRound( c[ 0 ] ), cvRound( c[ 1 ] ) );
        int radius = cvRound( c[ 2 ] );

        // 绘制圆心
        cv::circle( img, center, 1, cv::Scalar( 0, 100, 100 ), 3, cv::LINE_AA );

        // 绘制圆周
        cv::circle( img, center, radius, cv::Scalar( 255, 0, 0 ), 3, cv::LINE_AA );
    }

    // 显示带有检测出圆形的图像
    
    cv::imshow( "Detected Circles", img );

    // 等待按键后关闭窗口
    cv::waitKey( 0 );

    return 0;
}

运行结果

在这里插入图片描述


http://www.niftyadmin.cn/n/5671611.html

相关文章

vscode 配置django

创建运行环境 使用pip安装Django&#xff1a;pip install django。 创建一个新的Django项目&#xff1a;django-admin startproject myproject。 打开VSCode&#xff0c;并在项目文件夹中打开终端。 在VSCode中安装Python扩展&#xff08;如果尚未安装&#xff09;。 在项…

django+vue

1. diango 只能加载静态js&#xff0c;和flask一样 2. 关于如何利用vue创建web&#xff0c;请查看flask vue-CSDN博客 3. 安装django pip install django 4. 创建新项目 django-admin startproject myproject 5.django 中可以包含多个app 5.1 创建一个app cd myprojec…

前端-js:轮播图

学校官网都会有图片轮播&#xff0c;包括自动轮播及手动切换。 1. 原理&#xff1a; 在有限的区域内展示图片。 整个图片部分是一个胶卷 &#xff0c;当哪个图片在窗口位置展示哪个图片。 自动轮播&#xff1a;每隔一段时间调相对位置。 2. 实现 $1. 放5张图片 <div c…

关于ollama 在mac的部署问题

安装 官网链接 直接按需求下载即可 默认模型下载地址 macOS: ~/.ollama/models Linux: /usr/share/ollama/.ollama/models Windows: C:\Users<username>.ollama\models 根据需要的平台设置相应的环境变量&#xff1a; OLLAMA_MODELS 如Mac 设置 &#xff5e;/.zshrc …

爬虫 ----hook

目录 定义&#xff1a; 了解什么是hook? 举例 hook XHR请求 XMLHttpRequest 案例地址&#xff1a; Interceptors-拦截器 HOOK cookie操作 cookie 示范 常见的hook代码总结 1.Hook Cookie 2.Hook Header 3.Hook URL 4.Hook JSON.stringify 5.Hook JSON.parse 6.Ho…

速盾:高防cdn防御的时候会封ip吗?

高防CDN&#xff08;Content Delivery Network&#xff09;是一种用于提供网站或应用程序防护和内容分发的服务。它通过将内容分发到全球多个服务器上&#xff0c;帮助用户提高网站的访问速度和可用性&#xff0c;并提供强大的防护功能&#xff0c;包括防DDoS攻击、Web应用程序…

YOLOv9改进,YOLOv9主干网络替换为RepViT (CVPR 2024,清华提出,独家首发),助力涨点

摘要 轻量级视觉变换器(ViTs)在资源受限的移动设备上表现出优越的性能和较低的延迟,相比之下轻量级卷积神经网络(CNNs)稍显逊色。研究人员发现了许多轻量级 ViTs 和轻量级 CNNs 之间的结构联系。然而,它们在块结构、宏观和微观设计上的显著架构差异尚未得到充分研究。在…

【记录】Excel|不允许的操作:合并或隐藏单元格出现的问题列表及解决方案

人话说在前&#xff1a;这篇的内容是2022年5月写的&#xff0c;当时碰到了要批量处理数据的情况&#xff0c;但是又不知道数据为啥一直报错报错报错&#xff0c;说不允许我操作&#xff0c;最终发现是因为存在隐藏的列或行&#xff0c;于是就很无语地写了博客&#xff0c;但内容…