目录
运行环境:Windows 10 64 位 + Opencv3.4.1 + Visual Studio 2015
1、理论依据
针对水平方向排列分布的印刷体文本,因文本行中字符沿着近似水平直线分布。所以,沿着水平方向提取文本行所在矩形框,即可将文本行检测出来。如下图中的文本沿着红色直线水平分布:2、程序实现
1)图像灰度化
将输入图像转换成灰度图像
//Color image to grayscale image
cvtColor(src, gray, CV_BGR2GRAY);
2)文本行分割
利用 OTSU 二值化方法,将文本行与背景分割。
//Binary segmentation of text lines
threshold(gray, binary, 0, 255, THRESH_OTSU | THRESH_BINARY);
3)通过形态学腐蚀,将分割出来的文字字符连接在一起
//Define the erodent core
Mat rec = getStructuringElement(MORPH_RECT, Size(50, 3));
//Etch binary image along horizontal, join text line
Mat dilate0;
erode(binary, dilate0, rec);
Mat erode2;
//Image Reverse
bitwise_not(dilate0, erode2);
4)提取文本行所在的轮廓
vector<RotatedRect> rects;
vector<vector<Point>> counts;
vector<Vec4i> hierarchy;
//Extract the contour of the text line
findContours(erode2, counts, hierarchy, CV_RETR_LIST, CHAIN_APPROX_SIMPLE, Point(0, 0));
5)提取的文本行所在轮廓最小矩形框,并在原图标记检测矩形框
//Mark the detection rectangles in the original image
for (int i = 0; i<counts.size(); i++)
{
//Culling of small contours
if (contourArea(counts[i])<500)
continue;
//Calculates the smallest rectangle with a vertical boundary for an contour
Rect rect1 = boundingRect(counts[i]);
char ch[256];
cout << "hierarchy num" << hierarchy[i] << endl << endl;
/* RotatedRect rect = minAreaRect(counts[i]);
int width = rect.boundingRect().width;
int heigh = rect.boundingRect().height;
Point2f P[4];
rect.points(P);
for (int j = 0; j <= 3; j++)
{
line(input, P[j], P[(j + 1) % 4], Scalar(255,0,0), 1);
}*/
//Drawing Rectangular box
rectangle(dst, rect1, Scalar(0, 0, 255), 1);
}
6)检测结果
3、VS2015工程
VX公号“striveallen”回复“文本检测”, 即可获取文本检测工程的VS2015工程。内附Opencv3.4.1开源库,可直接运行工程,无需配置相关的库路径和环境变量。