Search code examples
imagemagickgraphicsmagick

Stitching images using GraphicsMagick with Blending


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?


Solution

  • 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")