How to avoid image display artifacts in Matlab?
Asked Answered
L

2

7

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).

Lw answered 16/8, 2014 at 18:35 Comment(9)
That's very peculiar. I displayed the same image using imshow and there aren't any edge artifacts that you showed. I'll have a look and will get back to you.Indreetloire
Thanks! I guess it only happens if the image is displayed slightly larger than its native size. It is also conceivable that it is a platform-dependent effect: I'm on Debian Linux (kernel 3.14) with NVidia graphics.Lw
@rayryeng, I added instructions that reproduce the effect on my system.Lw
Awesome. Let me check it out. The crosses at the bottom of the brain in between both lobes is very peculiar indeed.Indreetloire
You're right. Those artifacts are because it is trying to resize the image and place it into the figure. I'm gonna see if there is a way to honour the original size.Indreetloire
OK. I think I have a temporary solution. Try doing axis equal so that the aspect ratio of the image is the same as the original. Let me know if that works. Run this command right after your list of commands in your postIndreetloire
@rayryeng, no that doesn't help. As a matter of fact the artifacts even show up if I simply do image(im), axis equal. If I then resize the figure window manually, the artifacts change, but remain, until the window is much larger. – Just to be sure, you see the same effect on your system, right?Lw
Yes I do, but the crosses are very slight. It could be the resolution of my screen too. I'll try and figure out what's going on, because I'm rather curious myself on how to solve this.Indreetloire
Interesting question! And very clearly expressed. +1Felske
F
7

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

Felske answered 17/8, 2014 at 12:19 Comment(3)
Hello Luis, yes I was afraid it would come to that, but I'd hoped there would be a way to change the built-in interpolation algorithm. I now believe that Matlab uses nearest-neighbor interpolation for image display (fast but sh...) and I am surprised that a) there seems to be no way to change that and b) I never noticed these artifacts before.Lw
I timed imresize with the default interpolation method (which is 'bicubic') and found that for my image sizes and factors it needs about 3 ms per call, so it should be actually feasible to integrate into the GUI program I'm working on. I'll not accept your answer right now in the hope that someone else has another suggestion, but I'm pretty sure that this is the definitive answer. Thank you!Lw
@A.Donda I definitely agree. Let's wait to see if someone comes up with something better. Matlab should be able to handle this in a better way, and not force you to do the interpolation manuallyFelske
D
1

As has been mentioned, MATLAB uses a nearest-neighbor interpolation for both upsampling and downsampling images for display. Because the image window is user-resizeable, the artifacts due to this can change just by moving the window around.

One solution is to write a wrapper class for image display that monitors window events and resizes using imresize to more accurately display the data to the screen. I've written such a class, and it's publicly available. I do image processing work all the time, and MATLAB's inbuilt display system is very irritating. I use this one:

http://www.mathworks.com/matlabcentral/fileexchange/46051-rviewer

It's designed to be a drop-in replacement for image, and will properly resample the images.

Doggerel answered 14/4, 2015 at 16:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.