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

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

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

Но вместо отображения линий между точками функций в конце я использовал этот https://stackoverflow.com/a/20355545/622194 для создания панорамы из двух изображений. Но я не знаю, что делать, если я хочу добавить к панораме третье и четвертое изображение.

РЕДАКТИРОВАТЬ:

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

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


person Community    schedule 03.07.2014    source источник
comment
Ссылка на код, прокомментированный в ветке, отключена.   -  person ajeje    schedule 13.07.2015
comment
Ссылка pastebin больше не работает. Не могли бы вы снова сделать код доступным?   -  person creimers    schedule 04.01.2019


Ответы (3)


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

  1. Вычислить все попарные гомографии H_01, H_02, H_03, H_12, H_13, H_23, где гомография H_01 деформирует изображение I0 в I1 и т. Д.
  2. Выберите одно изображение привязки, например I1 какая позиция останется фиксированной, т.е. H_1 = Identity
  3. Найдите изображение, которое лучше согласуется с I1 на основе максимального количества согласованных совпадений, например I3
  4. Обновление H_3 = H_1 * inv(H_13) = inv(H_13) = H_31
  5. Найдите изображение, которое лучше соответствует I1 или I3, например, I2 соответствует I3
  6. Обновить H_2 = H_3 * H_23
  7. То же, что и выше для изображения I0
  8. Выполните настройку пакета для глобальной оптимизации выравнивания

См. Раздел 4 этой основополагающей статьи Автоматическое сшивание панорамных изображений с использованием неизменяемых функций для более подробного объяснения.

person memecs    schedule 03.07.2014
comment
Будет ли работать тот же подход, если я попытаюсь сделать панораму на 360 °? Где я знаю порядок изображений img0, img1 ... imgN. Достаточно, чтобы сохранить гомографию между img0-img1, img1-2 и imgN-1-imgN, а затем найти, чтобы найти преобразование между img0-img1, я использую H_01 и для (img0-img1) -img2, я бы использовал H_02 = H_01 * H_12? Это сработает? Я чувствую, что ваш подход предполагает, что я не знаю, должны ли изображения совпадать. Если я знаю последовательность изображений, я считаю, что бесполезно хранить гомографию между img0 и img5, поскольку они плохо совпадают. - person ; 04.07.2014
comment
Да, это подойдет для панорам 360 °. Регулировка связки будет важна для исправления глобального выравнивания и правильного обтекания панорамы. Конечно, если вы создаете алгоритм для конкретной панорамы и знаете, что некоторые изображения плохо совпадают, вы можете избежать вычисления гомографии между ними. - person memecs; 07.07.2014
comment
@memecs Ссылка на статью мертва. - person rex123; 25.09.2017
comment
Не могли бы вы немного подробнее Сделать корректировку пакета для глобальной оптимизации выравнивания? - person Philippe Remy; 14.09.2020

Хакерский подход

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

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, а затем использовать его для преобразования изображение i должно совпадать с изображением 0.

Для получения дополнительной информации о том, почему вы умножаете преобразования, см .: Преобразования и умножение матриц, в частности, часть" Состав преобразований ".

person Luke    schedule 03.07.2014
comment
Проблема с хакерским подходом состоит в том, что после деформации изображений будет сложно надежно оценить совпадающие признаки. - person memecs; 04.07.2014
comment
@memecs - совершенно верно. (Это то, что я имел в виду под искажением перспективы.) - person Luke; 04.07.2014
comment
Хорошо, не уверен, что я делаю это правильно, но вот мой код: pastebin.com/HLAnF62p Но это действительно не работа. Первые два изображения сшиты правильно, но когда я добавляю третье, я просто получаю что-то странное, окно становится очень большим, и я вижу только часть первых двух изображений, сшитых вместе, и ничего из третьего изображения. Это близко, но мне просто нужно выяснить, как правильно преобразовать третьи + изображения. Если я умножу на единичную матрицу, изображения будут нарисованы друг на друге с небольшим переводом. - person ; 04.07.2014

У меня была аналогичная проблема с пробелами между изображениями. Первое, что вам нужно сделать, это инициализировать накопленную матрицу гомографии для идентификации в первом кадре. Затем с каждым новым кадром вы должны умножать его на матрицу гомографии между текущим и следующим кадром. Помните, что нужно использовать матрицы 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 следующее.

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

person Borys Tymchenko    schedule 07.07.2017