问题描述:如何将试卷中填空题的下划线检测出来,便于后续的文字检测处理。
如图所示,直接对图像进行霍夫曼直线检测处理,那么其中的非直线部分,会对检测结果造成比较大的影响,无法准确检测出图像中直线的位置。如下图所示,便是使用灰度变换+canny边缘滤波+Hough直线检测处理的结果,可以发现会将一部分文字当作直线给误检处理。
本文的思路则是,在使用Hough直线检测前加一步形态学图像处理操作,降低文字对直线检测的干扰。我们知道形态学开操作可以有效避免二值图像中小的干扰块,降低二值图像中噪点过多的问题。
看一下处理结果
代码如下
void dectLines(Mat src, Mat dst)
{
//灰度化
Mat gray, binary,openImg;
cvtColor(src, gray, COLOR_BGR2GRAY);
imshow("gray", gray);
//二值化
threshold(gray, binary, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
imshow("binary", binary);
//形态学处理
Mat kern = getStructuringElement(MORPH_RECT, Size(20, 1));
morphologyEx(binary, openImg, MORPH_OPEN, kern);
imshow("open", openImg);
//膨胀操作,加强直线
Mat kern2 = getStructuringElement(MORPH_RECT, Size(3, 3));
morphologyEx(openImg, openImg, MORPH_DILATE, kern2);
imshow("膨胀", openImg);
//直线检测
vector<Vec4i>lines;
dst = src.clone();
HoughLinesP(openImg, lines, 1, 3.1415 / 180, 20, 20, 0);
for (size_t i = 0; i < lines.size(); i++)
{
line(dst, Point(lines[i][0], lines[i][1]), Point(lines[i][2], lines[i][3]), Scalar(0, 0, 255), 2, 8);
}
imwrite("result.jpg", dst);
}
解释:
(1)代码中将canny操作变为二值化处理,因为canny操作产生的边缘有时会对结果产生一定的影响。
(2)代码中在形态学处理后,又加了一步图像膨胀操作,这是为了避免一条直线中间会出现断点,使得直线变的不连续,而通过膨胀操作处理后,直线会被突出。