如何使用opencv集中和调整数字大小?

Posted

技术标签:

【中文标题】如何使用opencv集中和调整数字大小?【英文标题】:How to centralize and resize digits using opencv? 【发布时间】:2017-12-08 09:39:46 【问题描述】:

我想对一些扫描的表格(手工填写)进行 OCR。这是我第一次使用计算机视觉做一些严肃的事情。到目前为止,我能够找到包含日期字段数字的方块:

查看OpenCV 附带的示例手写数字数据集,我看到数字集中并调整为(20, 20)

由于这可能是一个相当普遍的问题,我想知道该算法是否已经在 OpenCV(或 numpyscipy 等)中实现,所以我不必重新发明***。

问题是:Python 中是否有内置管道来规范化样本?

【问题讨论】:

“标准化”是什么意思?你的意思是调整大小和居中?你已经完成了最难的部分——得到了轮廓!只需在轮廓周围找到cv2.boundingRect(),如果您不希望任何白色接触边框,可以将框的大小在各个方向上增加 1 或 2 px,然后将该 ROI 重新缩放到您想要的大小。 我要做的是为每个数字找到一个边界框,裁剪该部分,然后调整到所需的比例 是的,找到边界框和缩放很容易;还有纵横比需要考虑。许多年前,我编写了一个算法来生成一个仿射变换矩阵,该矩阵可以同时处理纵横比和大小,但我忘记了我是如何做到的(用它来将用户上传的图像裁剪为 PIL 中的标准尺寸)。不幸的是,该代码丢失了。 【参考方案1】:

不确定的内置管道,但如果您已经拥有轮廓,您可以通过执行以下操作(基于我的评论)来实现自己的:

获取轮廓的边界矩形(因此以它为中心)并裁剪该部分:

x,y,w,h = cv2.boundingRect(cnt)
imgCrop = img[x:(x+w), y:(y+h)]

将图像调整为所需大小(例如 20 x 20):

imgResized = cv2.resize(imgCrop, (20,20))   

您还可以按特定比例调整轴的大小,例如:

imgResized = cv2.resize(imgCrop, (0,0), fx=0.5, fy=0.5)  

scipy(如this 问题中所建议):

imgResized = scipy.misc.imresize(imgCrop, 0.5)  

奖励:查看this关于使用 Python 和 OpenCV 进行基本图像处理的精彩教程,其中他们展示了其他调整大小的方法,考虑到纵横比和插值以获得更好的结果,从中提取:

imgResized = cv2.resize(imgCrop, (20,20), interpolation = cv2.INTER_AREA)

【讨论】:

我的思想被美学困住了,但也许我可以忽略它。我想如果我将所有输入的大小调整为 20 x 20 并忽略纵横比,我想我不会有问题 - 只要我对训练集和测试集都这样做,它应该没问题。你怎么看? 我认为是的,你应该在训练、交叉验证和测试中使用相同的输入图像尺寸,因为像神经网络这样的大多数工具(你正在做 MNIST,我认为)需要相同尺寸的输入。但是,您不应完全忽略纵横比。如果您出现较大的变形,这可能会影响您的训练表现,因为某些数字(如数字 1)比其他数字窄。 为了防止这种情况,您可以检查生成的边界框纵横比(w/h)是否接近1.0。如果您有更多的宽度或高度,您可以在裁剪图像时添加更多像素(而不是 img[x:(x+w), y:(y+h)],您可以通过执行 img[((x-2):(x+w+2), y:(y+h)] 添加更多宽度像素)。反之,如果您想要更高的高度,请注意不要超出范围。【参考方案2】:

我最终使用了这个功能:

def norm_digit(im):
    h, w = im.shape
    if h > w:
        top, left = round(h * 0.1), round((1.2 * h - w) / 2)
    else:
        top, left = round(w * 0.1), round((1.2 * w - h) / 2)

    return cv2.resize(
        cv2.copyMakeBorder(im, top, top, left, left, cv2.BORDER_CONSTANT), 
        (20, 20)
    )

输入是已经裁剪到数字轮廓边界框的图像。它没有涵盖一些极端情况,但看起来这可能已经足够好了。

【讨论】:

以上是关于如何使用opencv集中和调整数字大小?的主要内容,如果未能解决你的问题,请参考以下文章

如何在opencv python中调整PNG图像的大小? [复制]

使OpenCV框架不可调整大小

如何在 OpenCV 中将图像调整为特定大小?

如何使用opencv制作全景照片

如何使用 matplotlib 调整子图中的图形大小

当使用 OpenCV 完成图像加载和调整大小时,Resnet50 会产生不同的预测