FastLineDetector(FLD)快速直线检测器的使用方法

news2024/11/29 4:43:33
  • 操作系统:ubuntu22.04
  • OpenCV版本:OpenCV4.9
  • IDE:Visual Studio Code
  • 编程语言:C++11

1.功能描述

opencv_contrib中有一个用于快速检测直线的类,叫FastLineDetector,下面介绍一下如何使用它,首先要用到一个cv::ximgproc::createFastLineDetector函数,然后会使用一个类EdgeDrawing,

2.类FastLineDetector

2.1 detect()函数

在输入图像中寻找线条。下图是采用算法默认参数进行处理后的输出结果。
在这里插入图片描述

2.1.1 原型
virtual void cv::ximgproc::FastLineDetector::detect	(
InputArray 	image,
OutputArray lines 
)		
2.1.2参数
  • 参数image 一个灰度图像(CV_8UC1格式)作为输入。如果只需要选择图像中的某个感兴趣区域(ROI)进行检测,可以使用如下方法:fld_ptr->detect(image(roi), lines, …); 然后将检测到的线条坐标加上ROI的偏移量,即 lines += Scalar(roi.x, roi.y, roi.x, roi.y)。这样处理后,得到的线条坐标会自动调整为相对于原图的正确位置。

  • 参数lines 一个由Vec4f元素组成的向量,用于指定线条的起始点和结束点。其中,Vec4f表示为(x1, y1, x2, y2),点1是线条的起点,点2是线条的终点。返回的线条方向设定为使得较亮的一侧位于线条的左侧。

2.2 drawSegments函数

在给定的图像上绘制线段

2.2.1原型
virtual void cv::ximgproc::FastLineDetector::drawSegments	(	
InputOutputArray 	image,
InputArray 	lines,
bool 	draw_arrow = false,
Scalar 	linecolor = Scalar(0, 0, 255),
int 	linethickness = 1 
)		

2.2.2参数
  • 参数 image 用于绘制线段的图像。此图像应大于或等于找到线段的原始图像尺寸。
  • 参数 lines 需要被绘制的线条的向量.
  • 参数 draw_arrow 如果为真,将绘制箭头头部.
  • 参数 linecolor 线的颜色.
  • 参数 linethickness 线的厚度.

3 类EdgeDrawing

这个类实现了一系列边缘检测与特征提取算法,包括ED(EdgeDrawing)[267]、EDLines [4]、EDPF [5] 和 EDCircles [6]。这些算法主要用于图像处理领域,旨在从图像中识别出边缘、线段、特定模式(如圆)以及可能的其他特征。EdgeDrawing专注于边缘的高效抽取,EDLines专门用于线段检测,EDPF可能是指在某些特定条件或优化下的边缘和线段检测,而EDCircles则是用于检测圆形结构。此类的实现能够为图像分析和计算机视觉任务提供强大的工具。

3.1函数 detectEdges (InputArray src)

该操作在灰度图像中检测边缘。

3.1.1原型
virtual void cv::ximgproc::EdgeDrawing::detectEdges	(	InputArray 	src	)	

3.2 函数detectLines

进行直线检测

3.2.1 原型

virtual void cv::ximgproc::EdgeDrawing::detectLines	(	
OutputArray 	lines	
)	

3.3函数detectEllipses

检测圆形和椭圆

3.3.1原型
virtual void cv::ximgproc::EdgeDrawing::detectEllipses	(	
OutputArray 	ellipses	
)	

3.4函数getSegments

返回检测到的边缘段组成的 std::vector<std::vector>,详情请参见 detectEdges() 函数

3.4.1原型
virtual std::vector<std::vector<Point> > cv::ximgproc::EdgeDrawing::getSegments	(		)	

4 createFastLineDetector函数

这个函数是创建一个FastLineDetector的智能指针,并且对他进行初始化。

4.1函数原型

Ptr<FastLineDetector> cv::ximgproc::createFastLineDetector	(	
int 	length_threshold = 10,
float 	distance_threshold = 1.414213562f,
double 	canny_th1 = 50.0,
double 	canny_th2 = 50.0,
int 	canny_aperture_size = 3,
bool 	do_merge = false 
)		

4.2参数描述

  • 参数length_threshold 长度阈值,线段长度小于这个阈值就会被丢弃。
  • 参数distance_threshold 距离阈值 如果一个点距离假设的线段超过此设定值,那么该点将被视为异常点
  • 参数canny_th1 Canny算法中的第一个阈值用于执行滞后阈值过程
  • 参数canny_th2 Canny算法中的第二个阈值用于执行滞后阈值过程
  • 参数canny_aperture_size 在Canny()算法中用于Sobel算子的孔径尺寸。如果设为零,则不应用Canny算法,直接将输入图像作为边缘图像使用。.
  • 参数 do_merge 如果为真,则将执行片段的增量合并。

5 示例代码

#include "opencv2/highgui.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/ximgproc.hpp"
#include <iostream>

using namespace std;
using namespace cv;
using namespace cv::ximgproc;

int main( int argc, char** argv )
{
    // 读取图像并转换为灰度
    cv::Mat image = cv::imread( "/media/dingxin/data/study/OpenCV/sources/images/line.jpg", cv::IMREAD_GRAYSCALE );
    if ( image.empty() )
    {
        std::cerr << "Could not open or find the image" << std::endl;
        return -1;
    }

    imshow( "原灰度图", image );

    // 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 performed
    int 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;

    //由于某些CPU的电源管理策略,首次运行算法时似乎需要更长的时间。
	//因此,我们在这里对算法进行10次运行,以充分预热CPU性能后,了解算法的实际处理时间。

    for ( int run_count = 0; run_count < 5; run_count++ )
    {
        double freq = getTickFrequency();
        lines.clear();
        int64 start = getTickCount();
        // 使用FLD检测线段
        fld->detect( image, lines );
        double duration_ms = double( getTickCount() - start ) * 1000 / freq;
        cout << "Elapsed time for FLD " << duration_ms << " ms." << endl;
    }
    // 显示用FLD找到的线
    Mat 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 lines
        ed->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 ellipses
        ed->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 );
    // 画圆和椭圆
    for ( 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;

    return 0;
}

6 结果

原图:
在这里插入图片描述
FLD结果图:

在这里插入图片描述

EdgeDrawing 检测结果(线段)
在这里插入图片描述
EdgeDrawing 结果(画圆和椭圆):
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

巴伦在接收链路中的应用

一、巴伦的定义 "巴伦"&#xff08;Balun&#xff09;&#xff0c;是一种平衡-不平衡转换器&#xff0c;通常用于将平衡信号&#xff08;如差分信号&#xff09;转换为不平衡信号&#xff08;如单端信号&#xff09;&#xff0c;或者反之。巴伦在无线通信、广播、天…

手机流畅运行470亿大模型:上交大发布LLM手机推理框架PowerInfer-2,提速29倍

卡奥斯智能交互引擎是卡奥斯基于海尔近40年工业生产经验积累和卡奥斯7年工业互联网平台建设的最佳实践&#xff0c;基于大语言模型和RAG技术&#xff0c;集合海量工业领域生态资源方优质产品和知识服务&#xff0c;旨在通过智能搜索、连续交互&#xff0c;实时生成个性化的内容…

GEE数据集——全球河流阻塞数据库 (GROD)1.1 版

全球河流阻塞数据库 (GROD) GROD v1.1&#xff08;文件名&#xff1a;GROD_v1.1.csv&#xff09;&#xff0c;即全球河流阻塞数据库 1.1 版&#xff0c;包含 30549 个人工识别的阻碍河流纵向流动的人为结构。谷歌地球引擎卫星地图上的所有河流障碍物都已在全球陆地卫星河宽&am…

2024年数字技术与智慧教育国际会议(DTSE 2024,7月26-28)

2024年数字技术与智慧教育国际会议&#xff08;DTSE 2024&#xff09;将于2024年7月26日在广东省广州市召开&#xff0c;本次会议专注于“数字技术与智慧教育”领域&#xff0c; 将汇集全球范围内的学者、研究人员以及教育技术开发者&#xff0c;共同探索和分享该领域内的最新学…

软件游戏缺失mfc100u.dll如何解决,教你多种有效的方法

在现代科技日新月异的时代&#xff0c;电脑已经成为我们生活和工作中不可或缺的一部分。然而&#xff0c;随着使用时间的增长&#xff0c;电脑也会出现各种各样的问题。其中&#xff0c;“电脑中丢失mfc100u.dll”是许多用户经常遇到的问题之一。那么&#xff0c;这个问题究竟是…

XXL-JOB分布式任务调度快速入门

文章目录 概念快速启动XXL-JOB调度初始化执行器项目配置执行器新增GLUE模式(Java)的任务新增BEAN模式&#xff08;类形式&#xff09;的任务BEAN模式&#xff08;方法形式&#xff09;的任务参考来源 概念 XXL-JOB是一个开源的分布式任务调度平台&#xff0c;它是一个轻量级、…

Web前端大作业:基于html+css+js的仿酷狗音乐项目(内附源码)

文章目录 一、项目介绍二、项目展示三、源码展示四、获取源码 一、项目介绍 课设是要仿照酷狗音乐的首页进行设计。酷狗音乐是国内知名的音乐应用程序,凭借其优秀的音乐库和智能推荐功能吸引了大量用户群体。模仿酷狗音乐的首页设计,可以让课设展现出专业水准,体现出对优秀产品…

Excel自定义排序和求和

概览 excel作为办公的常备工具&#xff0c;好记性不如烂笔头&#xff0c;在此梳理记录下&#xff0c;此篇文章主要是记录excel的自定义排序和求和 一. 自定义排序 举个例子 1. 填充自定义排序选项 实现步骤&#xff1a; 选定目标排序值&#xff1b;文件->选项->自定…

zypcy

一、浏览器调试 1、elements 2、Network 用于抓包 Preserve log&#xff1a;保留日志&#xff0c;所有日志都会被保留&#xff0c;而不是被覆盖&#xff0c;刷新前刷新后的日志都会被保留 Disable cache&#xff1a;禁止缓存&#xff0c;保证每次变化都是从服务器请求的数据&…

海洋CMS /js/player/dmplayer/dmku/ SQL注入漏洞复现(CVE-2024-29275)

0x01 产品简介 海洋CMS是一套专为不同需求的站长而设计的内容管理系统&#xff0c;灵活、方便、人性化设计、简单易用是最大的特色&#xff0c;可快速建立一个海量内容的专业网站。海洋CMS基于PHPMySql技术开发&#xff0c;完全开源免费 、无任何加密代码。 0x02 漏洞概述 海…

SAP 中的Incoterms国际贸易条款术语解释

之前写代码建交货单的时候总是会遇到这个字段&#xff0c;通常我们可能会填FOB或者CIF或者其他&#xff0c;但并不清楚这些都是什么意思&#xff0c;偶然间看到一篇帖子对此作了解释&#xff0c;也记录分享一下。 原文地址&#xff1a; Incoterms&#xff5c;FOB、CFR和CIF&a…

pom学习笔记:kimi的自动化操作

1.先看结构&#xff1a; 声明&#xff1a;我是初学&#xff0c;可能有不合理的地方。 2.Base层。 我是把原来一个kimi的自动问答的代码改过来。 分析&#xff1a;其实我是新手&#xff0c;因为我用的浏览器是固定的&#xff0c;也没有打算和别人用。所以浏览器层面年的全部写…

C语言,struct 结构体、union共用体的使用

//状态字节&#xff0c;根据数据定义几个标志&#xff0c;标志位依据联合体内部结构体进行变量定义 //目的&#xff0c;节省内存空间&#xff0c;省去特定字节 struct STATDATA {union{unsigned char stat;struct {unsigned stat0:1;unsigned stat1:1;unsigned stat2:1;unsign…

rtl8723du android5.1 6818 (wifi 部分)(第三部分)

这部分主要就是 应用了。具体的详细框架 在 android4.4 部分写的差不多的。 之前板卡依然是使用的 mt6620 ,所以在移植的过程中,需要把之前的 wifi 的驱动一点一点的去掉。 1 kernel 的修改。 将驱动拷贝到 wireless 下。 修改Kconfig 修改Makefile 2 驱动的Makefile 的修改…

塬号星球项目介绍

开发时间&#xff1a;2024 . 02~ 至今 已经部署上线&#xff08;可以在微信里搜索“塬号星球”&#xff09;&#xff0c;仍在完善阶段。 塬号星球——周边信息社交生活服务平台 项目介绍&#xff1a;项目主要是针对于在大学有流量却不知道该如何变现的朋友&#xff0c;比…

Oracle最终会扼杀MySQL?(译)

原文网站&#xff1a;https://www.percona.com/blog/is-oracle-finally-killing-mysql/ 作者&#xff1a;Peter Zaitsev 自从Oracle收购了MySQL后&#xff0c;很多人怀疑Oracle对开源MySQL的善意&#xff0c;这篇percona的文章深入分析了Oracle已经和将要对MySQL采取的措施&a…

欢乐钓鱼大师攻略:buff大全讲解,云手机托管使用教程!

《欢乐钓鱼大师》是一款充满趣味与挑战的钓鱼模拟游戏。在这款游戏中&#xff0c;玩家不仅能够体验到钓鱼的乐趣&#xff0c;还需要通过策略性地收集与使用不同的钓鱼装备来提升自己的钓鱼技巧和效率。本文将为你提供一份详细的游戏攻略&#xff0c;帮助你在游戏中轻松上手并快…

CNS-BL30H系列直流无刷电机驱动器|电机参数配置方法

CNS-BL30H系列直流无刷电机驱动器|电机包含CNS-BL30HB、CNS-BL30HDN、CNS-BL30HSN&#xff0c;采用一驱二设计&#xff0c;可以同时驱动两个小于48V/1000W的直流无刷电机&#xff0c;体积小巧&#xff0c;安装方便&#xff0c;接线快捷&#xff0c;本文重点介绍CNS-BL30H系列直…

什么是 URL 过滤?是如何保障浏览体验的?

互联网是一个无边无际的空间&#xff0c;几乎包含了你能想象到的一切。不幸的是&#xff0c;这意味着也存在着从不合适到非常危险的网站。这就是 URL 过滤可以发挥作用的地方。 一、URL 过滤的含义 我们希望您已经熟悉 URL&#xff08;统一资源定位器&#xff09;&#xff0c;…

Non-aligned Supervision for Real Image Dehazing

原文链接&#xff1a;https://www.semanticscholar.org/paper/Non-aligned-supervision-for-Real-Image-Dehazing-Fan-Guo/7595d39e71ae58343e8728fc1af0e18ffe38218b 数据集&#xff1a;https://www.cityscapes-dataset.com/ 真实的图像去雾的非对准监督 摘要 由于天气条件…