Noisy images not displayed correctly in Fiji

Hello everyone,
I noticed some strange behaviour when viewing noisy images with Fiji.
I was able to reproduce the issue on a second machine as well using simulated noise.

The image below was produced by creating a new empty image (single channel 16bit, 3838x3710px) and then applying noise (“add specified noise” with std 250)
Eventhough the noise is i.i.d., when I zoom out I see a grid pattern with four maxima:
noise
The pattern looks different when I use a different image size.

Thanks for the help!

1 Like

I’m thinking this might be a strange optical illusion/visualisation artifact. I’ve just done the same thing you did and had the same impression, but then I plotted the profile of a line drawn diagonally through the image:

Plot%20of%20Untitled

I’m not sure if I see anything untoward there. To double-check, I’ve tried fitting a high-order polynomial to the profile and got what was essentially a horizontal line, with any other coefficient being very small. It’s a strange one!

1 Like

I agree at displaying a noisy image at 100% there is no grid visible.
I guess it is an interpolation artifact when displaying the image at less than 100%.

I opend the screenshot from above in Fiji and looked at the histograms in the center and at one of the maxima. I do not think this is an optical illusion. I think it is a display problem involving the zoom, like schmiedc suggested.
gridHist2
gridHist1

Hello Alexander -

The effect you see is not narrowly caused by noise, and it is
not narrowly caused by display the image.

As Christopher mentioned, it is, in a sense, an artifact of
interpolation.

I would describe it as a moire pattern produced by the details of
ShortProcessor's resize() / getInterpolatedPixel()
methods interacting with the structure of the image.

Here is a (no noise) java PlugIn that illustrates this:

import ij.*;
import ij.plugin.PlugIn;
import ij.process.ImageProcessor;
import ij.process.ShortProcessor;

// illustrate moire pattern from resizing interpolation
public class My_Plugin implements PlugIn {
  public void run(String arg) {

    int hw = 4096;                        // linear size of (square) image
    int[] hws = { 512, 513, 514, 515 };   // linear sizes of scaled images
    
    ImagePlus imp = IJ.createImage ("moire: checkerboard", "16-bit black", hw, hw, 1);
    ShortProcessor ip = (ShortProcessor) imp.getProcessor();

    // checkerboard initialize
    int mid = 32768;
    int dif = 8192;
    int xsgn = 1;
    for (int x = 0; x < hw; x++) {
	int ysgn = 1;
	for (int y = 0; y < hw; y++) {
	    ip.putPixel (x, y, mid + xsgn * ysgn * dif);
	    ysgn *= -1;
	}
	xsgn *= -1;
    }
    imp.show();

    // resize to various sizes
    ip.setInterpolationMethod (ImageProcessor.BILINEAR);
    ShortProcessor ips[] = new ShortProcessor[hws.length];
    ImagePlus imps[] = new ImagePlus[hws.length];
    for (int i = 0; i < hws.length; i++) {
      ips[i] = (ShortProcessor) ip.resize (hws[i], hws[i]);
      imps[i] = new ImagePlus ("moire: scaled -- " + hws[i], ips[i]);
      imps[i].show();
    }
    
  }
}

And here are the images this PlugIn generates:

4096x4096 checkerboard:

512x512 resized:

513x513 resized

514x514 resized:

515x515 resized:

The original image is a checkerboard where the grayscale
alternates between two values from pixel to pixel.

The next image is the checkerboard downscaled by an
exact factor of eight to 512x512. In this case there is no
moire pattern (or, if you will, the length scale of the moire
pattern goes off to infinity).

The following three images are the original image downscaled
by successively smaller factors slightly less than eight. They
show moire patterns of (as is to be expected) decreasing
length scales.

So when you zoom out of an image (or Fiji zooms out for you
to fit the image on your screen), resize() (or some near
equivalent) is called, potentially producing this sort of moire
pattern. It’s less obvious in the “noise” image, but the regular
pixel structure of the noise is enough to produce one.

Thanks, mm