Automatically lining up two images that have some common elements

Over on genealogy.SE, I proposed a method of manipulating images to make "bleed through" less visible and the handwriting on the correct side of the page more legible.

Here are the original images:

The idea is to make a mirror image of the other page, and then remove things that are dark on the flipped page and lighter on the target page, and similarly keep things that are darker on the target page than the flipped page. Here's the flipped page:

page17cropflip = ImageReflect[page17crop, Left]


Here was the set of commands that worked tolerably well in this case (it looks better at full size):

With[{brightness = -0.3, contrast = 0, final = 0.903,
highbleed = 0.159, lowbleed = 0.221, method = "Cluster"},
ImageClip[
ImageClip[page17cropflip, {lowbleed, lowbleed + highbleed}]], {0,
final}], {contrast, brightness}], Method -> method]]


But I needed to crop the images by hand (I used ImageDifference to help line it up) so that the bleeding through text lined up with the actual text on the image of the facing page. Is there a way to automate this?

-
I'm also interested in improvements to my method. I think it could be better. –  Verbeia Jul 29 '14 at 10:35
Interesting question. I've done this specific operation by hand before (for full color images rather than text) and I think subtle distortions in the scans will require compensation in the alignment, especially with details as fine as text. I mean that a simple translation will not suffice, and you will need to "warp" the background image to produce a perfect alignment. Many of the image processing tools in v10 are new to me so I'm not sure where to start. Is there a function that is suitable for localized warping? –  Mr.Wizard Jul 30 '14 at 1:38
@Mr.Wizard: ImageTransformation can wrap. If you have per-pixel offsets (as you would have with many optical flow or non-parametric registration algorithms), this question might be useful: mathematica.stackexchange.com/questions/31274/… –  nikie Jul 30 '14 at 5:33
If this weren't a Mathematica-specific site I would suggest a simple manual technique using two minutes of Photoshop: i.stack.imgur.com/5Lm3z.jpg –  Rahul Jul 30 '14 at 8:03
@Mr.Wizard, I made an attempt at doing what you describe by doing correlations on smaller sub-images to get a local translation which varies across the image, then interpolating that data and using ImageForwardTransformation to apply the warp. It didn't work very well though. –  Simon Woods Jul 30 '14 at 8:04

Here's a first (very simple!) attempt:

{p1, p2} =
ColorConvert[Import[#],
"Grayscale"] & /@ {"http://i.stack.imgur.com/2hf7N.jpg",
"http://i.stack.imgur.com/WnVtF.jpg"};


A simple CorrelationDistance gives a surprisingly good estimate for the shift:

corr = ImageCorrelate[p1, ImageReflect[p2, Left -> Right],
CorrelationDistance]


shift = PixelValuePositions[corr, Min[ImageData[corr]]][[1]] -
ImageDimensions[p1]/2;
shiftedImgs = {p1,
ImageTransformation[ImageReflect[p2, Left -> Right], # - shift &,
PlotRange -> Full, DataRange -> Full]};
FlipView[shiftedImgs]


Now, I remember vaguely that PCA was a very cheap way to do blind source separation:

{u, s, v} =
SingularValueDecomposition[# - Mean[#] & /@
Flatten /@ ImageData /@ shiftedImgs, 2];
Image[Rescale[Partition[v[[All, 2]], 1000]]]


It seems that the "positive" pixels are one page, the "negative" pixels are the other one. (But I'm probably doing it wrong. I really have to look up how this works again.)

Column[MapThread[
Function[{sign, mirror},
ImageReflect[
Image[1 -
Rescale[Clip[sign*Partition[v[[All, 2]], 1000], {0, \[Infinity]}]],
ImageSize -> All], mirror]],
{
{1, -1},
{Left -> Left, Left -> Right}
}]]


Here's a before/after comparison:

Like I said, not perfect. But I think blind source separation techniques really are the way to go here. Both for separating the signal, as well as for choosing a good "correlation measure" to determine the shift between the images. That's why I posted this answer.

-
Thanks nikie, this is excellent, but the real challenge is stripping the bleedthrough of page 17 on page 18. I'm away from my Mathematica machine at the moment, so is there any chance you could show the unflipped version of the second-last image? –  Verbeia Jul 29 '14 at 22:45