Выравнивание изображений с помощью openCV - PullRequest
0 голосов
/ 27 июня 2019

У меня есть коллекция из примерно 250 изображений. Все они были отсканированы из книги, следовательно, все они немного сдвинуты или повернуты относительно друг друга. Теперь я хотел бы сделать некоторые извлечения данных на этих изображениях, но для того, чтобы сделать это автоматически, все позиции на всех изображениях должны быть идентичны. Вот почему мне нужно как-то выровнять эти изображения так, чтобы все позиции на всех изображениях соответствовали друг другу. Каков наилучший способ достичь этого? Я подумал, что openCV - лучший способ сделать это, но я не уверен, как мне начать.

Ниже приведен пример отсканированного изображения:

enter image description here

1 Ответ

1 голос
/ 27 июня 2019

Пунктирные линии, вероятно, хорошая якорная точка.

Вы можете использовать маску для выравнивания отдельных изображений. Сканируйте края масок для определения координат и используйте их для поворота и смещения изображений. Под этим я подразумеваю цикл по значениям верхнего ряда маски. Первый белый пиксель дает верхнюю центральную координату. Аналогично для других сторон маски. Вы можете сравнить эти значения на разных изображениях, чтобы определить смещение и вращение. Чтобы применить эти преобразования, прочитайте здесь . Это займет довольно много времени, хотя. Возможно, есть более простой вариант:

Я могу ошибаться, но, похоже, вы хотите выровнять страницы, чтобы вы могли извлечь графики, используя жестко закодированные значения. Другой, более простой подход - использовать findContours для создания подизображений «плиток». Затем они могут быть дополнительно обработаны. Это реализовано в приведенном ниже коде.

enter image description here

Разделенные изображения:

enter image description here

код:

    import cv2
    import numpy as np  
    # load image
    img_large=cv2.imread("BAgla.jpg")
    # resize for ease of use
    img_ori = cv2.resize(img_large, None, fx=0.2, fy=0.2, interpolation= cv2.INTER_CUBIC)
    # create grayscale
    img = cv2.cvtColor(img_ori, cv2.COLOR_BGR2GRAY)
    # create mask for image size
    mask = np.zeros((img.shape[:2]),dtype=np.uint8)
    # do a morphologic close to merge dotted line
    kernel = np.ones((8,8))
    res = cv2.morphologyEx(img,cv2.MORPH_OPEN, kernel)
    # detect edges for houglines
    edges = cv2.Canny(res, 50,50)
    # detect lines
    lines = cv2.HoughLines(edges,1,np.pi/180,200)
    # draw detected lines
    for line in lines:
            rho,theta = line[0]
            a = np.cos(theta)
            b = np.sin(theta)
            x0 = a*rho
            y0 = b*rho
            x1 = int(x0 + 1000*(-b))
            y1 = int(y0 + 1000*(a))
            x2 = int(x0 - 1000*(-b))
            y2 = int(y0 - 1000*(a))

            cv2.line(mask,(x1,y1),(x2,y2),(255),2)
            cv2.line(img,(x1,y1),(x2,y2),(127),2)

    # invert the mask for use with findcontours
    mask_inv = cv2.bitwise_not(mask)
    # use findcontours to get the boundingboxes of the tiles
    contours, hier = cv2.findContours(mask_inv,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
    boundingrects = []
    for cnt in contours:
            boundingrects.append(cv2.boundingRect(cnt))

    # findContours has no garanteed order, so sort array
    boundingrects.sort()

    # titles for window names / save file names
    title = ['Kaart', None, 'Smaakprofiel', 'Basiswaarden','Gelijkaardige bieren','Chemisch Profiel']

    # create images for top and bottom tiles
    for index in [0,2,3,5]:
            x,y,w,h = boundingrects[index]
            subimg = img_ori[y:y+h,x:x+w]
            cv2.imshow(title[index], subimg  )

    # combine middle tiles
    x1,y1,w1,h1 = boundingrects[1]
    x2,y2,w2,h2 = boundingrects[4]
    subimg = img_ori[y1:y2+h2,x1:x2+w2]
    cv2.imshow(title[4], subimg  )

    # display result
    cv2.imshow("Result", img  )
    cv2.imshow("Mask", mask  )
    cv2.waitKey(0)
    cv2.destroyAllWindows()

Обратите внимание, что я использовал уменьшенную версию изображения, поэтому учитывайте это при обработке изображений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...