Search code examples
opencvimage-processingcontouremgucvopencv3.1

What is difference between (CountNonZero) and (Moment M00) and (ContourArea) in OpenCV?


If I have a 3x3 binary image and there is a contour in locations(x,y): (0,0), (0,1), (1,0), (1,1)

I get the contour via findContours method.

I want to get this contour's area:

  • with CountNonZero: 4
  • with contourArea: 1
  • with Moment M00: 1

What is the correct answer and what is the difference between them?

This contour is square so the area is 2*2 = 4

So why is ContourArea equal to 1?

I am using EmguCV and this is my code:

VectorOfVectorOfPoint cont = new VectorOfVectorOfPoint();

    Image<Gray, byte> img = new Image<Gray, byte>(3,3);

    img[0, 0] = new Gray(255);
    img[0, 1] = new Gray(255);
    img[1, 0] = new Gray(255);
    img[1, 1] = new Gray(255);
    CvInvoke.FindContours(img, cont, null, Emgu.CV.CvEnum.RetrType.External, Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple);

    Moments m = CvInvoke.Moments(cont[0], true);
    Console.WriteLine(CvInvoke.ContourArea(cont[0]));

    CvInvoke.Imshow("ss", img);
    CvInvoke.WaitKey(0);

Solution

  • I’m not aware of implementation details, but I would suspect that the “contour” is a polygon that goes from pixel center to pixel center around the object. This polygon is smaller than the set of pixels, each edge is moved inwards by half a pixel distance.

    This is consistent with the area of a 2x2 pixel block being measured as 1 pixel.

    If you want to measure area, don’t use the contour functionality. Use connected component analysis (object labeling) and count the number of pixels in each connected component.


    OpenCV is not meant for precise quantification, and there are lots of things in it that don’t make sense to me.