Search code examples
image-processingfilteringdm-script

How to apply a Hanning window without changing calibration scale of an image in Digital Micrograph?


I want to apply a Hanning window to an image before I process 'FFT'. I found a script written by Ruben Bjorge:

number size, sizeX, sizeY, top, left, bottom, right, ii, posX, posY  
image front, hannX, hannY, hann, avg, hannout

front := GetFrontImage();
GetSize(front, sizeX, sizeY);
GetSelection(front, top, left, bottom, right);      

// Create Hanning window.
ii = 1;
hannX := CreateFloatImage("", (right-left), (bottom-top));
hannX = 0;
hannX[0, 0, 1, (right-left)] = 1 - cos( 2 * Pi() * icol / (right-left));
while( ii < (bottom-top) )
{
hannX[ii, 0, 2*ii, (right-left)] = hannX[0, 0, ii, (right-left)];
ii = ii * 2;
}

ii = 1;
hannY := CreateFloatImage("", (right-left), (bottom-top));
hannY = 0;
hannY[0, 0, (bottom-top), 1] = 1 - cos( 2 * Pi() * irow / (bottom-top));
while( ii < (right-left) )
{
hannY[0, ii, (bottom-top), 2*ii] = hannY[0, 0, (bottom-top), ii];
ii = ii * 2;
}

hann = hannX * hannY;

// Subtract average from image.
avg = front - Average(front);

// Multiply with Hanning window.
hannout = avg[top, left, bottom, right] * hann;

// Do fast Fourier transform and display image.
fft = RealFFT(hannout);

By using this script, the calibration scale of the FFT is changed to 1. But it should be 0.11948, as all shown in the pictures below.

enter image description here enter image description here

My question are: Is there a way to apply hanning window without changing the calibration scale of image?

Or how to calculate the scale of the FFT image in terms of the scale of original image?

Since the rest part of my script needs the correct scale of the fft image, I'll appreciate that if anyone could answer this long question. Thanks.


Solution

  • The key to preserving calibration info in DM image expressions is to work with image references and in-place operations on clones of image objects as much as possible. Your example script becomes much simpler and more efficient when you transform it to use such techniques, as follows:

    Image frontImage := GetFrontImage();
    
    // Step 1 - extract and get info about the front image selection
    Image frontSelection := frontImage[];
    Number selW = ImageGetDimensionSize(frontSelection, 0);
    Number selH = ImageGetDimensionSize(frontSelection, 1);
    
    // Step 2 - subtract average value from selection and apply Hanning window
    Image filteredSelection := ImageClone(frontSelection);
    filteredSelection -= Average(frontSelection);
    filteredSelection *= (1 - cos(2 * Pi() * icol / selW));
    filteredSelection *= (1 - cos(2 * Pi() * irow / selH));
    String selectionName = ImageGetName(frontImage) + " filtered selection";
    ImageSetName(filteredSelection, selectionName);
    
    // Step 3 - take FFT of filtered selection and display result
    Image filteredFFT := RealFFT(filteredSelection);
    ShowImage(filteredFFT);
    

    The main differences here are in the two sections marked Step 1 and Step 2.

    In Step 1, this script directly accesses the front image selection by using the selection operator, '[ ]'. This operator preserves the calibration (and tag) info of the original image.

    In Step 2, the ImageClone function makes a complete copy of the selection's image object, including its calibration (and tag) data. The next three lines do the mathematical processing in place, directly on the cloned selection. Note, in particular, that the Hanning window factors are applied very simply with a single image expression that is automatically applied to all the pixels of the result image. There is no need for the while loops used in the example script. In addition to adding code complexity, these are significantly slower than the implied looping done by the one-line image expressions. In fact, the Hanning window can be applied in a single line that includes both the x- and y-dependent factors, as follows:

    filteredSelection *= (1-cos(2*Pi() * icol/selW)) * (1-cos(2*Pi() * irow/selH));