Question

I have a bunch of images in a folder that are effectively just pieces of one image that was broken into overlapping parts. How can I quickly and programmatically recombine these images to create the original image?

I would prefer a solution that uses python or mathematica (or is an existing application), but I am open to other ideas as well (I am fairly proficient with Java).

Was it helpful?

Solution 2

Well, I no longer need to do this to do what I want to do, but I will share how I would do this if I were to write it in python (mix of psuedocode and python). Here I assume that the top left corner of subsequent images are always the point of overlap (which was true in my case). If you want to detect overlaps for any corner, you will need to detect which "corner" case you are in and add handling for each case.

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

Notes:

  1. Creating an image and pasting into it can be accomplised with PIL: http://29a.ch/2009/5/14/concatenating-images-using-python

  2. See this question for how to find a sub_image in an image (may need to convert image to another representation): Finding a subimage inside a Numpy image. Also, for any proficient programmer, it wouldn't be at all difficult to manually inspect pixels in the matrix of pixels to find the overlap. You could add in additional optimization if you know roughly where the overlap is likely to occur by simply searching in the more likely areas first.

OTHER TIPS

i realize this answer comes very late, but since i spent some time googling this problem, i thought i would post a fairly simple solution using 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])

You could use Autopano or something similar; if you want to roll it yourself, you might find SIFT algorithms useful http://www.janeriksolem.net/2009/02/sift-python-implementation.html?m=1

What you want is a tool for creating panoramas. There are various tools sold to do this with various features. Things to think about are:

  1. matching position vertically and horizontally
  2. varying brightness between images
  3. correcting for camera rotation and angle

Are you intent on using a Java specific solution? If you're open to something else, I'm doing something similar for a project, and came up with a bash script set for Linux.

To do this, I used

  1. Hugin and hugin-tools from the Ubuntu repositories
  2. Panotools perl wrapper scripts
  3. This guide to get the generation functionality working via command line. In the example, pto_gen doesn't exist after installing hugin, but is replaced my match-n-shift in the Panotools scripts.

If you want to batch process multiple panoramas sequentially, you'll have to come up with a way of sorting, executing and moving files around. That was the fun part with my scripting process. Stitching the pictures together was easy, making sure they went to the right place afterwards was a bit tricky.

Right now, using a 4-core Xeon system with 4 GB RAM, stitching a 50 image 360 degree panorama takes ~30-45 minutes.

In Mathematica, you can use ImageCorrespondingPoints within the overlap region, and then FindGeometricTransform to compute an affine transformation that takes one image into the other. Note that the size of the images and and overlap regions influence the accuracy of the transformation. If you are doing something complex (like combining satellite images), you will need an overall geometric model for the result and then map each image to it. In such cases an affine transformation may not be sufficient.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top