Gatan | AMETEKSkip to Main Content
No options found

Merge images

DigitalMicrograph Script

Combine two images of different intensity levels into one. Useful to merge diffraction patterns of different exposure times.

Preview

/////////////////////////////////////////////////////////////////////
// (c) Gatan Inc.
/////////////////////////////////////////////////////////////////////
// Merges two images of different intensisties replacing saturated pixels
// in the stronger image with scaled values from the weaker image.
// Especially useful for merging diffraction patterns.
//	
// Asks for a threshold value which should be less than the value of the saturated
// pixels.  Choose a value that excludes the saturated values as well as nearby 
// pixels that will contain some of the spilled over saturated charge.  Improper 
// selection will result in an incorrect scaling ratio that should be observable
// using a line plot in the merged image.
/////////////////////////////////////////////////////////////////////
//	last modified 08-July-2014 BS



// This littel method creates dummy images for testing.
image GetDummyExposure( number exp )
{
	image img:=RealImage("Test",4,256,256)
	number r1=20
	number r2=30
	img = 1 + sqrt((mod(icol,2*r2)-r2)**2 + (mod(irow,2*r2)-r2)**2)
	img = ( img<r2 ? exp(-((img-r1))) : 0  )
	img = log(1+img*img*abs(itheta*icol))*icol*abs(itheta)+sin((iwidth/2-iradius)+itheta*Pi())*50
	img -= min(img)
	img /= max(img)	
	img *= exp
	return (img>6000?6000:img)+random()*300
}


If ( TwoButtonDialog( "Do you want to create 2 dummy images?", "Yes", "No" ) )
{
	image lowExp = GetDummyExposure(10000 )
	lowExp.SetName( "low exposure (no saturation, too noisy in background" )
	image highExp = GetDummyExposure(100000 )
	highExp .SetName( "high exposure (saturation, good background" )
	DisplayAt( lowExp, 100, 100 )
	DisplayAt( highExp, 100, 400 )
}


// Set the default threshold value 
number threshold = 3500.												

// Prompt the user to select the two images for merging
image img1, img2														
if ( !GetTwoImages( "Select the two images for merging", img1, img2 ))	
	exit(0)

// Check both images are 2D...if not, throw an appropriate error
if (img1.ImageGetNumDimensions() != 2 || img2.ImageGetNumDimensions() != 2) 			
	Throw("Both input images must be 2-dimensional.")					


// Check the dimension sizes of the input images
// If they are incompatible, throw an error message and halt
number xs1, xs2, ys1, ys2												
img1.Get2dSize( xs1, ys1 )												
img2.Get2dSize( xs2, ys2 )												
if ( xs1 != xs2 || ys1 != ys2 )											
	Throw("Input images are not the same size.")

// Prompt the user to specify  a cutoff threshold; exit if cancel is hit
if ( !GetNumber( "Threshold (discard pixels above this value): ", threshold, threshold ) )	
	exit(0)																

// Determine which is the saturated (highest intensity) and low intensity images 
image hi_img =  ( sum( img1 ) <  sum( img2 ) ) ? img2 : img1			
image lo_img =  ( sum( img1 ) <= sum( img2 ) ) ? img1 : img2			

// Calculate the ratio of intensities in regions below the threshold intensity
number ratio = sum(hi_img*(hi_img < threshold)) / sum(lo_img*(hi_img < threshold))			

// Merge the images; if the intensity in the saturated image is below the threshold, 
// use this pixel divided by the ratio.  Else, use the low intensity pixel.
image merged_img = ( hi_img <= threshold ) && (ratio > 0) ? hi_img/ratio  : lo_img   

// Set the name of the merged image...and display it  
merged_img.SetName("Merged image")										
ShowImage( merged_img )
													
// Finally, post the computed ratio
Result( "Scaling ratio = " + ratio + "\n" )