我有如下图像:
我想找到8位数字的边界框。我的第一次尝试是将cv2与以下代码一起使用:
import cv2
import matplotlib.pyplot as plt
import cvlib as cv
from cvlib.object_detection import draw_bbox
im = cv2.imread('31197402.png')
bbox, label, conf = cv.detect_common_objects(im)
output_image = draw_bbox(im, bbox, label, conf)
plt.imshow(output_image)
plt.show()
不幸的是,这不起作用。有人有主意吗
解决方案中的问题可能是输入图像质量非常差。人物和背景之间几乎没有任何对比。来自
cvlib
的blob检测算法可能无法区分字符blob和背景,从而产生无用的二进制掩码。让我们尝试使用纯OpenCV
来解决这个问题我提议采取以下步骤:
让我们看看代码:
这里没有什么要讨论的,只需阅读
BGR
图像并将其转换为grayscale
。现在,让我们使用gaussian
方法应用adaptive threshold
。这是一个棘手的部分,因为参数是根据输入的质量手动调整的。该方法的工作原理是将图像划分为windowSize
单元格网格,然后应用局部阈值来找到前景和背景之间的最佳分离。可以将windowConstant
表示的附加常数添加到阈值以微调输出:您可以看到这样一个漂亮的二进制图像:
现在,如您所见,图像中有一些斑点噪声。让我们应用
area filter
来消除噪声。噪声小于感兴趣的目标斑点,因此我们可以根据面积轻松过滤它们,如下所示:这是过滤后的图像:
我们可以通过一些形态学来提高图像的质量。有些字符似乎已断开(请查看第一个
3
,它被断开为两个单独的blob)。我们可以应用关闭操作将其加入:这是“关闭”图像:
现在,您需要获取每个字符的
bounding boxes
。让我们检测每个水滴的外部轮廓,并在其周围拟合一个漂亮的矩形:最后一个
for
循环几乎是可选的。它从列表中获取每个边界矩形,并将其绘制在输入图像上,因此您可以看到每个单独的矩形,如下所示:让我们在二值图像上想象一下:
此外,如果要使用我们刚获得的边界框裁剪每个角色,请按如下方式进行操作:
这是获取单个边界框的方式。现在,可能您正试图将这些图像传递给
OCR
。我尝试将过滤后的二进制图像(在关闭操作之后)传递给pyocr
(这是我正在使用的OCR),并将其作为输出字符串:31197402
我用来获取封闭图像的
OCR
的代码如下:请注意
OCR
接收白色背景上的黑色字符,因此必须首先反转图像相关问题 更多 >
编程相关推荐