// Script to remove horizontal striping in images due to Cold FEG fluctuations. These are 
// frequently found in SEM/STEM images acquired on cold FEG systems.

// This script works by averaging the image intensity in each row. This is then propagated to
// fill an image the same size as the original, which is then divided into the original
// The resulting image shows marked reduction in FEG-induced banding.

// The script will work fine provided the image is of relatively flat intensity - eg a high 
// a resolution image - where the average intensity in each row is similar. However, if there
// are regions with large variations in intensity- eg coarse particles (dark), or large 
// voids (bright) then averaging across the whole image width will not work. This can be overcome 
// by having a tall, narrow rectangular region of interest present. In practice this will need to
// span the full height of the image. However, it can be difficult to draw such ROIs. Simply
// draw the ROI on the image to define the appropriate column to use (see below). The script will
// then automatically extend the ROI to the top and the bottom limits of the image. 

// Choose a vertical column in the image which excludes regions where the contrast changes.
// This could be down the edge of an image with a large centred particle - the vertical
// stripe should cover only the carbon support film (uniform intensity region). Make the column
// as wide as possible, consistent with not including regions of large intensity variation.

// The script will not change the original image, but creates a destriped version of the original
// with '(destriped)' added to the title.


// Based on an idea by William Costello.

// D. R. G. Mitchell, adminnospam@dmscripting.com (remove the nospam to make this address work)
// version:20201029, v3.0, October 2020, www.dmscripting.com


// Variables

Image front, meanprofile, outputimg, divideimg
Number width, height, x, meanval
String imgname


// Check that an image is displayed

number nodocs=countdocumentwindowsoftype(5)
if(nodocs<1)
	{
		showalert("Ensure an image exhibiting horizontal striping (due to FEG fluctations) is shown front-most.",2)
		exit(0)
	}


// Source the front image and some info

front:=getfrontimage()
GetSize(front, width, height)
getname(front, imgname)


// Check if an ROI is present

imagedisplay frontdisp=front.imagegetimagedisplay(0)
number norois=frontdisp.imagedisplaycountrois()
number top, left, bottom, right


if(norois==0) // no roi - use the full image
	{
		//Create an intensity profile image to store the variation in the average intensity in each row of the image
		// ie this is the fluctuation of the average intensity along the y axis of the image

		meanprofile = realimage("", 4, height, 1);
		meanprofile = 0
		meanprofile[irow,0] += front



		// normalise the profile by dividing by the mean of the image multiplied by width - remember collapsing the width dimension
		// so that each pixel in the vertical column of values is the sum of all the corresponding pixels in that row

		meanval = mean(front)
		meanprofile = meanprofile / (meanval*width)
	}
else // there is an ROI on the image so use the ROI for averaging
	{
		roi thisroi=frontdisp.imagedisplaygetroi(0)
		thisroi.roigetrectangle(top, left, bottom, right)
		
		
		// Set the ROI top and bottom to the top and bottom of the image respectively.
		
		top=0
		bottom=height
		thisroi.roisetrectangle(top, left, bottom, right)

		meanprofile = realimage("", 4, height, 1);
		meanprofile = 0
		number top=0
		meanprofile[irow,0] += front[top, left, bottom, right]
	}


// create the processing image (divideimg) in which the mean profile is propaged across the width of the image

divideimg=front.imageclone()
divideimg =0
divideimg=divideimg[icol,irow]+meanprofile[irow,icol]


// divide the original image by the divide image to remove the feg fluctuation

outputimg=front/divideimg


// output the result and copy the calibration and taggroups from the source to the destripedimage

showimage(outputimg)
setname(outputimg, imgname+" (destriped)")
imagecopycalibrationfrom(outputimg, front)
taggroup originaltags=front.imagegettaggroup()
taggroup destripedtags=outputimg.imagegettaggroup()
taggroupcopytagsfrom(destripedtags, originaltags)

imagedisplay outputdisp=outputimg.imagegetimagedisplay(0)
outputdisp.applydatabar()



