opencv/C++ 获取填空题的下划线

问题描述: 对于下面的一张图片,获取其中的直线部分。

opencv/C++ 获取填空题的下划线_第1张图片

能想到的有两种方式:

(1)先用canny检测边缘得到边缘图片,再用霍夫直线检测边缘图片中的直线

(2) 先将图像通过形态学操作腐蚀掉字母,然后在通过霍夫检测将直线展示出来

 

第一种方式的代码如下,然后用的trackbar拉动看来肯每个阈值对结果的影响。

事实这种方式,效果很差。

void detectline(int, void*) {
	//canny 检测
	Mat canny_out;
	Canny(src, canny_out, threshold_value, threshold_value * 2, 3, false);
	
	////霍夫直线检测
	vector lines;
	HoughLinesP(canny_out, lines,1, CV_PI / 180.0, 30, 30, 10);
	cvtColor(canny_out, canny_out, COLOR_GRAY2BGR);

	//最好是在canny检测出来的图像吧直线画出来,这样拉动track的时候才能看出线条的变化。
	for (size_t t = 0; t < lines.size(); t++) {
		Vec4i In = lines[t];
		line(canny_out, Point(In[0], In[1]), Point(In[2], In[3]), Scalar(0, 0, 255), 2, 8, 0);
	}
	imshow(output_win, canny_out);
}

 

opencv/C++ 获取填空题的下划线_第2张图片

opencv/C++ 获取填空题的下划线_第3张图片

 opencv/C++ 获取填空题的下划线_第4张图片

展示了三个阈值的结果,发现图片都糊掉了。受英文字母的影响,不能完整的检测出直线。

第二种方式的代码如下。

它的算法步骤:(1)二直化。(2)构建结构元素,消除字母。(3)膨胀处理,让直线更加明显。(4)霍夫直线检测。(5)记录直线的位置。

这里重点是:开操作中的size大小。

首先先腐蚀后膨胀的操作称之为开操作。它具有消除细小物体,在纤细处分离物体和平滑较大物体边界的作用。像字母这种有连接点的图像,消除的话用开操作比较合适。

一般提取水平直线用的是(n,1),提取垂直直线用的是(1,n)。

void morhpologyLines(int, void*) {
    
	//先二直化图像,必须先转换成单通道的图像
	Mat BinaryImage, morhpImage;
	cvtColor(src, gray, COLOR_BGR2GRAY);
	threshold(gray, BinaryImage, 0, 255, THRESH_BINARY_INV|THRESH_OTSU);
	imshow("binary image", BinaryImage);


	//构建结构元素,消除字母:重点在于kenerl中的size给的大小
	Mat kernel = getStructuringElement(MORPH_RECT, Size(50, 1), Point(-1, -1));
	morphologyEx(BinaryImage, morhpImage, MORPH_OPEN, kernel, Point(-1, -1));
	imshow("morhpolopy image", morhpImage);

	//膨胀操作,让直线更加的明显。
	kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
	dilate(morhpImage, morhpImage, kernel);
	imshow("dilate image", morhpImage);

	//获取直线
	vector lines;
	HoughLinesP(morhpImage, lines, 1, CV_PI / 180.0, 30, 20, 0);
	Mat resultimage = src.clone();
	for (size_t t = 0; t < lines.size(); t++) {
		Vec4i In = lines[t];
		line(gray, Point(In[0], In[1]), Point(In[2], In[3]), Scalar(0, 255, 255), 2, 8, 0);
	}
	imshow(output_win, gray);
}

 opencv/C++ 获取填空题的下划线_第5张图片

 opencv/C++ 获取填空题的下划线_第6张图片

 opencv/C++ 获取填空题的下划线_第7张图片

 opencv/C++ 获取填空题的下划线_第8张图片

你可能感兴趣的:(图像处理-opencv-C++)