14

What is the best way to draw a single contour in OpenCV? As far as i can see drawContours can only handle multiple contours.

Background: I want to change my code to a for each loop. The old code:

//vector<vector<Point> > contours = result of findContours(...)
for (int i = 0; i < contour.size; i++){
    if(iscorrect(contours[i])){
        drawContours(img, contours, i, color, 1, 8, hierarchy);
    }
 }

The way presented in this mailing list is pretty ugly:

for (vector<Point> contour : contours){
     if(iscorrect(contour)){
          vector<vector<Point> > con = vector<vector<Point> >(1, contour);
          drawContours(img, con, -1, color, 1, 8);
     }
}

Is there a cleaner way to draw single contours (vector< Point> Object)?

Sebastian Schmitz
  • 1,884
  • 3
  • 21
  • 41

3 Answers3

13

I had the same question, and the better way that I've found until now, is this:

for (vector<Point> contour : contours){
  if(iscorrect(contour)){
    drawContours(img, vector<vector<Point> >(1,contour), -1, color, 1, 8);
  }
}

This is almost the same that you have, but one line less.

My first thought was to use Mat(contour) but it didn't work.

If you've found a better way to do it, publish it here and share the wisdom.

Parmaia
  • 1,172
  • 1
  • 13
  • 28
  • With Optimization turned on it should be identical machine code after compilation. I have no better way, maybe with openCV update there will be implemented something. – Sebastian Schmitz Jun 24 '14 at 10:05
8

With OpenCV 3.0 polylines() is more flexible, and we can do, e.g.:

vector<Point> approx;
polylines(frame, approx, true, color, 1, 8);

In your loop this would be:

for (vector<Point> contour : contours) {
    if (iscorrect(contour)) {
        polylines(frame, approx, true, color, 1, 8);
    }
}
br1
  • 425
  • 4
  • 9
2

Using draw contours, it is not exactly pretty, but you don't need a loop.

std::vector<cv::Point> contour;
std::vector<std::vector<cv::Point> > contourVec;
contourVec.push_back(contour);

cv::drawContours(img,contourVec,0,color,1,8,hierarchy); //Replace i with 0 for index. 
David Nilosek
  • 1,422
  • 9
  • 13