OpenCV C++案例实战二十六《填空题区域检测》

本篇博客介绍了如何使用OpenCV的C++库进行填空题区域检测,主要步骤包括图像预处理、霍夫直线检测。通过大津阈值二值化、形态学开运算以及HoughLinesP函数,实现对直线的精确检测。案例展示了代码实现,并给出了最终检测结果。
摘要由CSDN通过智能技术生成

OpenCV C++案例实战二十六《填空题区域检测》


前言

本案例通过使用OpenCV中的霍夫直线检测HoughLinesP进行填空题区域检测(说白了就是进行直线检测),实现起来也很简单。

一、图像预处理

原图如图所示:

请添加图片描述

首先第一步先进行图像预处理,得到二值图像。

	Mat gray;
	cvtColor(src, gray, COLOR_BGR2GRAY);

	Mat gaussian;
	GaussianBlur(gray, gaussian, Size(3, 3), 0);

	Mat thresh;
	threshold(gaussian, thresh, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);

通过使用大津阈值进行图像二值化处理,如下图所示,得到一幅二值图像。接下来,需要提取出二值图中直线部分。由图像特征可以看出,直线部分又长又细,所以可以使用形态学操作对图像进行腐蚀操作,仅保留直线部分。在这里我使用的是形态学开操作(先腐蚀,后膨胀)保证能完整的提取出直线部分。由于直线部分又长又细,所以我们在创建kernel时,Size(width,height),width尽可能大一些,height尽可能小一些。这里我使用的是Size(25, 3)大小的kernel。

请添加图片描述

经形态学开操作处理之后的效果如图所示:

	Mat kernel = getStructuringElement(MORPH_RECT, Size(25, 3));
	morphologyEx(thresh, thresh, MORPH_OPEN, kernel);

请添加图片描述

二、霍夫直线检测

关于霍夫直线检测算法原理我在这里就不细说了,网上教程很多,解释的肯定也比我好。我在这里就简单介绍一下OpenCV中霍夫直线检测API使用。OpenCV中使用霍夫直线检测有两个API,一个是 cv::HoughLines() 标准和多尺度Hough变换;另一个是 cv::HoughLinesP() 渐进概率Hough变换。

void HoughLines( 
	InputArray image,  //输入图像,必须是8位二值图像
	OutputArray lines,   //结果存放位置,可以是N x 1双通道数组,也可以是一个N项类型为Vec2f的std::vector<>向量,用于存储rho和theta值                           
	double rho,  //直线所需分辨率(即累加平面的分辨率),单位是像素
	double theta, //直线所需分辨率(即累加平面的分辨率),单位是弧度
	int threshold,  //累加平面中算法用于判断线条属于一条直线的阈值                           
	double srn = 0, //srn和stn用于控制称为“多尺度Hough变换”(MHT)的SHT算法扩展,不用于标准Hough变换
	double stn = 0,                              
);
void HoughLinesP( 
	InputArray image, //输入图像,必须是8位二值图像
	OutputArray lines,  //结果存放位置,四通道(或Vec4i类型的向量),四通道分别是找出线段两端点坐标(x0,y0)和(x1,y1)(按顺序)                             
	double rho,  //直线所需分辨率(即累加平面的分辨率),单位是像素
	double theta,  //直线所需分辨率(即累加平面的分辨率),单位是弧度
	int threshold,    //累加平面中算法用于判断线条属于一条直线的阈值                                
	double minLineLength = 0, //返回线段的最小长度
	double maxLineGap = 0 //共线线段之间的最小间隔,防止算法把它们连成一条
);

这里我使用的是HoughLinesP进行直线检测,下面直接上源码。

三、源码

#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;

int main()
{

	Mat src = imread("test.jpg");
	if (src.empty())
	{
		cout << "can not read the image..." << endl;
		system("pause");
		return -1;
	}

	Mat gray;
	cvtColor(src, gray, COLOR_BGR2GRAY);

	Mat gaussian;
	GaussianBlur(gray, gaussian, Size(3, 3), 0);

	Mat thresh;
	threshold(gaussian, thresh, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);

	Mat kernel = getStructuringElement(MORPH_RECT, Size(25, 3));
	morphologyEx(thresh, thresh, MORPH_OPEN, kernel);

	vector<Vec4i>lines;
	HoughLinesP(thresh, lines, 1, CV_PI / 180, 100, 50, 10);

	for (int i = 0; i < lines.size(); i++)
	{
		line(src, Point(lines[i][0], lines[i][1]), Point(lines[i][2], lines[i][3]), Scalar(0, 0, 255), 2);
	}

	imshow("src", src);
	waitKey(0);
	destroyAllWindows();
	system("pause");
	return 0;
}

四、结果显示

请添加图片描述
请添加图片描述


总结

本文使用OpenCV C++ 进行填空题区域检测,其实原理很简单,主要操作有以下几点。
1、图像预处理,得到二值图像
2、霍夫直线检测,注意调参,参数不同,得到的结果也不太一样。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zero___Chen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值