Opencv学习之 LineSegmentDector(LSD)
简介
这个示例不涉及具体原理,主要演示了如何使用OpenCV对图像进行LSD直线检测。
cv::LineSegmentDetector 类
https://docs.opencv.org/3.4.1/db/d73/classcv_1_1LineSegmentDetector.html#details
Line segment detector class,该类基于论文《Rafael Grompone von Gioi, Jérémie Jakubowicz, Jean-Michel Morel, and Gregory Randall. Lsd: a line segment detector. 2012》 所写。
- 头文件
#include<opencv2/imgproc.hpp> - 主要步骤
(1) 使用 createLineSegmentDetector 创建 LSD detector (智能指针)
Ptr<LineSegmentDetector> ls = createLineSegmentDetector(LSD_REFINE_STD);
(2) 使用 LSD detector 进行LSD直线检测;
vector<Vec4i>lines; // 或vector<Vec4f>lines;
ls->detect(image,lines);
- image:A grayscale (CV_8UC1) input image. If only a roi needs to be selected, use: lsd_ptr->detect(image(roi), lines, …); lines += Scalar(roi.x, roi.y, roi.x, roi.y);
- lines:A vector of Vec4i or Vec4f elements specifying the beginning and ending point of a line. Where Vec4i/Vec4f is (x1, y1, x2, y2), point 1 is the start, point 2 - end. Returned lines are strictly oriented depending on the gradient.
(3) 使用 drawSegment 在图像中显示找到的直线
// Show found lines
Mat drawnLines(image); //深拷贝,drawnLines和image位于不同内存
ls->drawSegments(drawnLines, lines); //lines为上步直线检测的结果
代码地址:https://docs.opencv.org/3.0.0/d8/dd4/lsd_lines_8cpp-example.html
#include <iostream>
#include <string>
#include <opencv2/core/core.hpp>
#include <opencv2/core/utility.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
std::string in;
if (argc != 2)
{
std::cout << "Usage: lsd_lines [input image]. Now loading .." << std::endl;
in = "../data/building.jpg";
}
else
{
in = argv[1];
}
Mat image = imread(in, IMREAD_GRAYSCALE);
Mat dst;
#if 1
Canny(image, dst, 50, 200, 3); // Apply canny edge
#endif
// Create and LSD detector with standard or no refinement.
#if 1
Ptr<LineSegmentDetector> ls = createLineSegmentDetector(LSD_REFINE_STD);
#else
Ptr<LineSegmentDetector> ls = createLineSegmentDetector(LSD_REFINE_NONE);
#endif
double start = double(getTickCount());
vector<Vec4f> lines_std;
// Detect the lines
ls->detect(dst, lines_std);
double duration_ms = (double(getTickCount()) - start) * 1000 / getTickFrequency();
std::cout << "It took " << duration_ms << " ms." << std::endl;
// Show found lines
Mat drawnLines(image);
ls->drawSegments(drawnLines, lines_std);
imshow("Standard refinement", drawnLines);
waitKey();
return 0;
}
运行结果: