Single channel png displayed with colors - matlab

I'm checking out the ground truth segmentation masks of the pascal voc 2012 dataset. These are single channel 8-bit uint png files. However when I open these images in either the file browser (nautilus) or the image viewer (eog) they are displayed in colors.
Shouldn't it be displayed in grayscale?
When I store an image as single channel 8-bit uint png file using Matlab, it is displayed in grayscale as expected. What is the difference are there different types of png files?
How can I store it such that my image viewer displays them in colors?
This is the original single channel png:
This is the result after imread and imwrite. Note that NO channel has been added / removed:

Your image files contain indexed images, with an M-by-N index matrix and a P-by-3 colormap matrix. How can you tell? You need to get the second output from imread when loading your images:
[img, cmap] = imread('zuIra.png');
if isempty(cmap)
% Process data as a grayscale or RGB image
else
% Process data as an indexed image
end
If cmap is empty, your data is either an M-by-N grayscale intensity image or an M-by-N-by-3 Truecolor RGB image. Otherwise, you're dealing with an indexed color image, and will have to use both pieces of data in any processing of your image, such as viewing it with imshow:
imshow(img, cmap);
Or when resaving the data with imwrite:
imwrite(img, cmap, 'outfile.png');
If you would rather deal with a single image data matrix (which can make processing easier in some cases), you can convert the indexed image data and associated colormap into an RGB image with ind2rgb:
imgRGB = ind2rgb(img, cmap);

You are dealing with an 1 to 8 bits (variable) per pixel PNG with indexed colors.
When a format uses this technique, color information is not directly stored into the the image pixel data, but in a separate piece of data called palette. A palette can be defined as a predefined array of colors in which each element defines the trichromatic representation (RGB) of a specific color (8 bits per channel, for a total of 24 bits).
The image pixel data does not contain the full specification of a color in the RGB form, but only the indices to the palette colors. Of course, the palette must contain one entry for each pixel color present in the image.
This approach can be seen as a form of compression, in which only a limited set of colors is available in order to save up memory/storage and speed up the display of the image.
Long story short, the result of your imread call is not returning you the color information of the image. Your array contains the indices to the PNG palette elements.
Example
Let's say that you have n indexed PNG that has a width of 3 pixels and a height of 1 pixel. The first pixel is pure red, the second pixel is pure green and the third pixel is pure blue.
In the PNG binary data, the PLTE chunk will contain the following color definitions:
[255 0 0] % Pure Red
[0 255 0] % Pure Green
[0 0 255] % Pure Blue
and the IHDR chunk will define a single channel with the following data:
0 1 2
% 0 = index to the first palette color, pure red
% 1 = index to the second palette color, pure green
% 2 = index to the third palette color, pure blue

Related

Create a Gray level Mask using Matlab and write the same as a gray level image.

I am producing a gray level pattern to be loaded on my SLM (Spatial Light Modulator). The pattern is 1920x1080 pixels. I have 255 gray level values. I tried out this code to create a gray level mask . when I open in Matlab I could see it as gray level, but when I write the image as a bmp file and then it becomes a binary file. How can I resolve this. Following is my code.
clear all
close all
mask=zeros(1080,1920);
% imshow(mask,[])
for k=1:500
for i=1:1080
mask(i,k)=randperm(256,1);
end
end
% mask3=Fit_GrayLevel_To_SLM_Vector(mask);
imshow(mask,[])
imwrite(mask,'mymask4.bmp')
imshow does not make the same assumption as imwrite on the input image dynamic. More precisely, from the doc of imwrite:
If A is a grayscale or RGB color image of data type double or single, then imwrite assumes that the dynamic range is [0,1] and automatically scales the data by 255 before writing it to the file as 8-bit values
So store your data either in a uint8 array, or divide the pixel value by 255 before writing the file.

How to know the depth value of 24bit depth images in matlab

I am trying to deal with 24bit depth images from NYU Hand dataset in MATLAB.
When i tried to read images as below in MATLAB
img = imread('synthdepth_1_0006969.png');
the form of the variable( img) is 480x640x3 uint8.
My question is, in this case, how do i know the depth value from that?
When I read 8bit or 16bit images in MATLAB, each pixel show the depth value. But
in 24bit case, I don't know how to deal with it...
Thank you for reading my question.
Notice that the image data is 3 dimensional, with the third dimension having a size of 3. That third dimension encodes the red, green, and blue color planes in a Truecolor image. Three uint8 (i.e. unsigned 8-bit integer) color values equates to 24 bits of total color information per pixel.

what is map and level in im2bw in matlab?

I want to convert RGB image to binary image for processing in matlab ,
its important to choose variables exactly,
so I need to know exacly what is map and level in im2bw(x,map,level) ?
Map is used only when the image is of map datatype. Essentially map is a format of storing images where each pixel is represented by a number. The numbers are stored in a lookup table called map. The map images are often more compressible than regular images. When the image has to be displayed, the value of pixel is displayed based on the lookup table.
In this case, im2bw just looks at the greyscale value of each pixel and then thresholds.
The level is the greythresh of the image [0-1]. It can be used to change the luminescence of the image.
The map is a colormap. Here is the information from mathworks:
"A colormap is an m-by-3 matrix of real numbers between 0.0 and 1.0. Each row is an RGB vector that defines one color. The kth row of the colormap defines the kth color, where map(k,:) = [r(k) g(k) b(k)]) specifies the intensity of red, green, and blue."
The colormap can be used to change the image's colors.
http://www.mathworks.com/help/images/ref/im2bw.html
http://www.mathworks.com/help/matlab/ref/colormap.html

Obtaining the pixel values of gray scale image from a binary image

I do binary thresholding on a 16 bit gray scale image.This would help me in segmenting the region of interest.After binary thresholding,i would like to get the individual pixel intensities which are the intensities of the original 16 bit image and not the binary intensity values say 0,65535...
How can i do this?
Find the region of interest in image segmentation using the binary image. After this, use the pixel locations in the 16 bit image for further processing of the image.
To get a image from your original image, I and a binary (logical) segmented image BW:
I2 = I.*BW;
I2 should have the original values in the ROI and 0 elsewhere. Or, to get just a list of pixels and their values, via logical indexing:
I2 = I(BW);
Alternatively, depending on what you're doing, you may want to use regionprops:
stats = regionprops(BW,I,'MeanIntensity','PixelValues');
For a BW image showing the regions of interest, and a greyscale image I this will return the mean intensity and all list of all pixel values in I for each separate region (defined as a connected areas in BW).

matlab rgb values dilemma

When i wrote these commands
out = ones(size(ben))
imshow(out)
the output is a white picture but i expect almost dark picture because the rgb values are 1,1,1. when i give 255,255,255 it also gives a white picture. Isn't this a dilemma ?
Try out = ones(size(ben), 'uint8');
ones() by default creates an array of doubles. When imshow() gets an array of doubles it assumes that the pixel values range between 0 and 1, and assigns the white color to anything greater than 1. However, if you pass an array of uint8 to imshow() it will assume the range to be between 0 and 255.
You can also try using imagesc(); instead of imshow(), but you may need to do colormap gray after wards to get a grayscale image.
Another alternative is to rescale the image before display:
imshow(out / max(out(:)));