How to extract only object with white background using bounding box in MatLab?

Hi everyone,

I am a newbie in matlab.

I try to do segmentation to get seperately image and text in an image.

I use regionprops, so i got each boundingbox and one of the image is like this:

My problem is that I crop the original image to get each connected component using boundingbox. However, I want only the object for instance the coin with white background.

Any idea ?

_ EDITED _

I crop the original image to get each connected component using boundingbox .

My problem is that when the original image are cropped in rectangle shape, some background of the crop image have coin(that what i want) and some text or line within the rectangle shape (that i dont want),

How can I remove those text or line within the rectangle shape of the crop image?

2 Comments

Just to clarify what you would like to do: you would like to get bounding boxes on objects extracted from an image, but you only want the object itself and not what is in the background? For example, in the image you provided, you would like to extract bounding boxes around each of the four coins?
Sorry for confusing,
I already found the connected components and i can crop the image using their bounding box.
I crop the original image to get each connected component using boundingbox .
My problem is that when the original image are cropped in rectangle shape, some background of the crop image have coin(that what i want) and some text or line within the rectangle shape (that i dont want),
How can I remove those text or line within the rectangle shape of the crop image?

Sign in to comment.

 Accepted Answer

I think what you are looking for is activecontour. Active contours allow you to separate an image into foreground and background.
Using the image of coins you provided, the following code generates a binary image bw in which white pixels belong to the foreground (coins) and black pixels belong to the background:
% Open image
I = imread('coins.jpg');
% Convert to grayscale
I = rgb2gray(I);
% Show image
figure(1);
imshow(I)
title('Image with objects')
% mask is the initial contour state
mask = zeros(size(I));
mask(25:end-25,25:end-25) = 1;
% Show mask
figure(2);
imshow(mask);
title('Initial contour location')
% bw is a mask of the detected objects
numIter = 2500;
bw = activecontour(I, mask, numIter);
% Show detected objects
figure(3);
imshow(bw);
title('Detected objects')
When using activecontour, keep in mind that the default number of iterations is 100. Depending on the image you are working on, you might want to change that to a larger number of iterations. In the example code above I chose 2500 and all four coins are successfully separated.
Then, you can use the bwconncomp function to find each coin in the image as a connected component. However, noise might be present in bw after running active contours. You can use the bwareaopen function to perform a morphological opening on the binary image bw and remove connected components that have less than a certain number of pixels.
I included the entire script (extractCoins.m) with all operations, from opening the image to cropping the coins from their background and displaying them. This is the final result:

17 Comments

Thank Bruno Pop-Stefanov, That was very helpful.
I crop the original image to get each connected component using boundingbox .
My problem is that when the original image are cropped in rectangle shape, some background of the crop image have coin(that what i want) and some text or line within the rectangle shape (that i dont want),
How can I remove those text or line within the rectangle shape of the crop image?
Hi Vortana,
I edited my answer and included more code that crops each coin from the image and removes the background. In my code I chose to replace the background with black, but you can specify a different color.
I tested it and I got this error...
Undefined function 'activecontour' for input arguments of type 'uint8'.
Here the code
% Open image
I = imread('Coins.tif');
% Convert to grayscale
I = rgb2gray(I);
% Show image
figure(1);
imshow(I)
title('Image with objects')
% mask is the initial contour state
mask = zeros(size(I));
mask(25:end-25,25:end-25) = 1;
% Show mask
figure(2);
imshow(mask);
title('Initial contour location')
% bw is a mask of the detected objects
numIter = 2500;
bw = activecontour(I, mask, numIter);
% Show detected objects
figure(3);
imshow(bw);
title('Detected objects');
Any idea ?
It's a fairly new function. You probably have an old version of MATLAB. Please upgrade to get that function.
Back to the questions, if I got each connect components using regionprops, and I crop the original image using boundingbox.
I can crop each connected components in rectangle shape; however, in this rectangle shape there are some unwanted line or text.
how can I remove those lines or texts?
You might be able to use the active contour function that a user wrote and submitted to the File Exchange here but I have never used it so I cannot help you with that.
If you read further down in extractCoins.m, I use the mask with the connected components to get the pixels belonging to the foreground. You can write something similar after running bwconncomp:
% Find connected components
cc = bwconncomp(bw);
% Define mask for foreground
mask = zeros(cc.ImageSize);
% For each connected component
for i=1:cc.NumObjects
% Set foreground pixels to 1
mask(cc.PixelIdxList{i}) = 1;
end
% Transform into 3-channel mask
mask_rgb(:,:,1) = mask;
mask_rgb(:,:,2) = mask;
mask_rgb(:,:,3) = mask;
% Remove background
I_clean = I;
I_clean(~mask_rgb) = 0;
I_clean = reshape(I_clean, size(I));
Then, crop like in the rest of extractCoins.m.
Thank Bruno, I will try it and come back asap
I tested it ,
Error I_clean(~mask_rgb) = 0;
In an assignment A(I) = B, a matrix A cannot be resized.
I_clean should have 3 channels, like I. I updated extractCoins.m a few minutes after having edited my answer the first time. Re-download it to make sure you have the latest version.
Great, It works Thank so much
Can I change it to white background rather than black background?
Yes, replace the following line:
I_clean(~mask_rgb) = 0;
by:
I_clean(~mask_rgb) = 1;
Well, I think it works for you, but because my bw image has forground (black) and background (white), I have to modify your code to
% Only keep the coins, remove the rest
I_clean = I;
bw_rgb(:,:,1) = ~bw ;
bw_rgb(:,:,2) = ~bw;
bw_rgb(:,:,3) = ~bw;
I_clean(~bw_rgb) = 0;
I_clean = reshape(I_clean, size(I));
After this I get the image that has foreground (original image) the background (black),
Then I want to change the background to white so I tried your suggestion
I_clean(~mask_rgb) = 1;
However, the image still the same which is (foreground (original image) the background (black))
Hey, I changed
I_clean(~mask_rgb) = 1;
to
I_clean(~mask_rgb) = 255;
It changed to what I want foreground (original image) the background (black)
I applied these code to other images of coins, I saw some small parts of coins get color white, so I think it will affect the coins.
For example the result get from your code, one of the 1 Euro coin in the image above..
The black color invade the orginal background of the coin area.
How can we preserve the whole area of coin?
What do you think?
Hi sir i try this code my text extraction in image but i get error in undefined function 'activecontour' uint8.... plz solve this error
What version of MATLAB do you have? It was introduced in R2013a.
how to higlighted as per specific value of coin

Sign in to comment.

More Answers (1)

I want to be extract text from given image...... please help me to solve this problem...

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!