What is the size of indexed image of 512*512 with 256 color values? - pixel

If I have an image of resolutin of 512 * 512,
and this image is indexed with 256 color values,
how to calulate the size of the image (file size ) ?

The image itself can be calculate as follow
256 can be stored in one byte. So one pixel is 1 byte.
You have a 512*512 pixels.
512*512*1 = 262144 But on your disk, it will take a little more than those 262ko, as you have to count the bytes used for the file meta-information, and the color palette.
Check out the bmp header spec if you need more informations.

Related

8-bit color image matrix representation

I have just started learning image processing by myself, and I am using MATLAB. I have been getting myself familiarized with basic image operations. When I read the below image(res: 225x300), which is supposed to be an 8-bit color image, I expected the resultant matrix to have 3 dimensions with one each for RGB. A simple web search about 8-bit color image led me to Wikipedia with the following information:
The simplest form of quantization frequently called 8-bit truecolor is to simply assign 3 bits to red, 3 to green and 2 to blue (the human eye is less sensitive to blue light) to create a 3-3-2.
Therefore, I expected the image matrix to have 225x300x3 dimensions with the above distribution of bits b/w RGB. But after I checked the dimensions of the matrix of the image, I found it to be 225x300 unit8, which is what one expects from an 8-bit grayscale image. But the image is a color image, as seen by any image viewer. So what is that I lack in knowledge or doing wrong? Is the problem with how I read the image?
Also, it occurred to me that uint8 is the smallest unsigned integer class. So how can we have colored images of 4,8,10, etc., bits represented and created?
My code:
>> I_8bit = imread('input_images\8_bit.png');
>> size(I_8bit)
ans =
225 300
>> class(I_8bit)
ans =
'uint8'
>> I_24bit = imread('input_images\24_bit.png');
>> size(I_24bit)
ans =
225 300 3
>> class(I_24bit)
ans =
'uint8'
(source: https://en.wikipedia.org/wiki/Color_depth#/media/File:8_bit.png)
Matlab supports several types of images, including
RGB images, which allow arbitrary colors, stored in terms of R,G,B components. The image is defined by a 3D m×n×3 array
Indexed images, in which each pixel is defined by an index to a colormap. The image is defined by a 2D m×n array and a c×3 colormap, where c si the number of colors.
It looks like the image you are loading is indexed. So you need the two-output version of imread to get the 2D array and the colormap:
[I_8bit, cmap] = imread('input_images\8_bit.png');
To display the image you need to specify the 2D array and the colormap:
imshow(I_8bit, cmap)
You can see the effect of changing the colormap, for example
cmap_wrong = copper(size(cmap, 1)); % different colormap with the same size
imshow(I_8bit, cmap_wrong)
To convert to an RGB image, use ind2rgb:
I_8bit_RGB = ind2rgb(I_8bit, cmap);
which then you can display as
imshow(I_8bit_RGB)

What is the size of ppvBits returned by CreateDIBSection?

I am trying to capture the screen. I call CreateDIBSection using a BITMAPINFO initialized with the screen dimensions, number of planes = 1, bpp = 32, mode = rgb. It then returns me a pointer to the bitmap data in ppvBits. But how do I determine how many bytes are in this buffer? It doesn't fill out the biSizeImage for me. Should I be computing it from the bpp and dimensions? Something like width * height * (bpp/8)?
The docs for BITMAPINFOHEADER explain how to calculate the "stride" - that is the number of bytes from one row to the next.
For uncompressed RGB formats, the minimum stride is always the image
width in bytes, rounded up to the nearest DWORD. You can use the
following formula to calculate the stride:
stride = ((((biWidth * biBitCount) + 31) & ~31) >> 3)
To calculate the total number of bytes required for a bitmap you multiply the stride by the number of rows.
Note the requirement for bitmap rows to be DWORD-aligned - this is why the stride calculation is rounded up.

Write image with more than 256 labels

I have a 2-D labelled matrix that comes from bwlabel, but it could have labels with indices greater than 4000. It is simple to show via imshow with more than 256 colours:
img = zeros(1000, 1000);
%Put 4000 seeds
for numCentroid = 1:4000
x = randi([1 size(img, 1)]);
y = randi([1 size(img, 2)]);
img(x, y) = 1;
end
D = bwdist(img);
% Create the 'cell' regions
L_img = watershed(D); % We obtain a labelled image
imshow(L_img, repmat(colorcube(256), 20, 1));
However, when we do the same, but with imwrite:
imwrite(L_img, repmat(colorcube(256), 20, 1), 'p.tif');
And obtain this error:
Error using wtifc
Invalid colormap for 8 bit image, must have dimensions n X 3 (n<=256).
It is also reproducible with other formats such as png:
imwrite(uint16(randi([0 4000], 200)), colorcube(4001), 'p.png')
Error using writepng (line 76)
Invalid bitdepth for indexed image; must be 1, 2, 4, or 8.
Here's an example of the image we want to save:
What we want is to obtain an indexed image with each separated region labelled. How can we save this image?
Since we know it is a problem of the imwrite itself because it transforms the double matrix into uint8, we tried to put the same matrix as uint16. This is not working either.
Edit 1:
Showing the bit depth of the image in Matlab is the correct 16 bits.
imfinfo('p.tif')
However, if you check the same thing, but in Windows: right click on the file -> Properties -> Details, it has 8-bit depth. This correlates with:
help imwrite
Allowed Values for BitDepth of TIFF files Grayscale images: 1, 2, 4, 8, or 16
Grayscale images with an alpha channel: 8 or 16
Indexed images: 1, 2, 4, or 8
Truecolor images: 8 or 16
As Adriaan pointed out in his answer, you can write 16-bit TIFF files. If the file needs to be indexed (i.e. have a separate color map), and have 16-bit indices, then TIFF is the only standard file format I know of that will do the job.
Given the 16-bit index image, and a 4001-element color map:
data = uint16(randi([0 4000], 200));
cm = colorcube(4001);
then:
imwrite(data,cm,'p.tif')
will write this correctly to file:
cris#paella> tiffinfo p.tif
TIFF Directory at offset 0x13ba0 (80800)
Image Width: 200 Image Length: 200
Resolution: 72, 72 pixels/inch
Bits/Sample: 16
Compression Scheme: PackBits
Photometric Interpretation: palette color (RGB from colormap)
Orientation: row 0 top, col 0 lhs
Samples/Pixel: 1
Rows/Strip: 40
Planar Configuration: single image plane
Color Map: (present)
(tiffinfo is a program that comes with LibTIFF, and is often installed by default on Unix distros, I have installed LibTIFF on my Mac using Homebrew).
Note the "Bits/Sample: 16" line, and "Photometric Interpretation: palette color (RGB from colormap)". This TIFF file now has a color map with 65536 entries.
We can read the file back too:
[data2,cm2] = imread('p.tif');
isequal(data,data2) returns true, and class(data2) returns 'uint16'. cm2 is not the same as cm, as it contains many more entries (which are all 0). But cm2(1:4001,:) and cm are nearly identical, the differences come from cm being floating-point values, which were multiplied by 65535 and rounded for saving to the file.
The problem, as I expressed in comments underneath Adriaan's answer, is that most software will not read 16-bit indexed TIFF files. For example, Photoshop Elements will not open the p.tif file we created here, nor will Apple's Preview program. The reason is that Baseline TIFF (the lowest-common denominator standard that all TIFF readers must comply with) specifies only 4-bit and 8-bit indexed images. 16-bit indexed images is an extension.
Thus, if you want to save a 16-bit indexed image, first make sure that the target software will be able to read it.
According to the documentation, inputting a uint16 file writes a uint16 file, provided the file format supports that:
If A is of data type uint16 and the output file format supports 16-bit data (JPEG, PNG, and TIFF), then imwrite outputs 16-bit values. If the output file format does not support 16-bit data, then imwrite returns an error.
From the documentation on imwrite
img = rand(1e3);
L_img = bwlabel(img);
imshow(L_img, repmat(colorcube(256), 20, 1));
Warning: Image is too big to fit on screen; displaying at 67%
> In images.internal.initSize (line 71)
In imshow (line 305)
imwrite(L_img, repmat(colorcube(256), 20, 1), 'p.tif');
Error using wtifc
Invalid colormap for 8 bit image, must have dimensions n X 3 (n<=256).
Error in writetif (line 118)
wtifc(data, map, filename, writemode, colorspace, required_tags);
Error in imwrite (line 472)
feval(fmt_s.write, data, map, filename, paramPairs{:});
tmp = uint16(L_img);
imwrite(tmp, repmat(colorcube(256), 20, 1), 'p.tif'); %Writes the file to my disk

Image processing storage of image

I am unable to understand the following question, could any one explain me what exactly is it asking?
Suppose that an image of dimension 5*6 inches has detail to the
frequency of 600 dots per inch in each direction. How many samples are
required to preserve the information in the image? if the dynamic
range of the pixel values is between 0 and 200, how many megabytes do
we need to store the whole image without compression?
I tried to solve this way, but just first part I did I do not know this is correct or not:
5*6*600 = 18000
I think 18000 are total no of pixels required to preserve the information of image
but do not know this is correct or not but how to find megabytes for storage?
Well, it's 600 dpi in both the horizontal and the vertical.
Next you have to consider the bit depth. Looks like 200 values - I'm going to assume that's per channel. So 3 bytes per pixel.
( 5 * 600 ) * ( 6 * 600 ) = 10,800,000 pixels
10,800,000 * 3 = 32,400,000 bytes
32,400,000 / 1024 = 31,640.625 kilobytes
31,640.625 / 1024 = 30.899047852 megabytes

MATLAB imresize increases image size on disc on downscaling to half

I was trying to downscale a .png image using imresize by 0.5 which was originally 25 kB. However, on saving the scaled image using imwrite, the size of the saved image becomes 52 kB.
The following is the image and the commands:
image=imread('image0001.png');
B = imresize(image, 0.5);
imwrite(B,'img0001.png','png');
This also happens if the resolution is specified as follows:
B = imresize(image, [400 300]);
What is the reason for this? It seems to work fine when scaled to 0.15.
The reason is that imresize uses bicubic interpolation, thus producing additional pixel values. Your original image is small since it has small number of unique pixel values. After interpolation the number will increase, thus increasing the file size.
To preserve the number of unique values you can use: B = imresize(image, 0.5, 'nearest');. You can check it as follows:
image=imread('image0001.png');
B = imresize(image, 0.5);
numel(unique(image)); % gives 18
numel(unique(B)); % gives 256
with new interpolation:
image=imread('image0001.png');
B = imresize(image, 0.5, 'nearest');
numel(unique(image)); % gives 18
numel(unique(B)); % gives 18
Saving B now should produce smaller size.

Resources