OpenCV中更稳更快的边缘检测方法,快速查找线、圆、椭圆--EdgeDrawing-C++代码

本文主要是介绍OpenCV中更稳更快的边缘检测方法,快速查找线、圆、椭圆--EdgeDrawing-C++代码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

计算机视觉之家看到快速圆检测Edge Drawing,其效果比霍夫要好,速度更快(具体效果可以参考视觉之家的文章),上面C++代码不全,那么好的检测效果国内资料竟然那么少,后在opencv的开发文档中找到了C++代码,在此分享学习交流。

实战 | OpenCV中更稳更快的找圆方法--EdgeDrawing使用演示(详细步骤 + 代码)_opencv 找圆_计算机视觉之家的博客-CSDN博客

OpenCV: EdgeDrawing

OpenCV: fld_lines.cpp

#include <iostream>#include "opencv2/imgproc.hpp"
#include "opencv2/ximgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"using namespace std;
using namespace cv;
using namespace cv::ximgproc;int main(int argc, char** argv)
{string in;CommandLineParser parser(argc, argv, "{@input|corridor.jpg|input image}{help h||show help message}");if (parser.has("help")){parser.printMessage();return 0;}in = samples::findFile(parser.get<string>("@input"));Mat image = imread(in, IMREAD_GRAYSCALE);if( image.empty() ){return -1;}// Create FLD detector// Param               Default value   Description// length_threshold    10            - Segments shorter than this will be discarded// distance_threshold  1.41421356    - A point placed from a hypothesis line//                                     segment farther than this will be//                                     regarded as an outlier// canny_th1           50            - First threshold for//                                     hysteresis procedure in Canny()// canny_th2           50            - Second threshold for//                                     hysteresis procedure in Canny()// canny_aperture_size 3            - Aperturesize for the sobel operator in Canny().//                                     If zero, Canny() is not applied and the input//                                     image is taken as an edge image.// do_merge            false         - If true, incremental merging of segments//                                     will be performedint length_threshold = 10;float distance_threshold = 1.41421356f;double canny_th1 = 50.0;double canny_th2 = 50.0;int canny_aperture_size = 3;bool do_merge = false;Ptr<FastLineDetector> fld = createFastLineDetector(length_threshold,distance_threshold, canny_th1, canny_th2, canny_aperture_size,do_merge);vector<Vec4f> lines;// Because of some CPU's power strategy, it seems that the first running of// an algorithm takes much longer. So here we run the algorithm 10 times// to see the algorithm's processing time with sufficiently warmed-up// CPU performance.for (int run_count = 0; run_count < 5; run_count++) {double freq = getTickFrequency();lines.clear();int64 start = getTickCount();// Detect the lines with FLDfld->detect(image, lines);double duration_ms = double(getTickCount() - start) * 1000 / freq;cout << "Elapsed time for FLD " << duration_ms << " ms." << endl;}// Show found lines with FLDMat line_image_fld(image);fld->drawSegments(line_image_fld, lines);imshow("FLD result", line_image_fld);waitKey(1);Ptr<EdgeDrawing> ed = createEdgeDrawing();ed->params.EdgeDetectionOperator = EdgeDrawing::SOBEL;ed->params.GradientThresholdValue = 38;ed->params.AnchorThresholdValue = 8;vector<Vec6d> ellipses;for (int run_count = 0; run_count < 5; run_count++) {double freq = getTickFrequency();lines.clear();int64 start = getTickCount();// Detect edges//you should call this before detectLines() and detectEllipses()ed->detectEdges(image);// Detect linesed->detectLines(lines);double duration_ms = double(getTickCount() - start) * 1000 / freq;cout << "Elapsed time for EdgeDrawing detectLines " << duration_ms << " ms." << endl;start = getTickCount();// Detect circles and ellipsesed->detectEllipses(ellipses);duration_ms = double(getTickCount() - start) * 1000 / freq;cout << "Elapsed time for EdgeDrawing detectEllipses " << duration_ms << " ms." << endl;}Mat edge_image_ed = Mat::zeros(image.size(), CV_8UC3);vector<vector<Point> > segments = ed->getSegments();for (size_t i = 0; i < segments.size(); i++){const Point* pts = &segments[i][0];int n = (int)segments[i].size();polylines(edge_image_ed, &pts, &n, 1, false, Scalar((rand() & 255), (rand() & 255), (rand() & 255)), 1);}imshow("EdgeDrawing detected edges", edge_image_ed);Mat line_image_ed(image);fld->drawSegments(line_image_ed, lines);// Draw circles and ellipsesfor (size_t i = 0; i < ellipses.size(); i++){Point center((int)ellipses[i][0], (int)ellipses[i][1]);Size axes((int)ellipses[i][2] + (int)ellipses[i][3], (int)ellipses[i][2] + (int)ellipses[i][4]);double angle(ellipses[i][5]);Scalar color = ellipses[i][2] == 0 ? Scalar(255, 255, 0) : Scalar(0, 255, 0);ellipse(line_image_ed, center, axes, angle, 0, 360, color, 2, LINE_AA);}imshow("EdgeDrawing result", line_image_ed);waitKey();return 0;
}

这篇关于OpenCV中更稳更快的边缘检测方法,快速查找线、圆、椭圆--EdgeDrawing-C++代码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/387808

相关文章

Java实现任务管理器性能网络监控数据的方法详解

《Java实现任务管理器性能网络监控数据的方法详解》在现代操作系统中,任务管理器是一个非常重要的工具,用于监控和管理计算机的运行状态,包括CPU使用率、内存占用等,对于开发者和系统管理员来说,了解这些... 目录引言一、背景知识二、准备工作1. Maven依赖2. Gradle依赖三、代码实现四、代码详解五

SpringBoot基于MyBatis-Plus实现Lambda Query查询的示例代码

《SpringBoot基于MyBatis-Plus实现LambdaQuery查询的示例代码》MyBatis-Plus是MyBatis的增强工具,简化了数据库操作,并提高了开发效率,它提供了多种查询方... 目录引言基础环境配置依赖配置(Maven)application.yml 配置表结构设计demo_st

JAVA中整型数组、字符串数组、整型数和字符串 的创建与转换的方法

《JAVA中整型数组、字符串数组、整型数和字符串的创建与转换的方法》本文介绍了Java中字符串、字符数组和整型数组的创建方法,以及它们之间的转换方法,还详细讲解了字符串中的一些常用方法,如index... 目录一、字符串、字符数组和整型数组的创建1、字符串的创建方法1.1 通过引用字符数组来创建字符串1.2

深入理解C++ 空类大小

《深入理解C++空类大小》本文主要介绍了C++空类大小,规定空类大小为1字节,主要是为了保证对象的唯一性和可区分性,满足数组元素地址连续的要求,下面就来了解一下... 目录1. 保证对象的唯一性和可区分性2. 满足数组元素地址连续的要求3. 与C++的对象模型和内存管理机制相适配查看类对象内存在C++中,规

SpringCloud集成AlloyDB的示例代码

《SpringCloud集成AlloyDB的示例代码》AlloyDB是GoogleCloud提供的一种高度可扩展、强性能的关系型数据库服务,它兼容PostgreSQL,并提供了更快的查询性能... 目录1.AlloyDBjavascript是什么?AlloyDB 的工作原理2.搭建测试环境3.代码工程1.

Java调用Python代码的几种方法小结

《Java调用Python代码的几种方法小结》Python语言有丰富的系统管理、数据处理、统计类软件包,因此从java应用中调用Python代码的需求很常见、实用,本文介绍几种方法从java调用Pyt... 目录引言Java core使用ProcessBuilder使用Java脚本引擎总结引言python

Apache Tomcat服务器版本号隐藏的几种方法

《ApacheTomcat服务器版本号隐藏的几种方法》本文主要介绍了ApacheTomcat服务器版本号隐藏的几种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需... 目录1. 隐藏HTTP响应头中的Server信息编辑 server.XML 文件2. 修China编程改错误

Java中ArrayList的8种浅拷贝方式示例代码

《Java中ArrayList的8种浅拷贝方式示例代码》:本文主要介绍Java中ArrayList的8种浅拷贝方式的相关资料,讲解了Java中ArrayList的浅拷贝概念,并详细分享了八种实现浅... 目录引言什么是浅拷贝?ArrayList 浅拷贝的重要性方法一:使用构造函数方法二:使用 addAll(

Java中switch-case结构的使用方法举例详解

《Java中switch-case结构的使用方法举例详解》:本文主要介绍Java中switch-case结构使用的相关资料,switch-case结构是Java中处理多个分支条件的一种有效方式,它... 目录前言一、switch-case结构的基本语法二、使用示例三、注意事项四、总结前言对于Java初学者

使用Python实现大文件切片上传及断点续传的方法

《使用Python实现大文件切片上传及断点续传的方法》本文介绍了使用Python实现大文件切片上传及断点续传的方法,包括功能模块划分(获取上传文件接口状态、临时文件夹状态信息、切片上传、切片合并)、整... 目录概要整体架构流程技术细节获取上传文件状态接口获取临时文件夹状态信息接口切片上传功能文件合并功能小