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

Luis Mendo
  • 110,752
  • 13
  • 76
  • 147
A. Donda
  • 8,381
  • 2
  • 20
  • 49
  • 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. – rayryeng Aug 16 '14 at 18:55
  • 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. – A. Donda Aug 16 '14 at 19:03
  • @rayryeng, I added instructions that reproduce the effect on my system. – A. Donda Aug 16 '14 at 19:16
  • Awesome. Let me check it out. The crosses at the bottom of the brain in between both lobes is very peculiar indeed. – rayryeng Aug 16 '14 at 19:38
  • 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. – rayryeng Aug 16 '14 at 19:46
  • 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 post – rayryeng Aug 16 '14 at 19:47
  • @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? – A. Donda Aug 16 '14 at 23:26
  • 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. – rayryeng Aug 17 '14 at 00:34
  • Interesting question! And very clearly expressed. +1 – Luis Mendo Aug 17 '14 at 12:23

2 Answers2

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

Luis Mendo
  • 110,752
  • 13
  • 76
  • 147
  • 1
    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. – A. Donda Aug 17 '14 at 14:31
  • 1
    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! – A. Donda Aug 17 '14 at 14:31
  • @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 manually – Luis Mendo Aug 17 '14 at 14:52
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.

Tony
  • 949
  • 5
  • 20