【OpenCV】EDCircles一个带有错误检测控制的实时圆检测器


前言

数字图像中圆形物体的检测是图像处理和计算机视觉中一个重要且反复出现的问题,尤其在工业品自动检测、线描图像辅助矢量化、瞳孔和虹膜检测、圆形交通标志检测等自动化问题中有很多应用。
理想的圆检测算法对所有图像的内部参数都是固定的,即不需要对不同的图像进行参数调优,速度非常快,可以检测多个大大小小的圆,可以处理合成的、自然的和有噪声的图像,检测率高,准确率高,很少或没有错误检测。EDCircle提出的圆检测算法满足所有这些性质。

一、什么是EDCircle?

EDCircle一种实时的,无参数的圆检测算法,具有高的检测率,产生准确的结果,并控制错误的圆检测的数量。该算法利用了无参数边缘段检测器产生的连续(连通)边缘段集,即无参数边缘绘制(EDPF)算法;因此得名EDCircles。该算法首先利用EDPF算法对给定图像进行边缘分割,然后将边缘分割成线段。将检测到的线段转换为圆弧,使用两种启发式算法将圆弧拼接在一起,检测出候选圆和近圆椭圆。最后通过亥姆霍兹原理的反向验证步骤对候选对象进行验证,该方法消除了错误检测,只留下有效的圆和近圆椭圆。EDCircles可以在输入图像中检测圆形和椭圆形,并将结果以圆形和椭圆形参数的形式返回。它的应用包括自动化检查生产的产品、人眼虹膜和瞳孔检测、圆形交通信号灯检测等。

二、EDCircle的检测步骤

EDCircles遵循几个步骤来计算给定图像中的圆。其基本思路是提取图像中的线段,将其转换为圆弧,然后结合这些圆弧来检测圆和近圆椭圆。

一、实时边缘/边缘检测器(ED)
1.输入灰度图,通过通过诸如非最大抑制、滞后阈值化、侵蚀等操作来消除非边缘像素来工作。
2.识别图像中的一组锚点。
3.输出二进制边缘图,还输出一组边缘线段,每个边缘线段是一个连续的像素链。

二、无参数边缘提取的边缘检测方法(EDPF)
1.输入灰度图,检测给定图像中所有可能的边缘片段。
2.使用亥姆霍兹验证边缘。
3.检测边缘片段,去除错误边缘。

三、圆/椭圆检测(EDCircles)
1.输入灰度图,通过EDPF检测边缘部分,提取完整的圆和椭圆。
2.将剩余的边段转换为线段。
3.通过组合线段来检测圆弧。
4.连接圆弧以检测候选圆。
5.连接剩余的弧以检测近似圆形的椭圆候选对象。
6.使用亥姆霍兹原理验证候选圆/椭圆。
7.输出剩余的有效圆/椭圆。
参考https://blog.csdn.net/SiuooooBoom/article/details/109260998

三、算法实现

EDCircle的算法实现基于论文《EDCircles: A real-time circle detector with a false detection control》论文链接。本示例代码来自于EDlib,一个对EDCircle和EDLine的开源实现,开源代码https://github.com/CihanTopal/ED_Lib,OpenCV中也有对此算法的实现,OpenCV实现EDCircle。其目录结构如下:

在这里插入图片描述
EDCircles测试代码如下(示例1):

#include "EDLib.h"
#include <iostream>

using namespace cv;
using namespace std;

int main()
{
   
	//***************************** ED Edge Segment Detection *****************************
	//Detection of edge segments from an input image	

	double  t1, t2;
	t1 = getTickCount();
	int delay = 100;

	string input = "./ED_Lib-master/billiard.jpg";
	Mat testImg = imread(input, IMREAD_GRAYSCALE);
	imshow("Source Image", testImg);

	//Call ED constructor
	ED testED = ED(testImg, SOBEL_OPERATOR, 36, 8, 1, 10, 1.0, true); // apply ED algorithm

	//Show resulting edge image
	Mat edgeImg = testED.getEdgeImage();
	imshow("Edge Image - PRESS ANY KEY TO CONTINUE", edgeImg);
	waitKey(delay);
	imwrite("./EDResult/EdgeImage.png", edgeImg);
	
	//************************** EDPF Parameter-free Edge Segment Detection **************************
	// Detection of edge segments with parameter free ED (EDPF)
	EDPF testEDPF = EDPF(testImg);
	Mat edgePFImage = testEDPF.getEdgeImage();
	imshow("Edge Image Parameter Free", edgePFImage);
	waitKey(delay);
	imwrite("./EDResult/EDPF_EdgeImage.png", edgePFImage);
	//***************************** EDCIRCLES Circle Segment Detection *****************************
	//Detection of circles directly from the input image

	EDCircles testEDCircles = EDCircles(testImg);
	Mat circleImg = testEDCircles.drawResult(false, ImageStyle::BOTH);
	imshow("Circle Image 1", circleImg);
	imwrite("./EDResult/CircleImg1.png", circleImg);
	std::cout << "Number of circles with EDCirlces: " << testEDCircles.getCirclesNo()<< std::endl;
	//Detection of circles from already available EDPF or ED image
	testEDCircles = EDCircles(testEDPF);

	//Get circle information as [cx, cy, r]
	vector<mCircle> circles = testEDCircles.getCircles();

	//Get ellipse information as [cx, cy, a, b, theta]
	vector<mEllipse> ellipses = testEDCircles.getEllipses();

	//Circles and ellipses will be indicated in green and red, resp.
	circleImg = testEDCircles.drawResult(true, ImageStyle::BOTH);
	imwrite("./EDResult/CircleImg2.png", circleImg);

	int noCircles = testEDCircles.getCirclesNo();
	std::cout << "Number of circles with EDPF: " << noCircles << std::endl;
	waitKey(delay);

	//*********************** EDCOLOR Edge Segment Detection from Color Images **********************

	Mat colorImg = imread(input);
	EDColor testEDColor = EDColor(colorImg, 36, 4, 1.5, true); //last parameter for validation
	imshow("Color Edge Image - PRESS ANY KEY TO QUIT"
  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shanhedian2013

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值