Cut an area in binary Image

Hi Everybody, Please, I would like to cut the white pixels area from a binary image, so that the output will be this white area. From another question, I see a method that shows how to surround this area, but also I would like to cut automatically the part surrounded, which is a vehicle logo in my case. Here is the link to this method: http://www.mathworks.com/matlabcentral/answers/24041-cut-an-image
I've tried this method for some hours, and trying to edit it to see the results, but until now I even didnt get the surrounded line, please your help is welcome.
Thanks!
Nour.

1 Comment

Nour
Nour on 21 Dec 2014
Edited: Nour on 21 Dec 2014
Here is what I expect as output

Sign in to comment.

 Accepted Answer

There are several ways to crop the image. For example you can use regionprops() to find the bounding box, like I show in my Image Segmentation Tutorial http://www.mathworks.com/matlabcentral/fileexchange/?term=authorid%3A31862.
Or you could simply find the min and max rows and columns:
[rows, columns] = find(binaryImage);
topRow = min(rows);
bottomRow = max(rows);
leftColumn = min(columns);
rightColumn = max(columns);
croppedImage = binaryImage(topRow:bottomRow, leftColumn:rightColumn);
You could also find the bounding box by summing vertically and horizontally and then using find() like above.

14 Comments

Nour
Nour on 21 Dec 2014
Edited: Image Analyst on 21 Dec 2014
Hi, thanks for your help! I've tried the follow method with my 2 images, but the result is not ok.
I = imread('coins.png');
figure(1);
imshow(I);
bw = im2bw(I, graythresh(I));
bw2 = imfill(bw,'holes');
figure(2);
imshow(bw2);
L = bwlabel(bw2);
figure(3);
imshow(label2rgb(L, @jet, [.7 .7 .7]))
s = regionprops(L, 'BoundingBox');
subImage = imcrop(I, s(1).BoundingBox);
figure(4);
imshow(subImage);
%
Im = imread('Lw.jpg');
figure(5);
imshow(Im);
w = im2bw(Im, graythresh(Im));
w2 = imfill(w,'holes');
figure(6);
imshow(w2);
K = bwlabel(w2);
figure(7);
imshow(label2rgb(K, @jet, [.7 .7 .7]))
s = regionprops(K, 'BoundingBox');
subImage = imcrop(Im, s(1).BoundingBox);
figure(8);
imshow(subImage);
But my code is nowhere in sight in your code!
Here, I did it for you. In the code below IS my suggestion that you left out, and it produces the image shown below that.
% Read in original RGB image.
rgbImage = imread('C:\Users\Nour\Documents\Temporary\L1.jpg');
subplot(2, 2, 1);
imshow(rgbImage);
axis on;
fontSize = 30;
title('Original color image with white border', 'FontSize', fontSize);
% Convert to binary.
binaryImage = rgb2gray(rgbImage) > 128;
% Get rid of white border.
binaryImage = imclearborder(binaryImage);
subplot(2, 2, 2);
imshow(binaryImage);
axis on;
title('Binary Image', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
% Give a name to the title bar.
set(gcf, 'Name', 'Demo by ImageAnalyst', 'NumberTitle', 'Off')
% Find bounding box.
[rows, columns] = find(binaryImage);
topRow = min(rows);
bottomRow = max(rows);
leftColumn = min(columns);
rightColumn = max(columns);
% Crop the image.
croppedImage = binaryImage(topRow:bottomRow, leftColumn:rightColumn);
% Show cropped image
subplot(2, 2, 3);
imshow(croppedImage);
axis on;
title('Cropped Image', 'FontSize', fontSize);
Hi, thank you again! In fact, I've followed your suggestion to get the precedent method, and it wasn't ok cause of the white border. I just try yours, it is ok.
Thanks!
Please, can I make the bounding box a bit bigger? For example to add few pixels around the white area.
Sure.
margin = 5;
topRow = max([1, min(rows) - margin]);
bottomRow = min([rows, max(rows) + margin]);
leftColumn = max([1, min(columns) - margin]);
rightColumn = min([columns, max(columns) + margin]);
If that answers the question, please "Accept" it.
Hi, im trying it now. Sorry for the late, and happy new year.
I'm sorry, but I'm having some errors as follows:
Error using horzcat
CAT arguments dimensions are not
consistent.
Error in ExactLocationM2 (line 33)
bottomRow = min([rows, max(rows) + margin]);
Here is how I edit the code:
[rows, columns] = find(binaryImage);
margin = 5;
topRow = max([1, min(rows) - margin]);
bottomRow = min([rows, max(rows) + margin]);
leftColumn = max([1, min(columns) - margin]);
rightColumn = min([columns, max(columns) + margin]);
Please still need your help, tx!
rows is a column vector so you need a semicolon and you need to use the size of the image inside some of the max and min. Corrected code/demo is below:
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 20;
grayImage = mat2gray(peaks(300));
subplot(2, 2, 1);
imshow(grayImage, []);
axis on;
title('Original Image', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
binaryImage = grayImage > 0.75;
subplot(2, 2, 2);
imshow(binaryImage, []);
axis on;
title('Binary Image', 'FontSize', fontSize);
% Determine Cropping box.
[rowsInImage, columnsInImage] = size(binaryImage);
[rows, columns] = find(binaryImage);
margin = 10;
topRow = max([1; min(rows) - margin]);
bottomRow = min([rowsInImage; max(rows) + margin]);
leftColumn = max([1; min(columns) - margin]);
rightColumn = min([columnsInImage; max(columns) + margin]);
% Crop original and show it.
croppedOriginalImage = grayImage(topRow:bottomRow, leftColumn:rightColumn);
subplot(2, 2, 3);
imshow(croppedOriginalImage, []);
axis on;
title('Cropped Original Image', 'FontSize', fontSize);
% Crop binary and show it.
croppedBinaryImage = binaryImage(topRow:bottomRow, leftColumn:rightColumn);
subplot(2, 2, 4);
imshow(croppedBinaryImage, []);
axis on;
title('Cropped Binary Image', 'FontSize', fontSize);
If this works now, please "Accept" the answer.
Hi, yep it's working as I want.
But I have another question in the same way. Can I change the following method to get the same result with a margin:
% 1st method
w2 = imfill(b5,'holes'); figure(); imshow(w2);
K = bwlabel(w2); figure(); imshow(label2rgb(K, @jet, [.7 .7 .7]))
s = regionprops(K, 'BoundingBox'); subImage = imcrop(b5, s(1).BoundingBox); figure(); imshow(subImage);
% 2nd method
% Find bounding box. [rowsInImage, columnsInImage] = size(b5); [rows, columns] = find(b5); margin = 5; topRow = max([1; min(rows) - margin]); bottomRow = min([rowsInImage; max(rows) + margin]); leftColumn = max([1; min(columns) - margin]); rightColumn = min([columnsInImage; max(columns) + margin]); % Crop the image. croppedImage = b5(topRow:bottomRow, leftColumn:rightColumn); % Show cropped image figure(); imshow(b5); figure(); imshow(croppedImage);
The second method is as you tell me to do, and it is effective.
Tx!
Nour
Nour on 23 Jan 2015
Edited: Nour on 23 Jan 2015
Hi,
Every thing was normal before I change my system to windows 8. Now I have a problem with the following commands:
hgexport(gcf, 'L2w.jpg', hgexport('factorystyle'), 'Format', 'jpeg');
There is a white margin around the image, in windows 7 I didn't have this problem as the image is saved without any margin, it seems so strange to have this problem now.
Try Oliver Woodford's export_fig() instead. Check the File Exchange.
Hi, I've tried export_fig() few days ago, but I got some errors, actually I think I don't understand how to use it, please if you can help me with that.
Which File Exchange?
Thanks!
You can contact him at his web site with any error messages: http://undocumentedmatlab.com/blog/export_fig

Sign in to comment.

More Answers (0)

Categories

Find more on Creating, Deleting, and Querying Graphics Objects in Help Center and File Exchange

Asked:

on 21 Dec 2014

Commented:

on 14 Feb 2015

Community Treasure Hunt

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

Start Hunting!