Вопрос или проблема
Как выполнить шаблонное matching без OpenCV?
У меня есть счет-фактура документов, принадлежащих Amazon, eBay, Flipkart, SnapDeal, и я хочу извлечь меньше информации из счета-фактуры.
Поскольку такие поля, как номер заказа, имя клиента, детали заказа будут находиться на различных позициях в этих 4 шаблонах,
мне сначала нужно классифицировать, к какому из этих 4 шаблонов будет относиться входное изображение, и после определения шаблона я смогу выполнить свою следующую задачу извлечения текста с использованием tesseract и regex, написав код для конкретных шаблонов.
Когда я искал, я обнаружил, что только OpenCV имел эту возможность, и мне не удалось найти какую-либо модель сверточной нейронной сети. Существуют ли такие нейронные сети для шаблонного matching и классификации?
Я не могу использовать стандартную модель, доступную для классификации собак и кошек, потому что здесь я имею дело с изображением шаблонов счета-фактуры, которые содержат только текст с рядами и колонками в каком-то формате.
import numpy as np
import matplotlib.image as img
import matplotlib.pyplot as plt
from skimage.metrics import structural_similarity as ssim
def rgb2gray(rgb):
return np.dot(rgb[...,:3], [0.299, 0.587, 0.144])
full_image = rgb2gray(img.imread("img/full_image.png"))
sub_image = rgb2gray(img.imread("img/sub_image.png"))
full_w,full_h = full_image.shape[:2]
sub_w,sub_h = sub_image.shape[:2]
print(full_w,full_h)
print(sub_w,sub_h)
winW = 0
found = False
while winW < full_w - sub_w and found == False:
winH = 0
while winH < full_h - sub_h:
window = full_image[winW:winW+sub_w, winH:winH+sub_h]
if ssim(sub_image, window) > 0.80:
found = True
print("найдено", ssim(sub_image, window))
plt.imshow(window)
break
winH += 2
winW += 2
Вы можете использовать мою новую библиотеку для быстрого шаблонного matching без OpenCV. Посмотрите здесь, она называется OpenFDCM.
Вы можете попробовать это на Google Colab здесь.
pip install openfdcm
import openfdcm
templates = # Список массивов 4xN, где каждый массив представляет шаблон, описанный как N строк [x1, y1, x2, y2]^T
scene = # Массив 4xM, представляющий M строк сцены
# Выполнить шаблонное matching
max_tmpl_lines, max_scene_lines = 4, 4 # Параметры комбинаторного поиска.
depth = 30 # Дискретизация [0, pi].
coeff = 5.0 # Весовой коэффициент для повышения угловой стоимости относительно дистанционной стоимости в алгоритме FDCM.
scene_padding = 1.5 # Соотношение для дополнения изображений сцены, используемых в алгоритме FDCM, используйте, если лучшее соответствие может появиться на границах изображения.
distance_type = openfdcm.distance.L2 # или openfdcm.distance.L2_SQUARED или openfdcm.distance.L1
#num_threads = 4
threadpool = openfdcm.ThreadPool() # можно передать num_threads здесь, но по умолчанию он оптимален
featuremap_params = openfdcm.Dt3CpuParameters(depth, coeff, scene_padding, distance_type)
search_strategy = openfdcm.DefaultSearch(max_tmpl_lines, max_scene_lines)
optimizer_strategy = openfdcm.BatchOptimize(10, threadpool)
matcher = openfdcm.DefaultMatch()
penalizer = openfdcm.ExponentialPenalty(tau=1.5)
# Построить карту признаков FDCM и выполнить поиск
start_time = time.time()
featuremap = openfdcm.build_cpu_featuremap(scene, featuremap_params, threadpool)
raw_matches = openfdcm.search(matcher, search_strategy, optimizer_strategy, featuremap, templates, scene)
penalized_matches = openfdcm.penalize(penalizer, raw_matches, openfdcm.get_template_lengths(templates))
sorted_matches = openfdcm.sort_matches(penalized_matches)
search_time = time.time() - start_time
print(f"Поиск шаблонного matching завершен за {search_time:.4f} секунд.")
best_match = sorted_matches[0] # Лучшее соответствие (меньший счет) — первое
best_match_id = best_match.tmpl_idx
best_matched_tmpl = templates[best_match_id]
result_rotation = best_match.transform[0:2, 0:2]
result_translation = best_match.transform[0:2, 2]
.
Ответ или решение
Как выполнить сопоставление шаблонов без OpenCV
Сопоставление шаблонов — это важная задача в области компьютерного зрения, особенно когда речь идет о документальных изображениях, таких как накладные из различных интернет-магазинов, таких как Amazon, eBay, Flipkart и SnapDeal. Мы рассмотрим, как вы можете решить эту задачу без использования OpenCV, поскольку вы ищете альтернативные подходы для классификации и извлечения текста.
Проблема
У вас есть разные шаблоны для накладных документов, и вам нужно сначала классифицировать, к какому из шаблонов принадлежит входное изображение. После этого вы сможете использовать Tesseract и регулярные выражения для извлечения конкретных полей (таких как номер заказа, имя клиента и детали заказа).
Решение
Давайте рассмотрим метод, который не требует OpenCV: использование специализированной библиотеки OpenFDCM
. Это инструмент для быстрого сопоставления шаблонов, который может оказаться полезным для вашей задачи.
Установка библиотеки
Перед тем как начать, вам необходимо установить библиотеку OpenFDCM
. Вы можете сделать это с помощью следующей команды:
pip install openfdcm
Пример кода
Вот пример кода, который демонстрирует, как использовать OpenFDCM
для выполнения сопоставления шаблонов:
import openfdcm
import time
# Определяем шаблоны и сцену
templates = [...] # Список шаблонов (массивы, представляющие каждую накладную)
scene = [...] # Сцена, представляющая входное изображение
# Параметры для поиска
max_tmpl_lines, max_scene_lines = 4, 4 # Максимально допустимое количество строк в шаблонах
depth = 30 # Дискретизация [0, pi]
coeff = 5.0 # Фактор весов для улучшения соотношения угловых и расстояний
scene_padding = 1.5 # Параметр заполнения сцены
distance_type = openfdcm.distance.L2 # Тип расстояния для сравнения
# Настройка пулла потоков
threadpool = openfdcm.ThreadPool()
featuremap_params = openfdcm.Dt3CpuParameters(depth, coeff, scene_padding, distance_type)
search_strategy = openfdcm.DefaultSearch(max_tmpl_lines, max_scene_lines)
optimizer_strategy = openfdcm.BatchOptimize(10, threadpool)
matcher = openfdcm.DefaultMatch()
penalizer = openfdcm.ExponentialPenalty(tau=1.5)
# Построим карту признаков и выполним поиск
start_time = time.time()
featuremap = openfdcm.build_cpu_featuremap(scene, featuremap_params, threadpool)
raw_matches = openfdcm.search(matcher, search_strategy, optimizer_strategy, featuremap, templates, scene)
penalized_matches = openfdcm.penalize(penalizer, raw_matches, openfdcm.get_template_lengths(templates))
sorted_matches = openfdcm.sort_matches(penalized_matches)
search_time = time.time() - start_time
print(f"Сопоставление шаблонов завершено за {search_time:.4f} секунд.")
best_match = sorted_matches[0] # Лучшее совпадение (с наименьшим значением)
best_match_id = best_match.tmpl_idx
best_matched_tmpl = templates[best_match_id]
result_rotation = best_match.transform[0:2, 0:2]
result_translation = best_match.transform[0:2, 2]
Описание кода
-
Шаблоны и сцена: Вам необходимо определить, как будут представлены ваши шаблоны и целевая сцена в массивах.
-
Параметры поиска: Задайте параметры, такие как количество строк в шаблонах, глубина дискретизации и т.д.
-
Поиск совпадений: Используйте библиотечные функции для выполнения сопоставления шаблонов. Вы можете использовать различные метрики расстояния, чтобы улучшить точность.
-
Обработка результатов: Лучшее совпадение будет содержать информацию о том, какой шаблон лучше всего соответствует вашей сцене.
Заключение
Чтобы справиться с задачей сопоставления шаблонов для накладных документов, вы можете эффективно использовать библиотеки, отличные от OpenCV, такие как OpenFDCM. Этот подход позволяет вам не только классифицировать изображение, но и в дальнейшем извлекать нужную информацию с помощью Tesseract и регулярных выражений. Убедитесь, что вы адаптируете код под свои нужды и тестируете на ваших шаблонах для достижения наилучших результатов.