diff --git a/modules/python/api b/modules/python/api index c0b3d5d0d7..b56461d390 100644 --- a/modules/python/api +++ b/modules/python/api @@ -1499,6 +1499,15 @@ KalmanCorrect ROCvMat* KalmanPredict ROCvMat* CvKalman* kalman CvMat control NULL +SnakeImage points + IplImage image + CvPoints points + floats alpha + floats beta + floats gamma + CvSize win + CvTermCriteria criteria + int calc_gradient 1 # Optical Flow CalcOpticalFlowLK diff --git a/modules/python/cv.cpp b/modules/python/cv.cpp index 796d23c596..5bb444bcb6 100644 --- a/modules/python/cv.cpp +++ b/modules/python/cv.cpp @@ -1812,16 +1812,24 @@ struct floats { }; static int convert_to_floats(PyObject *o, floats *dst, const char *name = "no_name") { - PyObject *fi = PySequence_Fast(o, name); - if (fi == NULL) - return 0; - dst->count = PySequence_Fast_GET_SIZE(fi); - dst->f = new float[dst->count]; - for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) { - PyObject *item = PySequence_Fast_GET_ITEM(fi, i); - dst->f[i] = (float)PyFloat_AsDouble(item); + if (PySequence_Check(o)) { + PyObject *fi = PySequence_Fast(o, name); + if (fi == NULL) + return 0; + dst->count = PySequence_Fast_GET_SIZE(fi); + dst->f = new float[dst->count]; + for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) { + PyObject *item = PySequence_Fast_GET_ITEM(fi, i); + dst->f[i] = (float)PyFloat_AsDouble(item); + } + Py_DECREF(fi); + } else if (PyNumber_Check(o)) { + dst->count = 1; + dst->f = new float[1]; + dst->f[0] = PyFloat_AsDouble(o); + } else { + return failmsg("Expected list of floats, or float for argument '%s'", name); } - Py_DECREF(fi); return 1; } @@ -2552,6 +2560,16 @@ static PyObject *FROM_CvSubdiv2DEdge(CvSubdiv2DEdge r) return (PyObject*)m; } +static PyObject *FROM_CvPoints(CvPoints src) +{ + PyObject *pr; + pr = PyList_New(src.count); + for (int i = 0; i < src.count; i++) { + PyList_SetItem(pr, i, FROM_CvPoint(src.p[i])); + } + return pr; +} + /************************************************************************/ /* A few functions are too odd to be generated, @@ -3763,6 +3781,17 @@ static int zero = 0; #define constCvMat const CvMat #define FROM_constCvMatPTR(x) FROM_CvMatPTR((CvMat*)x) +#define cvSnakeImage(image, points, length, a, b, g, win, criteria, calc_gradient) \ + do { \ + int coeff_usage; \ + if ((alpha.count == 1) && (beta.count == 1) && (gamma.count == 1)) \ + coeff_usage = CV_VALUE; \ + else if ((length == alpha.count) && (alpha.count == beta.count) && (beta.count == gamma.count)) \ + coeff_usage = CV_ARRAY; \ + else \ + return (PyObject*)failmsg("SnakeImage weights invalid"); \ + cvSnakeImage(image, points, length, a, b, g, coeff_usage, win, criteria, calc_gradient); \ + } while (0) #include "generated0.i" diff --git a/tests/python/test.py b/tests/python/test.py index b62b07010d..8bdfb8de19 100644 --- a/tests/python/test.py +++ b/tests/python/test.py @@ -770,6 +770,26 @@ class FunctionTests(OpenCVTests): expected = 0.0 self.assertEqual(M[rj,cj], expected) + def test_SnakeImage(self): + src = self.get_sample("samples/c/lena.jpg", 0) + pts = [ (512-i,i) for i in range(0, 512, 8) ] + + # Make sure that weight arguments get validated + self.assertRaises(TypeError, lambda: cv.SnakeImage(cv.GetImage(src), pts, [1,2], .01, .01, (7,7), (cv.CV_TERMCRIT_ITER, 100, 0.1))) + + # Smoke by making sure that points are changed by call + r = cv.SnakeImage(cv.GetImage(src), pts, .01, .01, .01, (7,7), (cv.CV_TERMCRIT_ITER, 100, 0.1)) + if 0: + cv.PolyLine(src, [ r ], 0, 255) + self.snap(src) + self.assertEqual(len(r), len(pts)) + self.assertNotEqual(r, pts) + + # Ensure that list of weights is same as scalar weight + w = [.01] * len(pts) + r2 = cv.SnakeImage(cv.GetImage(src), pts, w, w, w, (7,7), (cv.CV_TERMCRIT_ITER, 100, 0.1)) + self.assertEqual(r, r2) + def test_Sum(self): for r in range(1,11): for c in range(1, 11):