How to multiply binary image and rgb image in matlab? - matlab

I have a binary image which is the segmented form of another color image .
As you know , a binary image is 2-d but an rgb image is 3-d , how can i multiply them together ?
i tried this code which resulted in a strange pic
function skinCrop(bwSkin,colorSkin)
for i = 1:size(colorSkin,1)
for j = 1:size(colorSkin,1)
if bwSkin(i,j) == 0
colorSkin(i,j,:) = 0;
end
end
end
imshow(colorSkin);
end
The original image was
The resulting image was :
I expected it to be a hand against a dark background , so why do the right part appear that way ?

You should avoid loops when not needed in matlab:
mask = cat(3,bwSkin,bwSkin,bwSkin);
output = mask.*colorSkin;
You might have to change the types in order for the multiplication to succeed:
output = uint8(mask).*colorSkin;
Or:
output = double(mask).*colorSkin;

You are using the wrong dimension length for your second dimension:
for j = 1:size(colorSkin,1)
should be
for j = 1:size(colorSkin,2)

A more efficient way to do the multiplication is
function mult = skinCrop( bwSkin, colorSkin )
%
% multiplying 3D color image with 2D mask
%
mult = nsxfun( #times, bwSkin, colorSkin );
% show the result
imshow( mult ); title('skin cropped image');
As #zenopy noted, you might need to cast your variable to double type.

Related

Interpolation algorithm all values 255 -MATLAB

I trying to create my own nearest neighbor interpolation algorithm in Matlab to enlarge an image of 556×612 to 1668×1836.
This is homework!!!
I have attempted this already but encounter the error where the values inside M gets (not all but most) transformed to 255 (White Space), and I cannot get my head around why. Any help would be appreciated! The picture is a picture of a zebra.
%Take in image and convert to greyscale
I = imread('Zebra.jpg');
Igray = rgb2gray(I);
% Step-3: Resize the image to enlarged 1668x1836 by interpolation
% Step-3(a) : Using nearest neighbour
%First we will need to work out the dimension of the image
[j , k] = size(Igray);
%Now we need to set the size of the image we want
NewX = 1836;
NewY = 1668;
% Work out ratio of old to new
ScaleX = NewX./(j-1);
ScaleY = NewY./(k-1);
%Image Buffer
M = zeros(NewX, NewY);
%Create output image
for count1 = 1:NewX
for count2 = 1:NewY
M(count1,count2) = Igray(1+round(count1./ScaleX),1+round(count2./ScaleY));
end
end
%Show Images
imshow(M);
title('Scaled Image NN');
try imshow(M,[]). You created M without specifying type, which makes it double. double images are [0-1], so imshow by default makes white everything with higher value than 1.
Alternatively, create M to be uint8 as the original image
M = zeros(NewX, NewY,'uint8');
even better code would be:
M = zeros(NewX, NewY,class(Igray));

Histogram of binary image in MATLAB

I'm trying to do a vertical histogram of a binary image. I don't want to use MATLAB's functions. How to do it?
I have tried this code but I don't know if it's correct or not:
function H = histogram_binary(image)
[m,n] = size(image);
H = zeros(1,256);
for i = 1:m
for j = 1:n
H(1,image(i,j)) = H(1,image(i,j))+1;
end
end
The image is:
The result:
Why can't I see the value of black pixels in the histogram?
% Read the binary image...
img = imread('66He7.png');
% Count total, white and black pixels...
img_vec = img(:);
total = numel(img_vec);
white = sum(img_vec);
black = total - white;
% Plot the result in the form of an histogram...
bar([black white]);
set(gca(),'XTickLabel',{'Black' 'White'});
set(gca(),'YLim',[0 total]);
Output:
For what concerns your code, it is not counting black pixels since they have a value of 0 and your loop start from 1... rewrite it as follows:
function H = histogram_binary(img)
img_vec = img(:);
H = zeros(1,256);
for i = 0:255
H(i+1) = sum(img_vec == i);
end
end
But keep in mind that counting all the byte occurrences on a binary image (that can only contain 0 or 1 values) is kinda pointless and will make your histogram lack readability. On a side note, avoid using image as a variable name, since this would override an existing function.
As mentioned by #beaker in the comments above, vertical histogram in such cases generally refers to a vertical projection. Here is a way to do this :
I = imread('YcP1o.png'); % Read input image
I1 = rgb2gray(I); % convert image to grayscale
I2 = im2bw(I1); % convert grayscale to binary
I3 = ~I2; % invert the binary image
I4 = sum(I3,1); % project the inverted binary image vertically
I5 = (I4>1); % ceil the vector
plot([1:1:size(I,2)],I5); ylim([0 2])
You can further check for 0->1 transitions to count the number of characters using sum(diff(I5)>0) which gives 13 as answer in this case.

bwlabel on enhanced image results in black image

I tried to enhance an image and perform connected component analysis but it returns a black image.
My code is
I = imread('Sub.png');
I=rgb2gray(I);
imshow(I)
J = adapthisteq(I);
imshow(J)
figure, imhist(J,64)
% I = contrast(I);
L = bwlabel(J);
figure,imshow(label2rgb(L,'jet','k','shuffle'));
Also how to number each blob after bwlabel
I think that is only a matter of scaling the intensity of J when you call bwlabel, since the image is of type uint8. Its maximal possible value is thus 255.
Using this line instead:
L = bwlabel(J/255);
Outputs the following:
Yay!

How to convert RGB images to grayscale in matlab without using rgb2gray

I'm currently using code:
i = imread('/usr/share/icons/matlab.png');
for k=1:1:m
for l=1:1:n
%a(k,l)=m*n;
a(k,l) = (.299*i(k,l,1))+(.587*i(k,l,2))+(.114*i(k,l,3));
end
end
imshow(a);
It shows only a white screen. Also the newly generated dimensions are n x m x 3 whereas it should be only m x n x 1.
If I use mat2gray it display the image like this
Since the image is a PNG, imread() is returning an integer image, with intensity values in the range [0 255] or equivalent, depending on the original bit depth. The conversion formula makes a a double image, which is expected to have intensities in the range [0 1]. Since all the pixel values in a are probably much greater than 1, they get clipped to 1 (white) by imshow().
The best option is to explicitly convert the image format before you start - this will take care of scaling things correctly:
i = imread('/usr/share/icons/matlab.png');
i = im2double(i);
a = .299*i(:,:,1) + .587*i(:,:,2) + .114*i(:,:,3); % no need for loops
imshow(a);
input=imread('test.jpg');
subplot(1,2,1), imshow(input), title('RGB Scale image');
[x,y,~] = size(input);
for i = 1:1:x
for j = 1:1:y
output(i,j) = 0.40*input(i,j,1) + 0.50*input(i,j,2) + 0.30*input(i,j,3);
end
end
subplot(1,2,2), imshow(output), title('Gray Scale image');

Matlab- zero padding

How to do this on matlab?
zero pad the face image with a five‐pixel
thick rim around the borders of the
image. show the resulting image.
Must be manual codes on script.
save this function as create_padded_image.m
function padded_image = create_padded_image(image, padding)
if nargin < 2
% if no padding passed - define it.
padding = 5;
end
if nargin < 1
% let's create an image if none is given
image = rand(5, 4)
end
% what are the image dimensions?
image_size = size(image);
% allocate zero array of new padded image
padded_image = zeros(2*padding + image_size(1), 2*padding + image_size(2))
% write image into the center of padded image
padded_image(padding+1:padding+image_size(1), padding+1:padding+image_size(2)) = image;
end
Then call it like this:
% read in image - assuming that your image is a grayscale image
$ image = imread(filename);
$ padded_image = create_padded_image(image)
This sounds like homework, so I will just give you a hint:
In MATLAB it is very easy to put the content of one matrix into another at precisely the correct place. Check out the help for matrix indexing and you should be able to solve it.
I realize you want to code this yourself, but for reference, you can use the PADARRAY function. Example:
I = imread('coins.png');
II = padarray(I,[5 5],0,'both');
imshow(II)
Note this works also for multidimensional matrices (RGB images for example)