opencv之获取试卷中填空线段

目标:获取试卷中的填空线位置,为后续的自动判卷进行定位。
方法: 形态学处理+霍夫变换。
待处理图像:
opencv之获取试卷中填空线段

1.假如直接对待处理图像进行霍夫直线检测,效果如下:opencv之获取试卷中填空线段
可以看到,会存在检测长度不足甚至漏检的情况,效果很不好。

2.下面使用形态学先对图片进行处理后再结合霍夫变换,效果如下:
opencv之获取试卷中填空线段
检测效果明显提升。

具体操作流程及代码:
1.操作流程:
(1)图像ROI获取
opencv之获取试卷中填空线段
(2)图像二值化
opencv之获取试卷中填空线段
(3)形态学处理:使用横向直线结构体去除图片中非直线部分
opencv之获取试卷中填空线段
(4)膨胀,得到效果更好的直线
opencv之获取试卷中填空线段
(5)霍夫直线检测并显示到原图中
opencv之获取试卷中填空线段

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;
}