- 操作系统:ubuntu22.04
- OpenCV版本:OpenCV4.9
- IDE:Visual Studio Code
- 编程语言:C++11
算法描述
检测图像中线段的类.。
遵循在 285中描述的算法。
函数原型1
绘制两组线,一组用蓝色,一组用红色,并计算非重叠(不匹配)的像素。
cpp
virtual int cv::LineSegmentDetector::compareSegments
(
const Size & size,
InputArray lines1,
InputArray lines2,
InputOutputArray image = noArray()
)
参数1
- 参数size:找到 lines1 和 lines2 的图像的大小。
- 参数lines1:需要绘制的第一组线段。它们以蓝色显示。
- 参数lines2:第二组线段。它们以红色显示。
- 参数image:可选的图像,在该图像上绘制线段。图像应该是彩色的(3通道),以便 lines1 和 lines2 能够以上述颜色绘制。
函数原型2
在一个输入图像中查找线条
cpp
virtual void cv::LineSegmentDetector::detect
(
InputArray image,
OutputArray lines,
OutputArray width = noArray(),
OutputArray prec = noArray(),
OutputArray nfa = noArray()
)
参数2
-
参数image:一个灰度(CV_8UC1类型)输入图像。如果只需要选择一个感兴趣区域(ROI),可以使用:lsd_ptr->detect(image(roi), lines, ...); 并且需要更新 lines 向量,加上偏移量 lines += Scalar(roi.x, roi.y, roi.x, roi.y);
-
参数ilines:由 Vec4f 类型元素组成的向量,指定了一条线段的起始点和终点。其中 Vec4f 的格式为 (x1, y1, x2, y2),点1为起点,点2为终点。返回的线段是严格根据梯度方向排列的。
-
参数iwidth:一个向量,包含了发现线段所在区域的宽度。例如,线段的宽度。
-
参数iprec:一个向量,包含了发现线段的精确度。
-
参数infa:一个包含在线段区域内误报数量的向量,精确到10%。数值越大,对数意义上检测得越好。
- -1 对应于平均有10个误报;
- 0 对应于平均有1个误报;
- 1 对应于平均有0.1个误报; 这个向量仅当对象类型设置为 LSD_REFINE_ADV 时才会计算。
函数原型3
在给定的图像上绘制线段
cpp
virtual void cv::LineSegmentDetector::drawSegments
(
InputOutputArray image,
InputArray lines
)
参数3
- 参数image:这指的是线条将要在其上绘制的图像。该图像应该大于或等于找到线条的图像的尺寸。
- 参数lines:这是一个需要绘制的线条的向量(集合)。
代码示例
cpp
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/line_descriptor/descriptor.hpp>
#include <opencv2/ximgproc.hpp>
#include <iostream>
int main(int argc, char** argv)
{
// 加载图像
cv::Mat img = cv::imread("/media/dingxin/data/study/OpenCV/sources/images/building.png",cv::IMREAD_GRAYSCALE);
if (img.empty())
{
std::cout << "Error loading image." << std::endl;
return -1;
}
// 创建用于绘制线段的新图像
cv::Mat lsd_img = img.clone();
// 创建 LineSegmentDetector
cv::Ptr<cv::LineSegmentDetector> lsd = cv::createLineSegmentDetector();
// 检测线段
std::vector<cv::Vec4i> lineSegments;
lsd->detect(img, lineSegments);
// 遍历并绘制每个线段
for (const auto& ls : lineSegments)
{
cv::Point pt1(ls[0], ls[1]);
cv::Point pt2(ls[2], ls[3]);
cv::line(lsd_img, pt1, pt2, cv::Scalar(0, 255, 0), 2); // 绘制绿色线条
}
// 显示结果图像
cv::imshow("original image", img);
cv::imshow("Line Segments", lsd_img);
cv::waitKey(0);
return 0;
}
运行结果
原始图:
画线段图: