OpenCVは「Pythonバインディングを公式サポートしてます!」と言ってるけどイマイチちゃんと動いてなかった。
[追記] SVN HEADで修正されました。
「Python版のSnakeImageバグってるよ!」と書いて以下のpatchを本家のtracに投げたら素早く修正されました。
https://code.ros.org/trac/opencv/ticket/393
Pythonバインディングに結構まだ粗があるのは確かだけど、公式にサポートする気持ちは強いんじゃないでしょうか。
以下もう修正されたのでどうでもいい
OpenCV1.0、1.1とかでどうなのかは知らないけど2.1とSVN版ではpythonから使うとcv.SnakeImageが動かない。
OpenCV2.1のPythonバインディングはSnakeImageがバグってる。SVN版はPythonバインディングからSnakeImageが消えている。(ちゃんと動いてねーから一旦削除ってことだろか。メーリングリストとかフォーラムとか巡っても言及が見当たらない)
しょうがないので自分で適当にPythonバインディングの修正。
~/work/OpenCV-2.1.0/interfaces/python % patch -p0 <opencv-2.1-snakeimage.patch
で適用。
opencv-2.1-snakeimage.patch
Index: api =================================================================== --- api (revision 3239) +++ api (working copy) @@ -1517,16 +1517,16 @@ KalmanPredict ROCvMat* CvKalman* kalman CvMat control NULL -SnakeImage - IplImage image - CvPoints points - floats alpha - floats beta - floats gamma - int coeff_usage - CvSize win - CvTermCriteria criteria - int calc_gradient 1 +#SnakeImage +# IplImage image +# CvPoints points +# floats alpha +# floats beta +# floats gamma +# int coeff_usage +# CvSize win +# CvTermCriteria criteria +# int calc_gradient 1 # Optical Flow CalcOpticalFlowLK Index: cv.cpp =================================================================== --- cv.cpp (revision 3239) +++ cv.cpp (working copy) @@ -1853,6 +1853,18 @@ return 1; } +static int convert_to_PyList(CvPoints *src, PyObject *dst, const char *name = "no_name") +{ + if (!PyList_Check(dst)) + return 0; + for (Py_ssize_t i = 0; i < src->count; i++) { + PyObject *pt = Py_BuildValue("(ii)", src->p[i].x, src->p[i].y); + PyList_SET_ITEM(dst, i, pt); + Py_INCREF(pt); + } + return 1; +} + struct CvPoint3D32fs { CvPoint3D32f *p; int count; @@ -3755,6 +3767,45 @@ return seq; } +static PyObject *pycvFixSnakeImage(PyObject *self, PyObject *args, PyObject *kw) +{ + IplImage* image; + PyObject *pyobj_image = NULL; + CvPoints points; + PyObject *pyobj_points = NULL; + floats alpha; + PyObject *pyobj_alpha = NULL; + floats beta; + PyObject *pyobj_beta = NULL; + floats gamma; + PyObject *pyobj_gamma = NULL; + int coeff_usage; + CvSize win; + PyObject *pyobj_win = NULL; + CvTermCriteria criteria; + PyObject *pyobj_criteria = NULL; + int calc_gradient = 1; + + const char *keywords[] = { "image", "points", "alpha", "beta", "gamma", "coeff_usage", "win", "criteria", "calc_gradient", NULL }; + if (!PyArg_ParseTupleAndKeywords(args, kw, "OOOOOiOO|i", (char**)keywords, &pyobj_image, &pyobj_points, &pyobj_alpha, &pyobj_beta, &pyobj_gamma, &coeff_usage, &pyobj_win, &pyobj_criteria, &calc_gradient)) + return NULL; + if (!convert_to_IplImage(pyobj_image, &image, "image")) return NULL; + if (!convert_to_CvPoints(pyobj_points, &points, "points")) return NULL; + if (!convert_to_floats(pyobj_alpha, &alpha, "alpha")) return NULL; + if (!convert_to_floats(pyobj_beta, &beta, "beta")) return NULL; + if (!convert_to_floats(pyobj_gamma, &gamma, "gamma")) return NULL; + if (!convert_to_CvSize(pyobj_win, &win, "win")) return NULL; + if (!convert_to_CvTermCriteria(pyobj_criteria, &criteria, "criteria")) return NULL; +#ifdef CVPY_VALIDATE_SnakeImage + CVPY_VALIDATE_SnakeImage(); +#endif + ERRWRAP(cvSnakeImage(image, points.p, points.count, alpha.f, beta.f, gamma.f, coeff_usage, win, criteria, calc_gradient)); + if (!convert_to_PyList(&points, pyobj_points, "points")) return NULL; + delete points.p; + + Py_RETURN_NONE; +} + static int zero = 0; /************************************************************************/ @@ -3788,6 +3839,7 @@ //{"_HOGDetectMultiScale", (PyCFunction)pycvHOGDetectMultiScale, METH_KEYWORDS, "_HOGDetectMultiScale(image, svm_classifier, win_stride=block_stride, scale=1.05, group_threshold=2, padding=(0,0), win_size=(64,128), block_size=(16,16), block_stride=(8,8), cell_size=(8,8), nbins=9, gammaCorrection=true) -> list_of_points"}, {"temp_test", temp_test, METH_VARARGS}, + {"SnakeImage", (PyCFunction)pycvFixSnakeImage, METH_KEYWORDS, "SnakeImage(image, points, alpha, beta, gamma, coeff_usage, win, criteria [, calc_gradient]) -> None"}, #include "generated1.i"