Сшивание нескольких изображений с использованием OpenCV (Python)

Привет, я видел много учебников, как делать простые сшивки изображений, используя две фотографии, и это не проблема.
Но что делать, когда я хочу сделать панораму с 4-6 изображений или более?

У меня есть код, который принимает список файлов изображений (изображения находятся в порядке от первого изображения в последовательности до последнего). Затем для каждого изображения я вычисляю дескрипторы функции SIFT , Но тогда я застрял, для двух изображений я бы установил совпадение с использованием FLD-kd-дерева и нашел совпадения между изображениями и вычислил Гомографию. Подобно этому учебнику http://docs.opencv.org/trunk/doc/py_tutorials/py_feature2d/py_feature_homography/py_feature_homography.html#py-feature-homography

Но вместо того, чтобы показывать линии между точками в конце, я использовал эту функцию qaru.site/info/349103/..., чтобы сделать панораму из двух изображений. Но я не уверен, что делать, когда я хочу добавить третье и четвертое изображение к панораме.

ИЗМЕНИТЬ:

Из ответов, которые я попытался реализовать, сшиваем изображения script, чтобы вычислить матрицу гомографии между изображениями, которые находятся рядом друг с другом в последовательности изображений. Поэтому, если у меня I1 I2 I3 и I4, теперь я имею H_12, H_23 и H_34. Затем я начинаю с строчки I1 и I2 с использованием H_12. Затем я хочу найти кумулятивную гомографию, чтобы сшить I3 до текущей панорамы. Я нажимаю H_13 = H_12 * H_23 и строчу изображение 3 в текущую панораму, но здесь я вижу очень заметный разрыв в своем панорамном изображении, и когда следующее изображение сшито, это еще больший зазор, и изображения очень растянуты. Вот мой код http://pastebin.com/dQjhE5VD

Может ли кто-нибудь сказать мне, правильно ли я использую этот подход или кто-то может заметить ошибку или увидеть, что я делаю неправильно.

Ответ 1

Шаг за шагом, предполагая, что вы хотите сшить четыре изображения I0, I1, I2, I3, ваша цель состоит в вычислении гомографий H_0, H_1, H_2, H_3;

  • Вычислить все попарные гомологии H_01, H_02, H_03, H_12, H_13, H_23, где гомография H_01 преобразует изображение I0 в I1 и т.д.
  • Выберите одно изображение привязки, например. I1, положение которого останется фиксированным i.e H_1 = Identity
  • Найдите изображение, которое лучше выравнивается с I1 на основе максимального количества согласованные соответствия, например. I3
  • Обновить H_3 = H_1 * inv (H_13) = inv (H_13) = H_31
  • Найти изображение, которое лучше соответствует I1 или I3, например I2, соответствующее I3
  • Обновление H_2 = H_3 * H_23
  • То же, что и выше для изображения I0
  • Устанавливает настройку связки для оптимизации по всему миру.

Подробное объяснение см. в разделе 4 этой оригинальной статьи https://www.cs.bath.ac.uk/brown/papers/ijcv2007.pdf.

Ответ 2

Хаккий подход

Самый простой способ (хотя и не суперэффективный) с учетом написанных вами функций - просто увеличить панорамное изображение, сшив его с каждым последующим изображением. Что-то вроде этого псевдокода:

panorama = images[0]
for i in 1:len(images)-1
    panorama = stitch(panorama,images[i])

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

Математический подход

Другой вариант, если вы знаете порядок, который хотите сшить, - это найти Гомографию с одного изображения на другое, а затем умножить их. Результатом является Гомография от этого изображения до изображения 0.

Например: H, который преобразует изображение 3 в линию с изображением 0, является H_03 = H_01 * H_12 * H_23. Где H_01 - это H, который преобразует изображение 1 в линию с изображением 0. (В зависимости от того, как их код определяет H, вам может потребоваться отменить вышеупомянутый порядок умножения.) Таким образом, вы будете умножать, чтобы получить H_0i, а затем использовать его для преобразования изображение я для выравнивания с изображением 0.

Для получения дополнительной информации о том, почему вы умножаете преобразования, см. https://www.math.lsu.edu/~verrill/teaching/linearalgebra/linalg/linalg5.html в частности часть "Состав преобразований".

Ответ 3

У меня была аналогичная проблема с разрывами между изображениями. Первое, что вам нужно сделать, - это создать свою накопленную матрицу гомографии для идентификации в первом кадре. Затем, с каждым новым фреймом, вы должны умножить его на матрицу гомографии между текущим и следующим кадром. Имейте в виду использование матриц numpy, а не массивов numpy. IDK почему, но они имеют разные процедуры умножения.

Вот мой код:

def addFramePair(self, images, ratio=0.75, reprojThresh=4.0, showMatches=False):        
    (imageA, imageB) = images
    (kpsA, featuresA) = self.detectAndDescribe(imageA)
    (kpsB, featuresB) = self.detectAndDescribe(imageB)

    H = self.matchKeypoints(kpsA, kpsB, featuresA, featuresB, ratio, reprojThresh)
    self.accHomography *= np.asmatrix(H)
    result = cv2.warpPerspective(imageA, np.linalg.inv(self.accHomography), (1600, 900))
    return result

imageA является текущим, imageB является следующим.

Надеюсь, что это поможет.