opencv中两个LSD直线检测算法的区别与应用

opencv中两个LSD直线检测算法的区别与应用

同样是Line Segment Detector(lsd)算法,opencv中提供了两种实现,并且位于不同的模块。下面分别介绍它们的使用方法:

1. LineSegmentDetector

由于源码许可证问题 OpenCV 3.4.6-3.4.15、4.1.0-4.5.3中无法使用这个方法

使用该类检测直线并显示的代码如下:

import cv2if __name__ == '__main__':img = cv2.imread("test.jpg")gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)gray_img = cv2.GaussianBlur(gray_img, (3,3), 2.0)#LineSegmentDetectorlsd = cv2.createLineSegmentDetector(refine=cv2.LSD_REFINE_NONE, scale=0.8, ang_th=35)lines_detected, width, prec, nfa = lsd.detect(gray_img)#lsd.drawSegments(img,lines_detected)#绘制检测结果for dline in lines_detected:x0 = int(round(dline[0][0]))y0 = int(round(dline[0][1]))x1 = int(round(dline[0][2]))y1 = int(round(dline[0][3]))cv2.line(mask, (x0, y0), (x1,y1), 255, 1, cv2.LINE_AA)cv2.imshow("Detected lines", img)cv2.waitKey(0)cv.destroyAllWindows()

c++示例代码如下(lsd_lines.cpp):

#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{cv::CommandLineParser parser(argc, argv,"{input   i|../data/building.jpg|input image}""{refine  r|false|if true use LSD_REFINE_STD method, if false use LSD_REFINE_NONE method}""{canny   c|false|use Canny edge detector}""{overlay o|false|show result on input image}""{help    h|false|show help message}");if (parser.get<bool>("help")){parser.printMessage();return 0;}parser.printMessage();String filename = parser.get<String>("input");bool useRefine = parser.get<bool>("refine");bool useCanny = parser.get<bool>("canny");bool overlay = parser.get<bool>("overlay");Mat image = imread(filename, IMREAD_GRAYSCALE);if( image.empty() ){cout << "Unable to load " << filename;return 1;}imshow("Source Image", image);if (useCanny){Canny(image, image, 50, 200, 3); // Apply Canny edge detector}// Create and LSD detector with standard or no refinement.Ptr<LineSegmentDetector> ls = useRefine ? createLineSegmentDetector(LSD_REFINE_STD) : createLineSegmentDetector(LSD_REFINE_NONE);double start = double(getTickCount());vector<Vec4f> lines_std;// Detect the linesls->detect(image, lines_std);double duration_ms = (double(getTickCount()) - start) * 1000 / getTickFrequency();std::cout << "It took " << duration_ms << " ms." << std::endl;// Show found linesif (!overlay || useCanny){image = Scalar(0, 0, 0);}ls->drawSegments(image, lines_std);String window_name = useRefine ? "Result - standard refinement" : "Result - no refinement";window_name += useCanny ? " - Canny edge detector used" : "";imshow(window_name, image);waitKey();return 0;
}

2. cv::line_descriptor::LSDDetector

这个类在opencv_contrib中实现。源码目录结构示例如下:在这里插入图片描述
如果c++编译opencv时未包含contrib模块;或在python中用pip安装了opencv-python而不是opencv-contrib-python,均无法使用该LSD直线检测方法。
python用户只管卸载opencv-python,安装opencv-contrib-python,前者是后者的子集。

pip uninstall opencv-python
pip install opencv-contrib-python

使用该类检测直线并显示的python代码如下:

import cv2if __name__ == '__main__':img = cv2.imread("test.jpg")gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)gray_img = cv2.GaussianBlur(gray_img, (3,3), 2.0)#LSDDetectorlsd = cv2.line_descriptor_LSDDetector.createLSDDetector()lines = lsd.detect(gray, 2, 1)for kl in lines:#绘制检测结果if kl.octave == 0:# cv.line only accepts integer coordinatept1 = (int(kl.startPointX), int(kl.startPointY))pt2 = (int(kl.endPointX), int(kl.endPointY))cv.line(img, pt1, pt2, [255, 0, 0], 2)cv.imshow('Detected lines', img)cv.waitKey(0)cv.destroyAllWindows()

c++示例代码如下(lines_extraction.cpp):

#include <iostream>
#include <opencv2/opencv_modules.hpp>
#include <opencv2/line_descriptor.hpp>
#include <opencv2/core/utility.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/highgui.hpp>using namespace cv;
using namespace cv::line_descriptor;
using namespace std;static const char* keys =
{ "{@image_path | | Image path }" };static void help()
{cout << "\nThis example shows the functionalities of lines extraction " << "furnished by BinaryDescriptor class\n"<< "Please, run this sample using a command in the form\n" << "./example_line_descriptor_lines_extraction <path_to_input_image>" << endl;
}int main( int argc, char** argv )
{/* get parameters from comand line */CommandLineParser parser( argc, argv, keys );String image_path = parser.get<String>( 0 );if( image_path.empty() ){help();return -1;}/* load image */cv::Mat imageMat = imread( image_path, 1 );if( imageMat.data == NULL ){std::cout << "Error, image could not be loaded. Please, check its path" << std::endl;return -1;}/* create a random binary mask */cv::Mat mask = Mat::ones( imageMat.size(), CV_8UC1 );/* create a pointer to a BinaryDescriptor object with deafult parameters */Ptr<LSDDetector> bd = LSDDetector::createLSDDetector();/* create a structure to store extracted lines */vector<KeyLine> lines;/* extract lines */cv::Mat output = imageMat.clone();bd->detect( imageMat, lines, 2, 1, mask );/* draw lines extracted from octave 0 */if( output.channels() == 1 )cvtColor( output, output, COLOR_GRAY2BGR );for ( size_t i = 0; i < lines.size(); i++ ){KeyLine kl = lines[i];if( kl.octave == 0){/* get a random color */int R = ( rand() % (int) ( 255 + 1 ) );int G = ( rand() % (int) ( 255 + 1 ) );int B = ( rand() % (int) ( 255 + 1 ) );/* get extremes of line */Point pt1 = Point2f( kl.startPointX, kl.startPointY );Point pt2 = Point2f( kl.endPointX, kl.endPointY );/* draw line */line( output, pt1, pt2, Scalar( B, G, R ), 3 );}}/* show lines on image */imshow( "LSD lines", output );waitKey();
}

3. 区别与应用

这两种LSD实现的处理结果基本一致,但是获取检测到的直线的端点坐标的方式有所不同:
前者的直线检测结果是numpy array类型,每个直线由4个浮点数表示(x1, y1, x2, y2);后者的检测结果的直线类型,具有起点和端点成员变量,分别是(startPointX,startPointY,endPointX,endPointY),并且还具有直线的方向(角度)和长度成员变量。
具体从上面两个代码片段的可视化部分展示的清清楚楚。

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

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

相关文章

vue中使用prettier

前言&#xff1a;prettier是一款有态度的代码格式化工具&#xff0c;它可以集成在IDE中&#xff0c;如VS Code、Web Storm等&#xff0c;也可以安装到我们开发的项目里面。本文主要讲解在Vue中集成prettier的过程&#xff0c;可以便于代码检测和格式化。 prettier官网 从官网的…

【论文笔记】Attention Is All You Need

【论文笔记】Attention Is All You Need 文章目录 【论文笔记】Attention Is All You NeedAbstract1 Introduction2 Background补充知识&#xff1a;软注意力 soft attention 和硬注意力 hard attention&#xff1f;补充知识&#xff1a;加法注意力机制和点乘注意力机制Extende…

MFC教程 -- Windows界面开发

MFC教程 -- Windows界面开发 Windows消息机制 初步认识MFC 要想熟练掌握 Windows 应用程序的开发&#xff0c; 首先需要理解 Windows 平台下程序运行的内部机制。如果想要更好的学习掌握 MFC&#xff0c;必须要先了解Windows 程序的内部运行机制&#xff0c;为我们扫清学习路…

【Java程序设计】【C00327】基于Springboot的高校教师教研信息填报系统(有论文)

基于Springboot的高校教师教研信息填报系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的高校教师教研信息填报系统&#xff0c;本系统有管理员、教研管理以及教研人员三种角色&#xff1b; 管理员&#xff1a…

【DAY05 软考中级备考笔记】线性表,栈和队列,串数组矩阵和广义表

线性表&#xff0c;栈和队列&#xff0c;串数组矩阵和广义表 2月28日 – 天气&#xff1a;阴转晴 时隔好几天没有学习了&#xff0c;今天补上。明天发工资&#xff0c;开心&#x1f604; 1. 线性表 1.1 线性表的结构 首先线性表的结构分为物理结构和逻辑结构 物理结构按照实…

Java开发的核心模式 - MVC

文章目录 1、MVC设计模式2、Web开发本质3、服务器的性能瓶颈 1、MVC设计模式 MVC设计模式示意图 在整个Java学习之旅中&#xff0c;MVC&#xff08;Model-View-Controller&#xff09;设计模式无疑占据着极其重要的地位&#xff0c;堪称理解和掌握Java项目开发精髓的钥匙。如…

Stable-Diffusion ubuntu服务器部署,报错解决方法(小白教程)

Stable Diffusion是一个深度学习模型&#xff0c;专注于生成高质量的图像。它由CompVis团队与Stability AI合作开发&#xff0c;并在2022年公开发布。这个模型使用文本提示&#xff08;text prompts&#xff09;生成详细、逼真的图像&#xff0c;是目前人工智能图像生成领域的一…

【底层学习】ArrayList源码学习

成员变量 学习源码前&#xff0c;我们还是先看一下ArrayList中成员变量有哪些 构造函数 ArrayList一共有三个构造函数。 第一个&#xff1a;带有指定初始容量的构造函数 第二个&#xff1a;空参构造 第三个&#xff1a;包含指定集合的构造函数 OK&#xff0c;看完构造函数&a…

仿真科普|CAE技术赋能无人机 低空经济蓄势起飞

喝一杯无人机送来的现磨热咖啡&#xff1b;在拥堵的早高峰打个“空中的士”上班&#xff1b;乘坐水陆两栖飞机来一场“陆海空”立体式观光……曾经只出现在科幻片里的5D城市魔幻场景&#xff0c;正逐渐走进现实。而推动上述场景实现的&#xff0c;就是近年来越来越热的“低空经…

webstorm 创建vue3 vite 项目

打开Webstorm,创建一个空项目 直接在当前项目执行创建vue3项目指令&#xff0c;打开主页terminal 回车后输入项目名字全部小写字母字 打开创建项目 项目插件安装 npm install 运行&#xff1a; npm run dev

如何调用GLM-4 API实现智能问答

诸神缄默不语-个人CSDN博文目录 GLM系列大模型是智谱AI提供的系列语言模型&#xff0c;GLM-4没有开源&#xff0c;只提供了API。本文介绍如何用Python语言调用GLM-4 API实现智能问答。 智谱AI为所有用户提供了18元免费额度&#xff0c;可以试用。 文章目录 1. 获得API key2. …

Qt|QTreewidget类下函数qt助手详解说明示例(上)

该系列持续更新&#xff0c;喜欢请一键三连&#xff0c;感谢各位大佬。 QT5.14.2 参考官方QT助手 文章目录 QTreeWidget ClasspropertiesPublic Functions默认构造函数默认析构函数添加根节点void addTopLevelItem(QTreeWidgetItem *item)添加多个根节点void addTopLevelItems…