使用OpenCV清洁文本图像以进行OCR读取 [英] Clean text images with OpenCV for OCR reading

查看:208
本文介绍了使用OpenCV清洁文本图像以进行OCR读取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我收到了一些需要处理的图像,以便对其中的一些信息进行OCR.这是原稿:

I received some images that need to be treated in order to OCR some information out of them. Here are the originals:

原始版本1

original 1

原始2

original 2

原始3

original 3

原始4

original 4

在使用以下代码处理它们之后:

After processing them with this code:

img = cv2.imread('original_1.jpg', 0) 
ret,thresh = cv2.threshold(img,55,255,cv2.THRESH_BINARY)
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, cv2.getStructuringElement(cv2.MORPH_RECT,(2,2)))
cv2.imwrite('result_1.jpg', opening)

我得到这些结果:

结果1

result 1

结果2

result 2

结果3

result 3

结果4

result 4

如您所见,有些图像在读取OCR时得到不错的结果,而另一些仍在背景中保持一些噪点.

As you can see, some images get nice results for OCR reading, other still maintain some noise in the background.

关于如何清理背景的任何建议?

Any suggestions as how to clean up the background?

推荐答案

MH304的答案非常简单明了.如果您无法使用形态学或模糊处理来获得更清晰的图像,请考虑使用区域滤镜".也就是说,过滤每个未显示最小面积的斑点.

MH304's answer is very nice and straightforward. In the case you can't use morphology or blurring to get a cleaner image, consider using an "Area Filter". That is, filter every blob that does not exhibit a minimum area.

使用opencv的 connectedComponentsWithStats ,这是一个非常基本的区域过滤器的 C ++ 实现:

Use opencv's connectedComponentsWithStats, here's a C++ implementation of a very basic area filter:

cv::Mat outputLabels, stats, img_color, centroids;

int numberofComponents = cv::connectedComponentsWithStats(bwImage, outputLabels, 
stats, centroids, connectivity);

std::vector<cv::Vec3b> colors(numberofComponents+1);
colors[i] = cv::Vec3b(rand()%256, rand()%256, rand()%256);

//do not count the original background-> label = 0:
colors[0] = cv::Vec3b(0,0,0);

//Area threshold:
int minArea = 10; //10 px

for( int i = 1; i <= numberofComponents; i++ ) {

    //get the area of the current blob:
    auto blobArea = stats.at<int>(i-1, cv::CC_STAT_AREA);

    //apply the area filter:
    if ( blobArea < minArea )
    {
        //filter blob below minimum area:
        //small regions are painted with (ridiculous) pink color
        colors[i-1] = cv::Vec3b(248,48,213);

    }

}

使用区域过滤器,您会在最嘈杂的图像上得到以下结果:

Using the area filter I get this result on your noisiest image:

**其他信息:

基本上,算法是这样的:

Basically, the algorithm goes like this:

  • 将二进制映像传递到 connectedComponentsWithStats .功能 将计算连接组件的数量,标签矩阵和 具有统计信息的附加矩阵-包括斑点面积.

  • Pass a binary image to connectedComponentsWithStats. The function will compute the number of connected components, matrix of labels and an additional matrix with statistics – including blob area.

准备大小为" numberOfcomponents "的颜色矢量,这将有助于可视化我们实际上正在过滤的斑点.颜色是通过 rand 函数随机生成的.从0到255的范围,每个像素3个值:BGR.

Prepare a color vector of size "numberOfcomponents", this will help visualize the blobs that we are actually filtering. The colors are generated randomly by the rand function. From a range 0 – 255, 3 values for each pixel: BGR.

考虑到背景为黑色,因此请忽略此连接的组件"及其颜色(黑色).

Consider that the background is colored in black, so ignore this "connected component" and its color (black).

设置面积阈值.此区域下的所有斑点或像素都将用(荒谬的)粉红色着色.

Set an area threshold. All blobs or pixels below this area will be colored with a (ridiculous) pink.

循环遍历所有找到的已连接组件(斑点),通过统计矩阵检索当前斑点的面积,并将其与面积阈值进行比较.

Loop thru all the found connected components (blobs), retrive the area for the current blob via the stats matrix and compare it to the area threshold.

如果该区域低于阈值,则将blob涂成粉红色(在这种情况下,但通常是黑色).

If the area is below the threshold, color the blob pink (in this case, but usually you want black).

这篇关于使用OpenCV清洁文本图像以进行OCR读取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆