I want to find the width and height of the connected component objects using regionprops 'BoundingBox' property in matlab.I find and mark the rectangles but I don't know how to extract the height and width.So how can I extract it?My code is given below
cc=bwconncomp(im);
stats=regionprops(cc,'BoundingBox');
for n = 1 : length(stats)
thisBB = stats(n).BoundingBox;
rectangle('Position', [thisBB(1),thisBB(2),thisBB(3),thisBB(4)],...
'EdgeColor','r','LineWidth',1 )
end
You have already extracted the width and height of the rectangle. The output of 'BoundingBox' in the BW case is
[ corner_x corner_y, width, height]
thisBB(3) is therefore the width, and thisBB(4) is the height.
The rectangle function expects exactly this as input: [x,y,w,h].
Related
To get a sub-image there is imcrop function. but I want to crop the sub-image using its centroid, (x,y) that was achieved already.
Image = 512x512
Centroid = (x,y) = (178.92, 207.20)
Also, the imcrop function doesn't get any input as Centroid.
B = imcrop(A, [col, row, width, height];
How to crop the sub-image using its centroid ?
Also, according to the specified size and position of the rectangle that is estimated using the center of (x, y)), the sub-image is cropped but its output wasn't correct.
Ex:
To calculate the input argument of `imcrop` function, we have:
Diam of Obj = 50 pixel.
then its window = 50x50 pixel.
and so 57/2 = 28 to add and subtract of centroid.
Win_Obj = imcrop(RNod,[c(1)-28, c(2)-28, c(1)+28, c(2)+28]);
According to your post and also the docs, the function imcrop() uses a rectangle as second parameter in the form [x_min y_min width height], so you just need to change your call of imcrop to the following form:
% c is the known centroid position
Win_Obj = imcrop(RNod, [c(1)-28 c(2)-28 2*28 2*28]);
This should give you a sub-image with your object in the center.
I have background subtracted images as input. The idea is to reduce search areas for person detection by using a smaller search area for the HOG algorithm. The output required is a bounding box around the person and the pixel positions of the box corners.
This is the input image:
This is the required output:
This is what I have tried so far:
x=imread('frame 0080.png');
y=im2bw(x);
s=regionprops(y);
imshow(y);
hold on
for i=1:numel(s)
rectangle('Position',s(i).BoundingBox,'edgecolor','y')
end
This was the output I got:
It looks like you have tried what I have suggested. However, you want the bounding box that encapsulates the entire object. This can easily be done by using the BoundingBox property, then calculating each of the four corners of each rectangle. You can then calculate the minimum spanning bounding box that encapsulates all of the rectangles which ultimately encapsulates the entire object.
I do notice that there is a thin white strip at the bottom of your image, and that will mess up the bounding box calculations. As such, I'm going to cut the last 10 rows of the image before we proceed calculating the minimum spanning bounding box. To calculate the minimum spanning bounding box, all you have to do is take all of the corners for all of the rectangles, then calculate the minimum and maximum x co-ordinates and minimum and maximum y co-ordinates. These will correspond to the top left of the minimum spanning bounding box and the bottom right of the minimum spanning bounding box.
When taking a look at the BoundingBox property using regionprops, each bounding box outputs a 4 element vector:
[x y w h]
x,y denote the top left co-ordinate of your bounding box. x would be the column and y would be the row of the top left corner. w,h denote the width and the height of the bounding box. We would use this and compute top left, top right, bottom left and bottom right of every rectangle that is detected. Once you complete this, stack all of these rectangle co-ordinates into a single 2D matrix, then calculate the minimum and maximum x and y co-ordinates. To calculate the rectangle, simply use the minimum x and y co-ordinates as the top left corner, then calculate the width and height by subtracting the maximum and minimum x and y co-ordinates respectively.
Without further ado, here's the code. Note that I want to extract all of the bounding box co-ordinates in a N x 4 matrix where N denotes the number of bounding boxes that are detected. You would have to use reshape to do this correctly:
% //Read in the image from StackOverflow
x=imread('http://i.stack.imgur.com/mRWId.png');
% //Threshold and remove last 10 rows
y=im2bw(x);
y = y(1:end-10,:);
% //Calculate all bounding boxes
s=regionprops(y, 'BoundingBox');
%// Obtain all of the bounding box co-ordinates
bboxCoords = reshape([s.BoundingBox], 4, []).';
% // Calculate top left corner
topLeftCoords = bboxCoords(:,1:2);
% // Calculate top right corner
topRightCoords = [topLeftCoords(:,1) + bboxCoords(:,3) topLeftCoords(:,2)];
% // Calculate bottom left corner
bottomLeftCoords = [topLeftCoords(:,1) topLeftCoords(:,2) + bboxCoords(:,4)];
% // Calculate bottom right corner
bottomRightCoords = [topLeftCoords(:,1) + bboxCoords(:,3) ...
topLeftCoords(:,2) + bboxCoords(:,4)];
% // Calculating the minimum and maximum X and Y values
finalCoords = [topLeftCoords; topRightCoords; bottomLeftCoords; bottomRightCoords];
minX = min(finalCoords(:,1));
maxX = max(finalCoords(:,1));
minY = min(finalCoords(:,2));
maxY = max(finalCoords(:,2));
% Draw the rectangle on the screen
width = (maxX - minX + 1);
height = (maxY - minY + 1);
rect = [minX minY width height];
% // Show the image
imshow(y);
hold on;
rectangle('Position', rect, 'EdgeColor', 'yellow');
This is the image I get:
I have a project to detect an object with background subtraction. But I can only set minimumblobarea with minimum pixel.. in my case, I need to set minimunblobarea to detect object in width and height to get specific object.. example : if there is an object bigger than width and height that I've set before, that object can't be detected.. so what should I do?
I Use this code
http://www.mathworks.com/help/vision/examples/motion-based-multiple-object-tracking.html
vision.BlobAnalysis returns bounding boxes of the detected blobs. The bounding box is a 4-element array of the form [x, y, width, height]. Once you have the bounding boxes you can easily check with ones have the width or the height that is too big, and exclude them.
Let's say you have N bounding boxes returned by vision.BlobAnalysys as an N-by-4 matrix called bboxes. You can use logical indexing to find boxes that are too big:
bigBoxesIdx = (bboxes(:, 3) > maxWidth) | (bboxes(:,4) > maxHeight);
bigBoxesIdx is now a logical array, where you have 1's for boxes that are too big, and 0's for the ones that are not. Note that you have to use the |, which stands for "element-wise or", rather than ||.
Now to throw away the boxes that are too big you simply do
bboxes(bigBoxesIdx, :) = [];
I have a mammographic image of size 1024 x 1024, and I have the center coordinates of the anomaly (338.314) and the radius (56) in pixels of the circle containing the anomaly. I desire to extract a region of interest of size 128 * 128 including the anomaly. I tried with
rect = [338-64,314-64,127,127];
crop = imcrop (img, rect) ;
but I obtien an ROI that does not contain the desired anomaly.
any suggestions please.
MATLAB's matrix indices are in (row,column) format, while rectangle's indices are usually in (x,y) format.
This means that you probably need to swap the two first elements of rectangle.
rect = [314-64,338-64,127,127];
crop = imcrop (img, rect) ;
I wrote a code for image cropping. I used imrect to draw a rectangle on the image and then get the position of it by using the method getposition. I wrote a function which uses image pixel coordinates for cropping operation. How can I create a relationship between values return by getposition method and image pixel coordinates.My code for cropping is as follows,
[rnum cnum dim]=size(img);
for h=1:dim
for i=1:width
for j=1:height
negative(i,j,h)=img(xmin+i,ymin+j,h);
end
end
end
width,height,xmin,ymin have to found from getposition method
Like you said, imrect's getPosition method will return:
[xmin ymin width height] = getPosition( h );
The first two values are the top-left corner of the rectangle, and the next two values are the length of the sides of the rectangle. These should all be in pixel coordinates if you are using imrect.
To crop an image based on these position values, you will start at the top-left corner of (xmin, ymin) and go to the bottom-right corner at (xmin+width-1, ymin+height-1).
You should not use for loops to get the pixel data, you can take advantage of MATLAB's vectorization characteristics and do the following:
CroppedImageMatrix = OriginalImageMatrix( [ymin : 1 : ymin+height-1],
[xmin : 1 : xmin+width-1],
: );
This will immediately "crop" the image and place the cropped data into the new matrix. You can do this because you are using a rectangular crop and all of the indices correspond to create a rectangular lattice of points. It would be "trickier" if this was not a rectangular crop.
This also will work the same for color or grayscale images because you do not need to index the channel dimension, you just take the values from every available channel.
P.S. - Documentation page for imrect: http://www.mathworks.com/help/images/ref/imrect.html