From e88ff6837a7f5fd0b2437d769e46afd2a72110ff Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Wed, 4 Apr 2012 11:35:51 +0000 Subject: [PATCH] added test for ticket #1719 and added a note about contour self-intersections to the docs --- ...uctural_analysis_and_shape_descriptors.rst | 13 ++++++++ modules/imgproc/test/test_moments.cpp | 30 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/modules/imgproc/doc/structural_analysis_and_shape_descriptors.rst b/modules/imgproc/doc/structural_analysis_and_shape_descriptors.rst index 84f80a30f..80be517be 100644 --- a/modules/imgproc/doc/structural_analysis_and_shape_descriptors.rst +++ b/modules/imgproc/doc/structural_analysis_and_shape_descriptors.rst @@ -30,6 +30,14 @@ The function computes moments, up to the 3rd order, of a vector shape or a raste 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: @@ -66,6 +74,10 @@ The normalized central moments 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`, @@ -342,6 +354,7 @@ The function computes a contour area. Similarly to :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: :: diff --git a/modules/imgproc/test/test_moments.cpp b/modules/imgproc/test/test_moments.cpp index ca53d8c7a..0152777cc 100644 --- a/modules/imgproc/test/test_moments.cpp +++ b/modules/imgproc/test/test_moments.cpp @@ -391,3 +391,33 @@ void CV_HuMomentsTest::prepare_to_validation( int /*test_case_idx*/ ) 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 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(); }