OpenCV bounding box

I am working on software that uses OpenCV in a C ++ environment. The goal is to locate the boxing glove and draw a bounding rectangle around the outlines of the gloves .

The problem I am running into is that the bounding box sinks more than once, in fact multiple boxes are drawn. What I've been trying to do over the past few days is to somehow eliminate the clipping count and draw only one large bounding box.

I've looked at some methods to fill an int object with its integer, which I believe will really help in this case.

Below I posted the code that was used to achieve the result displayed in the image:

vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
vector<Vec3f> vecCircles;               
vector<Vec3f>::iterator itrCircles;

while(1)
{
    Mat frame;
    cap >> frame; // get a new frame from camera
    /////////////////////
    Mat imgHSV;
    cvtColor( frame, imgHSV, CV_BGR2HSV );
    ////////////////////
    Mat blur_out;
    GaussianBlur(imgHSV, blur_out, Size(1,1),2.0,2.0);
    ////////////////////
    Mat range_out;
    inRange(blur_out, Scalar(100, 100, 100), Scalar(120, 255, 255), range_out);
    ////////////////////
    findContours(range_out, contours, hierarchy, CV_RETR_TREE,  CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );

     /// Approximate contours to polygons + get bounding rects and circles
     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 = 0; i < contours.size(); i++ )
     { 
         approxPolyDP( Mat(contours[i]), contours_poly[i], 3, true );
         boundRect[i] = boundingRect( Mat(contours_poly[i]) );
     }

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

      

enter image description here

If anyone can offer some advice or provide some source of information where I can find answers to my problems.

EDIT (quick update):

I was able to gradually improve the output image, gradually reaching a calm, satisfied result. The key was the use of blur and expansion, as well as in my function findContours()

. I changed CV_RETR_TREE

to CV_RETR_EXTERNAL

. There were a few other small things I did but the result is good:

enter image description here

Don't know if I should write this here or open a new stream ... But now I need help labeling components and extracting parameters such as center points and area. :)

+3


source to share


4 answers


Currently, you are drawing a bounding box around each path, and findContour will find an outline around each associated white or black component, which is abundant in your snapshot.

So the first thing I would like to do is filter out all this noise with some morphological operations on the thresholding: do an open and close , both of which are a combination of dilatation and erosion .



In your case, something like cvDilate (2 times); cvErode (4 times); cvDilate (2 times)

This should combine all the white blobs into one smooth blob, but the black hole in the middle will remain. You can find the correct size by size, but it's easier to call findContours with CV_RETR_EXTERNAL instead of CV_RETR_TREE, then it will only return the outermost contours.

+5


source


Have a look at my other answer in this question. Compile this code and don't forget to activate the code that is commented out.

Result



enter image description here

+6


source


Before finding the outlines, you must apply a morphological filter such as erode and dilate . After that you can find the outlines and omit the small ones by calculating its size , or with and the height of the bounding box. Finally, you can eliminate those inside another path using hierarchy .

+1


source


as b_m pointed out, you need to apply morphological operations. Then I would do something like finding the largest outline in the image and draw a bounding rectangle just around that outline. I have created the following function for my project, which I think will help you if used correctly.

CvSeq* findLargestContour(CvSeq* contours){

  CvSeq* current_contour = contours;
  double largestArea = 0;
  CvSeq* largest_contour = NULL;

  // check we at least have some contours

  if (contours == NULL){return NULL;}

  while (current_contour != NULL){

      double area = fabs(cvContourArea(current_contour));

      if(area > largestArea){
          largestArea = area;
          largest_contour = current_contour;
      }

      current_contour = current_contour->h_next;
  }

  // return pointer to largest

  return largest_contour;

}

      

0


source







All Articles