2

I am trying to automatically crop the image below to a bounding box. The background will always be the same colour. I have tried the answers at Find the edges of image and crop it in MATLAB and various applications and examples on Mathworks' file exchange but I get stuck at getting a proper boundingbox.

I was thinking to convert the image to black and white, converting it to binary and removing everything that's closer to white than black, but I'm not sure how to go about it.

PencilCase

Community
  • 1
  • 1
Jak
  • 471
  • 5
  • 20

3 Answers3

4

Here's a nice way

img = im2double(imread('https://i.stack.imgur.com/ZuiEt.jpg')); % read image and convert it to double in range [0..1]
b = sum( (1-img).^2, 3 ); % check how far each pixel from "white"

% display
figure; imshow( b > .5 ); title('non background pixels'); 

% use regionprops to get the bounding box
st = regionprops( double( b > .5 ), 'BoundingBox' ); % convert to double to avoid bwlabel of logical input

rect = st.BoundingBox; % get the bounding box

% display
figure; imshow( img );
hold on; rectangle('Position', rect ); 

enter image description here


Following Jak's request, here's the second line explained

after converting img to double type (using im2double), the image is stored in memory as h-by-w-by-3 matrix of type double. Each pixel has 3 values between 0 and 1 (not 255!), representing its RGB values 0 being dark and 1 being bright.
Thus (1-img).^2 checks, for each pixel and each channel (RGB) how far it is from 1 - bright. The darker the pixel - the larger this distance.
Next, we sum the distance per channel to a single value per pixel using sum( . ,3 ) command leaving us with h-by-w 2D matrix of distances of each pixels from white.
Finally, assuming background is bright white we select all pixels that are significantly far from birght b > .5. This threshold is not perfect, but it captures well the boundary of the object.

Community
  • 1
  • 1
Shai
  • 111,146
  • 38
  • 238
  • 371
3

Following the answer of Shai, I present a way to circumvent regionprops (image processing toolbox) just based on find on the black-white image.

% load
img = im2double(imread('https://i.stack.imgur.com/ZuiEt.jpg'));
% black-white image by threshold on check how far each pixel from "white"
bw = sum((1-img).^2, 3) > .5; 
% show bw image
figure; imshow(bw); title('bw image');

% get bounding box (first row, first column, number rows, number columns)
[row, col] = find(bw);
bounding_box = [min(row), min(col), max(row) - min(row) + 1, max(col) - min(col) + 1];

% display with rectangle
rect = bounding_box([2,1,4,3]); % rectangle wants x,y,w,h we have rows, columns, ... need to convert
figure; imshow(img); hold on; rectangle('Position', rect);
Community
  • 1
  • 1
NoDataDumpNoContribution
  • 10,591
  • 9
  • 64
  • 104
  • you are defining `rect` in an unconventional way: Matlab uses `[x y w h]` format (as you probably noted when you used `rectangle`). – Shai Jun 10 '14 at 09:49
  • @Jak you can ask this as a new question. – Shai Jun 10 '14 at 10:16
  • 1
    @Shai Matlab has this problem of defining x as secondary dimension in all image related methods. To avoid confusion on my side I skip x and y and often just talk about first dimension (rows) and second dimension (cols) which is more consistent with the rest of Matlab. Edited the code to make it visible more clearly. – NoDataDumpNoContribution Jun 10 '14 at 10:31
0

to crop an image first create boundry box where you want to crop.

crp = imcrop(original_image_name,boundry_box);

I have done this in my assignment. This really works!!!!!!