OpenCV calculate center of mass for a single contour I was recently going through some OpenCV code that finds the center of mass in a contour and realized there is potential room for optimisation.

What I noticed looking back through my code is when I calculate the mass I'm using contours.size() which makes me believe that I'm calculating the moments and center of mass for all of my contours.

In my cases this is not needed as I have a function that returns the largest contour that I have found getMaxAreaContourId(contours, imageSize); which returns an int that I can use like contours[largestContour] and largestContour would be set from the result of getMaxAreaContourId

So if I'm not mistaken would I be able to just find the moment and mass from a single contour and completely remove two for loops?

Because Ultimately I end up doing this:

int CenterOfContourX = mc[largestContour].x;
 int CenterOfContourY = mc[largestContour].y;

Really the end goal is to end up with two integers that represent the center of mass of my contour.

Code to optimise:

// Get the moments
mu.reserve(contours.size());
for( int i = 0; i &lt; contours.size(); i++ )
{ mu[i] = moments( contours[i], false ); }

// Get the mass centers:
std::vector&lt;cv::Point2f&gt; mc( contours.size() );
for( int i = 0; i &lt; contours.size(); i++ )
{ mc[i] = cv::Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 ); }
It seem like you can definitely merge the two loops together.

Also you should avoid iterating using i, instead, use iterators, or the range-based for loop (since C++11).

// if you needed this vector
mu.reserve(contours.size());

// Get the mass centers:
std::vector&lt;cv::Point2f&gt; mc( contours.size() );
for( auto&amp; c : contours )
{
  auto m = moments(c, false); 
  mu.push_back(m); // only if you need the mu vector
  mc.push_back(cv::Point2f( m.m10/m.m00 , m.m01/m.m00 )); 
}


And this can even be simplified to a call to std::transfer with std::back_inserter:

std::transform(
  std::begin(contours),
  std::end(contours),
  std::back_inserter(mc),
  [](const contour&amp; c) -&gt; cv::Point2f {
    auto m = moments(c, false);
    return cv::Point2f( m.m10/m.m00 , m.m01/m.m00 )
  }
);


And of course if you only need to know moments of one countour, there is no need to count it for all, but since you haven't included that part of the code, it's hard to tell anything about it.