opencv之获取试卷中填空线段
目标:获取试卷中的填空线位置,为后续的自动判卷进行定位。
方法: 形态学处理+霍夫变换。
待处理图像:
1.假如直接对待处理图像进行霍夫直线检测,效果如下:
可以看到,会存在检测长度不足甚至漏检的情况,效果很不好。
2.下面使用形态学先对图片进行处理后再结合霍夫变换,效果如下:
检测效果明显提升。
具体操作流程及代码:
1.操作流程:
(1)图像ROI获取
(2)图像二值化
(3)形态学处理:使用横向直线结构体去除图片中非直线部分
(4)膨胀,得到效果更好的直线
(5)霍夫直线检测并显示到原图中
2.实现代码:
#include "stdafx.h"
#include<opencv2/opencv.hpp>
#include<iostream>
#include "math.h"
using namespace std;
using namespace cv;
Mat src, dst, roiImage;
char* input = "input Image";
char* output = "output Image";
void morhpologyLines(int,void*);
int _tmain(int argc, _TCHAR* argv[])
{
src = imread("D:/pictures/ftest.png");
if (src.empty())
{
printf("could not found Img...");
return -1;
}
namedWindow(input, CV_WINDOW_AUTOSIZE);
namedWindow(output, CV_WINDOW_AUTOSIZE);
imshow(input, src);
Rect roi = Rect(10, 10, src.cols - 20, src.rows - 20);
roiImage = src(roi);
imshow("ROI", roiImage);
morhpologyLines(0, 0);
waitKey(0);
return 0;
}
void morhpologyLines(int, void*)
{
//binary image
Mat binaryImage, morhpImage;
cvtColor(roiImage, roiImage, CV_BGR2GRAY);
threshold(roiImage, binaryImage, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
imshow("binary",binaryImage);
//morphology operation
Mat kernel = getStructuringElement(MORPH_RECT, Size(40, 1), Point(-1, -1));
morphologyEx(binaryImage, morhpImage, MORPH_OPEN, kernel, Point(-1, -1));
imshow("morphology",morhpImage);
kernel = getStructuringElement(MORPH_RECT, Size(3, 3),Point(-1,-1));
dilate(morhpImage, morhpImage, kernel);
imshow("morphologys",morhpImage);
//hough lines
vector<Vec4i>lines;
HoughLinesP(morhpImage, lines, 1, CV_PI /180.0, 30, 30.0, 0);
Mat resultImg = roiImage.clone();
cvtColor(resultImg, resultImg, CV_GRAY2BGR);
for (size_t t = 0; t < lines.size(); t++)
{
Vec4i ln = lines[t];
line(resultImg, Point(ln[0], ln[1]), Point(ln[2], ln[3]),Scalar(0,0,255) ,2, 8, 0);
}
imshow(output, resultImg);
return;
}