Can Mathematica recompose an image?

Yesterday I showed how to locate a subimage inside a large image using ImageCorrelate. I will now show how to use the same approach to solve this problem.

Start by importing the images that you want to compose:

i1 = Import["http://i.stack.imgur.com/UjGAz.jpg"];
i2 = Import["http://i.stack.imgur.com/93kwm.jpg"];
GraphicsRow[{i1, i2}]

Mathematica graphics

Since the right image is not completely contained by the left image, we cannot use my answer from the other question. However, if we split the right image into small enough pieces then there will be a piece that is covered completely by the left image. By locating this piece in the left image we know two positions, one in each image, that correspond to each other.

pieces = ImagePartition[i2, 64]

Mathematica graphics

There may be several pieces that are covered by the left image, in which case there will be several good fits. I will select the piece that fits best, as given by ImageCorrelate.

minPixelValue[image_Image][subimage_Image] := Module[{corr, idata},
  corr = ImageCorrelate[image, subimage, EuclideanDistance];
  idata = ImageData[corr];
  idata = Map[Norm, idata, {2}];
  Min[idata]
  ]
bestFit = MinimalBy[Flatten[pieces], minPixelValue[i1]] // First;

Now I can find out where in the two images the piece that I selected as the best fit belongs:

{p1} = correspondingPixel[i1, bestFit];
{p2} = correspondingPixel[i2, bestFit];

GraphicsRow[{
  HighlightImage[i1, p1, Method -> {"DiskMarkers", 5}],
  HighlightImage[i2, p2, Method -> {"DiskMarkers", 5}]
  }]

Mathematica graphics

Finally we need to compose the images. This is easier to do if we know where one of the images is positioned in the complete image, and also the dimensions of the complete image. I will assume such knowledge for convenience sake. I'll start by creating a padded version of the left image:

i = Import["http://i.stack.imgur.com/S2ISp.jpg"]; (* Full image *)
{right, bottom} = ImageDimensions[i] - ImageDimensions[i1];
padded = ImagePad[i1, {{0, right - 1}, {bottom - 1, 0}}]

Mathematica graphics

And now I'll use ImageCompose to merge the images:

ImageCompose[padded, i2, p1, p2]

Mathematica graphics

We can apply the same method again to merge this image with the third image. In general, if there are $n$ images then they can be merged like this in a recursive manner. Unless all images overlap with each other the order in which images are merged will be important, so it may require finesse.


This is not very automated but perhaps it will motivate experts:

Copied the images

enter image description here

Changing image to graphic and finding corresponding points:

fun[img_] := 
 With[{id = ImageDimensions[img]}, {Texture[img], 
   Polygon[{{1, 1}, {id[[1]], 1}, id, {1, id[[2]]}}, 
    VertexTextureCoordinates -> {{0, 0}, {1, 0}, {1, 1}, {0, 1}}]}]
{ma, mb} = ImageCorrespondingPoints[a, b];
{mta, mtc} = ImageCorrespondingPoints[a, c];

Using manipulate and pasting desired bookmarks:

Manipulate[
 Graphics[{GeometricTransformation[
    fun[a]~Join~{Red, PointSize[0.025], Point[ma]}, 
    TranslationTransform[{x, y}]], Opacity[0.5], fun[b], Yellow, 
   PointSize[0.01], Point[mb]}],
 {x, -300, 10, Appearance -> "Labeled"}, {y, -300, 100, 
  Appearance -> "Labeled"}]

enter image description here

Manipulate[
 Graphics[{GeometricTransformation[
    fun[c]~Join~{Red, PointSize[0.025], Point[mtc]}, 
    TranslationTransform[{x, y}]], Opacity[0.5], 
   GeometricTransformation[fun[a], TranslationTransform[abt]], Yellow,
    PointSize[0.01], 
   GeometricTransformation[Point[mta], TranslationTransform[abt]]}],
 {x, -300, 10, Appearance -> "Labeled"}, {y, -300, 100, 
  Appearance -> "Labeled"}]

enter image description here

The bookmarks:

abt = "ab" /. {"ab" :> {x = -122.5`, y = -171.`}}
act = "ac" /. {"ac" :> {x = -128.`, y = 1.`}}

Piecing together:

Graphics[{GeometricTransformation[fun[a], TranslationTransform[abt]], 
  GeometricTransformation[fun[c], TranslationTransform[act]], fun[b]}]

The code could be made more concise. I do not have time at present (this was a "stream of consciousness"). I look forward to learning from other answers.

enter image description here

In case of doubt enter image description here