Opencv实战1 检测直线

1 直线检测

2.1 题目

        将下面试卷中横线检测出来,用红线替换。
Opencv实战1 检测直线_第1张图片

2.2 思路

2.2.1 思路一 霍夫直线检测(不恰当方法):

1、 转化为灰度图像。
2、 二值化。
3、 边缘检测。
4、 霍夫直线检测。
示例代码:

void MethodOne(Mat img)
{
	// 第一步:转化为灰度图像
	Mat grayImg;
	cvtColor(img, grayImg, COLOR_BGR2GRAY);

	// 第二步:二值化。
	threshold(grayImg, grayImg, 0, 255, THRESH_OTSU | THRESH_BINARY);

	// 第三步:边缘检测
	Canny(grayImg, grayImg, 100, 200, 3, false);

	// 第四步:霍夫直线检测
	vectorplines;
	HoughLinesP(grayImg, plines, 1, CV_PI / 180, 30, 18, 0);
	Mat dst = img.clone();
	for (size_t i = 0; i < plines.size(); i++)
	{
		Vec4f hline = plines[i];
		line(dst, Point(hline[0], hline[1]), Point(hline[2], hline[3]), Scalar(0,0,255), 1, LINE_AA);
	}
	imshow("dst", dst);
}

        在不断尝试霍夫直线的参数之后最终比较好的效果如下图,可以看到结果还是很不理想。
Opencv实战1 检测直线_第2张图片
2.2.2 思路二
1、 转化为灰度图像。
2、 二值化。
3、 边缘检测。
4、 形态学处理保留直线。
5、 霍夫直线检测。
示例代码:

void MethodTwo(Mat img)
{
	// 第一步:转化为灰度图像
	Mat grayImg;
	cvtColor(img, grayImg, COLOR_BGR2GRAY);

	// 第二步:二值化。
	threshold(grayImg, grayImg, 0, 255, THRESH_OTSU | THRESH_BINARY);

	// 第三步:边缘检测
	Canny(grayImg, grayImg, 100, 200, 3, false);

	// 第四步: 闭操作填充Y方向空洞
	Mat kernel = getStructuringElement(MORPH_RECT, Size(1, 3));
	morphologyEx(grayImg, grayImg, MORPH_CLOSE, kernel);

	// 第五步:开操作保留直线
	 kernel = getStructuringElement(MORPH_RECT, Size(20, 1));
	morphologyEx(grayImg, grayImg, MORPH_OPEN, kernel);

#if 0
	imshow("grayImg", grayImg);
	// 第六步:霍夫直线检测
	vectorplines;
	HoughLinesP(grayImg, plines, 1, CV_PI / 180, 20, 5, 0);
	Mat dst = img.clone();
	for (size_t i = 0; i < plines.size(); i++)
	{
		Vec4f hline = plines[i];
		line(dst, Point(hline[0], hline[1]), Point(hline[2], hline[3]), Scalar(0, 0, 255), 2, LINE_AA);
	}
#else
	// 创建红色背景的图片
	Mat redImg(grayImg.size(),CV_8UC3,Scalar(0,0,255));
	Mat RedLineImg;
	cvtColor(grayImg, RedLineImg,COLOR_GRAY2BGR);

	// 与操作得到只由红色直线黑色背景图
	RedLineImg &= redImg;
	imshow("RedLineImg", RedLineImg);

	// 与操作得到结果
	Mat dst = img.clone();
	dst = dst | RedLineImg;
#endif
	imshow("dst", dst);
}

        形态学处理后使用霍夫直线检测后的效果图如下,可以看出效果好的多了。
Opencv实战1 检测直线_第3张图片
        有意思的是在形态学直线提取之后,得到的直线反而非常好,比最终的霍夫直线检测效果还好,下图是利用图像与操作实现直线的标红,未使用霍夫直线,效果非常好,当然这要求背景是白色的。
Opencv实战1 检测直线_第4张图片

2.3 关键API

        morphologyEx:可以调节形态学算子,检测水平竖直线,效果非常好。

2.4 总结

        这个例子告诉我们,霍夫直线检测固然好,但是还是需要结合实际问题,霍夫检测前需要做预处理得出大致的直线图样,而并不是上来就使用霍夫直线检测。

你可能感兴趣的:(Opencv学习)