Image Conversions in Matlab - matlab

I converted an RGB image (which is in double format) to a gray scale image of the same format using rgb2gray in Matlab. Now I want to convert the same image from gray to RGB. I used gray2rgb in Matlab but it's giving an error. So how can we convert a grayscale image to an RGB image using Matlab?

Short answer: you can't. Not perfectly at least.
As Sean says, this is because you have dropped some information when converting to grayscale. In other words, converting back from grayscale to RGB is an under-determined inverse problem, so there is no easy solution.
Now this doesn't mean you can't try. If you have some prior on the image, you can use it in addition to the information you have left to compute an estimate of the original RGB image.
For example if you know (or suppose) that the original image was already grayscale (in an RGB container) then you can reverse the process exactly. This is what the gray2rgb function Sean mentions is doing.
Most of these are open problems, so it's probably beyond what you want.

I'm sorry to say it's not possible.
By converting the image to grayscale you've reduced the amount of information (3 dimensions at each pixel down to 1) and this can't be recovered.
The rgb2gray function is one included in Matlab and works fine.
The gray2rgb function is not a standard Matlab function. If you are referring to this function on Matlab central, it's documentation states it doesn't do anything useful but just creates a 3d matrix from the 1d matrix; the image will still be grayscale.

Related

Scramble the pixels of black and white images in Matlab

I have a series of black and white images (not greyscale, black and white; 2D matrices in Matlab), and I need to randomly scramble the pixels. I found this package in Mathworks File Exchange (https://it.mathworks.com/matlabcentral/fileexchange/66472-image-shuffle); one of the functions, imScrambleRand, does exactly what I need, but it works for RGB images (3D matrices). Is there a way to transform b&w images into 3D matrices so that I can use that function? Or can anyone suggest any other script that does what I need? Keep in mind that I'm not familiar with Matlab, but I'll do my best.
Thank you.
EDIT 1: When I import the BW image I get a 2D matrix of logic values (0 = black, 1 = white). I think the different data format (logic vs integer) is what yields errors when using the function for RGB images.
EDIT 2: I adapted the demo code from the aforementioned package and I used the suggestion by #Jonathan for transforming a 2D matrix into a 3D matrix, and added a loop to transform the logic values into RGB integer values, then use the imScrambleRand function. It works, but what I obtain is the following image: SCRAMBLED IMAGE. This is the BW picture I start with: BW IMAGE. So I checked the scrambled image, and the function from the FEX file actually scrambles within the RGB values, meaning that I found, for instance, a pixel with RGB 0,255,0. So I solved a problem but actually there's a problem within the function: it doesn't scramble pixels, it scrambles values generating colors that were not in the original picture.
EDIT 3: I used the code provided by #nhowe and I obtain exactly what I need, thanks!
EDIT 4: Ok, turns out it's not ok to scramble the pixels since it makes the image too scattered and different from the starting image (you don't say?), but I need to scramble BLOCKS OF PIXELS so that you can't really recognize the image but the black pixels are not too scattered. Is there a way to do that using the code provided by #nhowe?
EDIT 5: It should be ok with this function: https://it.mathworks.com/matlabcentral/fileexchange/56160-hio-been-hb-imagescramble
A simple way to scramble matrix M:
r = rand(size(M));
[~,ri] = sort(r(:));
M(ri) = M;
The simplest solution to go from grayscale to RGB might be this:
rgbImage = cat(3, grayImage, grayImage, grayImage);
Then apply your function from FEX and extract one color channel, assuming that the FEX function will yield three identical color channels.

im2double yields different results

I am trying to get RGB matrices for an image. When my image is 1200x1600, the following code
I=imread('testme.jpg');
I=im2double(I);
yields a 1200x1600x3 matrix and I can get RGB matrices but when the image is a screenshot of a part of this image, the code below
I=imread('testme_subpic.jpg');
I=im2double(I);
yields 167x228 matrix and I can't get the RGB matrices.
Likely, when I write
I=imread('testme.png');
I=im2double(I);
lines give me a 1200x1600 matrix.
My question is why can't I get a 3-dimensional matrix with the png or the smaller-sized jpg and how do I get it?
It is all about the way the images were saved.
Check wikipedia for some extra info about png pixel formats. To avoid this issue you can try to use MATLAB itself to write your images, that way you have control over pixel formats (imwrite)

YCbCr to RGB conversion MATLAB using ycbr2rgb results in pink picture

I'm trying to convert an YCbCr image to RGB ysing MATLAB's function ycbcr2rgb. My resulting picture ends up being pink, and converting back again afterwards (should give me the original picture?) creates yet another image mostly grey.
For reference I tried to convert each channel individually by formula and it ends up the same.
I'm using a bigtiff format because of large filesize and if any help the imfinfo shows compression using JPEG.
Here is my code:
x=imread('picture.tiff','Index',9); %(9 subresolutions)
rgb=ycbcr2rgb(x);
imshow(rgb);
Can it be because of MATLABs function using the originial definition of YCbCr using ranges from 16-235 while my image is ranging from 0-255? If so is there any means of correcting this using the inbuild function?
I have added the pictures here, first image is showing imshow(rgb), while the second image is the original ycbcr. What I noticed is that in the Windows image viewer it actually shows it correct, it's just MATLAB's imshow that displays it pink after conversion.
Is there any chance you could point me in the right direction?
Thanks
Sonny
Apparently imread reads YCbCr images as RGB when loading it, which is why the problem occured.
Thanks for the help to all of you.
imread documentation
This link gives all the conversion formulae:
http://www.easyrgb.com/index.php?X=MATH&H=11
The below code converts image from RGB space to YCbCr space and back.
rgb = imread('board.tif');
imshow(rgb);
figure;
ycbcr = rgb2ycbcr(rgb);
imshow(ycbcr);
figure;
rgb2 = ycbcr2rgb(ycbcr);
imshow(rgb2);
Use MATLABs built in functions only. Also, if you're facing issues while converting from ycbcr to rgb you should probably try to convert the image to other form and then convert that form to RGB. (a dirty hack)
Just divide the image by 256 before converting it back to RGB.
y = ycbcr2rgb(z/256); % z holds the YCbCr image.
Worked for me.
Hope that helps :)

How to plot an HSV image with Matlab?

I'am interested in finding a way to plot an HSV image in Matlab. I know i can do it by converting it into RGB first but I want to figure out whether there is a direct way. Thanks.
Ther is the hsv2rgb function to convert an hsv image to rgb, in case you were about to convert the values yourself.
Since monitors work with rgb the image has to be converted at some place before display, so i think it doesn't really matter when this takes place. I don't know of any more direct matlab approach than using hsv2rgb and then show the image and i do not think there is one. (of course you could put those two into a user defined script if that helps making code more readable).

converting binary image to gray scale image in Matlab

I working on Optical Character Recognition system.
I want to convert the license plate image from binary to gray scale.
let's look at the next example:
this is the binary image:
and this is the gray scale:
what I want to know is if there is a way to convert it from binary to the gray, or this is not possible because i've lost the information when I converted the picture to binary at the beginning.
any idea how to do this? thanks
To convert a binary image of class logical to a grayscale image of class double, you simply call
double(yourBinaryImage)
EDIT
To revert from a binary image to the grayscale image you had before thresholding is impossible without the grayscale image, since by thresholding you have dropped all the grayscale texture information.
Maybe you can use the distance transform to achieve a gray scale image from a binary image. In MATLAB, try bwdist or something like that.
The result, of course, will not be the original gray scale image.
I think you cannot exactly get the grayscale image which you have shown from the binary image. What you can do is convert the image into grayscale and then do gaussian noising to spread the edge and then you can also add random noise to the whole image. So, now your new grayscale image will look a lot different than binary image.