Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid image display artifacts in Matlab?

When I display a bitmap image using image in a Matlab figure window, I'm experiencing strange artifacts:

What I'm referring to are the cross-shaped structures which are particularly visible at the edges of the brain slice, but present throughout.

These structures are not in the underlying image data, which are exactly identical to those in this image:

enter image description here

I assume the artifacts have to do with the slight rescaling that is necessary to match the image to the given axes size.

Does someone have an idea how to avoid these artifacts? I tried changing the figure 'Renderer', which does indeed affect the artifact, but does not let it vanish.


How to reproduce the effect:

  1. save the second image as "image.png"

  2. execute:

    im = imread('image.png');
    image(im)
    set(gca, 'Units', 'pixels')
    set(gca, 'Position', [76.1094204520027 576.387782501678 343.969568136048 357.502797046319])
    
  3. maximize the figure window, so that the axes with the image becomes visible

Native image dimensions are 306 x 318, but it is displayed at about 344 x 358 pixels.


I did some further experiments and found that the effect is not specific to this image, the particular positioning, or the colormap:

[x, y] = meshgrid(-1:0.01:1);
imagesc(cos(10*sqrt(x.^2 + y.^2)))

giving

for a specific size of the figure window shows the same kind of artifacts.

It would be interesting to know whether the artefact is specific to my Matlab version (2013a) or platform (Debian Linux, kernel 3.14 with NVidia graphics).

like image 429
A. Donda Avatar asked Aug 16 '14 18:08

A. Donda


1 Answers

It looks to me as if the artifacts are caused by Matlab interpolating to translate picture pixels into screen pixels.

It would be nice to be able to change the interpolation method used by Matlab when displaying the image, but that doesn't seem to be possible (changing 'renderer' doesn't help). So you could manually interpolate the image to match the display size, and then display that interpolated image, for which one image pixel now corresponds to one screen pixel. That way Matlab doesn't have to interpolate.

To do the interpolation I've used the imresize function. I find all available interpolation methods give more or less the same results, except 'box', which is even worse than Matlab's automatic screen interpolation. I attach some results:

  • First picture is obtained with your approach. You can see artifacts in its left and right edges, and in the lower inner diagonal edges. Code:

    m = 344;
    n = 358;
    image(im)
    set(gca, 'units', 'pixels', 'Position', [40 40 m n])
    
  • Second picture applies manual interpolation with imresize using 'box' option. The artifacts are similar, or even more pronounced.

    imr = imresize(double(im)/255, [m n], 'box'); %// convert to double and 
    %// interpolate to size [m, n]
    image(imr/max(imr(:))) %// display with image size matching display size.
    %// Normalization is required because the interpolation may give values
    %// out of the interval [0 1]
    set(gca, 'units', 'pixels', 'Position', [40 40 m n])
    
  • Third figure is as the second but with 'bilinear' option. The artifacts are very attenuated, although still visible in some parts. Other interpolation methods give similar results.

enter image description here

enter image description here

enter image description here

like image 99
Luis Mendo Avatar answered Sep 30 '22 20:09

Luis Mendo