Possible bug in cv::moments (Bug #1719)
Description
I was trying to get the centroid of a series of points recently, and I noticed that this particular sequence of points returned an m00
of 0.0. The code below shows the issue I've run into:
#include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <iostream> using namespace cv; using namespace std; int main(int argc, char* argv[]) { 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); cout << "m.m00 = " << m.m00 << endl; cout << "m.m01 = " << m.m01 << endl; cout << "m.m01 = " << m.m10 << endl; return 0; }
Is this supposed to return all zeros with this call? Thanks!
Associated revisions
added test for ticket #1719 and added a note about contour self-intersections to the docs
Merge pull request #1719 from ilya-lavrenov:ocl_gaussianBlur
History
Updated by Stefan Balke almost 13 years ago
Got the same problem.
From my mail to Will:
Hi Will,
I got the same problem,
try out five Points and it will work.
I suppose that due to calculating the moments via green's law,
you need a minimum amount of points.
Do you have a deeper understanding of calculating it?
In the end I will kick contours smaller than 4 pixels out of my vector.
Best regards
Stefan
#include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <iostream> using namespace cv; using namespace std; int main(int argc, char* argv[]) { 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)); points.push_back(Point(49, 53)); Moments m = moments(points, false); cout << "m.m00 = " << m.m00 << endl; cout << "m.m01 = " << m.m01 << endl; cout << "m.m01 = " << m.m10 << endl; return 0; }
Does anyone know how openCV does the discrete calculation of Green's law?
Looked up the source code but didn't get the answer....
Thanks
Stefan
Updated by Vadim Pisarevsky almost 13 years ago
the contour contains self-intersections, thus the result is correct (i.e. it complies the Green formula). To handle butterfly contours correctly, you need to add a stub vertex at the intersection of the lines and change the ordering of vertices so that the contour will just touch itself, but not intersect, i.e. you should be able to draw the whole shape in either clockwise or counter-clockwise direction and not change the direction.
I added the note about it into the reference manual in SVN trunk.
- Status changed from Open to Cancelled
- Assignee set to Vadim Pisarevsky
Updated by Will Lucas almost 13 years ago
Thanks for the information about Green's formula! I learned something new! I switched to just averaging the contour locations, which worked for my specific problem.
Updated by Stefan Balke almost 13 years ago
To find these intersections one could use a sweep line algorithm:
http://www.cs.uu.nl/geobook/pseudo.pdf
cf. pp. 3-4