OpenCV 中的 (CountNonZero) 和 (Moment M00) 以及 (ContourArea) 有什么区别?

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

如果我有一个 3x3 的二进制图像并且在位置 (x,y) 中有一个轮廓:(0,0), (0,1), (1,0), (1,1)

我通过findContours方法得到轮廓。

我想得到这个轮廓的面积:

正确答案是什么,它们之间有什么区别?

这个等高线是正方形所以面积是2*2 = 4

那么为什么 ContourArea 等于 1?

我正在使用 EmguCV,这是我的代码:

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);

我不知道实现细节,但我怀疑“轮廓”是一个从像素中心到对象周围像素中心的多边形。此多边形小于像素集,每条边向内移动半个像素距离。

这与将 2x2 像素块的面积测量为 1 个像素一致。

如果要测量面积,请不要使用等高线功能。使用连通分量分析(对象标记)并计算每个连通分量中的像素数。


OpenCV不是用来精确量化的,里面有很多东西我看不懂

相关,您的轮廓是一个边长为 1 像素的正方形 ==> 面积 = 1 像素的平方。

这是图像和轮廓的样子:

image: 
 [[255 255   0]
 [255 255   0]
 [  0   0   0]]

contour: 
 [[[0 0]]

 [[0 1]]

 [[1 1]]

 [[1 0]]]

area: 
1.0