MATLAB overlaying white area of binary image with rgb image - matlab

I am using MATLAB 2012b.
I was able to get the objects outline in an image:
using method of Active Contour Segmentation and the result is in binary mask:
How can I fill the white area of the binary image with the original rgb image?
Basically what I want is to make the background completely black.
Here is my code:
gambarOri = imread(pathGambar);
A = rgb2gray(gambarOri );
mask = zeros(size(A)); mask(10:end-10,10:end-10) = 1;
BW = activecontour(A, mask, 500);
figure, subplot(1, 2, 1), imshow(A), title('Grayscale');
subplot(1, 2, 2), imshow(BW), title('Segmented image in Binary');

You cannon overlay an RGB on a binary image, since the data types do not match. What you can do is to modify your RGB image according to the binary image. For instance you can replace values of the RGB image in false areas of BW with zeros:
% separating RGB channels:
R = gambarOri(:, :, 1);
G = gambarOri(:, :, 2);
B = gambarOri(:, :, 3);
% placing zeros where BW is FALSE:
R(~BW) = 0;
G(~BW) = 0;
B(~BW) = 0;
% concatenate color layers into final result:
blackBG = cat(3, R, G, B);
% figure; imshow(blackBG)
With this result for your provided image:

You can use bsxfun:
blackBG = uint8(bsxfun(#times, double(gambarOri), BW));

Related

2D Fourier Transform of RGB Image Showing up as a White Image

I'm trying to read two 'bmp' format images by imread function in Matlab.
For the first image, it returns a matrix of 512*512 uint8 and for the second one 512*512*3 uint8.
after doing Fourier transformation for img2, it shows white image. any idea?
img1 = imread('I1.bmp');
img2 = imread('I2.bmp');
mag1 = abs(img1);
mag2 = abs(img2);
phase1 = angle(double(img1));
phase2 = angle(double(img2));
subplot(2, 2, 1);
subimage(img1);
subplot(2, 2, 2);
subimage(img2);
FFT1 = fft2(double(img1));
FFT2 = fft2(double(img2));
subplot(2, 2, 3);
imshow(log(abs(fftshift(FFT1))), [0 10]);
colormap(gray);
colorbar;
subplot(2, 2, 4);
imshow(log(abs(fftshift(FFT2))), [0 10]);
colormap(gray);
colorbar;
The issue is that the second image is RGB and fft2 performs the 2D FFT on each channel separately and returns a matix the same size as the input. When you try to display the resulting RGB image (where each channel is the FFT of each channel), it is going to show up as all white.
If you actually want the FFT of each channel, then you'll want to display the FFT separately for each one
% Display red FFT
imshow(log(abs(fftshift(FFT2(:,:,1)))), [0 10]);
Your other option is to convert the image to a grayscale image before taking the FFT
img2 = rgb2gray(img2);
FF2 = ff2(img2);
imshow(log(abs(fftshift(FFT2(:,:,1)))), [0 10]);

Assigning colors to segmented pictures in MATLAB

I was dealing with color segmentation with MATLAB. I used k-means clustering based on this document and come this far codewise;
global imgRGB;
global imgLAB;
img = imgRGB;
cform = makecform('srgb2lab');
imgLAB = applycform(img, cform);
ab = double(imgLAB(:,:,2:3));
rows = size(ab,1)
cols = size(ab,2);
ab = reshape(ab, rows*cols, 2);
cluster = 5;
[idx center] = kmeans(ab, cluster, 'distance', 'sqEuclidean', 'Replicates', 5);
label = reshape(idx, rows, cols);
figure; imshow(label, []);
imgSeg = cell(5);
rgb_label = repmat(pixel_labels, [1 1 3]);
for k=1:cluster
color = img;
color(rgb_label ~= k) = 0;
imgSeg{k} = color;
end
figure;
imshow(imgSeg{1});
I take image as input that is why it is defined global.
For a colored image like the one in link, it produces the grayscale output.
I think it assigns gray tones as colors but I need to assign a color to each cluster. I mean not gray tone but a color. How can I achieve that?
You should use a different colormap for your figure, when displaying the labels directly.
Try:
figure;
imshow(label, []);
colormap( rnad(max(imgSeg{1}(:))+1, 3) ); % use random color map
However, if you wish to convert the pixel_labels to an RGB image (3 color channels per pixel), you want to use ind2rgb (instead of replicating the labels to all channels). Replace rgb_label = repmat(pixel_labels, [1 1 3]); with
rgb_label = ind2rgb(pixel_labels, rand(max(pixel_labels(:)),3));

Filling region of RGB image specified by polygon in Matlab

After finding boundaries of my regions of interest in an RGB image I want to fill them with specific color on the original picture
img=imread('I.png');
BW=~im2bw(img,0.5);
B = bwboundaries(a2);
for k = 1:length(B)
boundary = B{k};
% here should color everything inside boundary in blue
end
What function can I use to do this? I tried also using imshow() and than ploting regions on it, but don't know how to save it in the original resolution.
If you insist on filling with polygon, you can use fill, but then you might face some problems:
img = imread('Prueba.jpg');
figure;
imshow(img)
BW = ~im2bw(img, 0.55);
B = bwboundaries(BW);
hold on
for k = 1:length(B)
boundary = B{k};
fill(boundary(:, 2), boundary(:, 1), 'b')
end
As shown in this example, there are regions of the image that are surrounded by a boundary but they are actually supposed to be outside the boundary.
Instead, in this way you can avoid the issue:
imgR = img(:, :, 1);
imgG = img(:, :, 2);
imgB = img(:, :, 3);
imgR(BW) = 0;
imgG(BW) = 0;
imgB(BW) = intmax(class(imgB));
IMG = cat(3, imgR, imgG, imgB);
figure; imshow(IMG)

Matlab: Removing white cells from image

I would like to only remove white blood cells and keep red blood cells from the image below. What is the best way to do this in Matlab?
format longg;
format compact;
fontSize = 16;
rgbImage = imread('E:\GP_Final\DS\CL_13-09_image2.jpg');
[rows columns numberOfColorBands] = size(rgbImage);
% imshow(rgbImage, []);
% title('Original Color Image', 'FontSize', fontSize);
hsv = rgb2hsv(rgbImage);
% figure(2),imshow(hsv);
% Display the color channels.
hueImage = hsv(:, :, 1);
saturationImage = hsv(:, :, 2);
valueImage = hsv(:, :, 3);
subplot(2, 2, 2);
imshow(hueImage, []);
title('Hue Channel', 'FontSize', fontSize);
subplot(2, 2, 3);
imshow(saturationImage, []);
title('Saturation Channel', 'FontSize', fontSize);
subplot(2, 2, 4);
imshow(valueImage, [])
title('Value Channel', 'FontSize', fontSize);
[pixelCounts values] = hist(hueImage, 500);
figure;
bar(values, pixelCounts);
title('Histogram of Hue Channel', 'FontSize', fontSize);
redPixels = hueImage > 0.3 & hueImage >0.8 & valueImage <= 0.9;
% figure(10);
% imshow(redPixels);
% title('Map of red Pixels', 'FontSize', fontSize);
saturationImage(redPixels) = saturationImage(redPixels) *3.5;
% figure(7),imshow(saturationImage);
% title('New Saturation Channel', 'FontSize', fontSize);
% Combine back to form new hsv image
hsvImage = cat(3, hueImage, saturationImage, valueImage);
% Convert back to RGB color space.
rgbImage = hsv2rgb(hsvImage);
figure(8), imshow(rgbImage);
title('RGB Image with Enhanced red', 'FontSize', fontSize);
se1 = strel('disk',1);
erodedBW = imerode(redPixels,se1);
se2 = strel('disk',2);
dilatedBW2 = imdilate(erodedBW,se2);
se3 = strel('disk',1);
openedBW = imopen(dilatedBW2,se3);
filledBW=imfill(openedBW,'holes');
figure(3), imshow(filledBW);title('after fill holes ');
bw3=bwareaopen(filledBW,80);
figure(5), imshow(bw3);title('after remove small objects ');
that is i did but it not work for all images, there is any way to solve it ?
You wish to remove out the deep purple cell in the middle of the image. It's a very simple task in looking at the colour distribution in the HSV colour space. I wouldn't look at the hue in this case because the colour distribution of the image will most likely have similar hues. The saturation is what I would aim for.
Let's read in the image from StackOverflow, convert the image to HSV and look at the saturation component:
im = imread('http://i.stack.imgur.com/OQUKj.jpg');
hsv = rgb2hsv(im2double(im));
imshow(hsv(:,:,2))
We get this image:
You can clearly see that the "red" blood cell has a higher saturation than the background, and so we can do some simple thresholding. A saturation of 0.4 seems to work for me:
mask = hsv(:,:,2) > 0.4;
imshow(mask);
We get this:
There are some spurious pixels, so we can remove this with a bwareaopen operation. Any pixels whose areas are below 300 I remove:
mask_remove = bwareaopen(mask, 300);
imshow(mask_remove);
We get this:
Now, there are holes in this remaining cell. We can remedy this by filling these holes using imfill and selecting the holes option:
mask_fill = imfill(mask_remove, 'holes');
imshow(mask_fill);
We get this:
I'm going to dilate this mask slightly to make sure we get rid of the rest of the purple surroundings:
se = strel('square', 7);
mask_final = imdilate(mask_fill, se);
The last thing to do is to use this mask and mask the original image, then produce a final image with the white blood cell remove. Simply invert the mask and multiply this with the original image, then fill in the missing information with white:
mask_final = repmat(mask_final, [1 1 3]);
out = im .* uint8(~mask_final);
out(mask_final) = 255;
imshow(out);
We get this:
You can import the image by dragging it into the workspace or clicking the 'import' button in Matlab. This will give you a width x height x 3 matrix which contains the RGB values per pixel. By thresholding the red, green a blue values, you can select which pixels to edit. Using imview() and imsave(), you can view and store the result.
To edit multiple images, you can use (replace png with the extension you have):
fileNames = [cellstr('name1'), cellstr('name2')]; % The images to process without extension.
for i = 1:length(fileNames)
img = imread([char(fileNames(i)), '.png']);
% Process the image here.
% ...
imwrite([char(fileNames(i)), '-edited.png'], 'png');
end

How to convert an indexed image to rgb image in MATLAB?

I did a gaussian filter and the image become index. I have to use imagesc to show the determine the color difference. How can I convert it to rgb so that I can do further process.
Edited Added some images, top is the 'original image', 'imshow(C)', 'imagesc(C)' respectively. Then I just want the 'C' variable to be like imagesc image. Is it possible??
Edited Here is my coding, see from gaussian onward
% Read Image
rgb = imread('barcode.jpg');
% Resize Image
rgb = imresize(rgb,0.33);
%figure(),imshow(rgb);
% Convert from RGB to Gray
Igray = rgb2gray(rgb);
BW2 = edge(Igray,'canny');
%figure(),imshow(BW2);
% Perform the Hough transform
[H, theta, rho] = hough(BW2);
% Find the peak pt in the Hough transform
peak = houghpeaks(H);
% Find the angle of the bars
barAngle = theta(peak(2));
J = imrotate(rgb,barAngle,'bilinear','crop');
%figure(),imshow(J);
Jgray = double(rgb2gray(J));
% Calculate the Gradients
[dIx, dIy] = gradient(Jgray);
%if min(dIx(:))<= -100 && max(dIx(:))>=100 || min(dIy(:))<=-100 && max(dIy(:))>=100
if barAngle <= 65 && barAngle >=-65 && min(dIx(:))<= -100
B = abs(dIx) - abs(dIy);
else
B = abs(dIy) - abs(dIx);
end
% Low-Pass Filtering
H = fspecial('gaussian', 20, 10);
C = imfilter(B, H);
C = imclearborder(C);
figure(),imshow(C);
figure(),imagesc(C);colorbar;
RGB = ind2rgb(X,map)
RGB is just eye-candy at this point, you can't magically add information that isn't there.
EDIT
In your code, C is a gray-scale image, because B is gray-scale which in terms is caused by the fact that it is composed from gradients dIx and dIy that originate from an image, you yourself make grayscale explicitly with the line Jgray = double(rgb2gray(J));