2

I have written a script in python that utilises the max() method, I am trying to recreate a similar program in c++ but I am having trouble obtaining the value for the largest contour in a mask.

I have tried to use the max_element() function from the algorithm library in C++ but to no avail. I have also tried to dereference the iterator but receive a series of errors, here is my code:

if (contours.size() > 0)
{
    c = *max_element(contours.begin(), contours.end());
    //not compiling
}

Here is the error:

no match for 'operator=' (operand types are 'std::vector<std::vector<cv::Point_<int> > >' and 'std::vector<cv::Point_<int> >')

Here is how I do it in Python:

if len(contours) > 0;
        #find largest contour in mask, use to compute minEnCircle 
        c = max(contours, key = cv2.contourArea)
        (x,y), radius) = cv2.minEnclosingCircle(c)
        M = cv2.moments(c)
Miki
  • 40,887
  • 13
  • 123
  • 202
randy sandy
  • 89
  • 1
  • 14

2 Answers2

9

In your Python example you are passing a comparator as the key argument

c = max(contours, key = cv2.contourArea)

The equivalent of doing this is to pass a comparator to std::max_element as well

auto c = *std::max_element(contours.begin(),
                           contours.end(),
                           [](std::vector<cv::Point> const& lhs, std::vector<cv::Point> const& rhs)
          {
              return contourArea(lhs, false) < contourArea(rhs, false);
          });

In this case c will be of type std::vector<cv::Point> which represents a contour.

Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
  • 3
    typenames are ok ;D – Miki Nov 22 '16 at 12:23
  • Thank you for your prompt reply, I tried to compile this however received an error stating " 'auto' changes meaning in c++11; please remove it". – randy sandy Nov 22 '16 at 13:40
  • 1
    After compiling without 'auto' I receive an error stating " lamba expressions only available with -std=c++11 or std-gnu++11. – randy sandy Nov 22 '16 at 13:41
  • 2
    Did you previously define the variable `c`? If so, it needs to be declared `std::vector`, then you can remove the `auto` within your `if` block. Yes lambdas are only available in C++11 or later, if you are using a previous compiler version you can [write a functor](https://stackoverflow.com/questions/356950/c-functors-and-their-uses) instead which will act the same way. – Cory Kramer Nov 22 '16 at 14:06
  • 1
    Thank you for the illumination upon functors!! I am using gcc-4.9 on Qt and so I discovered that I needed to amend my .pro file to include the line "QMAKE_CXXFLAGS += -std=c++11" . Thanks again! – randy sandy Nov 22 '16 at 14:25
0

I assume the collection is a nested vector of points according to what findContours function from OpenCV requires.

In such case you can see an example of the solution: Find Biggest Contour Using C++

Basically you call contourArea to acquire the actual area taken by the contour, or boundingRect alternatively minAreaRect to determine the area a contour can be enclosed with. Depends on what you actually require.

Community
  • 1
  • 1
Dusteh
  • 1,496
  • 16
  • 21