double m02, double m30, double m21, double m12, double m03 );
Moments( const CvMoments& moments );
operator CvMoments() const;
+
+ // spatial moments
+ double m00, m10, m01, m20, m11, m02, m30, m21, m12, m03;
+ // central moments
+ double mu20, mu11, mu02, mu30, mu21, mu12, mu03;
+ // central normalized moments
+ double nu20, nu11, nu02, nu30, nu21, nu12, nu03;
+ }
In case of a raster image, the spatial moments :math:`\texttt{Moments::m}_{ji}` are computed as:
The moments of a contour are defined in the same way but computed using the Green's formula (see http://en.wikipedia.org/wiki/Green_theorem). So, due to a limited raster resolution, the moments computed for a contour are slightly different from the moments computed for the same rasterized contour.
+.. note::
+
+ Since the contour moments are computed using Green formula, you may get seemingly odd results for contours with self-intersections, e.g. a zero area (``m00``) for butterfly-shaped contours.
+
.. seealso::
:ocv:func:`contourArea`,
:ocv:func:`moments` , the area is computed using the Green formula. Thus, the returned area and the number of non-zero pixels, if you draw the contour using
:ocv:func:`drawContours` or
:ocv:func:`fillPoly` , can be different.
+Also, the function will most certainly give a wrong results for contours with self-intersections.
Example: ::
TEST(Imgproc_Moments, accuracy) { CV_MomentsTest test; test.safe_run(); }
TEST(Imgproc_HuMoments, accuracy) { CV_HuMomentsTest test; test.safe_run(); }
+
+class CV_SmallContourMomentTest : public cvtest::BaseTest
+{
+public:
+ CV_SmallContourMomentTest() {}
+ ~CV_SmallContourMomentTest() {}
+protected:
+ void run(int)
+ {
+ try
+ {
+ vector<Point> points;
+ points.push_back(Point(50, 56));
+ points.push_back(Point(53, 53));
+ points.push_back(Point(46, 54));
+ points.push_back(Point(49, 51));
+
+ Moments m = moments(points, false);
+ double area = contourArea(points);
+
+ CV_Assert( m.m00 == 0 && m.m01 == 0 && m.m10 == 0 && area == 0 );
+ }
+ catch(...)
+ {
+ ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
+ }
+ }
+};
+
+TEST(Imgproc_ContourMoment, small) { CV_SmallContourMomentTest test; test.safe_run(); }