соответствие функции opencv пустому шаблону - PullRequest
0 голосов
/ 20 февраля 2019

Я пытался сопоставить отсканированную формуляру с ее пустым шаблоном.Цель состоит в том, чтобы повернуть и масштабировать его, чтобы соответствовать шаблону.

Source fomular, to be rescaled and rotated Template
Source (left), template (right)
Matches Homography warp result
Match (left), Homography warp (right)
Шаблон не содержит какого-либо очень специфического логотипа, крестика фиксации или прямоугольной рамки , которая могла бы помочь мне с сопоставлением элементов или образцов.Хуже того, отсканированная формуляра может быть искажена, изменена и содержит рукописные подписи и штампы.

Мой подход, после неудачного тестирования соответствия функций ORB, заключался в том, чтобы сконцентрироваться на форме формы (строки и столбцы).

Изображения, которые я здесь предоставляю, получаются путем восстановления линий после обнаружения сегмента (LSD) с определенным минимальным размером.Большая часть того, что остается для источника и шаблона, - это сам макет документа.

В следующем сценарии (который должен работать из коробки вместе с изображениями) я пытаюсь выполнить сопоставление объектов ORB, но не могу сделать этоработать, потому что он концентрируется на краях, а не на макете документа.

import cv2  # using opencv-python v3.4
import numpy as np
from imutils import resize


# alining image using ORB descriptors, then homography warp
def align_images(im1, im2,MAX_MATCHES=5000,GOOD_MATCH_PERCENT = 0.15):

    # Detect ORB features and compute descriptors.
    orb = cv2.ORB_create(MAX_MATCHES)
    keypoints1, descriptors1 = orb.detectAndCompute(im1, None)
    keypoints2, descriptors2 = orb.detectAndCompute(im2, None)

    # Match features.
    matcher = cv2.DescriptorMatcher_create(cv2.DESCRIPTOR_MATCHER_BRUTEFORCE_HAMMING)
    matches = matcher.match(descriptors1, descriptors2, None)

    # Sort matches by score
    matches.sort(key=lambda x: x.distance, reverse=False)

    # Remove not so good matches
    numGoodMatches = int(len(matches) * GOOD_MATCH_PERCENT)
    matches = matches[:numGoodMatches]

    # Draw top matches
    imMatches = cv2.drawMatches(im1, keypoints1, im2, keypoints2, matches, None)

    # Extract location of good matches
    points1 = np.zeros((len(matches), 2), dtype=np.float32)
    points2 = np.zeros((len(matches), 2), dtype=np.float32)

    for i, match in enumerate(matches):
        points1[i, :] = keypoints1[match.queryIdx].pt
        points2[i, :] = keypoints2[match.trainIdx].pt

    # Find homography
    h, mask = cv2.findHomography(points1, points2, cv2.RANSAC)

    # Use homography
    if len(im2.shape) == 2:
        height, width = im2.shape
    else:
        height, width, channels = im2.shape
    im1Reg = cv2.warpPerspective(im1, h, (width, height))

    return im1Reg, h, imMatches

template_fn = './stack/template.jpg'
image_fn = './stack/image.jpg'

im = cv2.imread(image_fn, cv2.IMREAD_GRAYSCALE)
template = cv2.imread(template_fn, cv2.IMREAD_GRAYSCALE)

# aligh images
imReg, h, matches = align_images(template,im)

# display output
cv2.imshow('im',im)
cv2.imshow('template',template)
cv2.imshow('matches',matches)
cv2.imshow('result',imReg)
cv2.waitKey(0)
cv2.destroyAllWindows()

Есть ли способ заставить алгоритм сопоставления с образцом работать на изображении слева (источник)?(другая идея состояла в том, чтобы оставить только пересечения линий)

В качестве альтернативы я пытался выполнить сопоставление инвариантного шаблона масштаба и поворота для циклов и при сохранении максимальной корреляции, но это слишком много ресурсов и не очень надежно.

Поэтому я ищу подсказки в правильном направлении, используя opencv.

1 Ответ

0 голосов
/ 28 февраля 2019

РЕШЕНИЕ

Проблема заключалась в том, чтобы уменьшить изображение до того, что действительно имеет значение: макет.
Кроме того, ORB был неподходящим, так как он не столь надежен (поворот и размеринвариант) как SIFT и AKAZE.

Я поступил следующим образом:

  • преобразование изображений в черно-белое
  • используйте обнаружение сегмента линии и линии фильтра короче, чем1/60 ширины
  • реконструирует изображение из сегментов (ширина линии не оказывает большого влияния)
  • (необязательно: изменение размера изображений для ускорения остальных)
  • применить преобразование Гаусса к реконструкции линии, 1/25 ширины
  • обнаружение и сопоставление объектов с использованием алгоритма SIFT (запатентовано) или AKAZE (бесплатно)
  • найти гомографию и деформировать источникизображение в соответствии с шаблоном

Matches AKAZE
Спички для AKAZE

Matches SIFT
Спички для SIFT

Я заметил:

  • макетmplate должен совпадать, иначе он будет придерживаться только того, что распознает
  • Обнаружение линии лучше с более высоким разрешением, тогда возможно уменьшение размера, так как применяются гауссианы
  • SIFT производит больше функций и кажется более надежнымчем аказе
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...