Avi Maikoo - 9 months ago 69

C++ Question

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 Source

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 :)