Учет точек 'i' и 'j' в Python OCR
Я пытаюсь создать систему распознавания текста в Python - первая часть включает в себя извлечение всех символов из изображения. Это прекрасно работает, и все персонажи разделены в свои ограничивающие рамки.
Код прилагается ниже:
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 имеют "точки" над ними, код принимает точки в виде отдельных ограничивающих рамок. Я использую библиотеку regionprops. Было бы также хорошей идеей изменить размер и нормализовать каждую ограничивающую рамку?
Как бы я изменил этот код для учета I и J? Насколько я понимаю, мне нужно объединить ограничивающие рамки, которые находятся рядом? Попробовал без удачи... Спасибо.
1 ответ
Да, вы обычно хотите нормализовать содержимое ваших ограничивающих рамок, чтобы они соответствовали входным измерениям вашего классификатора символов (при условии, что вы работаете с классификаторами символов с явной сегментацией, а не с неявным сегментированием классификаторов последовательностей).
Для объединения вертикально изолированных CC одной и той же буквы, например, 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. Теперь нам нужно только применить каждую маску и обрезать белые области, чтобы получить ограничивающие рамки для каждого персонажа. После нормализации их размера мы можем напрямую передать их в классификатор (учтите, что мы теряем информацию о строках по возрастанию и спуску, а также соотношение ширины и высоты, и это может быть полезно в качестве функции для классификатора; так что это должно помочь в явной подаче их в классификатор в дополнение к нормализованному содержимому ограничивающего прямоугольника).