Open CV 提取直线
要求
需求是这样的:我们要提取出下图填空题中的空行,以便统计空行数。
显然,这是我自己随手写的,但是直线还算比较直。我觉得这个应该也能做吧。
开始做
好,那就试试吧,首先我增加下亮度,整个图灰蒙蒙的看着难受。
通过如下代码操作:
Mat src_output;
src.convertTo(src_output, -1,3,0);//3是亮度
在2、3、4、6个亮度中我选了个3,看着还行。
接着我们要将背景色变为黑色(就是反相)
为啥要反相?
来,你不反相试试:
据沙雕老师嗯嗯叽叽的解释,形态学操作的背景要求是黑色的xxxx之类的。(我才不信)
好,在二值化的同时我们乖乖反相一下:
//二值化
cvtColor(src_output, graySrc, CV_BGR2GRAY);
threshold(graySrc, graySrc, 0,255, THRESH_BINARY_INV | THRESH_OTSU);
imshow("th_out", graySrc);
其中 THRESH_BINARY_INV
就是二值化并反相的参数
接着我们要做形态学操作了:
//先准备一个Kernel(Size比较重要,这里的20,1表示长20px、高为1px。那么这个kernel就表示你要找长20高1的图形)
Mat kernel = getStructuringElement(MORPH_RECT, Size(20, 1));
//告诉形态学Ex你要对谁操作,保存到谁那,进行什么操作(是开还是闭还是别的),你的kernel叫啥
morphologyEx(graySrc, graySrc, MORPH_OPEN, kernel);
形态学操作后,我们得到几个直线:
是不是多了一条?没办法,谁让我quantum写连着了。
好,既然只剩直线了,那我们就上霍夫老哥的直线检测了。
//霍夫直线检测
//注意api
vector<Vec4i> lines;
HoughLinesP(graySrc, lines,1,CV_PI / 180.0,10,7.0,0);
这里需要注意,API是HoughLinesP(graySrc, lines,1,CV_PI / 180.0,10,7.0,0);
后面有个P!千万别忘了!害死我了找了半天问题。
讲霍夫检测到的直线全部存放在lines里,接下来我们就foreach画出来。
for (size_t i = 0; i < lines.size(); i++)
{
Vec4i currPoints = lines[i];
//这里可以骚着写
line(src, Point(currPoints[0],currPoints[1]), Point(lines[i][2],lines[i][3]), Scalar(0, 0, 255));
}
我就画在原图上。
结果
全部代码
(src是原图)
#pragma region 直线检测
Mat src_output;
src.convertTo(src_output, -1,3,0);//3是亮度
imshow("src_out2", src_output);//现在这个亮度还不错
//二值化
cvtColor(src_output, graySrc, CV_BGR2GRAY);
threshold(graySrc, graySrc, 0,255, THRESH_BINARY_INV | THRESH_OTSU);
imshow("th_out", graySrc);
//形态学操作
Mat kernel = getStructuringElement(MORPH_RECT, Size(20, 1));
morphologyEx(graySrc, graySrc, MORPH_OPEN, kernel);
imshow("mor", graySrc);
//霍夫直线检测
//注意api
vector<Vec4i> lines;
HoughLinesP(graySrc, lines,1,CV_PI / 180.0,10,7.0,0);
for (size_t i = 0; i < lines.size(); i++)
{
Vec4i currPoints = lines[i];
//这里可以骚着写
line(src, Point(currPoints[0],currPoints[1]), Point(lines[i][2],lines[i][3]), Scalar(0, 0, 255));
}
imshow("src", src);
#pragma endregion
waitKey(0);
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。