0

I have an image with a white background and trying to extract the object within it using MATLAB. I tried different techniques (bounded box) but I am not getting desired results. I have tried this StackOverflow post but it isn't quite working: MATLAB Auto Crop

How I can extract the object? Any idea which technique is suitable?

The image is shown below:

Community
  • 1
  • 1
  • Nice image. Can you precise what is the desired result ? – Ratbert Feb 20 '15 at 16:37
  • Show manually what would be the desired result. – Ander Biguri Feb 20 '15 at 16:39
  • I guess you have several images (scans) with a cheque randomly positionned and orientated, and you want to extract the cheque as a rectangle image. Do you confirm ? – Ratbert Feb 20 '15 at 16:40
  • Please note that your background is NOT white. There is a shadow on the right side, which can complicate things. – Ratbert Feb 20 '15 at 16:44
  • it will effect the result. but any suggestions how i can do that? which technique i should use to extract image? – raja hassan Feb 20 '15 at 16:56
  • I am not good at image processing at all, so this can be a really long shot, but I guess that you may want to bother of trying some. What I was thinking about was if you somehow could make the gray background white. It would be the data on the cheque that is the most important I mean. The assumption is then that the things looking gray should have about the same intensity for all color and be quite much brighter than the black text. If this is possible to do, it would be easier to apply the code you tried. You can also copy the image data and modify the copy. Then cut in non modified. – patrik Feb 20 '15 at 18:03
  • This is a difficult problem because the lower portion of the cheque has almost the same intensity and contrast with the background. Standard thresholding techniques will not work. You will most likely need some user intervention in order to help you out (Graph Cuts, Random Walks, etc.). BTW, do you have some control on the scanning media? Can you perhaps place a darker sheet of paper on the scanner bed before scanning the check? – rayryeng Feb 20 '15 at 19:37

1 Answers1

4

I propose the following workflow:

  1. Binarize the image
  2. Get the centroid and orientation of the main object
  3. Crop the image to set the center of the object at the center of the image
  4. Rotate the object with respect to the center to compensate for the tilt
  5. Crop again to get the object

In practice, step 1 turned out to be rather complicated to perform because of the shadow and of the not-so-well-defined boundaries between the white part of the object and the background. The trick I used relies on the fact that, because of the many details inside the object (and the jpg compression) there is a lot of "noise" all over it. So looking for edges combined with a BW-dilation produced a very decent binarized image. I then used regioprops to filter the small outliers and get the properties of the object.

Here is the code:

% --- Load image
Img = imread('Tilted.jpg');

% --- Binarisation

% Find edges and dilate to get a bloc
BW = edge(mean(Img,3),'sobel');
BW = imdilate(BW, strel('disk',5));

% Get BW image
RP = regionprops(BW, 'Area', 'PixelIdxList', 'Centroid', 'Orientation');
[~, i] = max([RP(:).Area]);
BW = Img(:,:,1)*0;
BW(RP(i).PixelIdxList) = 1;
x = RP(i).Centroid(1);
y = RP(i).Centroid(2);
theta = -RP(i).Orientation;

% imshow(BW)
% plot(x+[0 500*cos(theta*pi/180)], y+[0 500*sin(theta*pi/180)]);
% return

% --- First crop
w = min(x-1, size(Img,2)-x);
h = min(y-1, size(Img,1)-y);
C = Img(ceil(y-h):floor(y+h), ceil(x-w):floor(x+w),:);

% --- Rotate image
R = imrotate(C, theta);
R(R==0) = 255;

% --- Second crop

% Parameters (to adjust)
th = 70;
margin = 25; 

% Remove grey levels
Rwg = std(double(R),0,3).^2;

% Get x-bounds
sx = sum(Rwg,1);
x1 = max(find(sx>prctile(sx,th), 1, 'first')-margin, 1);
x2 = min(find(sx>prctile(sx,30), 1, 'last')+margin, size(Rwg,1));

% Get y-bounds
sy = sum(Rwg,2);
y1 = max(find(sy>prctile(sy,th), 1, 'first')-margin, 1);
y2 = min(find(sy>prctile(sy,th), 1, 'last')+margin, size(Rwg,1));

Res = R(y1:y2, x1:x2, :);

% --- Display
imshow(Res)

Of course, if you have many different images to process this may not work every time. This code is only a starting point and you now have to modify it to meet your precise needs.

Best,

Ratbert
  • 5,463
  • 2
  • 18
  • 37
  • 1
    Ho, and if you are satisfied with the answer, you can say thank you by either mark the problem as solved or by sending me one of your checks ;-) – Ratbert Feb 21 '15 at 10:54
  • Adjust th and/or margin – Ratbert Feb 21 '15 at 11:50
  • @rajahassan: approved your edit with the intention to hide personally identifiable information. – Jonas Feb 21 '15 at 13:44
  • @rajahassan: OK, I removed the image from the answer. But this was nothing more than a part of the image you posted ... – Ratbert Feb 21 '15 at 19:28