Сшивание изображений с точно совпадающими (пиксель к пикселю) перекрытиями

У меня есть куча изображений в папке, которые фактически представляют собой части одного изображения, разбитого на перекрывающиеся части. Как я могу быстро и программно рекомбинировать эти изображения, чтобы создать исходное изображение?

Я бы предпочел решение, использующее python или mathematica (или существующее приложение), но я также открыт для других идей (я неплохо разбираюсь в Java).


person Muhd    schedule 24.06.2012    source источник
comment
Другим вариантом использования могут быть скриншоты из 2D-игр с прокруткой. Моя проблема по существу такая же, как и та, что представлена ​​в это закрытый вопрос   -  person Muhd    schedule 24.06.2012
comment
Вы можете найти эти вопросы и ответы полезными: mathematica.stackexchange.com/q/1911/121   -  person Mr.Wizard    schedule 24.06.2012


Ответы (6)


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

import cv2
#works in version 4.2
cv2.__version__

#mode=0 photos, mode=1 scans
stitcher = cv2.Stitcher.create(mode=1)

img1 = cv2.imread("frame-0021.png")
img2 = cv2.imread("frame-0022.png")

result = stitcher.stitch((img1, img2))
cv2.imwrite("stitched.png", result[1])
person nils-holmberg    schedule 26.03.2020

Что ж, мне больше не нужно делать это, чтобы делать то, что я хочу, но я поделюсь, как бы я это сделал, если бы написал это на python (смесь псевдокода и python). Здесь я предполагаю, что верхний левый угол последующих изображений всегда является точкой наложения (что было верно в моем случае). Если вы хотите обнаружить перекрытия для любого угла, вам нужно будет определить, в каком «угловом» случае вы находитесь, и добавить обработку для каждого случая.

images = list of images to be stitched, loaded from directory
stitched_image = images[0]

for (image in images):
    if first image then skip it (continue)
    else combine_images(stitched_image, image)

def combine_images (stitched_image, image_to_add):
    top_left_corner = top left corner of image_to_add 
    // top_left_corner dimensions need to be big enough that you don't have a false positive, 
    // but not so big that the overlap doesn't exist
    coordinates = find_coordinates(stitched_image,top_left_corner)

    new_width = max(stitched_image.width,image_to_add.width + coordinates.x)
    new_height = max(stitched_image.height,image_to_add.width + coordinates.y)
    new_image = new Image(new_width,new_height) // See note 1
    new_image.paste(stitched_image,(0,0))
    new_image.paste(image_to_add,(coordinates.x,coordinates.y))

    stitched_image = new_image

def find_coordinates (image,sub_image):
    // See note 2 below for how to implement

Примечания:

  1. Создать изображение и вставить в него можно с помощью PIL: http://29a.ch/2009/5/14/concatenating-images-using-python

  2. См. этот вопрос, чтобы узнать, как найти sub_image в изображении (может потребоваться преобразовать изображение в другое представление): Поиск части изображения внутри изображения Numpy. Кроме того, для любого опытного программиста не составит труда вручную проверить пиксели в матрице пикселей, чтобы найти перекрытие. Вы можете добавить дополнительную оптимизацию, если примерно знаете, где может произойти перекрытие, просто сначала выполнив поиск в наиболее вероятных областях.

person Muhd    schedule 24.06.2012

Вы можете использовать Autopano или что-то подобное; если вы хотите свернуть его самостоятельно, вам могут пригодиться алгоритмы SIFT http://www.janeriksolem.net/2009/02/sift-python-implementation.html?m=1

person Hugh Bothwell    schedule 24.06.2012

Вам нужен инструмент для создания панорам. Для этого продаются различные инструменты с различными функциями. О чем следует подумать:

  1. соответствие положения по вертикали и горизонтали
  2. разная яркость между изображениями
  3. корректировка поворота и угла камеры
person stark    schedule 24.06.2012
comment
Хотя инструменты панорамы будут работать (вроде как), большинство или все из них выполняют смешивание, а это не то, что мне нужно. Кроме того, они не оптимизированы для моего варианта использования, когда пиксели точно совпадают для определенной области обоих изображений. - person Muhd; 24.06.2012

Вы намерены использовать специальное решение для Java? Если вы открыты для чего-то еще, я делаю что-то подобное для проекта и придумал набор скриптов bash для Linux.

Для этого я использовал

  1. Hugin и Hugin-tools из репозиториев Ubuntu
  2. Panotools Perl-скрипты-оболочки
  3. Это руководство, чтобы заставить функцию генерации работать через командную строку. В примере pto_gen не существует после установки Hugin, но заменяется моим match-n-shift в скриптах Panotools.

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

Прямо сейчас, используя 4-ядерную систему Xeon с 4 ГБ ОЗУ, сшивка 360-градусной панорамы из 50 изображений занимает примерно 30–45 минут.

person Jason    schedule 24.06.2012
comment
Более сложный и трудоемкий, чем то, что мне нужно. Мне нужно что-то, что просто быстро находит соответствующую строку или столбец пикселей и объединяется в этой точке. - person Muhd; 24.06.2012

В Mathematica вы можете использовать ImageCorrespondingPoints в пределах области перекрытия, а затем FindGeometricTransform для вычисления аффинного преобразования, переводящего одно изображение в другое. Обратите внимание, что размер изображений и областей перекрытия влияют на точность преобразования. Если вы делаете что-то сложное (например, объединение спутниковых изображений), вам понадобится общая геометрическая модель для результата, а затем сопоставление с ней каждого изображения. В таких случаях аффинного преобразования может быть недостаточно.

person stuartw    schedule 27.06.2012