4

I have to stitch number of tiles using GraphicsMagick to create one single image. I am currently using -convert with -mosaic with some overlap to stitch tiles. But the stitched image has border where the overlap is done.

Following is the command I am using:

gm convert -background transparent 
-page "+0+0" "E:/Images/Scan 001_TileScan_001_s00_ch00.tif" 
-page "+0+948" "E:/Images/Scan 001_TileScan_001_s01_ch00.tif" 
-page "+0+1896" "E:/Images/Scan 001_TileScan_001_s02_ch00.tif" 
-page "+0+2844" "E:/Images/Scan 001_TileScan_001_s03_ch00.tif" 
-mosaic "E:/Output/temp/0.png"

The final image looks like this: Final Image with Overlap Border

How to stitch and Blend without Border?

Community
  • 1
  • 1
Nitesh Saxena
  • 199
  • 15

2 Answers2

7

I've been part of several projects to make seamless image mosaics. There are a couple of other factors you might like to consider:

  1. Flatfielding. Take a shot of a piece of white card with your lens and lighting setup, then use that to flatten out the image lightness. I don't know if GM has a thing to do this, @fmw42 would know. A flatfield image is specific to a lighting setup, lens aperture setting, focus setting and zoom setting, so you need to lock focus/aperture/zoom after taking one. You'll need to do this correction in linear light.

  2. Lens distortion. Some lenses, especially wide-angle ones, will introduce significant geometric distortion. Take a shot of a piece of graph paper and check that the lines are all parallel. It's possible to use a graph-paper shot to automatically generate a lens model you can use to remove geometric errors, but simply choosing a lens with low distortion is easier.

  3. Scatter. Are you moving the object or the camera? Is the lighting moving too? You can have problems with scatter if you shift the object: bright parts of the object will scatter light into dark areas when they move under a light. You need to model and remove this or you'll see seams in darker areas.

  4. Rotation. You can get small amounts of rotation, depending on how your translation stage works and how carefully you've set the camera up. You can also get the focus changing across the field. You might find you need to correct for this too.

libvips has a package of functions for making seamless image mosaics, including all of the above features. I made an example for you: with these source images (near IR images of painting underdrawing):

enter image description here

Entering:

$ vips mosaic cd1.1.jpg cd1.2.jpg join.jpg horizontal 531 0 100 0

Makes a horizontal join to the file join.jpg. The numbers give a guessed overlap of 100 pixels -- the mosaic program will do a search and find the exact position for you. It then does a feathered join using a raised cosine to make:

enter image description here

Although the images have been flatfielded, you can see a join. This is because the camera sensitivity has changed as the object has moved. The libvips globalbalance operation will automatically take the mosaic apart, calculate a set of weightings for each frame that minimise average join error, and reassemble it.

For this pair I get:

enter image description here

nip2, the libvips GUI, has all this with a GUI interface. There's a chapter in the manual (press F1 to view) about assembling large image mosaics:

https://github.com/jcupitt/nip2/releases

Global balance won't work from the CLI, unfortunately, but it will work from any of the libvips language bindings (C#, Python, Ruby, JavaScript, C, C++, Go, Rust, PHP etc. etc.). For example, in pyvips you can write:

import pyvips
    
left = pyvips.Image.new_from_file("cd1.1.jpg")
right = pyvips.Image.new_from_file("cd1.2.jpg")
join = left.mosaic(right, "horizontal", 531, 0, 100, 0)
balance = join.globalbalance()
balance.write_to_file("x.jpg")
jcupitt
  • 10,213
  • 2
  • 23
  • 39
  • Nice feature, John. Very impressive. – fmw42 May 05 '18 at 16:54
  • Very helpful. Thanks @user894762. I was able to create mosaic with libvips. The 'globalbalance' operation is not working. Using command: vips globalbalance mosaic.tif outputMosaic.tif. – Nitesh Saxena May 07 '18 at 08:58
  • This shows the following error: im_global_balance: mosaic root not found in desc file. Is this really a mosaiced image? – Nitesh Saxena May 07 '18 at 09:00
  • 1
    Yes, globalbalance won't work from the command-line, unfortunately. You need to use it from nip2 or from Python. Did you try the Windows build of nip2? Start it, then click File / Open Examples / 1_pt. – jcupitt May 07 '18 at 09:44
  • @user894763, Oh!. I need to use this with command line, as later I need to use it in my application and I could send commands from my application. Any other option to use this via Command-line or some API? – Nitesh Saxena May 08 '18 at 05:05
  • You can use it from any of the bindings, so C#, Python, Ruby, JavaScript, C, C++, Go, Rust, PHP etc. etc. – jcupitt May 08 '18 at 07:18
  • I added a python example, including globalbalance. – jcupitt May 11 '18 at 11:29
2

Here is an example using ImageMagick. But since colors are different, you will only mitigate the sharp edge with a ramped blend. The closer the colors are and the more gradual the blend (i.e. over a larger area), the less it will show.

1) Create red and blue images

convert -size 500x500 xc:red top.png

enter image description here

convert -size 500x500 xc:blue btm.png

enter image description here

2) Create mask that is solid white for most and a gradient where you want to overlap them. Here I have 100 pixels gradient for 100 pixel overlap

convert -size 500x100 gradient: -size 500x400 xc:black -append -negate mask_btm.png

enter image description here

convert mask_btm.png -flip mask_top.png

enter image description here

3) Put masks into the alpha channels of each image

convert top.png mask_top.png -alpha off -compose copy_opacity -composite top2.png

enter image description here

convert btm.png mask_btm.png -alpha off -compose copy_opacity -composite btm2.png

enter image description here

4) Mosaic the two images one above the other with an overlap of 100

convert -page +0+0 top2.png -page +0+400 btm2.png -background none -mosaic result.png

enter image description here

See also my tidbit about shaping the gradient at http://www.fmwconcepts.com/imagemagick/tidbits/image.php#composite1. But I would use a linear gradient for such work (as shown here), because as you overlap linear gradients they sum to a constant white, so the result will be fully opaque where they overlap.

One other thing to consider is trying to match the colors of the images to some common color map. This can be done by a number of methods. For example, histogram matching or mean/std (brightness/contrast) matching. See for example, my scripts: histmatch, matchimage and redist at http://www.fmwconcepts.com/imagemagick/index.php and ImageMagick -remap at https://www.imagemagick.org/Usage/quantize/#remap

fmw42
  • 46,825
  • 10
  • 62
  • 80
  • Gradient won't work with my use-case as the blend may be visible as you mentioned. In my case, Colors depends on the input images which are taken from a microscopic camera and can vary. – Nitesh Saxena May 08 '18 at 05:12
  • There is no other way to blend but gradients as far as I know other than simple averaging over the whole region. But that could show doubling of features, if they are offset. But to make sure it does not show a transition, you need to color balance/match the images first so that the colors are as close as possible before blending as I mentioned above. See John Cupitt's solution above. It matches the two images before blending. – fmw42 May 08 '18 at 05:24