在 OCR python 中考虑 'i' 和 'j' 个点
Accounting for 'i' and 'j' dots in OCR python
我正在尝试在 python 中创建一个 OCR 系统 - 第一部分涉及从图像中提取所有字符。这很好用,所有字符都被分隔到它们自己的边界框中。
下面附上代码:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from scipy.misc import imread,imresize
from skimage.segmentation import clear_border
from skimage.morphology import label
from skimage.measure import regionprops
image = imread('./ocr/testing/adobe.png',1)
bw = image < 120
cleared = bw.copy()
clear_border(cleared)
label_image = label(cleared,neighbors=8)
borders = np.logical_xor(bw, cleared)
label_image[borders] = -1
print label_image.max()
fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(6, 6))
ax.imshow(bw, cmap='jet')
for region in regionprops(label_image):
if region.area > 20:
minr, minc, maxr, maxc = region.bbox
rect = mpatches.Rectangle((minc, minr), maxc - minc, maxr - minr,
fill=False, edgecolor='red', linewidth=2)
ax.add_patch(rect)
plt.show()
但是,由于字母 i 和 j 的顶部有 'dots',代码将这些点作为单独的边界框。我正在使用 regionprops 库。调整每个边界框的大小和规范化也是个好主意吗?
我将如何修改此代码以说明 i 和 j?我的理解是我需要合并附近的边界框?试过没有运气...谢谢。
是的,您通常希望规范化边界框的内容以适应字符分类器的输入维度(假设您正在处理具有显式分割的字符分类器,而不是隐式分割的序列分类器)。
用于合并同一字母的垂直隔离抄送,例如i 和 j,我会尝试各向异性高斯滤波器(x 方向上的西格玛非常小,y 方向上的西格玛较大)。确切的参数化将取决于您的输入数据,但应该很容易通过实验找到合适的值,以便所有字母都恰好产生一个 CC。
另一种方法是分析与其他 CC 水平重叠的 CC,并合并重叠超过某个相对阈值的那些对。
举例说明:
# Anisotropic Gaussian
from scipy.ndimage.filters import gaussian_filter
filtered = gaussian_filter(f, (2,0))
plt.imshow(filtered, cmap=plt.cm.gray)
# Now threshold
bin = filtered < 1
plt.imshow(bin, cmap=plt.cm.gray)
很容易看出每个字符现在都由一个 CC 表示。现在我们几乎只需要应用每个蒙版并裁剪白色区域以结束每个角色的边界框。在规范化它们的大小后,我们可以直接将它们提供给分类器(考虑到我们丢失了 ascender/descender 行信息以及 width/height 比率,但这些可能作为分类器的一个特征很有用;所以它应该有所帮助除了归一化的边界框内容外,还明确地将它们提供给分类器)。
我正在尝试在 python 中创建一个 OCR 系统 - 第一部分涉及从图像中提取所有字符。这很好用,所有字符都被分隔到它们自己的边界框中。
下面附上代码:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from scipy.misc import imread,imresize
from skimage.segmentation import clear_border
from skimage.morphology import label
from skimage.measure import regionprops
image = imread('./ocr/testing/adobe.png',1)
bw = image < 120
cleared = bw.copy()
clear_border(cleared)
label_image = label(cleared,neighbors=8)
borders = np.logical_xor(bw, cleared)
label_image[borders] = -1
print label_image.max()
fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(6, 6))
ax.imshow(bw, cmap='jet')
for region in regionprops(label_image):
if region.area > 20:
minr, minc, maxr, maxc = region.bbox
rect = mpatches.Rectangle((minc, minr), maxc - minc, maxr - minr,
fill=False, edgecolor='red', linewidth=2)
ax.add_patch(rect)
plt.show()
但是,由于字母 i 和 j 的顶部有 'dots',代码将这些点作为单独的边界框。我正在使用 regionprops 库。调整每个边界框的大小和规范化也是个好主意吗?
我将如何修改此代码以说明 i 和 j?我的理解是我需要合并附近的边界框?试过没有运气...谢谢。
是的,您通常希望规范化边界框的内容以适应字符分类器的输入维度(假设您正在处理具有显式分割的字符分类器,而不是隐式分割的序列分类器)。
用于合并同一字母的垂直隔离抄送,例如i 和 j,我会尝试各向异性高斯滤波器(x 方向上的西格玛非常小,y 方向上的西格玛较大)。确切的参数化将取决于您的输入数据,但应该很容易通过实验找到合适的值,以便所有字母都恰好产生一个 CC。
另一种方法是分析与其他 CC 水平重叠的 CC,并合并重叠超过某个相对阈值的那些对。
举例说明:
# Anisotropic Gaussian
from scipy.ndimage.filters import gaussian_filter
filtered = gaussian_filter(f, (2,0))
plt.imshow(filtered, cmap=plt.cm.gray)
# Now threshold
bin = filtered < 1
plt.imshow(bin, cmap=plt.cm.gray)
很容易看出每个字符现在都由一个 CC 表示。现在我们几乎只需要应用每个蒙版并裁剪白色区域以结束每个角色的边界框。在规范化它们的大小后,我们可以直接将它们提供给分类器(考虑到我们丢失了 ascender/descender 行信息以及 width/height 比率,但这些可能作为分类器的一个特征很有用;所以它应该有所帮助除了归一化的边界框内容外,还明确地将它们提供给分类器)。