Convert grayscale uint8 image to RGB uint8 image - matlab

I have a code to run, which uses an original image and a mask image. The code assumes that the original image is RGB, but my original image is gray scale. This must be the result of the MATLAB whos command when I run the code:
Name Size Bytes Class Attributes
mask 308x206 63448 logical
origImg 308x206x3 190344 uint8
The mask is produced by making part of the image white and the rest is black (in a simple software like windows paint).
I want to use a gray-scale image as the origImg and produce the mask from the origImg in windows paint, but the result of the MATLAB whos command is as follows when I want to use custom photos with attributes as I said:
Name Size Bytes Class Attributes
mask 490x640x3 940800 uint8
origImg 490x640 313600 uint8
I have to convert the origImage dimension to x3 and remove the x3 from the mask, and also convert its class from unit8 to logical. In that case, I think that the code should work properly.
What should I do here in order to prepare the origImg and mask for that goal?
origImg=imread('G:\the_path\to\my_custom\image.png');
mask=imread('G:\the_path\to\my_custom\image_mask.png');
% I have to do something here to make it work.
whos;
% Rest of the code...

I am not sure if I understand you correctly.
To make a RGB image out of a gray-scale image, which still shows up as a gray-scale image, you can use
origImg = repmat(origImg,1,1,3);
which just repeats your gray-scale image for every channel of the RGB image.
For the mask, you have to do the opposite. since I don't know your image_mask.png file, I assume that it is a RGB image that uses only black and white. In this case, all three channels are the same and you could simply use one of them for the mask, doesn't matter which one:
mask = mask(:,:,1);
To convert it to logical, use
mask=logical(mask);

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 create an inverse gray scale?

I have an image with dark blue spots on a black background. I want to convert this to inverse gray scale. By inverse, I mean, I want the black ground to be white.
When I convert it to gray scale, it makes everything look black and it makes it very hard to differentiate.
Is there a way to do an inverse gray scale where the black background takes the lighter shades?
Or, another preferable option is to represent the blue as white and the black as black.
I am using img = rgb2gray(img); in MATLAB for now.
From mathworks site:
IM2 = imcomplement(IM)
Is there a way to do an inverse gray scale where the black
background takes the lighter shades?
Based on your image description I created an image sample.png:
img1 = imread('sample.png'); % Read rgb image from graphics file.
imshow(img1); % Display image.
Then, I used the imcomplement function to obtain the complement of the original image (as suggested in this answer).
img2 = imcomplement(img1); % Complement image.
imshow(img2); % Display image.
This is the result:
Or, another preferable option is to represent the blue as white and
the black as black.
In this case, the simplest option is to work with the blue channel. Now, depending on your needs, there are two approaches you can use:
Approach 1: Convert the blue channel to a binary image (B&W)
This comment suggests using the logical operation img(:,:,3) > 0, which will return a binary array of the blue channel, where every non-zero valued pixel will be mapped to 1 (white), and the rest of pixels will have a value of 0 (black).
While this approach is simple and valid, binary images have the big disadvantage of loosing intensity information. This can alter the perceptual properties of your image. Have a look at the code:
img3 = img1(:, :, 3) > 0; % Convert blue channel to binary image.
imshow(img3); % Display image.
This is the result:
Notice that the round shaped spots in the original image have become octagon shaped in the binary image, due to the loss of intensity information.
Approach 2: Convert the blue channel to grayscale image
A better approach is to use a grayscale image, because the intensity information is preserved.
The imshow function offers the imshow(I,[low high]) overload, which adjusts the color axis scaling of the grayscale image through the DisplayRange parameter.
One very cool feature of this overload, is that we can let imshow do the work for us.
From the documentation:
If you specify an empty matrix ([]), imshow uses [min(I(:)) max(I(:))]. In other words, use the minimum value in I as black, and the maximum value as white.
Have a look at the code:
img4 = img1(:, :, 3); % Extract blue channel.
imshow(img4, []); % Display image.
This is the result:
Notice that the round shape of the spots is preserved exactly as in the original image.

imshow() displays a white image for a grey image

I have computed an image with values between 0 and 255. When I use imageview(), the image is correctly displayed, in grey levels, but when I want to save this image or display it with imshow, I have a white image, or sometimes some black pixels here and there:
Whereas with imageview():
Can some one help me?
I think that you should use imshow(uint8(image)); on the image before displaying it.
Matlab expects images of type double to be in the 0..1 range and images that are uint8 in the 0..255 range. You can convert the range yourself (but change values in the process), do an explicit cast (and potentially loose precision) or instruct Matlab to use the minimum and maximum value found in the image matrix as the white and black value to scale to when visualising.
See the following example with an uint8 image present in Matlab:
im = imread('moon.tif');
figure; imshow(im);
figure; imshow(double(im));
figure; imshow(double(im), []);
figure; imshow(im2double(im));

Sobel filter is working on the original i/p image but not on the copy of it

I want to apply Sobel and other filter at an image but i can see the results of filter only if i use the filters at original input image. But if i implement the filter at a copy of inout image then nothing happens and just a white output image appears.
In the following code i am implementing the filter at original inputImage but i want to get results by implementing it at copyImage.
inputImage=imread('tex.png');
copyImage=double(inputImage);
for i=1:size(C,1)-2
for j=1:size(C,2)-2
%Sobel mask for x-direction:
Gx=((2*C(i+2,j+1)+C(i+2,j)+C(i+2,j+2))-(2*C(i,j+1)+C(i,j)+C(i,j+2)));
%Sobel mask for y-direction:
Gy=((2*C(i+1,j+2)+C(i,j+2)+C(i+2,j+2))-(2*C(i+1,j)+C(i,j)+C(i+2,j)));
%The gradient of the image
inputImage(i,j)=sqrt(Gx.^2+Gy.^2);
end
end
imshow with a double argument expects the values to be in the range 0.0 (black) to 1.0 (white). Anything greater than 1 is clipped to white. Since presumably inputImage is integer, using double(inputImage) doesn't rescale and you end up with double values in ranges like 0-255 or 0-65535 depending on the bit depth, which therefore just show as white.
If you need double format, use im2double which rescales the values correctly. Otherwise, just create an integer copy with copyImage = inputImage.
If you don't have the Image Processing Toolbox for im2double, you can do an unsigned integer-to-double image conversion with:
dblimg = double(img) ./ double(intmax(class(img)));

How to get the red image from gray image in matlab

i have an image let say a=imread('example.bmp'i got all three channel from it :
R=a(:,:,1);
G=a(:,:,2);
B=a(:,:,3);
and i have the gray image of it:
igray=rgb2gray(a);
Can I get the red component from the gray image ?
No, you can't, since igray will be a two dimensional image (a is three dimensional, with the third dimension being colors planes), containing only intensity values for each pixel.
To convert an RGB image to grayscale, rbg2gray uses a formula you can find here
As you can see, it's a 3 variables equation, therefore you can't find them using intensity value alone.
The rgb2gray function effectively does this to every RGB pixel (type edit rgb2gray):
Gray = 0.298936021293776*Red+0.587043074451121*Green+0.114020904255103*Blue;
If you only have Gray in the equation above then you have one equation with three unknowns. More information is needed to solve for Red.
If you just want an RGB image where every channel has the same components, i.e., those created by rgb2gray, then use
igray(:,:,3) = rgb2gray(a); % Set last component first to fully allocate array
igray(:,:,1) = igray(:,:,3);
igray(:,:,2) = igray(:,:,3);
Or an RGB image where all the channels are equivalent to the red channel:
igray(:,:,3) = a(:,:,1);
igray(:,:,1) = a(:,:,1);
igray(:,:,2) = a(:,:,1);
The repmat function can be used as well if you prefer.
While nothing in horchler's very long answer is incorrect, I think you just want to get the red channel from the rgb image which is very easy.
A=imread('colorImg.jpg')
redChannel=A(:,:,1)
That's it!
That will return a matrix of type uint8, to convert to double, just do double(redChannel) and you can multipy/divide it by 255 as necessary.