Image quality loss when importing?

I'm having an issue with importing an image to MatLab.
The image when opened in photos looks like this:
However after running this code:
imagefile = "MRI-brain-tumor-image.png";
I = imread(imagefile);
imshow(I)
The figue from MatLab looks like this:
These are the first lines of code in this script, so I must be using imread or imshow wrong, but looking through their descriptions on mathworks I can't find my error.
Thanks in advance!

2 Comments

Please attach 'MRI-brain-tumor-image.png' with the paperclip icon so we can try it on the original file.

Sign in to comment.

 Accepted Answer

DGM
DGM on 6 Dec 2022
Edited: DGM on 6 Dec 2022
Use the recommended syntax for indexed images.
[inpict map] = imread('MRI-brain-tumor-image.png');
imshow(inpict,map);
The 'colormap' parameter for imshow() is used for displaying grayscale inputs in pseudocolor using a unform quantization. It might sound similar, but the mapping will not generally be correct if you feed it an arbitrarily quantized image.
% create a linear grayscale ramp which does not span
% the full range of its numeric class
w = 150;
graypict = uint8(repmat(0:w-1,[round(w/2) 1]));
% create a smooth colormap of equal length
map = parula(w);
% demonstrate the difference in mapping behaviors
% each map entry corresponds to the unique values in graypict
subplot(2,1,1); imshow(graypict,map);
% each map entry corresponds to a uniform quantization of the interval [0 255]
subplot(2,1,2); imshow(graypict,'colormap',map);
While there appears to be a distinction made in the documentation, it's rather unclear in my opinion.

9 Comments

Why the difference?
fileName = 'MRI-brain-tumor-image.png';
% Read indexed image. It is not grayscale.
[grayImage, cmap] = imread(fileName);
whos grayImage
Name Size Bytes Class Attributes grayImage 370x286 105820 uint8
subplot(1, 2, 1);
imshow(grayImage, cmap);
impixelinfo;
colorbar;
fontSize = 10;
title('In MATLAB Without ColorMap option', 'FontSize', fontSize)
subplot(1, 2, 2);
imshow(grayImage, 'ColorMap', cmap);
impixelinfo;
title('In MATLAB With ColorMap option', 'FontSize', fontSize)
colorbar;
I'm confused as to why passing the colormap in directly (like we used to do it) behaves differently than the new way of using the 'ColorMap' option to imshow. From what I see in the documentation they seem to be equivalent, but clearly they are not for some reason.
That is an odd difference, but thank you for showing this! It's working now.
DGM
DGM on 6 Dec 2022
Edited: DGM on 6 Dec 2022
Everything is happening simultaneously here, but I added an example demonstrating the difference in the behaviors with imshow(). Note that the example uses a smooth colormap. Even large errors in the mapping still allow the image to retain continuity. Since the map in the MRI image is not smooth, any small offset/scaling of the mapping will create gross discontinuities in the rendered image.
@Alexandria Baughman that just fixes the displayed image, not the actual image. I think what you really need to do is what I showed in my comment below
and that is to use ind2gray. This actually changes the image so that you can now do image analysis on it. Simply changing the options to imshow() does not do that. "inpict" will still have indexed values, not gray levels. Do you understand the difference and why I say to use ind2gray() instead? If not, let me know. If so, please click the "Vote" icon for my answer.
I just saw your other comment, I was using im2gray and it wasn't doing anything. I'll switch it over to ind2gray as well.
I agree with IA on this. Working with indexed images can pose obstacles -- even for display-only purposes. While for analysis, converting to a grayscale image is ideal, some display purposes may still require extra measures, as imshow()/image()/imagesc() still internally treat grayscale images as if they are indexed images. Bear that in mind if you intend to display the image with other graphics objects in the same axes.
I have another related question, if you would.
If I input only the file name for "MRI-brain-tumor-image.png" it returns the "correct" input image
imagename = "MRI-brain-tumor-image.png";
[I, map] = imread(imagename);
figure('Name','Input Image')
imshow(I,map);
imagedata = importdata(imagefile);
However, if I use the whole path (including name) it returns the image with the messed up color map.
filepath="C:\Users\Alexa\OneDrive\not college\Documents\Documents\College\MatLab\BME\Proj09";
imagename = "MRI-brain-tumor-image.png";
imagefile = strcat(filepath,'\',imagename);
[I, map] = imread(imagefile);
figure('Name','Input Image')
imshow(I,map);
imagedata = importdata(imagefile);
I would change the code to just use the name, but when I try to load any of the other images with just the name I get a 'File does not exist' error. I've attached the other image I've been using to test my code. (Image_1.png)
One thing to avoid is
imagefile = strcat(filepath,'\',imagename);
instead, use
imagefile = fullfile(filepath,imagename);
That won't be causing any mapping issues though. So long as the different path expressions point to the same file, the output from imread() should be identical. That's something that can be tested.
imagename = "MRI-brain-tumor-image.png";
filepath="C:\Users\Alexa\OneDrive\not college\Documents\Documents\College\MatLab\BME\Proj09";
imagefile = fullfile(filepath,imagename);
[I1, map1] = imread(imagename);
[I2, map2] = imread(imagefile);
% test to see that the two calls return the same data
isequal(I1,I2)
isequal(map1,map2)
My guess is that there's something else happening outside the scope of these two code snippets. Perhaps it's something such as calls to caxis() or colormap() that would upset the mapping of the displayed image.
Regarding this code in DGM's answer:
subplot(2,1,1); imshow(graypict,map);
% each map entry corresponds to a uniform quantization of the interval [0 255]
subplot(2,1,2); imshow(graypict,'colormap',map);
The variable graypict is being used in two different syntaxes:
imshow(X,map)
imshow(I,Name,Value)
The first call to imshow in DGM's code, then, interprets the first argument as X, a matrix of index values, and the values in X are used directly to look up colors from the second argument, map.
In the second call, the first argument is interpreted as I, a matrix containing grayscale values. Years ago, we used to call that an "intensity image" in the doc (hence the variable name "I"), and that term might be helpful here. When imshow displays a grayscale / intensity image, it scales the matrix values linearly to look up the colors in the colormap. The specific scaling depends on the data type of the input matrix. For a uint8 input matrix, the value 0 corresponds to the first colormap color, and the value 255 corresponds to the last colormap color. In this case, the input matrix values only go up to 155, and so the displayed colors come from the lower half (roughly) of the colormap.
Normally, imshow uses a grayscale colormap for the imshow(I) syntax. When you use imshow(I,'Colormap',map), however, imshow uses the colormap you specify. The documentation clue, admittedly subtle, is the sentence, "Use this argument [the Colormap name-value argument] to view grayscale images in false color."
The correspondence between matrix values and displayed colors is fully controlled by the image's CData, CLim, and CDataMapping properties, plus the Colormap property of either the axes or figure object.

Sign in to comment.

More Answers (1)

Good question. The image is an indexed image, not a regular gray scale image. I did this in MATLAB:
fileName = 'MRI-brain-tumor-image.png';
% Read indexed image. It is not grayscale.
[grayImage, cmap] = imread(fileName);
whos grayImage
subplot(1, 2, 1);
imshow(grayImage, []);
impixelinfo;
fontSize = 20;
title('In MATLAB Without colormap', 'FontSize', fontSize)
subplot(1, 2, 2);
imshow(grayImage, 'Colormap', cmap);
impixelinfo;
title('In MATLAB With colormap', 'FontSize', fontSize)
colorbar;
g = gcf;
g.Name = 'Displayed from MATLAB'
I also brought it up in the Windows Picture viewer.
The Picture Viewer is on the left. The middle image above is just displaying the raw image in MATLAB. However if you ask it to return a colormap, you will see there is a colormap stored with the image, which means that the image is an indexed image, therefore the middle image would not be correct since it did not use the colormap while displaying it. The right image is displayed in MATLAB using the stored colormap, which should give the correct looking image, but it doesn't. And I don't know why. What's really weird is that the Windows picture viewer seems to be able to figure out the correct colormap and use it, but I don't know how.
Do you know how these images were made? Many or most medical images are saved in dicom format. Did this image originate in a dicom format? If so I'd recommend you use that dicom file and the dicomread function.

2 Comments

These are images for a project. I've downloaded them from a professor's post, so I don't have access to the original image. I do have other images and they seem to be working fine.
The program is suposed to identify the tumor by finding the large white patch, do you know if there is a workaround for the center of the tumor not loading correctly? I think there is a 'perimiter' variable in regionprops (which we're suposed to use). Could I make a slightly altered code for this image using that function?
I would insist the professor give you the good images. Anyway, you can convert the indexed image into a grayscale image with ind2gray
fileName = 'MRI-brain-tumor-image.png';
% Read indexed image. It is not grayscale.
[grayImage, cmap] = imread(fileName);
% Convert from indexed image into grayscale image.
grayImage = ind2gray(grayImage, cmap);
% Display gray scale image.
imshow(grayImage, []);
impixelinfo;

Sign in to comment.

Categories

Products

Release

R2022b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!