× {{alert.msg}} Never ask again
Get notified about new tutorials RECEIVE NEW TUTORIALS

Crop image by detecting a specific large object or blob in image?

Ray Phan
Jan 30, 2015
<p>It looks like the deer in your image is pretty much connected and closed. What we can do is use <code>regionprops</code> to find all of the bounding boxes in your image. Once we do this, we can find the bounding box that gives the <strong>largest</strong> area, which will presumably be your deer. Once we find this bounding box, we can crop your image and focus on the deer entirely. As such, assuming your image is stored in <code>im</code>, do this:</p> <pre><code>im = im2bw(im); %// Just in case... bound = regionprops(im, 'BoundingBox', 'Area'); %// Obtaining Bounding Box co-ordinates bboxes = reshape([bound.BoundingBox], 4, []).'; %// Obtain the areas within each bounding box areas = [bound.Area].'; %// Figure out which bounding box has the maximum area [~,maxInd] = max(areas); %// Obtain this bounding box %// Ensure all floating point is removed finalBB = floor(bboxes(maxInd,:)); %// Crop the image out = im(finalBB(2):finalBB(2)+finalBB(4), finalBB(1):finalBB(1)+finalBB(3)); %// Show the images figure; subplot(1,2,1); imshow(im); subplot(1,2,2); imshow(out); </code></pre> <p>Let's go through this code slowly. We first convert the image to binary just in case. Your image may be an RGB image with intensities of 0 or 255... I can't say for sure, so let's just do a binary conversion just in case. We then call <code>regionprops</code> with the <code>BoundingBox</code> property to find every bounding box of every unique object in the image. This bounding box is the <strong>minimum spanning bounding box</strong> to ensure that the object is contained within it. Each bounding box is a 4 element array that is structured like so:</p> <pre><code>[x y w h] </code></pre> <p>Each bounding box is delineated by its origin at the top left corner of the box, denoted as <code>x</code> and <code>y</code>, where <code>x</code> is the horizontal co-ordinate while <code>y</code> is the vertical co-ordinate. <code>x</code> increases positively from left to right, while <code>y</code> increases positively from top to bottom. <code>w,h</code> are the width and height of the bounding box. Because these points are in a structure, I extract them and place them into a single 1D vector, then reshape it so that it becomes a <code>M x 4</code> matrix. Bear in mind that this is the only way that I know of that can extract values in arrays for each structuring element efficiently without any <code>for</code> loops. This will facilitate our searching to be quicker. I have also done the same for the <code>Area</code> property. For each bounding box we have in our image, we also have the attribute of the total area encapsulated within the bounding box. </p> <p>Thanks to @Shai for the spot, we can't simply use the bounding box co-ordinates to determine whether or not something has the biggest area within it as we could have a thin diagonal line that could drive the bounding box co-ordinates to be higher. As such, we also need to rely on the <strong>total area</strong> that the object takes up within the bounding box as well. Simply put, it's just the sum of all of the pixels that are contained within the object.</p> <p>Therefore, we search the entire area vector that we have created to see which has the maximum area. This corresponds to your deer. Once we find this location, extract the bounding box locations, then use this to crop the image. Bear in mind that the bounding box values may have floating point numbers. As the image co-ordinates are in integer based, we need to remove these floating point values before we decide to crop. I decided to use <code>floor</code>. I then write code that displays the original image, with the cropped result.</p> <p>Bear in mind that this will <strong>only</strong> work if there is just one object in the image. If you want to find multiple objects, check <a href="http://www.mathworks.com/help/images/ref/bwboundaries.html" rel="nofollow"><code>bwboundaries</code></a> in MATLAB. Otherwise, I believe this should get you started.</p> <p>Just for completeness, we get the following result:</p> <p><img src="http://i.stack.imgur.com/gVAWa.png" alt="enter image description here"></p> <p>This tip was originally posted on <a href="http://stackoverflow.com/questions/24310294/Crop%20image%20by%20detecting%20a%20specific%20large%20object%20or%20blob%20in%20image?/24310570">Stack Overflow</a>.</p>
comments powered by Disqus