Сшивание нескольких изображений с использованием 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 является следующим.
Надеюсь, что это поможет.