OpenCV与AI深度学习 | 实战 | OpenCV中更稳更快的找圆方法--EdgeDrawing使用演示(详细步骤 + 代码)

本文来源公众号“OpenCV与AI深度学习”,仅用于学术分享,侵权删,干货满满。

原文链接:实战 | OpenCV中更稳更快的找圆方法--EdgeDrawing使用演示(详细步骤 + 代码)

导  读

    本文主要介绍如何在OpenCV中使用EdgeDrawing模块查找圆(详细步骤 + 代码)。

背景介绍

    从OpenCV4.5.2开始,Contrib模块中封装了开源库ED_Lib用于查找图像中的直线、线段、椭圆和圆。Github地址:

https://github.com/CihanTopal/ED_Lib

    算法原理简介:

    边缘绘制(ED)算法是一种解决边缘检测问题的主动方法。与许多其他遵循减法方法的现有边缘检测算法相比(即在图像上应用梯度滤波器后,根据多种规则消除像素,例如 Canny 中的非极大值抑制和滞后),ED 算法通过加法策略工作,即逐一选取边缘像素,因此称为“边缘绘制”。然后我们处理这些随机形状的边缘段以提取更高级别的边缘特征,即直线、圆、椭圆等。从阈值梯度幅度中提取边缘像素的流行方法是非极大值抑制,它测试每个像素是否具有最大值沿其梯度方向的梯度响应,如果没有则消除。然而,此方法不检查相邻像素的状态,因此可能会导致低质量(在边缘连续性、平滑度、薄度、定位方面)边缘片段。ED 不是非极大值抑制,而是指向一组边缘像素,并通过最大化边缘段的总梯度响应来将它们连接起来。因此,它可以提取高质量的边缘片段,而不需要额外的滞后步骤。

    OpenCV中使用介绍文档

https://docs.opencv.org/4.5.2/d1/d1c/classcv_1_1ximgproc_1_1EdgeDrawing.html

使用步骤

    EdgeDrawing类是在Contrib的ximgproc模块中,C++中使用它需要满足以下条件:

    ① OpenCV >= 4.5.2

    ② CMake编译Contrib模块

    ③ 包含edge_drawing.hpp头文件

    Python中使用需要安装opencv-python-contrib >=4.5.2

【1】Python中使用演示:

#公众号--OpenCV与AI深度学习
'''
This example illustrates how to use cv.ximgproc.EdgeDrawing class.
Usage:ed.py [<image_name>]    image argument defaults to board.jpg
'''
# Python 2/3 compatibility
from __future__ import print_function
import numpy as np
import cv2 as cv
import random as rng
import sysrng.seed(12345)def main():try:fn = sys.argv[1]except IndexError:fn = 'board.jpg'src = cv.imread(cv.samples.findFile(fn))gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)cv.imshow("source", src)ssrc = src.copy() * 0lsrc = src.copy()esrc = src.copy()ed = cv.ximgproc.createEdgeDrawing()# you can change parameters (refer the documentation to see all parameters)EDParams = cv.ximgproc_EdgeDrawing_Params()EDParams.MinPathLength = 50     # try changing this value between 5 to 1000EDParams.PFmode = False         # default value try to switch it to TrueEDParams.MinLineLength = 20     # try changing this value between 5 to 100EDParams.NFAValidation = True   # default value try to switch it to Falseed.setParams(EDParams)# Detect edges# you should call this before detectLines() and detectEllipses()ed.detectEdges(gray)segments = ed.getSegments()lines = ed.detectLines()ellipses = ed.detectEllipses()# Draw detected edge segmentsfor i in range(len(segments)):color = (rng.randint(0,256), rng.randint(0,256), rng.randint(0,256))cv.polylines(ssrc, [segments[i]], False, color, 1, cv.LINE_8)cv.imshow("detected edge segments", ssrc)# Draw detected linesif lines is not None:  # Check if the lines have been found and only then iterate over these and add them to the imagelines = np.uint16(np.around(lines))for i in range(len(lines)):cv.line(lsrc, (lines[i][0][0], lines[i][0][1]), (lines[i][0][2], lines[i][0][3]), (0, 0, 255), 1, cv.LINE_AA)cv.imshow("detected lines", lsrc)# Draw detected circles and ellipsesif ellipses is not None:  # Check if circles and ellipses have been found and only then iterate over these and add them to the imagefor i in range(len(ellipses)):center = (int(ellipses[i][0][0]), int(ellipses[i][0][1]))axes = (int(ellipses[i][0][2])+int(ellipses[i][0][3]), int(ellipses[i][0][2])+int(ellipses[i][0][4]))angle = ellipses[i][0][5]color = (0, 0, 255)if ellipses[i][0][2] == 0:color = (0, 255, 0)cv.ellipse(esrc, center, axes, angle, 0, 360, color, 2, cv.LINE_AA)cv.imshow("detected circles and ellipses", esrc)cv.waitKey(0)print('Done')if __name__ == '__main__':print(__doc__)main()
cv.destroyAllWindows()

执行指令:ed.py [<image_name>]

实例1: edge_drawing.py 1.png

实例2: edge_drawing.py 2.png

实例3: edge_drawing.py 3.png

说明:上述图中,绿色表示找到的椭圆,红色表示找到的圆。

当然,EdgeDrawing还可以获取边缘信息和查找直线,效果如下:

【2】C++中使用演示:

//公众号--OpenCV与AI深度学习
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/ximgproc/edge_drawing.hpp>using namespace std;
using namespace cv;
using namespace ximgproc;int main() {Mat src = imread("./imgs/11.bmp");if (src.empty()) {cout << "src image is empty, check again!" << endl;return -1;}// resize(src, src, Size(), 0.2, 0.2);imshow("src", src);Mat gray;cvtColor(src, gray, COLOR_BGR2GRAY);double start = static_cast<double>(getTickCount()); //计时开始Ptr<EdgeDrawing> ed = createEdgeDrawing();ed->params.EdgeDetectionOperator = EdgeDrawing::PREWITT;ed->params.MinPathLength = 50; // try changing this value between 5 to 1000ed->params.PFmode = false; // default value try to switch it to trueed->params.MinLineLength = 10; // try changing this value between 5 to 100ed->params.NFAValidation = false; // default value try to switch it to falseed->params.GradientThresholdValue = 20;ed->detectEdges(gray);vector<Vec4i> lines = ed->detectLines();vector<Vec7f> ellipses = ed->detectEllipses();Mat src_edges, src_lines, src_ellipses;src_edges = src.clone();src_lines = src.clone();src_ellipses = src.clone();for (size_t i = 0; i < lines.size(); i++) {line(src_lines, Point(lines[i][0], lines[i][1]), Point(lines[i][2], lines[i][3]), Scalar(0, 255, 0), 2, LINE_AA);}for (size_t i = 0; i < ellipses.size(); i++) {Vec3f c = ellipses[i].clone();ellipse(src_ellipses, Point(c[0], c[1]), Size(c[2], c[3]), c[4], 0, 360, Scalar(0, 0, 255), 2, LINE_AA);}imshow("Detected Edges", src_edges);imshow("Detected Lines", src_lines);imshow("Detected Ellipses", src_ellipses);waitKey(0);return 0;
}

实例1: 

实例2: 

实例3:

简单总结

    总体来说EdgeDrawing提供的找圆和直线的方法简单易用且效果好,简单情况下使用默认参数即可。参数调整可以参考文档自己尝试,这里挑几个常用简单说明一下。

Ptr<EdgeDrawing> ed = createEdgeDrawing();
ed->params.EdgeDetectionOperator = EdgeDrawing::LSD;
ed->params.MinPathLength = 50; // try changing this value between 5 to 1000
ed->params.PFmode = false; //defaut value try to swich it to true
ed->params.MinLineLength = 10; // try changing this value between 5 to 100
ed->params.NFAValidation = true; // defaut value try to swich it to false
ed->params.GradientThresholdValue = 20;

【1】算法使用的梯度算子,可选4种,默认是PREWITT,大家可以设置不同的梯度算子尝试效果。

【2】梯度阈值GradientThresholdValue,值越小,更能找到对比度低的圆。比如下面分别是梯度阈值为100和50的效果:

【3】NFAValidation:默认值为true。指示是否将NFA(错误警报数)算法用于直线和椭圆验证。设置为false时,能找到更多圆或直线。

【4】MinPathLength:最小连接像素长度处理以创建边缘段。在梯度图像中,为创建边缘段而处理的最小连接像素长度。具有高于GradientThresholdValue的值的像素将被处理,默认值为10。比如下面分别是比如下面分别是梯度阈值为50和10的效果(值越小,更小的圆被找到):

THE END !

文章结束,感谢阅读。您的点赞,收藏,评论是我继续更新的动力。大家有推荐的公众号可以评论区留言,共同学习,一起进步。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/456522.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

pycharm 中提示ModuleNotFoundError: No module named ‘distutils‘

在Pycharm 中的命令行中输入 pip install setuptools&#xff0c;即可解决

K8S测试pod内存和CPU资源不足

只设置requests参数 mysql主从pod启动后监控 读压测之后 同时设置limits和requests&#xff0c;只调低内存值 监控 压力测试 同时设置limits和requests&#xff0c;只调低CPU值 初始状态 开始压测 结论 对于CPU&#xff0c;如果pod中服务使用CPU超过设置的limits&…

(小白教程)MPV.NET 播放器安装和添加插件脚本Bilibili弹幕

MPV.NET安装和添加插件脚本 MPV跨平台播放器&#xff1a;该播放器基于流行的mpv媒体播放器。mpv.net 设计为与 mpv 兼容&#xff0c;几乎所有 mpv 功能都可用&#xff0c;这意味着官方mpv 手册适用于 mpv.net&#xff0c;差异记录在mpv.net 手册中。 主要差异是mpv.net为MPV添加…

Linux 字符设备驱动 之 无法归类的《杂项设备驱动》

学习目标&#xff1a; 了解 杂项设备驱动 和普通字符设备的异同&#xff0c;及杂项设备驱动程序的写法 学习内容&#xff1a; 一、杂项设备驱动的特别之处 杂项设备&#xff08;Miscellaneous Devices&#xff09;是一种通用的设备类型&#xff0c;用于表示那些不适合其他设备…

基于springboot企业微信SCRM管理系统源码带本地搭建教程

系统是前后端分离的架构&#xff0c;前端使用Vue2&#xff0c;后端使用SpringBoot2。 技术框架&#xff1a;SpringBoot2.0.0 Mybatis1.3.2 Shiro swagger-ui jpa lombok Vue2 Mysql5.7 运行环境&#xff1a;jdk8 IntelliJ IDEA maven 宝塔面板 系统与功能介绍 基…

ubuntu 安装haproxy

####安装##### sudo apt update sudo apt install haproxy sudo haproxy -v sudo systemctl status haproxy sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg-org####配置站点##### nano /etc/haproxy/haproxy.cfgfrontend www-httpbind *:5001mode httpdefault_ba…

SAP RFC 的几种类型

SRFC: ARFC: ARFC: TRFC: QRFC: QRFC-QIN Scheduler: *RFC: tables: RSTRFCTA RFC-TEST: Outbound Queue: STOP/RESTART (after STOP) RSTRFCTB RFC TEST: Outbound Queue: Get/Execute LUWs from Local/Remote Syst RSTRFCTC RFC-TEST: Inbound Que…

当有违法数据时,浏览器不解析,返回了undefined,导致数据不解析

现象&#xff1a;页面上没有看到数据 排查&#xff1a;断点到线上的源码里&#xff1a;1、协议回调确实没有拿到数据是个undefined 2、network里看服务确实响应了数据 3、控制台没有任何报错。 心情&#xff1a;莫名其妙的现象 我本地有json格式化工具&#xff0c;copy进去后&…

【论文阅读】Tabbed Out: Subverting the Android Custom Tab Security Model

论文链接&#xff1a;Tabbed Out: Subverting the Android Custom Tab Security Model | IEEE Conference Publication | IEEE Xplore 总览 “Tabbed Out: Subverting the Android Custom Tab Security Model” 由 Philipp Beer 等人撰写&#xff0c;发表于 2024 年 IEEE Symp…

linux入门之必掌握知识点

#1024程序员节&#xff5c;征文# Linux基础 top命令详解 top命令是用来查看进程系统资源使用情况的工具&#xff0c;它可以动态的现实。 top命令执行后&#xff0c;按大写M可以按内存使用情况进行排序&#xff0c;大写P可以按CPU使用情况进行排序&#xff0c;大写H可以显示线…

vue-vant框架引入

一、工具说明 vscode编辑器 二、安装 使用包管理器安装 npm install vant -S 查看是否安装成功&#xff1a;查看项目下的package.json文件中的依赖是否有vant: 三、导入 1、按需导入 按照node_mouduls目录下的vant文件夹的lib目录中的路径导入你要的组件 2、整体导入 在…

WPS电信定制版 v12.8.2.18205 自带 VBA\无广告

下载&#xff08;哪个方便就下哪个&#xff09;&#xff1a;【1】https://pan.quark.cn/s/5373bf6cdcf5【2】链接: https://pan.baidu.com/s/1Vn2Bbhp8px-BBtlalkIIYg?pwdjgry 提取码: jgry 软件介绍&#xff1a; 1、VBA 组件更换为电信定制版&#xff0c;签名日期&#xf…

【进阶OpenCV】 (19)-- Dlib库 --人脸表情识别

文章目录 表情识别一、原理二、代码实现1. 摄像头前预处理2. 计算嘴唇变化3. 绘制嘴唇轮廓4. 显示结果5. 完整代码展示 总结 表情识别 目标&#xff1a;识别人物的喜悦状态。 一、原理 我们在对一张人脸图片进行关键点定位后&#xff0c;得到每个关键点的位置&#xff1a; 比…

疯狂变现!5分钟教你如何高效率制作AI商业海报!

在这个快节奏的时代&#xff0c;效率就是生命力。无论你是创业者、还是设计师&#xff0c;制作吸引人的详情海报都是日常工作中不可或缺的一环。传统的设计从构思到定稿&#xff0c;往往需要数小时甚至数天的时间。但现在&#xff0c;有了AI技术的加持——仅5分钟&#xff0c;你…

红帽Linux认证与其他认证相比优势在哪?

在各种各样的 IT 认证里头&#xff0c;红帽 Linux 认证凭借自身独特的地方和长处崭露头角。那红帽 Linux 认证跟其他认证相比&#xff0c;长处到底在啥地方呢&#xff1f; 接下来就给大伙简单说道说道。 首先&#xff0c;红帽 Linux 认证特别注重实践。它主要考查考生实际操作…

AI智能监测系统:全面赋能燃气安全管理的智能化转型方案

燃气安全智能化的需求&#xff1a; 随着燃气供应系统的广泛应用&#xff0c;燃气安全成为城市管理和企业运营中的重要环节。由于燃气泄漏、操作不规范等事故会造成巨大的人员伤亡和财产损失&#xff0c;传统的安全管理方法往往效率低下&#xff0c;依赖人工巡检&#xff0c;无…

JavaEE----多线程(二)

文章目录 1.进程的状态2.线程的安全引入3.线程安全的问题产生原因4.synchronized关键字的引入4.1修饰代码块4.2修饰实例方法4.3修饰静态方法4.4对象头介绍4.5死锁-可重入的特性 5.关于死锁的分析总结5.1死锁的分析5.2死锁成因的必要条件5.3死锁的解决方案 1.进程的状态 public…

深入了解 kotlinx-datetime:配置与使用指南

深入了解 kotlinx-datetime&#xff1a;配置与使用指南 在Kotlin多平台开发中&#xff0c;处理日期和时间是常见的需求。kotlinx-datetime库提供了强大且简洁的API来帮助开发者应对这一挑战。本文将详细介绍如何配置kotlinx-datetime库&#xff0c;并通过生动的示例演示其核心…

java中Set,Map,List集合的比较(不包含增删改查函数方法)

目录 1. 集合的简介2. List3. Set4. Map5. 比较5.1 结构特点5.2 实现类5.3 区别 6. 其他问题6.1 集合与数组的区别6.2 哪些集合类是线程安全的 7. 参考链接 1. 集合的简介 所有的集合类和集合接口都在java.util包下。 在内存中申请一块空间用来存储数据&#xff0c;在Java中集…

[网络协议篇] UDP协议

文章目录 1. 简介2. 特点3. UDP数据报结构4. 基于UDP的应用层协议5. UDP安全性问题6. 使用udp传输数据的系统就一定不可靠吗&#xff1f;7. 基于UDP的主机探活 python实现 1. 简介 User Datagram Protocol&#xff0c;用户数据报协议&#xff0c;基于IP协议提供面向无连接的网…