Convert matlab.graphics.primitive.Image (output of imagesc) to rgb array - image

I'm using the MATLAB function
imagesc(my_gray_valued_image)
to visualize my_gray_valued_image: [1024x1024] double array with values from 0.0 - 1.0 (gray values) using colormaps like jet.
I want to store the output as a RGB image ([1024x1024x3] double array). However the output of the function is a Image object (matlab.graphics.primitive.Image) that contains the original array (Image.CData) but doesn't allow to extract the colorscaled image.
Following a similar (although confusingly cluttered) question (How to convert an indexed image to rgb image in MATLAB?) I tried the following, but that gave me a plain blue image:
RGB = ind2rgb(my_gray_valued_image, jet);
imshow(RGB);

here for arbitrary colormap:
im = rand(5); % input [0-1] image
figure;
h = imagesc(im); % imagesc handle
title('imagesc output')
cdata = h.CData; % get image data (if you don't have variable 'im')
cm = colormap(h.Parent); % get axes colormap
n = size(cm,1); % number of colors in colormap
c = linspace(h.Parent.CLim(1),h.Parent.CLim(2),n); % intensity range
ind = reshape(interp1(c,1:n,im(:),'nearest'),size(im)); % indexed image
rgb = ind2rgb(ind,cm); % rgb image
figure;
imshow(rgb,'InitialMagnification','fit');
title('rgb image')

You can use ind2rgb to convert an intensity image into RGB using a colormap of your choice; but make sure that the range of the input is from 1 to the number of colors in the colormap. This is because ind2rgb maps value 1 to the first color, 2 to the second etc.
im = rand(5,5); % example intensity image
cmap = jet(256); % desired colormap
result = ind2rgb(ceil(size(cmap,1)*im), cmap);
The reason why you are getting a blue image is that ind2rgb clips the values of the input image to the range from 1 to the number of colors in the colormap. So, if the input image has values between 0 and 1 they are all mapped to 1, that is, to the first color in the colormap.

Related

how to add rgb image and rgba image based on opacity value of the rgba image

lets say one image is shaped (x,y,3) and another (x,y,4). Now depending on whether the value of pixel in the 4th layer is 0 or non zero. I need to replace pixel values in the first image using the following rule.
if pixel in the 4th layer is 0 return image has values= value in (x,y,3) at that pixel in the rgb image
if non zero return image has value = value in value at that pixel in the rgba image
the return image should have shape (x,y,3)
If I understand you correctly, you effectively want to use the alpha part of the RGBA image as a binary mask. Assuming A is the rgb base image and B the rgba top image, both represented as numpy arrays:
mask = B[:, :, 3] > 0.5 # you can also use another threshold here
A[mask] = B[mask, 0:3]
Both images must have the same shape for this.
Alternatively, you can also overlay the second image on top of the first one using the alpha channel instead of using a binary mask:
A = (1-B[:,:,3])*A + B[:,:,3]*B[:,:,0:3]
You can do:
mask = img2[...,3] > 0
new_img = np.where(mask[...,None], img2[...,:3], img1)
Also without need for broadcasting:
mask = img2[...,3:] > 0
new_img = np.where(mask, img2[...,:3], img1)

MATLAB: Convert imagesc() RESULT to an image

Let say we have grayscale image im:
And use imagesc(im) to get:
With code:
im = rgb2gray(im2single(imread('tesla.jpg'))); % get image
h = imagesc(log(abs(fftshift(fft2(im))))); % imagesc handle
How can one convert the intensity graphic h (2nd image) to a standard RGB image (2x2 float matrix that one can manipulate, crop, etc) in matlab?
I don't need the axes, numbers or tics of the intensity image, I only need to maintain the color.
Thank you.
%turn off the axes
axis off
%save the image
saveas(h,'test.png')
%read the saved image
im_fft = imread('test.png');
%remove white border
sum_img = sum(im_fft,3); sum_img(sum_img(:) ~= 255*3) = 0; sum_img = logical(sum_img);
im_fft = im_fft(~all(sum_img,2), ~all(sum_img,1),:);
%Done!
figure, imshow(im_fft)
The resulting image can be used only for presentations/illustrations, not for analysis - quantization and sampling corrupts it significantly

Like an ordinary indexed image,in the figure’s colormap. The difference is that the matrix values are linearly

find pixels location that have value/color =white
for i=1:row
for j=1:colo
if i==x if the row of rgb image is the same of pixel location row
end
end
end
end
what's Wrong
You can use logical indexing.
For logical indexing to work, you need the mask (bw2) to be the same size as RGB.
Since RGB is 3D matrix, you need to duplicate bw2 three times.
Example:
%Read sample image.
RGB = imread('autumn.tif');
%Build mask.
bw2 = zeros(size(RGB, 1), size(RGB, 2));
bw2(1+(end-30)/2:(end+30)/2, 1+(end-30)/2:(end+30)/2) = 1;
%Convert bw2 mask to same dimensions as RGB
BW = logical(cat(3, bw2, bw2, bw2));
RGB(BW) = 255;
figure;imshow(RGB);
Result (just decoration):
In case you want to fix your for loops implementation, you can do it as follows:
[x, y] = find(bw2 == 1);
[row, colo, z]=size(RGB); %size of rgb image
for i=1:row
for j=1:colo
if any(i==x) %if the row of rgb image is the same of pixel location row
if any(j==y(i==x)) %if the colos of rgb image is the same of pixel loca colo
RGB(i,j,1)=255; %set Red color channel to 255
RGB(i,j,2)=255; %set Green color channel to 255
RGB(i,j,3)=255; %set Blue color channel to 255
end
end
end
end
[x, y] = find(bw2 == 1)
x and y are arrays unless there is only one pixel is white.
However, if i==x and if j==y are comparing a single number with an array. This is wrong.
As Anthony pointed out, x and y are arrays so i==x and j==y won't work as intended. Furthermore RGB(i,j) only uses the first two dimensions, but RGB images have three dimensions. Lastly, from an optimization point of view, the for-loops are unnecessary.
%% Create some mock data.
% Generate a black/white image.
bw2 = rand(10);
% Introduce some 1's in the BW image
bw2(1:5,1:5)=1;
% Generate a RGB image.
RGB = rand(10,10,3)*255;
%% Do the math.
% Build a mask from the bw2 image
bw_mask = bw2 == 1;
% Set RGB at bw_mask pixels to white.
RGB2 = bsxfun(#plus, bw_mask*255, bsxfun(#times, RGB, ~bw_mask)); % MATLAB 2016a and earlier
RGB2 = bw_mask*255 + RGB .* ~bw_mask; % MATLAB 2016b and later.

How to output result of rgb2hsv (causes colour values to be between 0-1) as a uint8 image?

I want to convert 2 RGB images to HSV images then calculate the difference between the two images saturation and output this resulting image as a uint8 image. Here is the code I've tried but uint8 is converting the intensities to 1 or 0 resulting in a binary image essentially.
inputImage = rgb2hsv(inputImage);
background = rgb2hsv(background);
sDiff = imabsdiff(background(:,:,2), inputImage(:,:,2));
sDiff = uint8(sDiff);
figure, imshow(sDiff, []);
Its outputting a binary image though. I tried:
gDiff = double(sDiff) * 255;
But the resulting intensities are either 255 or 0.
Use sDiff = uint8(sDiff.*256); to convert it to uint8 format

How to show histogram of RGB image in Matlab?

I read an image in matlab using
input = imread ('sample.jpeg');
Then I do
imhist(input);
It gives this error:
??? Error using ==> iptcheckinput
Function IMHIST expected its first input, I or X, to be two-dimensional.
Error in ==> imhist>parse_inputs at 275
iptcheckinput(a, {'double','uint8','logical','uint16','int16','single'}, ...
Error in ==> imhist at 57
[a, n, isScaled, top, map] = parse_inputs(varargin{:});
After running size(input), I see my input image is of size 300x200x3. I know the third dimension is for color channel, but is there any way to show histogram of this? Thanks.
imhist displays a histogram of a grayscale or binary images. Use rgb2gray on the image, or use imhist(input(:,:,1)) to see one of the channel at a time (red in this example).
Alternatively you can do this:
hist(reshape(input,[],3),1:max(input(:)));
colormap([1 0 0; 0 1 0; 0 0 1]);
to show the 3 channels simultaneously...
I pefere to plot the histogram for Red, Green and Blue in one plot:
%Split into RGB Channels
Red = image(:,:,1);
Green = image(:,:,2);
Blue = image(:,:,3);
%Get histValues for each channel
[yRed, x] = imhist(Red);
[yGreen, x] = imhist(Green);
[yBlue, x] = imhist(Blue);
%Plot them together in one plot
plot(x, yRed, 'Red', x, yGreen, 'Green', x, yBlue, 'Blue');
An histogarm plot will have number of pixels for the intensity levels.
Yours is an rgb image. So you first need to convert it to an intensity image.
The code here will be:
input = imread ('sample.jpeg');
input=rgb2gray(input);
imhist(input);
imshow(input);
You will be able to get the histogram of the image.
img1=imread('image.jpg');
img1=rgb2gray(img1);
subplot(2,2,1);
imshow(img1);
title('original image');
grayImg=mat2gray(img1);
subplot(2,2,2);
imhist(grayImg);
title('original histogram');
Remember to include
mat2gray();
because it converts the matrix A to the intensity image grayImg. The returned matrix grayImg contains values in the range 0.0 (black) to 1.0 (full intensity or white).
Histogram is useful to analyze pixel distribution in an image. Histogram plots number of pixel in an image with respect to intensity value.
img1=imread('image.jpg');
hist(img1);

Resources