Сшивание нескольких изображений с помощью OpenCV (Python)
Привет, я видел много уроков, как сделать простое сшивание изображения, используя две фотографии, и это не проблема.
Но что делать, если я хочу сделать панораму из 4-6 изображений или больше?
У меня есть код, который принимает в списке файлов изображений (изображения в порядке от первого изображения в последовательности до последнего). Затем для каждого изображения я вычисляю дескрипторы функции SIFT. Но потом я застрял, для двух изображений я бы установил сопоставление, используя kd-дерево FLANN, и нашел совпадения между изображениями и вычислил гомографию. Аналогично этому учебнику http://docs.opencv.org/trunk/doc/py_tutorials/py_feature2d/py_feature_homography/py_feature_homography.html
Но вместо того, чтобы показать линии между характерными точками в конце, я использовал эту функцию /questions/6534189/kak-pokazat-vse-izobrazhenie-pri-ispolzovanii-opencv-warpperspective/6534190#6534190 чтобы сделать панораму из 2 изображений. Но я не уверен, что делать, когда я хочу добавить третье и четвертое изображение в панораму.
РЕДАКТИРОВАТЬ:
Исходя из ответов, я попытался реализовать свой сценарий сшивания изображений для вычисления матрицы гомографии между изображениями, которые расположены рядом друг с другом в последовательности изображений. Так что, если у меня есть 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
Может кто-нибудь сказать мне, если я использую правильный подход для этого или кто-то может определить ошибку или посмотреть, что я делаю неправильно.
3 ответа
Шаг за шагом, предполагая, что вы хотите сшить четыре изображения 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, какая позиция останется неизменной, например, H_1= Идентичность
- Найти изображение, которое лучше выравнивается по 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 этого оригинального документа " Автоматическое сшивание панорамных изображений с использованием инвариантных функций" для более подробного объяснения.
Хакерский подход
Самый простой способ (хотя и не суперэффективный) с учетом написанных вами функций - просто увеличить изображение панорамы, сшивая его с каждым последующим изображением. Примерно такой псевдокод:
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.
Сведения о том, почему вы умножаете преобразования, см. В разделе " Преобразования и умножение матриц", в частности, в части "Состав преобразований".
У меня была похожая проблема с промежутками между изображениями. Первое, что вы должны сделать, это инициализировать накопленную матрицу гомографии для идентификации в первом кадре. Затем с каждым новым кадром вы должны умножить его на матрицу гомографии между текущим и следующим кадром. Будьте внимательны, чтобы использовать числовые матрицы, а не числовые массивы. ИДК почему, но у них разные процедуры умножения.
Вот мой код:
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 является следующим.
Надеюсь это поможет.