网上c++的opencv教程太少了
刚好我今天花了一下午部署了opencv环境,用上了LSD算法,效果不错,故分享给大家
问:contrib是什么?
答:contrib是opencv的附加第三方库,有很多先进的算法
LSD是2010年新推出的算法,相比起1962年的Hough霍夫检测算法,它先进一大截,有成功率高,可以检测出直线的长度的优点
可以参考这个文章:OpenCV直线检测算法汇总
https://blog.csdn.net/weixin_46838716/article/details/125492966
直线检测汇总
效果展示:
参考这个链接:
VS编译OpenCV + Contrib
预计花费时间:2小时
最后只需要那个install文件夹就行
我把那个文件夹传到网盘了 网盘链接
重点在于添加这两个库的地址
(如果还有错误,我也不会。。)
#include
#include
#include
using namespace cv;
using namespace std;
int main()
{
string file = "C:\\Users\\Desktop\\DSC01.jpg"; //填自己的图片链接
Mat img = imread(file);
Mat image = img.clone();
Mat grayImage;
cvtColor(image, grayImage, COLOR_BGR2GRAY); //先把图片灰度化
//*****核心代码*****//
//Canny(grayImage, grayImage, 50, 50, 3); //可选canny边缘检测算法,但没必要,直线算法效果已经够好了
#if 0
Ptr<LineSegmentDetector> lsd = createLineSegmentDetector(LSD_REFINE_ADV);//或者两种LSD算法,这边用的是standard的
#else
Ptr<LineSegmentDetector> lsd = createLineSegmentDetector(LSD_REFINE_NONE);//这个算法找到的直线更多
#endif
vector<Vec4f> lines;
//进入检测直线算法
lsd->detect(grayImage, lines);//这里把检测到的直线线段都存入了lines_std中,4个float的值,分别为起点的坐标,和终点的坐标
//*****************//
for (int i = 0; i < lines.size(); i++)
{
cout << lines[i][0] << " " << lines[i][1] << " "
<< lines[i][2] << " " << lines[i][3] << endl;
//这里可以进行筛选直线
Point p0 = Point(lines[i][0], lines[i][1]);
Point p1 = Point(lines[i][2], lines[i][3]);
line(image, p0, p1, Scalar(0, 50, 255), 3, CV_AA);//画出直线
}
//画出所有的直线
Mat drawnLines(image.clone());
lsd->drawSegments(drawnLines, lines);
imshow("Standard refinement", drawnLines);
waitKey(0);
return 0;
}
如果你想调参,也可以用以下代码
调参代码:
double scale = 0.8,
double sigma_scale = 0.6, double quant = 2.0, double ang_th = 22.5,
double log_eps = 0, double density_th = 0.7, int n_bins = 1024;
Ptr<LineSegmentDetector> lsd = createLineSegmentDetector(LSD_REFINE_NONE,
scale,
sigma_scale,
quant, ang_th,
log_eps,
density_th,
n_bins);
vector<Vec4f> lines;
//进入检测直线算法
lsd->detect(grayImage, lines);
参考链接:https://blog.csdn.net/thequitesunshine007/article/details/116382216
推荐使用局部直方图均衡,
参考链接
再推荐下我使用的模糊算法,用来消除瑕疵
//我称之为模糊的三明治结构,效果很好
blur(image, image, Size(5, 5)); //平均模糊用来平滑边缘
GaussianBlur(image, image, Size(5, 5), 0, 0);//高斯模糊用来消除瑕疵点
blur(image, image, Size(5, 5));