Avi Maikoo Avi Maikoo - 1 month ago 23
C++ Question

How to get the bounding box of ROI

Im trying to get the bounding box of a footprint image. Im using find contours to draw the bounding boxes, but instead of getting a bounding box for the entire footprint, i am getting bounding boxes for the individual components of the footprint. Using the suggestions made below, I am still not getting the desired results. Here is the code I am using: Mat ROI_Detection::getBoundingBox_Train(Mat inputImage) {
outputImage = inputImage.clone();
Mat imageContours = inputImage.clone();

RNG rng(12345);
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;

// Find contours
findContours(imageContours, contours, hierarchy, CV_RETR_TREE,
CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

vector<vector<Point> > contours_poly(contours.size());
vector<Rect> boundRect(contours.size());
vector<Point2f> center(contours.size());
vector<float> radius(contours.size());

for (int i = 1; i < contours.size(); i++) {
approxPolyDP(Mat(contours[i]), contours_poly[i], 3, true);
boundRect[i] = boundingRect(Mat(contours_poly[i]));
//minEnclosingCircle( (Mat)contours_poly[i], center[i], radius[i] );
}

/// Draw polygonal contour + bonding rects + circles
Mat boundingBox = Mat::zeros(outputImage.size(), CV_8UC3);
for (int i = 0; i < contours.size(); i++) {
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255),
rng.uniform(0, 255));
drawContours(boundingBox, contours_poly, i, color, 1, 8,
vector<Vec4i>(), 0, Point());
rectangle(boundingBox, boundRect[i].tl(), boundRect[i].br(), color, 2,
8, 0);
//circle( boundingBox, center[i], (int)radius[i], color, 2, 8, 0 );
}


int topLeft_X = 0;
int topLeft_Y = 0;
int bottomRight_X = 0;
int bottomRight_Y = 0;

for (int i = 0; i < boundRect.size(); i++) {
if (boundRect[i].x < topLeft_X)
topLeft_X = boundRect[i].x;

if (boundRect[i].y < topLeft_Y)
topLeft_Y = boundRect[i].y;

if ((boundRect[i].width + boundRect[i].x) > bottomRight_X)
bottomRight_X = (boundRect[i].width + boundRect[i].x);

if ((boundRect[i].height + boundRect[i].y) > bottomRight_Y)
bottomRight_Y = (boundRect[i].height + boundRect[i].y);
}

boundingBox = Mat::zeros(outputImage.size(), CV_8UC3);
Rect rect(topLeft_X,topLeft_Y,bottomRight_X - topLeft_X ,bottomRight_Y - topLeft_Y);
rectangle(outputImage,rect,Scalar(200,0,0),2, 8, 0);

return outputImage;


}

Sample picture of output: (https://i.stack.imgur.com/MaKqK.png)

Answer

Why don't you try iterating over all boundingboxes, saving the lowest of X & Y values, and the highest of X + width and Y + height values.

Given these, you can construct a boundingbox

cv::Rect(Xlow, Ylow, Xhigh-Xlow, Yhigh-Ylow)

Also, next time, please describe what you have tried already - I assume you haven't put a lot of effort into this one yourself :)