opencv案例直线检测
学了有段时间的opencv和C++基础了,现在想拿一个案例过来练练手,现在科技进步,阅卷工作已经不需要以前的人工操作了,现在有一份英语试卷摆在面前,如下图
我们怎么去检测图中填空题上面的横线了,我的第一反应是这个题应该很简单,霍夫直线轻易就可以搞定了,话不多说,直接上代码。
Mat canny_image;
vector<Vec4i> lines;
Canny(src, canny_image, threshold_value, threshold_value * 2, 3, false); // canny边缘检测
HoughLinesP(canny_image, lines, 1, CV_PI / 180.0, 30, 30, 0); // 霍夫直线检测
src.copyTo(dst);
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(186, 88, 255), 1, LINE_AA, 0);
}
imshow(outputWindow, dst);
threshold = 20时:
threshold = 100时:
threshold = 255时:
然而事实并不尽如人意,没有全部检测出来,开始我以为是阈值选择造成的误差,我尝试改变threshold_value 的值,却依然没有检测出来。无奈感叹到:理想很丰满,现实很骨感。
这时候事情就很难办了,显然通过寻找边缘,再去做霍夫检测这条路是行不通的,因此我们通过图像形态学操作来寻找直线,利用霍夫直线检测获取位置信息并显示。
Mat binary_image, gray_image, morph_image, dilate_image, kernel;
cvtColor(src, gray_image, COLOR_BGR2GRAY);
threshold(gray_image, binary_image, 0, 255, THRESH_BINARY | THRESH_OTSU); //二值化,THRESH_OTSU自动确定阈值
bitwise_not(binary_image, binary_image, Mat()); //取反
kernel = getStructuringElement(MORPH_RECT, Size(20, 1), Point(-1, -1));
morphologyEx(binary_image, morph_image, MORPH_OPEN, kernel, Point(-1, -1)); //开操作
kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
dilate(morph_image, dilate_image, kernel, Point(-1, -1)); //膨胀
Mat canny_image;
vector<Vec4i> lines;
Canny(dilate_image, canny_image, threshold_value, threshold_value * 2, 3, false); // canny边缘检测
HoughLinesP(canny_image, lines, 1, CV_PI / 180.0, 20, 5, 0); // 霍夫直线检测
src.copyTo(dst);
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(186, 88, 255), 1, LINE_AA, 0);
}
imshow(outputWindow, dst);
结果如下图: