From d3a159d3cc9b0d5b21b0cdb059cbdff596043317 Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Wed, 4 May 2011 17:31:48 +0000 Subject: [PATCH] added missing Python wrappers for OpenCV 1.x --- modules/python/src1/api | 1804 ++++++++++++ modules/python/src1/cv.cpp | 4144 ++++++++++++++++++++++++++++ modules/python/src1/defs | 339 +++ modules/python/src1/gen.py | 631 +++++ modules/python/src1/hdr_parser.pyc | Bin 0 -> 17939 bytes 5 files changed, 6918 insertions(+) create mode 100644 modules/python/src1/api create mode 100644 modules/python/src1/cv.cpp create mode 100644 modules/python/src1/defs create mode 100644 modules/python/src1/gen.py create mode 100755 modules/python/src1/hdr_parser.pyc diff --git a/modules/python/src1/api b/modules/python/src1/api new file mode 100644 index 0000000000..9936407704 --- /dev/null +++ b/modules/python/src1/api @@ -0,0 +1,1804 @@ +# Macros +CV_RGB CvScalar + double red + double grn + double blu +CV_MAT_CN int + int i +CV_MAT_DEPTH int + int i +Scalar CvScalar + double val0 + double val1 0 + double val2 0 + double val3 0 +ScalarAll CvScalar + double val0123 +RealScalar CvScalar + double val0 +CV_IABS int + int a +CV_CMP int + int a + int b +CV_SIGN int + int a +CV_FOURCC int + char c1 + char c2 + char c3 + char c4 +CV_MAKETYPE int + int depth + int cn +CV_8UC int + int n +CV_8SC int + int n +CV_16UC int + int n +CV_16SC int + int n +CV_32SC int + int n +CV_32FC int + int n +CV_64FC int + int n + +# Initialization +CloneImage IplImage* + IplImage image +SetImageCOI + IplImage image + int coi +GetImageCOI int + IplImage image +SetImageROI + IplImage image + CvRect rect +ResetImageROI + IplImage image +GetImageROI CvRect + IplImage image +CloneMat CvMat* + CvMat mat +CloneMatND CvMatND* + CvMatND mat + +# Accessing Elements and sub-Arrays + +Get1D CvScalar + CvArr arr + int idx +Get2D CvScalar + CvArr arr + int idx0 + int idx1 +Get3D CvScalar + CvArr arr + int idx0 + int idx1 + int idx2 +GetND CvScalar + CvArr arr + ints indices +GetReal1D double + CvArr arr + int idx0 +GetReal2D double + CvArr arr + int idx0 + int idx1 +GetReal3D double + CvArr arr + int idx0 + int idx1 + int idx2 +GetRealND double + CvArr arr + ints idx +mGet double + CvMat mat + int row + int col +Set1D + CvArr arr + int idx + CvScalar value +Set2D + CvArr arr + int idx0 + int idx1 + CvScalar value +Set3D + CvArr arr + int idx0 + int idx1 + int idx2 + CvScalar value +SetND + CvArr arr + ints indices + CvScalar value +SetReal1D + CvArr arr + int idx + double value +SetReal2D + CvArr arr + int idx0 + int idx1 + double value +SetReal3D + CvArr arr + int idx0 + int idx1 + int idx2 + double value +SetRealND + CvArr arr + ints indices + double value +mSet + CvMat mat + int row + int col + double value +ClearND + CvArr arr + ints idx + +# Sequences +CV_IS_SEQ_INDEX int + CvSeq s +CV_IS_SEQ_CURVE int + CvSeq s +CV_IS_SEQ_CLOSED int + CvSeq s +CV_IS_SEQ_CONVEX int + CvSeq s +CV_IS_SEQ_HOLE int + CvSeq s +CV_IS_SEQ_SIMPLE int + CvSeq s + + +# Curves and Shapes +Line + CvArr img + CvPoint pt1 + CvPoint pt2 + CvScalar color + int thickness 1 + int lineType 8 + int shift 0 +Rectangle + CvArr img + CvPoint pt1 + CvPoint pt2 + CvScalar color + int thickness 1 + int lineType 8 + int shift 0 +Circle + CvArr img + CvPoint center + int radius + CvScalar color + int thickness 1 + int lineType 8 + int shift 0 +Ellipse + CvArr img + CvPoint center + CvSize axes + double angle + double start_angle + double end_angle + CvScalar color + int thickness 1 + int lineType 8 + int shift 0 +EllipseBox + CvArr img + CvBox2D box + CvScalar color + int thickness 1 + int lineType 8 + int shift 0 +FillPoly + CvArr img + pts_npts_contours polys + CvScalar color + int lineType 8 + int shift 0 +FillConvexPoly + CvArr img + CvPoints pn + CvScalar color + int lineType 8 + int shift 0 +PolyLine + CvArr img + pts_npts_contours polys + int is_closed + CvScalar color + int thickness 1 + int lineType 8 + int shift 0 + +#Text +InitFont font + CvFont font /O + int fontFace + double hscale + double vscale + double shear 0 + int thickness 1 + int lineType 8 +PutText + CvArr img + char* text + CvPoint org + CvFont* font + CvScalar color +GetTextSize textSize,baseline + char* textString + CvFont* font + CvSize textSize /O + int baseline /O + +# Point Sets and Contours +DrawContours + CvArr img + CvSeq contour + CvScalar external_color + CvScalar hole_color + int max_level + int thickness 1 + int lineType 8 + CvPoint offset cvPoint(0,0) + +# RTTI and Generic Functions +Save + char* filename + generic structPtr + char* name NULL + char* comment NULL +Load generic + char* filename + CvMemStorage storage NULL + char* name NULL + +# Accessing Elements and sub-Arrays +GetRow submat + CvArr arr + CvMat submat /J:arr,O,A + int row +GetRows submat + CvArr arr + CvMat submat /J:arr,O,A + int startRow + int endRow + int deltaRow 1 +GetCol submat + CvArr arr + CvMat submat /J:arr,O,A + int col +GetCols submat + CvArr arr + CvMat submat /J:arr,O,A + int startCol + int endCol +GetDiag submat + CvArr arr + CvMat submat /J:arr,O,A + int diag 0 +GetSubRect submat + CvArr arr + CvMat submat /J:arr,O,A + CvRect rect +GetSize CvSize + CvArr arr +GetElemType int + CvArr arr + +# Copying and Filling +Copy + CvArr src + CvArr dst + CvArr mask NULL +Set + CvArr arr + CvScalar value + CvArr mask NULL +SetZero + CvArr arr +Zero + CvArr arr +SetIdentity + CvArr mat + CvScalar value cvRealScalar(1) +Range + CvArr mat + double start + double end + +# Transforms and Permutations +# Reshape, ReshapeND - requires special data refcount code +Repeat + CvArr src + CvArr dst +Flip + CvArr src + CvArr dst NULL + int flipMode 0 +Split + CvArr src + CvArr dst0 + CvArr dst1 + CvArr dst2 + CvArr dst3 +CvtPixToPlane + CvArr src + CvArr dst0 + CvArr dst1 + CvArr dst2 + CvArr dst3 +Merge + CvArr src0 + CvArr src1 + CvArr src2 + CvArr src3 + CvArr dst +MixChannels + cvarr_count src /K + cvarr_count dst + intpair fromTo +RandShuffle + CvArr mat + CvRNG* rng + double iter_factor 1.0 +Sort + CvArr src + CvArr dst + CvArr idxmat + int flags 0 + +# Arithmetic, Logic and Comparison +LUT + CvArr src + CvArr dst + CvArr lut +ConvertScale + CvArr src + CvArr dst + double scale 1.0 + double shift 0.0 +CvtScale + CvArr src + CvArr dst + double scale 1.0 + double shift 0.0 +Scale + CvArr src + CvArr dst + double scale 1.0 + double shift 0.0 +Convert + CvArr src + CvArr dst +ConvertScaleAbs + CvArr src + CvArr dst + double scale 1.0 + double shift 0.0 +Add + CvArr src1 + CvArr src2 + CvArr dst + CvArr mask NULL +AddS + CvArr src + CvScalar value + CvArr dst + CvArr mask NULL +AddWeighted + CvArr src1 + double alpha + CvArr src2 + double beta + double gamma + CvArr dst +Sub + CvArr src1 + CvArr src2 + CvArr dst + CvArr mask NULL +SubS + CvArr src + CvScalar value + CvArr dst + CvArr mask NULL +SubRS + CvArr src + CvScalar value + CvArr dst + CvArr mask NULL +Mul + CvArr src1 + CvArr src2 + CvArr dst + double scale 1.0 +Div + CvArr src1 + CvArr src2 + CvArr dst + double scale 1.0 +And + CvArr src1 + CvArr src2 + CvArr dst + CvArr mask NULL +AndS + CvArr src + CvScalar value + CvArr dst + CvArr mask NULL +Or + CvArr src1 + CvArr src2 + CvArr dst + CvArr mask NULL +OrS + CvArr src + CvScalar value + CvArr dst + CvArr mask NULL +Xor + CvArr src1 + CvArr src2 + CvArr dst + CvArr mask NULL +XorS + CvArr src + CvScalar value + CvArr dst + CvArr mask NULL +Not + CvArr src + CvArr dst +Cmp + CvArr src1 + CvArr src2 + CvArr dst + int cmpOp +CmpS + CvArr src + double value + CvArr dst + int cmpOp +InRange + CvArr src + CvArr lower + CvArr upper + CvArr dst +InRangeS + CvArr src + CvScalar lower + CvScalar upper + CvArr dst +Max + CvArr src1 + CvArr src2 + CvArr dst +MaxS + CvArr src + double value + CvArr dst +Min + CvArr src1 + CvArr src2 + CvArr dst +MinS + CvArr src + double value + CvArr dst +AbsDiff + CvArr src1 + CvArr src2 + CvArr dst +AbsDiffS + CvArr src + CvArr dst + CvScalar value +Abs + CvArr src + CvArr dst + +# Statistics +CountNonZero int + CvArr arr +Sum CvScalar + CvArr arr +Avg CvScalar + CvArr arr + CvArr mask NULL +AvgSdv mean,stdDev + CvArr arr + CvScalar mean /O + CvScalar stdDev /O + CvArr mask NULL +MinMaxLoc minVal,maxVal,minLoc,maxLoc + CvArr arr + double minVal /O + double maxVal /O + CvPoint minLoc /O + CvPoint maxLoc /O + CvArr mask NULL +Norm double + CvArr arr1 + CvArr arr2 + int normType CV_L2 + CvArr mask NULL +Reduce + CvArr src + CvArr dst + int dim -1 + int op CV_REDUCE_SUM + +# Linear Algebra +DotProduct double + CvArr src1 + CvArr src2 +Normalize + CvArr src + CvArr dst + double a 1.0 + double b 0.0 + int norm_type CV_L2 + CvArr mask NULL +CrossProduct + CvArr src1 + CvArr src2 + CvArr dst +ScaleAdd + CvArr src1 + CvScalar scale + CvArr src2 + CvArr dst +GEMM + CvArr src1 + CvArr src2 + double alpha + CvArr src3 + double beta + CvArr dst + int tABC 0 +MatMulAdd + CvArr src1 + CvArr src2 + CvArr src3 + CvArr dst +MatMul + CvArr src1 + CvArr src2 + CvArr dst +Transform + CvArr src + CvArr dst + CvMat transmat + CvMat shiftvec NULL +PerspectiveTransform + CvArr src + CvArr dst + CvMat mat +MulTransposed + CvArr src + CvArr dst + int order + CvArr delta NULL + double scale 1.0 +Trace CvScalar + CvArr mat +Transpose + CvArr src + CvArr dst +Det double + CvArr mat +Invert double + CvArr src + CvArr dst + int method CV_LU +Solve + CvArr A + CvArr B + CvArr X + int method CV_LU +SVD + CvArr A + CvArr W + CvArr U NULL + CvArr V NULL + int flags 0 +SVBkSb + CvArr W + CvArr U + CvArr V + CvArr B + CvArr X + int flags +EigenVV + CvArr mat + CvArr evects + CvArr evals + double eps + int lowindex 0 + int highindex 0 +CalcCovarMatrix + cvarr_count vects /K + CvArr covMat + CvArr avg + int flags +Mahalonobis + CvArr vec1 + CvArr vec2 + CvArr mat +CalcPCA + CvArr data + CvArr avg + CvArr eigenvalues + CvArr eigenvectors + int flags +ProjectPCA + CvArr data + CvArr avg + CvArr eigenvectors + CvArr result +BackProjectPCA + CvArr proj + CvArr avg + CvArr eigenvects + CvArr result + +# Math Functions +Round int + double value +Floor int + double value +Ceil int + double value +Sqrt float + float value +InvSqrt float + float value +Cbrt float + float value +FastArctan float + float y + float x +IsNaN int + double value +IsInf int + double value +CartToPolar + CvArr x + CvArr y + CvArr magnitude + CvArr angle NULL + int angleInDegrees 0 +PolarToCart + CvArr magnitude + CvArr angle + CvArr x + CvArr y + int angleInDegrees 0 +Pow + CvArr src + CvArr dst + double power +Exp + CvArr src + CvArr dst +Log + CvArr src + CvArr dst +SolveCubic + CvMat coeffs + CvMat roots +SolvePoly + CvMat coeffs + CvMat roots + int maxiter 10 + int fig 10 + +# Random Number Generation +RNG CvRNG + int64 seed -1LL +RandArr + CvRNG* rng + CvArr arr + int distType + CvScalar param1 + CvScalar param2 +RandInt unsigned + CvRNG* rng +RandReal double + CvRNG* rng + +# Discrete Transforms +DFT + CvArr src + CvArr dst + int flags + int nonzeroRows 0 +GetOptimalDFTSize int + int size0 +MulSpectrums + CvArr src1 + CvArr src2 + CvArr dst + int flags +DCT + CvArr src + CvArr dst + int flags + +# Sequences +SeqRemove + CvSeq seq + int index +ClearSeq + CvSeq seq +CloneSeq + CvSeq seq + CvMemStorage storage +SeqRemoveSlice + CvSeq seq + CvSlice slice +SeqInvert + CvSeq seq + +# Miscellaneous Functions +CheckArr int + CvArr arr + int flags 0 + double min_val 0 + double max_val 0 +KMeans2 double + CvArr samples + int nclusters + CvArr labels + CvTermCriteria termcrit + int attempts 1 + int flags 0 + CvArr centers NULL + +# Gradients, Edges, Corners and Features +Sobel + CvArr src + CvArr dst + int xorder + int yorder + int apertureSize 3 +Laplace + CvArr src + CvArr dst + int apertureSize 3 +Canny + CvArr image + CvArr edges + double threshold1 + double threshold2 + int aperture_size 3 +PreCornerDetect + CvArr image + CvArr corners + int apertureSize 3 +CornerEigenValsAndVecs + CvArr image + CvArr eigenvv + int blockSize + int aperture_size 3 +CornerMinEigenVal + CvArr image + CvArr eigenval + int blockSize + int aperture_size 3 +CornerHarris + CvArr image + CvArr harris_dst + int blockSize + int aperture_size 3 + double k 0.04 +FindCornerSubPix corners + CvArr image + CvPoint2D32fs corners + CvSize win + CvSize zero_zone + CvTermCriteria criteria +GoodFeaturesToTrack cornerCount + CvArr image + CvArr eigImage + CvArr tempImage + cvpoint2d32f_count cornerCount + double qualityLevel + double minDistance + CvArr mask NULL + int blockSize 3 + int useHarris 0 + double k 0.04 +ExtractSURF keypoints,descriptors + CvArr image + CvArr mask + CvSeqOfCvSURFPoint* keypoints /O + CvSeqOfCvSURFDescriptor* descriptors /O + CvMemStorage storage + CvSURFParams params +GetStarKeypoints CvSeqOfCvStarKeypoint* + CvArr image + CvMemStorage storage + CvStarDetectorParams params cvStarDetectorParams() + +# Sampling, Interpolation and Geometrical Transforms +GetRectSubPix + CvArr src + CvArr dst + CvPoint2D32f center +GetQuadrangleSubPix + CvArr src + CvArr dst + CvMat mapMatrix +Resize + CvArr src + CvArr dst + int interpolation CV_INTER_LINEAR +WarpAffine + CvArr src + CvArr dst + CvMat mapMatrix + int flags CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS + CvScalar fillval cvScalarAll(0) +GetAffineTransform + CvPoint2D32f* src + CvPoint2D32f* dst + CvMat mapMatrix +GetRotationMatrix2D + CvPoint2D32f center + double angle + double scale + CvMat mapMatrix +WarpPerspective + CvArr src + CvArr dst + CvMat mapMatrix + int flags CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS + CvScalar fillval cvScalarAll(0) +GetPerspectiveTransform + CvPoint2D32f* src + CvPoint2D32f* dst + CvMat mapMatrix +Remap + CvArr src + CvArr dst + CvArr mapx + CvArr mapy + int flags CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS + CvScalar fillval cvScalarAll(0) +ConvertMaps + CvArr mapx + CvArr mapy + CvArr mapxy + CvArr mapalpha +LogPolar + CvArr src + CvArr dst + CvPoint2D32f center + double M + int flags CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS + +# Morphological Operations +CreateStructuringElementEx IplConvKernel* + int cols + int rows + int anchorX + int anchorY + int shape + ints values {NULL,0} +Erode + CvArr src + CvArr dst + IplConvKernel* element NULL + int iterations 1 +Dilate + CvArr src + CvArr dst + IplConvKernel* element NULL + int iterations 1 +MorphologyEx + CvArr src + CvArr dst + CvArr temp + IplConvKernel* element + int operation + int iterations 1 + +# Filters and Color Conversion +Smooth + CvArr src + CvArr dst + int smoothtype CV_GAUSSIAN + int param1 3 + int param2 0 + double param3 0 + double param4 0 +Filter2D + CvArr src + CvArr dst + CvMat kernel + CvPoint anchor cvPoint(-1,-1) +CopyMakeBorder + CvArr src + CvArr dst + CvPoint offset + int bordertype + CvScalar value cvScalarAll(0) +Integral + CvArr image + CvArr sum + CvArr sqsum NULL + CvArr tiltedSum NULL +CvtColor + CvArr src + CvArr dst + int code +Threshold + CvArr src + CvArr dst + double threshold + double maxValue + int thresholdType +AdaptiveThreshold + CvArr src + CvArr dst + double maxValue + int adaptive_method CV_ADAPTIVE_THRESH_MEAN_C /ch_adaptive_method + int thresholdType CV_THRESH_BINARY /ch_threshold_type + int blockSize 3 + double param1 5 + +# Pyramids and the Applications +PyrDown + CvArr src + CvArr dst + int filter CV_GAUSSIAN_5x5 +PyrUp + CvArr src + CvArr dst + int filter CV_GAUSSIAN_5x5 +PyrSegmentation comp + IplImage src + IplImage dst + CvMemStorage storage + CvSeq* comp /O + int level + double threshold1 + double threshold2 +PyrMeanShiftFiltering + CvArr src + CvArr dst + double sp + double sr + int max_level 1 + CvTermCriteria termcrit cvTermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,5,1) + +# Image Segmentation, Connected Components and Contour Retrieval +FloodFill comp + CvArr image + CvPoint seed_point + CvScalar new_val + CvScalar lo_diff cvScalarAll(0) + CvScalar up_diff cvScalarAll(0) + CvConnectedComp comp /O + int flags 4 + CvArr mask NULL +Watershed + CvArr image + CvArr markers + +# Image and Contour Moments +Moments moments + cvarrseq arr + CvMoments moments /O + int binary 0 +GetSpatialMoment double + CvMoments* moments + int x_order + int y_order +GetCentralMoment double + CvMoments* moments + int x_order + int y_order +GetNormalizedCentralMoment double + CvMoments* moments + int x_order + int y_order + +# Special Image Transforms +HoughLines2 CvSeq* + CvArr image + CvMemStorage storage + int method + double rho + double theta + int threshold + double param1 0 + double param2 0 +HoughCircles + CvArr image + CvMat circle_storage + int method + double dp + double min_dist + double param1 100 + double param2 100 + int min_radius 0 + int max_radius 0 +DistTransform + CvArr src + CvArr dst + int distance_type CV_DIST_L2 + int mask_size 3 + floats mask {NULL,0} + CvArr labels NULL +Inpaint + CvArr src + CvArr mask + CvArr dst + double inpaintRadius + int flags + +# Histograms +ClearHist + CvHistogram hist +CalcArrHist + CvArrs image + CvHistogram hist + int accumulate 0 + CvArr mask NULL +CalcHist + IplImages image + CvHistogram hist + int accumulate 0 + CvArr mask NULL +NormalizeHist + CvHistogram hist + double factor +ThreshHist + CvHistogram hist + double threshold +CompareHist double + CvHistogram hist1 + CvHistogram hist2 + int method +# CopyHist +CalcBackProject + IplImages image + CvArr back_project + CvHistogram hist +CalcArrBackProject + CvArrs image + CvArr back_project + CvHistogram hist +CalcBackProjectPatch + IplImages images + CvArr dst + CvSize patch_size + CvHistogram hist + int method + float factor +CalcProbDensity + CvHistogram hist1 + CvHistogram hist2 + CvHistogram dst_hist + double scale 255 +EqualizeHist + CvArr src + CvArr dst +QueryHistValue_1D double + CvHistogram hist + int idx0 +QueryHistValue_2D double + CvHistogram hist + int idx0 + int idx1 +QueryHistValue_3D double + CvHistogram hist + int idx0 + int idx1 + int idx2 +QueryHistValue_nD double + CvHistogram hist + ints idx + +# Matching +MatchTemplate + CvArr image + CvArr templ + CvArr result + int method +MatchShapes double + CvSeq object1 + CvSeq object2 + int method + double parameter 0 + +# Contour Processing Functions +ApproxChains CvSeq* + CvSeq src_seq + CvMemStorage storage + int method CV_CHAIN_APPROX_SIMPLE + double parameter 0 + int minimal_perimeter 0 + int recursive 0 +BoundingRect CvRect + cvarrseq points + int update 0 +ContourArea double + cvarrseq contour + CvSlice slice CV_WHOLE_SEQ +ArcLength double + cvarrseq curve + CvSlice slice CV_WHOLE_SEQ + int isClosed -1 + +# Computational Geometry +MaxRect CvRect + CvRect* rect1 + CvRect* rect2 +# TODO PointSeqFromMat +BoxPoints points + CvBox2D box + CvPoint2D32f_4 points /O,A +FitEllipse2 CvBox2D + CvArr points +ConvexHull2 CvSeq* + cvarrseq points + CvMemStorage storage + int orientation CV_CLOCKWISE + int return_points 0 +CheckContourConvexity int + cvarrseq contour +ConvexityDefects CvSeqOfCvConvexityDefect* + cvarrseq contour + CvSeq convexhull + CvMemStorage storage +PointPolygonTest double + cvarrseq contour + CvPoint2D32f pt + int measure_dist +MinAreaRect2 CvBox2D + cvarrseq points + CvMemStorage storage NULL +MinEnclosingCircle int,center,radius + cvarrseq points + CvPoint2D32f center /O + float radius /O + +# Planar Subdivisions + +Subdiv2DGetEdge CvSubdiv2DEdge + CvSubdiv2DEdge edge + CvNextEdgeType type +Subdiv2DNextEdge CvSubdiv2DEdge + CvSubdiv2DEdge edge +Subdiv2DRotateEdge CvSubdiv2DEdge + CvSubdiv2DEdge edge + int rotate +Subdiv2DEdgeOrg CvSubdiv2DPoint* + CvSubdiv2DEdge edge +Subdiv2DEdgeDst CvSubdiv2DPoint* + CvSubdiv2DEdge edge +CreateSubdivDelaunay2D CvSubdiv2D* + CvRect rect + CvMemStorage storage +SubdivDelaunay2DInsert CvSubdiv2DPoint* + CvSubdiv2D* subdiv + CvPoint2D32f pt +CalcSubdivVoronoi2D + CvSubdiv2D* subdiv +ClearSubdivVoronoi2D + CvSubdiv2D* subdiv +FindNearestPoint2D CvSubdiv2DPoint* + CvSubdiv2D* subdiv + CvPoint2D32f pt + +# Object Detection +HaarDetectObjects CvSeqOfCvAvgComp* + CvArr image + CvHaarClassifierCascade* cascade + CvMemStorage storage + double scale_factor 1.1 /ch_doubleAbove1 + int min_neighbors 3 + int flags 0 + CvSize min_size cvSize(0,0) + +ComputeCorrespondEpilines + CvMat points + int whichImage + CvMat F + CvMat lines +ConvertPointsHomogeneous + CvMat src + CvMat dst +ProjectPoints2 + CvMat objectPoints + CvMat rvec + CvMat tvec + CvMat cameraMatrix + CvMat distCoeffs + CvMat imagePoints + CvMat dpdrot NULL + CvMat dpdt NULL + CvMat dpdf NULL + CvMat dpdc NULL + CvMat dpddist NULL +ReprojectImageTo3D + CvArr disparity + CvArr _3dImage + CvMat Q + int handleMissingValues 0 +RQDecomp3x3 eulerAngles + CvMat M + CvMat R + CvMat Q + CvMat Qx NULL + CvMat Qy NULL + CvMat Qz NULL + CvPoint3D64f eulerAngles /O +FindHomography + CvMat srcPoints + CvMat dstPoints + CvMat H + int method 0 + double ransacReprojThreshold 3.0 + CvMat status NULL +CreateStereoBMState CvStereoBMState* + int preset CV_STEREO_BM_BASIC + int numberOfDisparities 0 +CreateStereoGCState CvStereoGCState* + int numberOfDisparities + int maxIters +FindStereoCorrespondenceBM + CvArr left + CvArr right + CvArr disparity + CvStereoBMState* state +FindStereoCorrespondenceGC + CvArr left + CvArr right + CvArr dispLeft + CvArr dispRight + CvStereoGCState* state + int useDisparityGuess 0 +CalibrateCamera2 + CvMat objectPoints + CvMat imagePoints + CvMat pointCounts + CvSize imageSize + CvMat cameraMatrix + CvMat distCoeffs + CvMat rvecs + CvMat tvecs + int flags 0 +CalibrationMatrixValues fovx,fovy,focalLength,principalPoint,pixelAspectRatio + CvMat calibMatr + CvSize image_size + double apertureWidth 0 + double apertureHeight 0 + double fovx /O + double fovy /O + double focalLength /O + CvPoint2D64f principalPoint /O + double pixelAspectRatio /O +FindExtrinsicCameraParams2 + CvMat objectPoints + CvMat imagePoints + CvMat cameraMatrix + CvMat distCoeffs + CvMat rvec + CvMat tvec + int useExtrinsicGuess 0 +FindFundamentalMat int + CvMat points1 + CvMat points2 + CvMat fundamentalMatrix + int method CV_FM_RANSAC + double param1 1. + double param2 0.99 + CvMat status NULL +StereoCalibrate + CvMat objectPoints + CvMat imagePoints1 + CvMat imagePoints2 + CvMat pointCounts + CvMat cameraMatrix1 + CvMat distCoeffs1 + CvMat cameraMatrix2 + CvMat distCoeffs2 + CvSize imageSize + CvMat R + CvMat T + CvMat E NULL + CvMat F NULL + CvTermCriteria term_crit cvTermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,30,1e-6) + int flags CV_CALIB_FIX_INTRINSIC +GetOptimalNewCameraMatrix + CvMat cameraMatrix + CvMat distCoeffs + CvSize imageSize + double alpha + CvMat newCameraMatrix + CvSize newImageSize cvSize(0,0) + CvRect* validPixROI NULL +InitIntrinsicParams2D + CvMat objectPoints + CvMat imagePoints + CvMat npoints + CvSize imageSize + CvMat cameraMatrix + double aspectRatio 1. +StereoRectify roi1,roi2 + CvMat cameraMatrix1 + CvMat cameraMatrix2 + CvMat distCoeffs1 + CvMat distCoeffs2 + CvSize imageSize + CvMat R + CvMat T + CvMat R1 + CvMat R2 + CvMat P1 + CvMat P2 + CvMat Q NULL + int flags CV_CALIB_ZERO_DISPARITY + double alpha -1 + CvSize newImageSize cvSize(0,0) + CvRect roi1 /O + CvRect roi2 /O +StereoRectifyUncalibrated + CvMat points1 + CvMat points2 + CvMat F + CvSize imageSize + CvMat H1 + CvMat H2 + double threshold 5 +Rodrigues2 + CvMat src + CvMat dst + CvMat jacobian 0 +Undistort2 + CvArr src + CvArr dst + CvMat cameraMatrix + CvMat distCoeffs +InitUndistortMap + CvMat cameraMatrix + CvMat distCoeffs + CvArr map1 + CvArr map2 +InitUndistortRectifyMap + CvMat cameraMatrix + CvMat distCoeffs + CvMat R + CvMat newCameraMatrix + CvArr map1 + CvArr map2 +UndistortPoints + CvMat src + CvMat dst + CvMat cameraMatrix + CvMat distCoeffs + CvMat R NULL + CvMat P NULL +DecomposeProjectionMatrix eulerAngles + CvMat projMatrix + CvMat cameraMatrix + CvMat rotMatrix + CvMat transVect + CvMat rotMatrX NULL + CvMat rotMatrY NULL + CvMat rotMatrZ NULL + CvPoint3D64f eulerAngles /O +DrawChessboardCorners + CvArr image + CvSize patternSize + CvPoint2D32fs corners + int patternWasFound + +CreatePOSITObject CvPOSITObject* + CvPoint3D32fs points +POSIT rotationMatrix,translation_vector + CvPOSITObject* posit_object + CvPoint2D32f* imagePoints + double focal_length + CvTermCriteria criteria + CvMatr32f_i rotationMatrix /O,A + CvVect32f_i translation_vector /O,A + +EstimateRigidTransform + CvArr A + CvArr B + CvMat M + int full_affine + +# Accumulation of Background Statistics +Acc + CvArr image + CvArr sum + CvArr mask NULL +SquareAcc + CvArr image + CvArr sqsum + CvArr mask NULL +MultiplyAcc + CvArr image1 + CvArr image2 + CvArr acc + CvArr mask NULL +RunningAvg + CvArr image + CvArr acc + double alpha + CvArr mask NULL + +# Motion Templates +UpdateMotionHistory + CvArr silhouette + CvArr mhi + double timestamp + double duration +CalcMotionGradient + CvArr mhi /ch_matF + CvArr mask + CvArr orientation /ch_matF + double delta1 + double delta2 + int apertureSize 3 /ch_aperture +CalcGlobalOrientation double + CvArr orientation + CvArr mask + CvArr mhi + double timestamp + double duration +SegmentMotion CvSeq* + CvArr mhi + CvArr seg_mask + CvMemStorage storage + double timestamp + double seg_thresh + +# Object Tracking +MeanShift comp + CvArr prob_image + CvRect window + CvTermCriteria criteria + CvConnectedComp comp /O +CamShift int,comp,box + CvArr prob_image + CvRect window + CvTermCriteria criteria + CvConnectedComp comp /O + CvBox2D box /O +CreateKalman CvKalman* + int dynam_params + int measure_params + int control_params 0 +KalmanCorrect ROCvMat* + CvKalman* kalman + CvMat measurement +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 + CvArr prev + CvArr curr + CvSize winSize + CvArr velx + CvArr vely +CalcOpticalFlowBM + CvArr prev /ch_image8 + CvArr curr /ch_image8 + CvSize blockSize + CvSize shiftSize + CvSize max_range + int usePrevious + CvArr velx /ch_vel + CvArr vely /ch_vel +CalcOpticalFlowHS + CvArr prev /ch_image8 + CvArr curr /ch_image8 + int usePrevious + CvArr velx /ch_vel_64 + CvArr vely /ch_vel_64 + double lambda + CvTermCriteria criteria +CalcOpticalFlowFarneback + CvArr prev /ch_image8 + CvArr curr /ch_image8 + CvArr flow + double pyr_scale 0.5 + int levels 3 + int winsize 15 + int iterations 3 + int poly_n 7 + double poly_sigma 1.5 + int flags 0 + +# Highgui +ConvertImage + CvArr src + CvArr dst + int flags 0 +NamedWindow + char* name + int flags CV_WINDOW_AUTOSIZE +DestroyWindow + char* name +DestroyAllWindows +ResizeWindow + char* name + int width + int height +MoveWindow + char* name + int x + int y +ShowImage + char* name + CvArr image +GetTrackbarPos int + char* trackbarName + char* windowName +SetTrackbarPos + char* trackbarName + char* windowName + int pos +#WaitKey int +# int delay 0 +SaveImage + char* filename + CvArr image +CaptureFromFile CvCapture* + char* filename +CreateFileCapture CvCapture* + char* filename +CaptureFromCAM CvCapture* + int index +CreateCameraCapture CvCapture* + int index +GrabFrame int + CvCapture* capture +RetrieveFrame ROIplImage* + CvCapture* capture +QueryFrame ROIplImage* + CvCapture* capture +GetCaptureProperty double + CvCapture* capture + int property_id +SetCaptureProperty int + CvCapture* capture + int property_id + double value +CreateVideoWriter CvVideoWriter* + char* filename + int fourcc + double fps + CvSize frame_size + int is_color 1 +WriteFrame int + CvVideoWriter* writer + IplImage image +EncodeImage CvMat* + char* ext + CvArr image + ints0 params {&zero,1} +DecodeImage IplImage* + CvMat buf + int iscolor CV_LOAD_IMAGE_COLOR +DecodeImageM CvMat* + CvMat buf + int iscolor CV_LOAD_IMAGE_COLOR +StartWindowThread +SetWindowProperty + char* name + int prop_id + double prop_value +GetWindowProperty double + char* name + int prop_id + +GetTickCount int64 +GetTickFrequency int64 + +# cvaux stuff +HOGDetectMultiScale CvSeq* + CvArr image + CvMemStorage storage + CvArr svm_classifier NULL + CvSize win_stride cvSize(0,0) + double hit_threshold 0 + double scale 1.05 + int group_threshold 2 + CvSize padding cvSize(0,0) + CvSize win_size cvSize(64,128) + CvSize block_size cvSize(16,16) + CvSize block_stride cvSize(8,8) + CvSize cell_size cvSize(8,8) + int nbins 9 + int gammaCorrection 1 + +GrabCut + CvArr image + CvArr mask + CvRect rect + CvArr bgdModel + CvArr fgdModel + int iterCount + int mode + +# These functions are handwritten in cv.cpp; they appear here as 'doconly' declarations +# so that their documentation can be auto-generated +ApproxPoly /doconly + cvarrseq src_seq + CvMemStorage storage + int method + double parameter 0.0 + int parameter2 0 +CalcEMD2 /doconly + CvArr signature1 + CvArr signature2 + int distance_type + PyCallableObject* distance_func NULL + CvArr cost_matrix NULL + CvArr flow NULL + float lower_bound 0.0 + PyObject* userdata NULL +CalcOpticalFlowPyrLK currFeatures,status,track_error /doconly + CvArr prev + CvArr curr + CvArr prevPyr + CvArr currPyr + CvPoint2D32f* prevFeatures + CvSize winSize + int level + CvTermCriteria criteria + int flags + CvPoint2D32f* guesses + CvPoint2D32f currFeatures /O + char status /O + float track_error /O +ClipLine point1,point2 /doconly + CvSize imgSize + CvPoint pt1 + CvPoint pt2 +CreateData /doconly + CvArr arr +CreateHist CvHistogram /doconly + ints dims + int type + ranges ranges None + int uniform 1 +CreateImageHeader IplImage* /doconly + CvSize size + int depth + int channels +CreateImage IplImage* /doconly + CvSize size + int depth + int channels +CreateMatHeader CvMat /doconly + int rows + int cols + int type +CreateMat CvMat /doconly + int rows + int cols + int type +CreateMatNDHeader CvMatND /doconly + ints dims + int type +CreateMatND CvMatND /doconly + ints dims + int type +CreateMemStorage CvMemStorage /doconly + int blockSize +CreateTrackbar /doconly + char* trackbarName + char* windowName + int value + int count + PyCallableObject* onChange +FindChessboardCorners corners /doconly + CvArr image + CvSize patternSize + CvPoint2D32fs corners /O + int flags CV_CALIB_CB_ADAPTIVE_THRESH +FindContours /doconly + CvArr image + CvMemStorage storage + int mode CV_RETR_LIST + int method CV_CHAIN_APPROX_SIMPLE + CvPoint offset (0,0) +FitLine line /doconly + CvArr points + int dist_type + double param + double reps + double aeps + PyObject* line /O +GetDims /doconly + CvArr arr +GetHuMoments hu /doconly + CvMoments moments + PyObject* hu /O +GetImage /doconly + CvMat arr +GetMat /doconly + IplImage arr + int allowND 0 +GetMinMaxHistValue min_value,max_value,min_idx,max_idx /doconly + CvHistogram hist + CvScalar min_value /O + CvScalar max_value /O + ints min_idx /O + ints max_idx /O +InitLineIterator line_iterator /doconly + CvArr image + CvPoint pt1 + CvPoint pt2 + iter line_iterator /O + int connectivity 8 + int left_to_right 0 +LoadImageM /doconly + char* filename + int iscolor CV_LOAD_IMAGE_COLOR +LoadImage /doconly + char* filename + int iscolor CV_LOAD_IMAGE_COLOR +ReshapeMatND /doconly + CvMat arr + int newCn + ints newDims +Reshape /doconly + CvArr arr + int newCn + int newRows +SetData /doconly + CvArr arr + PyObject* data + int step +SetMouseCallback /doconly + char* windowName + PyCallableObject* onMouse + PyObject* param None +Subdiv2DLocate loc,where /doconly + CvSubdiv2D* subdiv + CvPoint2D32f pt + int loc /O + edgeorpoint where /O +WaitKey /doconly + int delay 0 diff --git a/modules/python/src1/cv.cpp b/modules/python/src1/cv.cpp new file mode 100644 index 0000000000..298a75c5d9 --- /dev/null +++ b/modules/python/src1/cv.cpp @@ -0,0 +1,4144 @@ +#include + +#include + +#include +#include +#include +#include +#include + +#define MODULESTR "cv" + +static PyObject *opencv_error; + +struct memtrack_t { + PyObject_HEAD + int owner; + void *ptr; + int freeptr; + Py_ssize_t size; + PyObject *backing; + CvArr *backingmat; +}; + +struct iplimage_t { + PyObject_HEAD + IplImage *a; + PyObject *data; + size_t offset; +}; + +struct cvmat_t { + PyObject_HEAD + CvMat *a; + PyObject *data; + size_t offset; +}; + +struct cvmatnd_t { + PyObject_HEAD + CvMatND *a; + PyObject *data; + size_t offset; +}; + +struct cvhistogram_t { + PyObject_HEAD + CvHistogram h; + PyObject *bins; +}; + +struct cvmemstorage_t { + PyObject_HEAD + CvMemStorage *a; +}; + +struct cvseq_t { + PyObject_HEAD + CvSeq *a; + PyObject *container; // Containing cvmemstorage_t +}; + +struct cvset_t { + PyObject_HEAD + CvSet *a; + PyObject *container; // Containing cvmemstorage_t + int i; +}; + +struct cvsubdiv2d_t { + PyObject_HEAD + CvSubdiv2D *a; + PyObject *container; // Containing cvmemstorage_t +}; + +struct cvsubdiv2dpoint_t { + PyObject_HEAD + CvSubdiv2DPoint *a; + PyObject *container; // Containing cvmemstorage_t +}; + +struct cvsubdiv2dedge_t { + PyObject_HEAD + CvSubdiv2DEdge a; + PyObject *container; // Containing cvmemstorage_t +}; + +struct cvlineiterator_t { + PyObject_HEAD + CvLineIterator iter; + int count; + int type; +}; + +typedef IplImage ROIplImage; +typedef const CvMat ROCvMat; +typedef PyObject PyCallableObject; + +struct cvfont_t { + PyObject_HEAD + CvFont a; +}; + +struct cvcontourtree_t { + PyObject_HEAD + CvContourTree *a; +}; + +struct cvrng_t { + PyObject_HEAD + CvRNG a; +}; + +static int is_iplimage(PyObject *o); +static int is_cvmat(PyObject *o); +static int is_cvmatnd(PyObject *o); +static int convert_to_CvArr(PyObject *o, CvArr **dst, const char *name = "no_name"); +static int convert_to_IplImage(PyObject *o, IplImage **dst, const char *name = "no_name"); +static int convert_to_CvMat(PyObject *o, CvMat **dst, const char *name = "no_name"); +static int convert_to_CvMatND(PyObject *o, CvMatND **dst, const char *name = "no_name"); +static PyObject *what_data(PyObject *o); +static PyObject *FROM_CvMat(CvMat *r); +static PyObject *FROM_ROCvMatPTR(ROCvMat *r); +static PyObject *shareDataND(PyObject *donor, CvMatND *pdonor, CvMatND *precipient); + +#define FROM_double(r) PyFloat_FromDouble(r) +#define FROM_float(r) PyFloat_FromDouble(r) +#define FROM_int(r) PyInt_FromLong(r) +#define FROM_int64(r) PyLong_FromLongLong(r) +#define FROM_unsigned(r) PyLong_FromUnsignedLong(r) +#define FROM_CvBox2D(r) Py_BuildValue("(ff)(ff)f", r.center.x, r.center.y, r.size.width, r.size.height, r.angle) +#define FROM_CvScalar(r) Py_BuildValue("(ffff)", r.val[0], r.val[1], r.val[2], r.val[3]) +#define FROM_CvPoint(r) Py_BuildValue("(ii)", r.x, r.y) +#define FROM_CvPoint2D32f(r) Py_BuildValue("(ff)", r.x, r.y) +#define FROM_CvPoint3D64f(r) Py_BuildValue("(fff)", r.x, r.y, r.z) +#define FROM_CvSize(r) Py_BuildValue("(ii)", r.width, r.height) +#define FROM_CvRect(r) Py_BuildValue("(iiii)", r.x, r.y, r.width, r.height) +#define FROM_CvSeqPTR(r) _FROM_CvSeqPTR(r, pyobj_storage) +#define FROM_CvSubdiv2DPTR(r) _FROM_CvSubdiv2DPTR(r, pyobj_storage) +#define FROM_CvPoint2D64f(r) Py_BuildValue("(ff)", r.x, r.y) +#define FROM_CvConnectedComp(r) Py_BuildValue("(fNN)", (r).area, FROM_CvScalar((r).value), FROM_CvRect((r).rect)) + +#if PYTHON_USE_NUMPY +static PyObject *fromarray(PyObject *o, int allowND); +#endif + +static void translate_error_to_exception(void) +{ + PyErr_SetString(opencv_error, cvErrorStr(cvGetErrStatus())); + cvSetErrStatus(0); +} + +#define ERRCHK do { if (cvGetErrStatus() != 0) { translate_error_to_exception(); return NULL; } } while (0) +#define ERRWRAPN(F, N) \ + do { \ + try \ + { \ + F; \ + } \ + catch (const cv::Exception &e) \ + { \ + PyErr_SetString(opencv_error, e.err.c_str()); \ + return N; \ + } \ + ERRCHK; \ + } while(0) +#define ERRWRAP(F) ERRWRAPN(F, NULL) // for most functions, exception -> NULL return + +/************************************************************************/ + +static int failmsg(const char *fmt, ...) +{ + char str[1000]; + + va_list ap; + va_start(ap, fmt); + vsnprintf(str, sizeof(str), fmt, ap); + va_end(ap); + + PyErr_SetString(PyExc_TypeError, str); + return 0; +} + +/************************************************************************/ + +/* These get/setters are polymorphic, used in both iplimage and cvmat */ + +static PyObject *PyObject_FromCvScalar(CvScalar s, int type) +{ + int i, spe = CV_MAT_CN(type); + PyObject *r; + if (spe > 1) { + r = PyTuple_New(spe); + for (i = 0; i < spe; i++) + PyTuple_SET_ITEM(r, i, PyFloat_FromDouble(s.val[i])); + } else { + r = PyFloat_FromDouble(s.val[0]); + } + return r; +} + +static PyObject *cvarr_GetItem(PyObject *o, PyObject *key); +static int cvarr_SetItem(PyObject *o, PyObject *key, PyObject *v); + +// o is a Python string or buffer object. Return its size. + +static Py_ssize_t what_size(PyObject *o) +{ + void *buffer; + Py_ssize_t buffer_len; + + if (PyString_Check(o)) { + return PyString_Size(o); + } else if (PyObject_AsWriteBuffer(o, &buffer, &buffer_len) == 0) { + return buffer_len; + } else { + assert(0); // argument must be string or buffer. + return 0; + } +} + + +/************************************************************************/ + +CvMat *PyCvMat_AsCvMat(PyObject *o) +{ + assert(0); // not yet implemented: reference counting for CvMat in Kalman is unclear... + return NULL; +} + +#define cvReleaseIplConvKernel(x) cvReleaseStructuringElement(x) +#include "generated3.i" + +/* iplimage */ + +static void iplimage_dealloc(PyObject *self) +{ + iplimage_t *pc = (iplimage_t*)self; + cvReleaseImageHeader((IplImage**)&pc->a); + Py_DECREF(pc->data); + PyObject_Del(self); +} + +static PyObject *iplimage_repr(PyObject *self) +{ + iplimage_t *cva = (iplimage_t*)self; + IplImage* ipl = (IplImage*)(cva->a); + char str[1000]; + sprintf(str, "nChannels); + d += strlen(d); + sprintf(d, "width=%d ", ipl->width); + d += strlen(d); + sprintf(d, "height=%d ", ipl->height); + d += strlen(d); + sprintf(d, "widthStep=%d ", ipl->widthStep); + d += strlen(d); + sprintf(d, ")>"); + return PyString_FromString(str); +} + +static PyObject *iplimage_tostring(PyObject *self, PyObject *args) +{ + iplimage_t *pc = (iplimage_t*)self; + IplImage *i; + if (!convert_to_IplImage(self, &i, "self")) + return NULL; + if (i == NULL) + return NULL; + int bps; + switch (i->depth) { + case IPL_DEPTH_8U: + case IPL_DEPTH_8S: + bps = 1; + break; + case IPL_DEPTH_16U: + case IPL_DEPTH_16S: + bps = 2; + break; + case IPL_DEPTH_32S: + case IPL_DEPTH_32F: + bps = 4; + break; + case IPL_DEPTH_64F: + bps = 8; + break; + default: + return (PyObject*)failmsg("Unrecognised depth %d", i->depth); + } + int bpl = i->width * i->nChannels * bps; + if (PyString_Check(pc->data) && bpl == i->widthStep && pc->offset == 0 && ((bpl * i->height) == what_size(pc->data))) { + Py_INCREF(pc->data); + return pc->data; + } else { + int l = bpl * i->height; + char *s = new char[l]; + int y; + for (y = 0; y < i->height; y++) { + memcpy(s + y * bpl, i->imageData + y * i->widthStep, bpl); + } + PyObject *r = PyString_FromStringAndSize(s, l); + delete s; + return r; + } +} + +static struct PyMethodDef iplimage_methods[] = +{ + {"tostring", iplimage_tostring, METH_VARARGS}, + {NULL, NULL} +}; + +static PyObject *iplimage_getnChannels(iplimage_t *cva) +{ + return PyInt_FromLong(((IplImage*)(cva->a))->nChannels); +} +static PyObject *iplimage_getwidth(iplimage_t *cva) +{ + return PyInt_FromLong(((IplImage*)(cva->a))->width); +} +static PyObject *iplimage_getheight(iplimage_t *cva) +{ + return PyInt_FromLong(((IplImage*)(cva->a))->height); +} +static PyObject *iplimage_getdepth(iplimage_t *cva) +{ + return PyLong_FromUnsignedLong((unsigned)((IplImage*)(cva->a))->depth); +} +static PyObject *iplimage_getorigin(iplimage_t *cva) +{ + return PyInt_FromLong(((IplImage*)(cva->a))->origin); +} +static void iplimage_setorigin(iplimage_t *cva, PyObject *v) +{ + ((IplImage*)(cva->a))->origin = PyInt_AsLong(v); +} + +static PyGetSetDef iplimage_getseters[] = { + {(char*)"nChannels", (getter)iplimage_getnChannels, (setter)NULL, (char*)"nChannels", NULL}, + {(char*)"channels", (getter)iplimage_getnChannels, (setter)NULL, (char*)"nChannels", NULL}, + {(char*)"width", (getter)iplimage_getwidth, (setter)NULL, (char*)"width", NULL}, + {(char*)"height", (getter)iplimage_getheight, (setter)NULL, (char*)"height", NULL}, + {(char*)"depth", (getter)iplimage_getdepth, (setter)NULL, (char*)"depth", NULL}, + {(char*)"origin", (getter)iplimage_getorigin, (setter)iplimage_setorigin, (char*)"origin", NULL}, + {NULL} /* Sentinel */ +}; + +static PyMappingMethods iplimage_as_map = { + NULL, + &cvarr_GetItem, + &cvarr_SetItem, +}; + +static PyTypeObject iplimage_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, /*size*/ + MODULESTR".iplimage", /*name*/ + sizeof(iplimage_t), /*basicsize*/ +}; + +static void iplimage_specials(void) +{ + iplimage_Type.tp_dealloc = iplimage_dealloc; + iplimage_Type.tp_as_mapping = &iplimage_as_map; + iplimage_Type.tp_repr = iplimage_repr; + iplimage_Type.tp_methods = iplimage_methods; + iplimage_Type.tp_getset = iplimage_getseters; +} + +static int is_iplimage(PyObject *o) +{ + return PyType_IsSubtype(o->ob_type, &iplimage_Type); +} + +/************************************************************************/ + +/* cvmat */ + +static void cvmat_dealloc(PyObject *self) +{ + cvmat_t *pc = (cvmat_t*)self; + if (pc->data) { + Py_DECREF(pc->data); + } + cvFree(&pc->a); + PyObject_Del(self); +} + +static PyObject *cvmat_repr(PyObject *self) +{ + CvMat *m = ((cvmat_t*)self)->a; + char str[1000]; + sprintf(str, "type); + d += strlen(d); + switch (CV_MAT_DEPTH(m->type)) { + case CV_8U: strcpy(d, "8U"); break; + case CV_8S: strcpy(d, "8S"); break; + case CV_16U: strcpy(d, "16U"); break; + case CV_16S: strcpy(d, "16S"); break; + case CV_32S: strcpy(d, "32S"); break; + case CV_32F: strcpy(d, "32F"); break; + case CV_64F: strcpy(d, "64F"); break; + } + d += strlen(d); + sprintf(d, "C%d ", CV_MAT_CN(m->type)); + d += strlen(d); + sprintf(d, "rows=%d ", m->rows); + d += strlen(d); + sprintf(d, "cols=%d ", m->cols); + d += strlen(d); + sprintf(d, "step=%d ", m->step); + d += strlen(d); + sprintf(d, ")>"); + return PyString_FromString(str); +} + +static PyObject *cvmat_tostring(PyObject *self, PyObject *args) +{ + CvMat *m; + if (!convert_to_CvMat(self, &m, "self")) + return NULL; + + int bps; // bytes per sample + + switch (CV_MAT_DEPTH(m->type)) { + case CV_8U: + case CV_8S: + bps = CV_MAT_CN(m->type) * 1; + break; + case CV_16U: + case CV_16S: + bps = CV_MAT_CN(m->type) * 2; + break; + case CV_32S: + case CV_32F: + bps = CV_MAT_CN(m->type) * 4; + break; + case CV_64F: + bps = CV_MAT_CN(m->type) * 8; + break; + default: + return (PyObject*)failmsg("Unrecognised depth %d", CV_MAT_DEPTH(m->type)); + } + + int bpl = m->cols * bps; // bytes per line + cvmat_t *pc = (cvmat_t*)self; + if (PyString_Check(pc->data) && bpl == m->step && pc->offset == 0 && ((bpl * m->rows) == what_size(pc->data))) { + Py_INCREF(pc->data); + return pc->data; + } else { + int l = bpl * m->rows; + char *s = new char[l]; + int y; + for (y = 0; y < m->rows; y++) { + memcpy(s + y * bpl, m->data.ptr + y * m->step, bpl); + } + PyObject *r = PyString_FromStringAndSize(s, l); + delete s; + return r; + } +} + +static struct PyMethodDef cvmat_methods[] = +{ + {"tostring", cvmat_tostring, METH_VARARGS}, + {NULL, NULL} +}; + +static PyObject *cvmat_gettype(cvmat_t *cva) +{ + return PyInt_FromLong(cvGetElemType(cva->a)); +} + +static PyObject *cvmat_getstep(cvmat_t *cva) +{ + return PyInt_FromLong(cva->a->step); +} + +static PyObject *cvmat_getrows(cvmat_t *cva) +{ + return PyInt_FromLong(cva->a->rows); +} + +static PyObject *cvmat_getcols(cvmat_t *cva) +{ + return PyInt_FromLong(cva->a->cols); +} + +static PyObject *cvmat_getchannels(cvmat_t *cva) +{ + return PyInt_FromLong(CV_MAT_CN(cva->a->type)); +} + +#if PYTHON_USE_NUMPY +#include "numpy/ndarrayobject.h" + +// A PyArrayInterface, with an associated python object that should be DECREF'ed on release +struct arrayTrack { + PyArrayInterface s; + PyObject *o; +}; + +static void arrayTrackDtor(void *p) +{ + struct arrayTrack *at = (struct arrayTrack *)p; + delete at->s.shape; + delete at->s.strides; + if (at->s.descr) + Py_DECREF(at->s.descr); + Py_DECREF(at->o); +} + +// Fill in fields of PyArrayInterface s using mtype. This code is common +// to cvmat and cvmatnd + +static void arrayinterface_common(PyArrayInterface *s, int mtype) +{ + s->two = 2; + + switch (CV_MAT_DEPTH(mtype)) { + case CV_8U: + s->typekind = 'u'; + s->itemsize = 1; + break; + case CV_8S: + s->typekind = 'i'; + s->itemsize = 1; + break; + case CV_16U: + s->typekind = 'u'; + s->itemsize = 2; + break; + case CV_16S: + s->typekind = 'i'; + s->itemsize = 2; + break; + case CV_32S: + s->typekind = 'i'; + s->itemsize = 4; + break; + case CV_32F: + s->typekind = 'f'; + s->itemsize = 4; + break; + case CV_64F: + s->typekind = 'f'; + s->itemsize = 8; + break; + default: + assert(0); + } + + s->flags = NPY_WRITEABLE | NPY_NOTSWAPPED; +} + +static PyObject *cvmat_array_struct(cvmat_t *cva) +{ + CvMat *m; + convert_to_CvMat((PyObject *)cva, &m, ""); + + arrayTrack *at = new arrayTrack; + PyArrayInterface *s = &at->s; + + at->o = cva->data; + Py_INCREF(at->o); + + arrayinterface_common(s, m->type); + + if (CV_MAT_CN(m->type) == 1) { + s->nd = 2; + s->shape = new npy_intp[2]; + s->shape[0] = m->rows; + s->shape[1] = m->cols; + s->strides = new npy_intp[2]; + s->strides[0] = m->step; + s->strides[1] = s->itemsize; + } else { + s->nd = 3; + s->shape = new npy_intp[3]; + s->shape[0] = m->rows; + s->shape[1] = m->cols; + s->shape[2] = CV_MAT_CN(m->type); + s->strides = new npy_intp[3]; + s->strides[0] = m->step; + s->strides[1] = s->itemsize * CV_MAT_CN(m->type); + s->strides[2] = s->itemsize; + } + s->data = (void*)(m->data.ptr); + s->descr = PyList_New(1); + char typestr[10]; + sprintf(typestr, "<%c%d", s->typekind, s->itemsize); + PyList_SetItem(s->descr, 0, Py_BuildValue("(ss)", "x", typestr)); + + return PyCObject_FromVoidPtr(s, arrayTrackDtor); +} + +static PyObject *cvmatnd_array_struct(cvmatnd_t *cva) +{ + CvMatND *m; + convert_to_CvMatND((PyObject *)cva, &m, ""); + + arrayTrack *at = new arrayTrack; + PyArrayInterface *s = &at->s; + + at->o = cva->data; + Py_INCREF(at->o); + + arrayinterface_common(s, m->type); + + int i; + if (CV_MAT_CN(m->type) == 1) { + s->nd = m->dims; + s->shape = new npy_intp[s->nd]; + for (i = 0; i < s->nd; i++) + s->shape[i] = m->dim[i].size; + s->strides = new npy_intp[s->nd]; + for (i = 0; i < (s->nd - 1); i++) + s->strides[i] = m->dim[i].step; + s->strides[s->nd - 1] = s->itemsize; + } else { + s->nd = m->dims + 1; + s->shape = new npy_intp[s->nd]; + for (i = 0; i < (s->nd - 1); i++) + s->shape[i] = m->dim[i].size; + s->shape[s->nd - 1] = CV_MAT_CN(m->type); + + s->strides = new npy_intp[s->nd]; + for (i = 0; i < (s->nd - 2); i++) + s->strides[i] = m->dim[i].step; + s->strides[s->nd - 2] = s->itemsize * CV_MAT_CN(m->type); + s->strides[s->nd - 1] = s->itemsize; + } + s->data = (void*)(m->data.ptr); + s->descr = PyList_New(1); + char typestr[10]; + sprintf(typestr, "<%c%d", s->typekind, s->itemsize); + PyList_SetItem(s->descr, 0, Py_BuildValue("(ss)", "x", typestr)); + + return PyCObject_FromVoidPtr(s, arrayTrackDtor); +} +#endif + +static PyGetSetDef cvmat_getseters[] = { + {(char*)"type", (getter)cvmat_gettype, (setter)NULL, (char*)"type", NULL}, + {(char*)"step", (getter)cvmat_getstep, (setter)NULL, (char*)"step", NULL}, + {(char*)"rows", (getter)cvmat_getrows, (setter)NULL, (char*)"rows", NULL}, + {(char*)"cols", (getter)cvmat_getcols, (setter)NULL, (char*)"cols", NULL}, + {(char*)"channels",(getter)cvmat_getchannels, (setter)NULL, (char*)"channels", NULL}, + {(char*)"width", (getter)cvmat_getcols, (setter)NULL, (char*)"width", NULL}, + {(char*)"height", (getter)cvmat_getrows, (setter)NULL, (char*)"height", NULL}, +#if PYTHON_USE_NUMPY + {(char*)"__array_struct__", (getter)cvmat_array_struct, (setter)NULL, (char*)"__array_struct__", NULL}, +#endif + {NULL} /* Sentinel */ +}; + +static PyMappingMethods cvmat_as_map = { + NULL, + &cvarr_GetItem, + &cvarr_SetItem, +}; + +static PyTypeObject cvmat_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, /*size*/ + MODULESTR".cvmat", /*name*/ + sizeof(cvmat_t), /*basicsize*/ +}; + +static int illegal_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + PyErr_SetString(opencv_error, "Cannot create cvmat directly; use CreateMat() instead"); + return -1; +} + +static void cvmat_specials(void) +{ + cvmat_Type.tp_dealloc = cvmat_dealloc; + cvmat_Type.tp_as_mapping = &cvmat_as_map; + cvmat_Type.tp_repr = cvmat_repr; + cvmat_Type.tp_methods = cvmat_methods; + cvmat_Type.tp_getset = cvmat_getseters; + cvmat_Type.tp_init = illegal_init; +} + +static int is_cvmat(PyObject *o) +{ + return PyType_IsSubtype(o->ob_type, &cvmat_Type); +} + +/************************************************************************/ + +/* cvmatnd */ + +static void cvmatnd_dealloc(PyObject *self) +{ + cvmatnd_t *pc = (cvmatnd_t*)self; + Py_DECREF(pc->data); + cvFree(&pc->a); + PyObject_Del(self); +} + +static PyObject *cvmatnd_repr(PyObject *self) +{ + CvMatND *m = ((cvmatnd_t*)self)->a; + char str[1000]; + sprintf(str, "type); + d += strlen(d); + sprintf(d, ")>"); + return PyString_FromString(str); +} + +static size_t cvmatnd_size(CvMatND *m) +{ + int bps = 1; + switch (CV_MAT_DEPTH(m->type)) { + case CV_8U: + case CV_8S: + bps = CV_MAT_CN(m->type) * 1; + break; + case CV_16U: + case CV_16S: + bps = CV_MAT_CN(m->type) * 2; + break; + case CV_32S: + case CV_32F: + bps = CV_MAT_CN(m->type) * 4; + break; + case CV_64F: + bps = CV_MAT_CN(m->type) * 8; + break; + default: + assert(0); + } + size_t l = bps; + for (int d = 0; d < m->dims; d++) { + l *= m->dim[d].size; + } + return l; +} + +static PyObject *cvmatnd_tostring(PyObject *self, PyObject *args) +{ + CvMatND *m; + if (!convert_to_CvMatND(self, &m, "self")) + return NULL; + + int bps; + switch (CV_MAT_DEPTH(m->type)) { + case CV_8U: + case CV_8S: + bps = CV_MAT_CN(m->type) * 1; + break; + case CV_16U: + case CV_16S: + bps = CV_MAT_CN(m->type) * 2; + break; + case CV_32S: + case CV_32F: + bps = CV_MAT_CN(m->type) * 4; + break; + case CV_64F: + bps = CV_MAT_CN(m->type) * 8; + break; + default: + return (PyObject*)failmsg("Unrecognised depth %d", CV_MAT_DEPTH(m->type)); + } + + int l = bps; + for (int d = 0; d < m->dims; d++) { + l *= m->dim[d].size; + } + int i[CV_MAX_DIM]; + int d; + for (d = 0; d < m->dims; d++) { + i[d] = 0; + } + int rowsize = m->dim[m->dims-1].size * bps; + char *s = new char[l]; + char *ps = s; + + int finished = 0; + while (!finished) { + memcpy(ps, cvPtrND(m, i), rowsize); + ps += rowsize; + for (d = m->dims - 2; 0 <= d; d--) { + if (++i[d] < cvGetDimSize(m, d)) { + break; + } else { + i[d] = 0; + } + } + if (d < 0) + finished = 1; + } + + return PyString_FromStringAndSize(s, ps - s); +} + +static struct PyMethodDef cvmatnd_methods[] = +{ + {"tostring", cvmatnd_tostring, METH_VARARGS}, + {NULL, NULL} +}; + +static PyObject *cvmatnd_getchannels(cvmatnd_t *cva) +{ + return PyInt_FromLong(CV_MAT_CN(cva->a->type)); +} + +static PyGetSetDef cvmatnd_getseters[] = { +#if PYTHON_USE_NUMPY + {(char*)"__array_struct__", (getter)cvmatnd_array_struct, (setter)NULL, (char*)"__array_struct__", NULL}, +#endif + {(char*)"channels",(getter)cvmatnd_getchannels, (setter)NULL, (char*)"channels", NULL}, + {NULL} /* Sentinel */ +}; + +static PyMappingMethods cvmatnd_as_map = { + NULL, + &cvarr_GetItem, + &cvarr_SetItem, +}; + +static PyTypeObject cvmatnd_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, /*size*/ + MODULESTR".cvmatnd", /*name*/ + sizeof(cvmatnd_t), /*basicsize*/ +}; + +static void cvmatnd_specials(void) +{ + cvmatnd_Type.tp_dealloc = cvmatnd_dealloc; + cvmatnd_Type.tp_as_mapping = &cvmatnd_as_map; + cvmatnd_Type.tp_repr = cvmatnd_repr; + cvmatnd_Type.tp_methods = cvmatnd_methods; + cvmatnd_Type.tp_getset = cvmatnd_getseters; +} + +static int is_cvmatnd(PyObject *o) +{ + return PyType_IsSubtype(o->ob_type, &cvmatnd_Type); +} + +/************************************************************************/ + +/* cvhistogram */ + +static void cvhistogram_dealloc(PyObject *self) +{ + cvhistogram_t *cvh = (cvhistogram_t*)self; + Py_DECREF(cvh->bins); + PyObject_Del(self); +} + +static PyTypeObject cvhistogram_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, /*size*/ + MODULESTR".cvhistogram", /*name*/ + sizeof(cvhistogram_t), /*basicsize*/ +}; + +static PyObject *cvhistogram_getbins(cvhistogram_t *cvh) +{ + Py_INCREF(cvh->bins); + return cvh->bins; +} + +static PyGetSetDef cvhistogram_getseters[] = { + {(char*)"bins", (getter)cvhistogram_getbins, (setter)NULL, (char*)"bins", NULL}, + {NULL} /* Sentinel */ +}; + +static void cvhistogram_specials(void) +{ + cvhistogram_Type.tp_dealloc = cvhistogram_dealloc; + cvhistogram_Type.tp_getset = cvhistogram_getseters; +} + +/************************************************************************/ + +/* cvlineiterator */ + +static PyObject *cvlineiterator_iter(PyObject *o) +{ + Py_INCREF(o); + return o; +} + +static PyObject *cvlineiterator_next(PyObject *o) +{ + cvlineiterator_t *pi = (cvlineiterator_t*)o; + + if (pi->count) { + pi->count--; + + CvScalar r; + cvRawDataToScalar( (void*)(pi->iter.ptr), pi->type, &r); + PyObject *pr = PyObject_FromCvScalar(r, pi->type); + + CV_NEXT_LINE_POINT(pi->iter); + + return pr; + } else { + return NULL; + } +} + +static PyTypeObject cvlineiterator_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, /*size*/ + MODULESTR".cvlineiterator", /*name*/ + sizeof(cvlineiterator_t), /*basicsize*/ +}; + +static void cvlineiterator_specials(void) +{ + cvlineiterator_Type.tp_iter = cvlineiterator_iter; + cvlineiterator_Type.tp_iternext = cvlineiterator_next; +} + +/************************************************************************/ + +/* memtrack */ + +/* Motivation for memtrack is when the storage for a Mat is an array or buffer +object. By setting 'data' to be a memtrack, can deallocate the storage at +object destruction. + +For array objects, 'backing' is the actual storage object. memtrack holds the reference, +then DECREF's it at dealloc. + +For MatND's, we need to cvDecRefData() on release, and this is what field 'backingmat' is for. + +If freeptr is true, then a straight cvFree() of ptr happens. + +*/ + + +static void memtrack_dealloc(PyObject *self) +{ + memtrack_t *pi = (memtrack_t*)self; + if (pi->backing) + Py_DECREF(pi->backing); + if (pi->backingmat) + cvDecRefData(pi->backingmat); + if (pi->freeptr) + cvFree(&pi->ptr); + PyObject_Del(self); +} + +static PyTypeObject memtrack_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, /*size*/ + MODULESTR".memtrack", /*name*/ + sizeof(memtrack_t), /*basicsize*/ +}; + +Py_ssize_t memtrack_getreadbuffer(PyObject *self, Py_ssize_t segment, void **ptrptr) +{ + *ptrptr = &((memtrack_t*)self)->ptr; + return ((memtrack_t*)self)->size; +} + +Py_ssize_t memtrack_getwritebuffer(PyObject *self, Py_ssize_t segment, void **ptrptr) +{ + *ptrptr = ((memtrack_t*)self)->ptr; + return ((memtrack_t*)self)->size; +} + +Py_ssize_t memtrack_getsegcount(PyObject *self, Py_ssize_t *lenp) +{ + return (Py_ssize_t)1; +} + +PyBufferProcs memtrack_as_buffer = { + memtrack_getreadbuffer, + memtrack_getwritebuffer, + memtrack_getsegcount +}; + +static void memtrack_specials(void) +{ + memtrack_Type.tp_dealloc = memtrack_dealloc; + memtrack_Type.tp_as_buffer = &memtrack_as_buffer; +} + +/************************************************************************/ + +/* cvmemstorage */ + +static void cvmemstorage_dealloc(PyObject *self) +{ + cvmemstorage_t *ps = (cvmemstorage_t*)self; + cvReleaseMemStorage(&(ps->a)); + PyObject_Del(self); +} + +static PyTypeObject cvmemstorage_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, /*size*/ + MODULESTR".cvmemstorage", /*name*/ + sizeof(cvmemstorage_t), /*basicsize*/ +}; + +static void cvmemstorage_specials(void) +{ + cvmemstorage_Type.tp_dealloc = cvmemstorage_dealloc; +} + +/************************************************************************/ + +/* cvfont */ + +static PyTypeObject cvfont_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, /*size*/ + MODULESTR".cvfont", /*name*/ + sizeof(cvfont_t), /*basicsize*/ +}; + +static void cvfont_specials(void) { } + +/************************************************************************/ + +/* cvrng */ + +static PyTypeObject cvrng_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, /*size*/ + MODULESTR".cvrng", /*name*/ + sizeof(cvrng_t), /*basicsize*/ +}; + +static void cvrng_specials(void) +{ +} + +/************************************************************************/ + +/* cvcontourtree */ + +static PyTypeObject cvcontourtree_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, /*size*/ + MODULESTR".cvcontourtree", /*name*/ + sizeof(cvcontourtree_t), /*basicsize*/ +}; + +static void cvcontourtree_specials(void) { } + + +/************************************************************************/ + +/* cvsubdiv2dedge */ + +static PyTypeObject cvsubdiv2dedge_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, /*size*/ + MODULESTR".cvsubdiv2dedge", /*name*/ + sizeof(cvsubdiv2dedge_t), /*basicsize*/ +}; + +static int cvsubdiv2dedge_compare(PyObject *o1, PyObject *o2) +{ + cvsubdiv2dedge_t *e1 = (cvsubdiv2dedge_t*)o1; + cvsubdiv2dedge_t *e2 = (cvsubdiv2dedge_t*)o2; + if (e1->a < e2->a) + return -1; + else if (e1->a > e2->a) + return 1; + else + return 0; +} + +static PyObject *cvquadedge_repr(PyObject *self) +{ + CvSubdiv2DEdge m = ((cvsubdiv2dedge_t*)self)->a; + char str[1000]; + sprintf(str, ""); + return PyString_FromString(str); +} + +static void cvsubdiv2dedge_specials(void) { + cvsubdiv2dedge_Type.tp_compare = cvsubdiv2dedge_compare; + cvsubdiv2dedge_Type.tp_repr = cvquadedge_repr; +} + +/************************************************************************/ + +/* cvseq */ + +static void cvseq_dealloc(PyObject *self) +{ + cvseq_t *ps = (cvseq_t*)self; + Py_DECREF(ps->container); + PyObject_Del(self); +} + +static PyObject *cvseq_h_next(PyObject *self, PyObject *args); +static PyObject *cvseq_h_prev(PyObject *self, PyObject *args); +static PyObject *cvseq_v_next(PyObject *self, PyObject *args); +static PyObject *cvseq_v_prev(PyObject *self, PyObject *args); + +static struct PyMethodDef cvseq_methods[] = +{ + {"h_next", cvseq_h_next, METH_VARARGS}, + {"h_prev", cvseq_h_prev, METH_VARARGS}, + {"v_next", cvseq_v_next, METH_VARARGS}, + {"v_prev", cvseq_v_prev, METH_VARARGS}, + {NULL, NULL} +}; + +static Py_ssize_t cvseq_seq_length(PyObject *o) +{ + cvseq_t *ps = (cvseq_t*)o; + if (ps->a == NULL) + return (Py_ssize_t)0; + else + return (Py_ssize_t)(ps->a->total); +} + +static PyObject* cvseq_seq_getitem(PyObject *o, Py_ssize_t i) +{ + cvseq_t *ps = (cvseq_t*)o; + CvPoint *pt; + struct pointpair{ + CvPoint a, b; + } *pp; + CvPoint2D32f *pt2; + CvPoint3D32f *pt3; + + if (i < cvseq_seq_length(o)) { + switch (CV_SEQ_ELTYPE(ps->a)) { + + case CV_SEQ_ELTYPE_POINT: + pt = CV_GET_SEQ_ELEM(CvPoint, ps->a, i); + return Py_BuildValue("ii", pt->x, pt->y); + + case CV_SEQ_ELTYPE_GENERIC: + switch (ps->a->elem_size) { + case sizeof(CvQuadEdge2D): + { + cvsubdiv2dedge_t *r = PyObject_NEW(cvsubdiv2dedge_t, &cvsubdiv2dedge_Type); + r->a = (CvSubdiv2DEdge)CV_GET_SEQ_ELEM(CvQuadEdge2D, ps->a, i); + r->container = ps->container; + Py_INCREF(r->container); + return (PyObject*)r; + } + case sizeof(CvConnectedComp): + { + CvConnectedComp *cc = CV_GET_SEQ_ELEM(CvConnectedComp, ps->a, i); + return FROM_CvConnectedComp(*cc); + } + default: + printf("seq elem size is %d\n", ps->a->elem_size); + printf("KIND %d\n", CV_SEQ_KIND(ps->a)); + assert(0); + } + return PyInt_FromLong(*CV_GET_SEQ_ELEM(unsigned char, ps->a, i)); + + case CV_SEQ_ELTYPE_PTR: + case CV_SEQ_ELTYPE_INDEX: + return PyInt_FromLong(*CV_GET_SEQ_ELEM(int, ps->a, i)); + + case CV_32SC4: + pp = CV_GET_SEQ_ELEM(pointpair, ps->a, i); + return Py_BuildValue("(ii),(ii)", pp->a.x, pp->a.y, pp->b.x, pp->b.y); + + case CV_32FC2: + pt2 = CV_GET_SEQ_ELEM(CvPoint2D32f, ps->a, i); + return Py_BuildValue("ff", pt2->x, pt2->y); + + case CV_SEQ_ELTYPE_POINT3D: + pt3 = CV_GET_SEQ_ELEM(CvPoint3D32f, ps->a, i); + return Py_BuildValue("fff", pt3->x, pt3->y, pt3->z); + + default: + printf("Unknown element type %08x\n", CV_SEQ_ELTYPE(ps->a)); + assert(0); + return NULL; + } + } else + return NULL; +} + +static PyObject* cvseq_map_getitem(PyObject *o, PyObject *item) +{ + if (PyInt_Check(item)) { + long i = PyInt_AS_LONG(item); + if (i < 0) + i += cvseq_seq_length(o); + return cvseq_seq_getitem(o, i); + } else if (PySlice_Check(item)) { + Py_ssize_t start, stop, step, slicelength, cur, i; + PyObject* result; + + if (PySlice_GetIndicesEx((PySliceObject*)item, cvseq_seq_length(o), + &start, &stop, &step, &slicelength) < 0) { + return NULL; + } + + if (slicelength <= 0) { + return PyList_New(0); + } else { + result = PyList_New(slicelength); + if (!result) return NULL; + + for (cur = start, i = 0; i < slicelength; + cur += step, i++) { + PyList_SET_ITEM(result, i, cvseq_seq_getitem(o, cur)); + } + + return result; + } + } else { + PyErr_SetString(PyExc_TypeError, "CvSeq indices must be integers"); + return NULL; + } +} + +static +PySequenceMethods cvseq_sequence = { + cvseq_seq_length, + NULL, + NULL, + cvseq_seq_getitem +}; + +static PyMappingMethods cvseq_mapping = { + cvseq_seq_length, + cvseq_map_getitem, + NULL, +}; + +static PyTypeObject cvseq_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, /*size*/ + MODULESTR".cvseq", /*name*/ + sizeof(cvseq_t), /*basicsize*/ +}; + +static void cvseq_specials(void) +{ + cvseq_Type.tp_dealloc = cvseq_dealloc; + cvseq_Type.tp_as_sequence = &cvseq_sequence; + cvseq_Type.tp_as_mapping = &cvseq_mapping; + cvseq_Type.tp_methods = cvseq_methods; +} + +#define MK_ACCESSOR(FIELD) \ +static PyObject *cvseq_##FIELD(PyObject *self, PyObject *args) \ +{ \ + cvseq_t *ps = (cvseq_t*)self; \ + CvSeq *s = ps->a; \ + if (s->FIELD == NULL) { \ + Py_RETURN_NONE; \ + } else { \ + cvseq_t *r = PyObject_NEW(cvseq_t, &cvseq_Type); \ + r->a = s->FIELD; \ + r->container = ps->container; \ + Py_INCREF(r->container); \ + return (PyObject*)r; \ + } \ +} + +MK_ACCESSOR(h_next) +MK_ACCESSOR(h_prev) +MK_ACCESSOR(v_next) +MK_ACCESSOR(v_prev) +#undef MK_ACCESSOR + +/************************************************************************/ + +/* cvset */ + +static void cvset_dealloc(PyObject *self) +{ + cvset_t *ps = (cvset_t*)self; + Py_DECREF(ps->container); + PyObject_Del(self); +} + +static PyTypeObject cvset_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, /*size*/ + MODULESTR".cvset", /*name*/ + sizeof(cvset_t), /*basicsize*/ +}; + +static PyObject *cvset_iter(PyObject *o) +{ + Py_INCREF(o); + cvset_t *ps = (cvset_t*)o; + ps->i = 0; + return o; +} + +static PyObject *cvset_next(PyObject *o) +{ + cvset_t *ps = (cvset_t*)o; + + while (ps->i < ps->a->total) { + CvSetElem *e = cvGetSetElem(ps->a, ps->i); + int prev_i = ps->i++; + if (e != NULL) { + return cvseq_seq_getitem(o, prev_i); + } + } + return NULL; +} + +static void cvset_specials(void) +{ + cvset_Type.tp_dealloc = cvset_dealloc; + cvset_Type.tp_iter = cvset_iter; + cvset_Type.tp_iternext = cvset_next; +} + +/************************************************************************/ + +/* cvsubdiv2d */ + +static PyTypeObject cvsubdiv2d_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, /*size*/ + MODULESTR".cvsubdiv2d", /*name*/ + sizeof(cvsubdiv2d_t), /*basicsize*/ +}; + +static PyObject *cvsubdiv2d_getattro(PyObject *o, PyObject *name) +{ + cvsubdiv2d_t *p = (cvsubdiv2d_t*)o; + if (strcmp(PyString_AsString(name), "edges") == 0) { + cvset_t *r = PyObject_NEW(cvset_t, &cvset_Type); + r->a = p->a->edges; + r->container = p->container; + Py_INCREF(r->container); + return (PyObject*)r; + } else { + PyErr_SetString(PyExc_TypeError, "cvsubdiv2d has no such attribute"); + return NULL; + } +} + +static void cvsubdiv2d_specials(void) +{ + cvsubdiv2d_Type.tp_getattro = cvsubdiv2d_getattro; +} + +/************************************************************************/ + +/* cvsubdiv2dpoint */ + +static PyTypeObject cvsubdiv2dpoint_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, /*size*/ + MODULESTR".cvsubdiv2dpoint", /*name*/ + sizeof(cvsubdiv2dpoint_t), /*basicsize*/ +}; + +static PyObject *cvsubdiv2dpoint_getattro(PyObject *o, PyObject *name) +{ + cvsubdiv2dpoint_t *p = (cvsubdiv2dpoint_t*)o; + if (strcmp(PyString_AsString(name), "first") == 0) { + cvsubdiv2dedge_t *r = PyObject_NEW(cvsubdiv2dedge_t, &cvsubdiv2dedge_Type); + r->a = p->a->first; + r->container = p->container; + Py_INCREF(r->container); + return (PyObject*)r; + } else if (strcmp(PyString_AsString(name), "pt") == 0) { + return Py_BuildValue("(ff)", p->a->pt.x, p->a->pt.y); + } else { + PyErr_SetString(PyExc_TypeError, "cvsubdiv2dpoint has no such attribute"); + return NULL; + } +} + +static void cvsubdiv2dpoint_specials(void) +{ + cvsubdiv2dpoint_Type.tp_getattro = cvsubdiv2dpoint_getattro; +} + +/************************************************************************/ +/* convert_to_X: used after PyArg_ParseTuple in the generated code */ + +/*static int convert_to_PyObjectPTR(PyObject *o, PyObject **dst, const char *name = "no_name") +{ + *dst = o; + return 1; +} + +static int convert_to_PyCallableObjectPTR(PyObject *o, PyObject **dst, const char *name = "no_name") +{ + *dst = o; + return 1; +}*/ + +static int convert_to_char(PyObject *o, char *dst, const char *name = "no_name") +{ + if (PyString_Check(o) && PyString_Size(o) == 1) { + *dst = PyString_AsString(o)[0]; + return 1; + } else { + (*dst) = 0; + return failmsg("Expected single character string for argument '%s'", name); + } +} + +static int convert_to_CvMemStorage(PyObject *o, CvMemStorage **dst, const char *name = "no_name") +{ + if (PyType_IsSubtype(o->ob_type, &cvmemstorage_Type)) { + (*dst) = (((cvmemstorage_t*)o)->a); + return 1; + } else { + (*dst) = (CvMemStorage*)NULL; + return failmsg("Expected CvMemStorage for argument '%s'", name); + } +} + +static int convert_to_CvSeq(PyObject *o, CvSeq **dst, const char *name = "no_name") +{ + if (PyType_IsSubtype(o->ob_type, &cvseq_Type)) { + (*dst) = (((cvseq_t*)o)->a); + return 1; + } else { + (*dst) = (CvSeq*)NULL; + return failmsg("Expected CvSeq for argument '%s'", name); + } +} + +static int convert_to_CvSize(PyObject *o, CvSize *dst, const char *name = "no_name") +{ + if (!PyArg_ParseTuple(o, "ii", &dst->width, &dst->height)) + return failmsg("CvSize argument '%s' expects two integers", name); + else + return 1; +} + +static int convert_to_CvScalar(PyObject *o, CvScalar *s, const char *name = "no_name") +{ + if (PySequence_Check(o)) { + PyObject *fi = PySequence_Fast(o, name); + if (fi == NULL) + return 0; + if (4 < PySequence_Fast_GET_SIZE(fi)) + return failmsg("CvScalar value for argument '%s' is longer than 4", name); + for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) { + PyObject *item = PySequence_Fast_GET_ITEM(fi, i); + if (PyFloat_Check(item) || PyInt_Check(item)) { + s->val[i] = PyFloat_AsDouble(item); + } else { + return failmsg("CvScalar value for argument '%s' is not numeric", name); + } + } + Py_DECREF(fi); + } else { + if (PyFloat_Check(o) || PyInt_Check(o)) { + s->val[0] = PyFloat_AsDouble(o); + } else { + return failmsg("CvScalar value for argument '%s' is not numeric", name); + } + } + return 1; +} + +static int convert_to_CvPointPTR(PyObject *o, CvPoint **p, const char *name = "no_name") +{ + if (!PySequence_Check(o)) + return failmsg("Expected sequence for point list argument '%s'", name); + PyObject *fi = PySequence_Fast(o, name); + if (fi == NULL) + return 0; + *p = new CvPoint[PySequence_Fast_GET_SIZE(fi)]; + for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) { + PyObject *item = PySequence_Fast_GET_ITEM(fi, i); + if (!PyTuple_Check(item)) + return failmsg("Expected tuple for element in point list argument '%s'", name); + if (!PyArg_ParseTuple(item, "ii", &((*p)[i].x), &((*p)[i].y))) { + return 0; + } + } + Py_DECREF(fi); + return 1; +} + +static int convert_to_CvPoint2D32fPTR(PyObject *o, CvPoint2D32f **p, const char *name = "no_name") +{ + PyObject *fi = PySequence_Fast(o, name); + if (fi == NULL) + return 0; + *p = new CvPoint2D32f[PySequence_Fast_GET_SIZE(fi)]; + for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) { + PyObject *item = PySequence_Fast_GET_ITEM(fi, i); + if (!PyTuple_Check(item)) + return failmsg("Expected tuple for CvPoint2D32f argument '%s'", name); + if (!PyArg_ParseTuple(item, "ff", &((*p)[i].x), &((*p)[i].y))) { + return 0; + } + } + Py_DECREF(fi); + return 1; +} + +#if 0 // not used +static int convert_to_CvPoint3D32fPTR(PyObject *o, CvPoint3D32f **p, const char *name = "no_name") +{ + PyObject *fi = PySequence_Fast(o, name); + if (fi == NULL) + return 0; + *p = new CvPoint3D32f[PySequence_Fast_GET_SIZE(fi)]; + for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) { + PyObject *item = PySequence_Fast_GET_ITEM(fi, i); + if (!PyTuple_Check(item)) + return failmsg("Expected tuple for CvPoint3D32f argument '%s'", name); + if (!PyArg_ParseTuple(item, "fff", &((*p)[i].x), &((*p)[i].y), &((*p)[i].z))) { + return 0; + } + } + Py_DECREF(fi); + return 1; +} +#endif + +static int convert_to_CvStarDetectorParams(PyObject *o, CvStarDetectorParams *dst, const char *name = "no_name") +{ + if (!PyArg_ParseTuple(o, + "iiiii", + &dst->maxSize, + &dst->responseThreshold, + &dst->lineThresholdProjected, + &dst->lineThresholdBinarized, + &dst->suppressNonmaxSize)) + return failmsg("CvRect argument '%s' expects four integers", name); + else + return 1; +} + +static int convert_to_CvRect(PyObject *o, CvRect *dst, const char *name = "no_name") +{ + if (!PyArg_ParseTuple(o, "iiii", &dst->x, &dst->y, &dst->width, &dst->height)) + return failmsg("CvRect argument '%s' expects four integers", name); + else + return 1; +} + +static int convert_to_CvRectPTR(PyObject *o, CvRect **dst, const char *name = "no_name") +{ + *dst = new CvRect; + if (!PyArg_ParseTuple(o, "iiii", &(*dst)->x, &(*dst)->y, &(*dst)->width, &(*dst)->height)) + return failmsg("CvRect argument '%s' expects four integers", name); + else + return 1; +} + +static int convert_to_CvSlice(PyObject *o, CvSlice *dst, const char *name = "no_name") +{ + if (!PyArg_ParseTuple(o, "ii", &dst->start_index, &dst->end_index)) + return failmsg("CvSlice argument '%s' expects two integers", name); + else + return 1; +} + +static int convert_to_CvPoint(PyObject *o, CvPoint *dst, const char *name = "no_name") +{ + if (!PyArg_ParseTuple(o, "ii", &dst->x, &dst->y)) + return failmsg("CvPoint argument '%s' expects two integers", name); + else + return 1; +} + +static int convert_to_CvPoint2D32f(PyObject *o, CvPoint2D32f *dst, const char *name = "no_name") +{ + if (!PyArg_ParseTuple(o, "ff", &dst->x, &dst->y)) + return failmsg("CvPoint2D32f argument '%s' expects two floats", name); + else + return 1; +} + +static int convert_to_CvPoint3D32f(PyObject *o, CvPoint3D32f *dst, const char *name = "no_name") +{ + if (!PyArg_ParseTuple(o, "fff", &dst->x, &dst->y, &dst->z)) + return failmsg("CvPoint3D32f argument '%s' expects three floats", name); + else + return 1; +} + +static int convert_to_IplImage(PyObject *o, IplImage **dst, const char *name) +{ + iplimage_t *ipl = (iplimage_t*)o; + void *buffer; + Py_ssize_t buffer_len; + + if (!is_iplimage(o)) { + return failmsg("Argument '%s' must be IplImage", name); + } else if (PyString_Check(ipl->data)) { + cvSetData(ipl->a, PyString_AsString(ipl->data) + ipl->offset, ipl->a->widthStep); + assert(cvGetErrStatus() == 0); + *dst = ipl->a; + return 1; + } else if (ipl->data && PyObject_AsWriteBuffer(ipl->data, &buffer, &buffer_len) == 0) { + cvSetData(ipl->a, (void*)((char*)buffer + ipl->offset), ipl->a->widthStep); + assert(cvGetErrStatus() == 0); + *dst = ipl->a; + return 1; + } else { + return failmsg("IplImage argument '%s' has no data", name); + } +} + +static int convert_to_CvMat(PyObject *o, CvMat **dst, const char *name) +{ + cvmat_t *m = (cvmat_t*)o; + void *buffer; + Py_ssize_t buffer_len; + + if (!is_cvmat(o)) { +#if !PYTHON_USE_NUMPY + return failmsg("Argument '%s' must be CvMat", name); +#else + PyObject *asmat = fromarray(o, 0); + if (asmat == NULL) + return failmsg("Argument '%s' must be CvMat", name); + // now have the array obect as a cvmat, can use regular conversion + return convert_to_CvMat(asmat, dst, name); +#endif + } else { + m->a->refcount = NULL; + if (m->data && PyString_Check(m->data)) { + assert(cvGetErrStatus() == 0); + char *ptr = PyString_AsString(m->data) + m->offset; + cvSetData(m->a, ptr, m->a->step); + assert(cvGetErrStatus() == 0); + *dst = m->a; + return 1; + } else if (m->data && PyObject_AsWriteBuffer(m->data, &buffer, &buffer_len) == 0) { + cvSetData(m->a, (void*)((char*)buffer + m->offset), m->a->step); + assert(cvGetErrStatus() == 0); + *dst = m->a; + return 1; + } else { + return failmsg("CvMat argument '%s' has no data", name); + } + } +} + +static int convert_to_CvMatND(PyObject *o, CvMatND **dst, const char *name) +{ + cvmatnd_t *m = (cvmatnd_t*)o; + void *buffer; + Py_ssize_t buffer_len; + + if (!is_cvmatnd(o)) { + return failmsg("Argument '%s' must be CvMatND", name); + } else if (m->data && PyString_Check(m->data)) { + m->a->data.ptr = ((uchar*)PyString_AsString(m->data)) + m->offset; + *dst = m->a; + return 1; + } else if (m->data && PyObject_AsWriteBuffer(m->data, &buffer, &buffer_len) == 0) { + m->a->data.ptr = ((uchar*)buffer + m->offset); + *dst = m->a; + return 1; + } else { + return failmsg("CvMatND argument '%s' has no data", name); + } +} + +static int convert_to_CvArr(PyObject *o, CvArr **dst, const char *name) +{ + if (o == Py_None) { + *dst = (void*)NULL; + return 1; + } else if (is_iplimage(o)) { + return convert_to_IplImage(o, (IplImage**)dst, name); + } else if (is_cvmat(o)) { + return convert_to_CvMat(o, (CvMat**)dst, name); + } else if (is_cvmatnd(o)) { + return convert_to_CvMatND(o, (CvMatND**)dst, name); + } else { +#if !PYTHON_USE_NUMPY + return failmsg("CvArr argument '%s' must be IplImage, CvMat or CvMatND", name); +#else + PyObject *asmat = fromarray(o, 0); + if (asmat == NULL) + return failmsg("CvArr argument '%s' must be IplImage, CvMat, CvMatND, or support the array interface", name); + // now have the array obect as a cvmat, can use regular conversion + return convert_to_CvArr(asmat, dst, name); +#endif + } +} + +static int convert_to_CvHistogram(PyObject *o, CvHistogram **dst, const char *name = "no_name") +{ + if (PyType_IsSubtype(o->ob_type, &cvhistogram_Type)) { + cvhistogram_t *ht = (cvhistogram_t*)o; + *dst = &ht->h; + return convert_to_CvArr(ht->bins, &(ht->h.bins), "bins"); + } else { + *dst = (CvHistogram *)NULL; + return failmsg("Expected CvHistogram for argument '%s'", name); + } +} + +// Used by FillPoly, FillConvexPoly, PolyLine +struct pts_npts_contours { + CvPoint** pts; + int* npts; + int contours; +}; + +static int convert_to_pts_npts_contours(PyObject *o, pts_npts_contours *dst, const char *name = "no_name") +{ + PyObject *fi = PySequence_Fast(o, name); + if (fi == NULL) + return 0; + dst->contours = PySequence_Fast_GET_SIZE(fi); + dst->pts = new CvPoint*[dst->contours]; + dst->npts = new int[dst->contours]; + for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) { + if (!convert_to_CvPointPTR(PySequence_Fast_GET_ITEM(fi, i), &dst->pts[i], name)) + return 0; + dst->npts[i] = PySequence_Size(PySequence_Fast_GET_ITEM(fi, i)); // safe because convert_ just succeeded + } + Py_DECREF(fi); + return 1; +} + +class cvarrseq { +public: + union { + CvSeq *seq; + CvArr *mat; + }; + int freemat; + cvarrseq() { + freemat = false; + } + ~cvarrseq() { + if (freemat) { + cvReleaseMat((CvMat**)&mat); + } + } +}; + +static int is_convertible_to_mat(PyObject *o) +{ +#if PYTHON_USE_NUMPY + if (PyObject_HasAttrString(o, "__array_struct__")) { + PyObject *ao = PyObject_GetAttrString(o, "__array_struct__"); + if (ao != NULL && + PyCObject_Check(ao) && + ((PyArrayInterface*)PyCObject_AsVoidPtr(ao))->two == 2) { + return 1; + } + } +#endif + return is_iplimage(o) && is_cvmat(o) && is_cvmatnd(o); +} + +static int convert_to_cvarrseq(PyObject *o, cvarrseq *dst, const char *name = "no_name") +{ + if (PyType_IsSubtype(o->ob_type, &cvseq_Type)) { + return convert_to_CvSeq(o, &(dst->seq), name); + } else if (is_convertible_to_mat(o)) { + int r = convert_to_CvArr(o, &(dst->mat), name); + return r; + } else if (PySequence_Check(o)) { + PyObject *fi = PySequence_Fast(o, name); + if (fi == NULL) + return 0; + Py_ssize_t size = -1; + // Make a pass through the sequence, checking that each element is + // a sequence and that they are all the same size + for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) { + PyObject *e = PySequence_Fast_GET_ITEM(fi, i); + + if (!PySequence_Check(e)) + return failmsg("Sequence '%s' must contain sequences", name); + if (i == 0) + size = (int)PySequence_Size(e); + else if (size != PySequence_Size(e)) + return failmsg("All elements of sequence '%s' must be same size", name); + } + assert(size != -1); + CvMat *mt = cvCreateMat((int)PySequence_Fast_GET_SIZE(fi), 1, CV_32SC(size)); + dst->freemat = true; // dealloc this mat when done + for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) { + PyObject *e = PySequence_Fast_GET_ITEM(fi, i); + PyObject *fe = PySequence_Fast(e, name); + assert(fe != NULL); + int *pdst = (int*)cvPtr2D(mt, i, 0); + for (Py_ssize_t j = 0; j < size; j++) { + PyObject *num = PySequence_Fast_GET_ITEM(fe, j); + if (!PyNumber_Check(num)) { + return failmsg("Sequence must contain numbers", name); + } + *pdst++ = PyInt_AsLong(num); + } + Py_DECREF(fe); + } + Py_DECREF(fi); + dst->mat = mt; + return 1; + } else { + return failmsg("Argument '%s' must be CvSeq, CvArr, or a sequence of numbers"); + } +} + +struct cvarr_count { + CvArr **cvarr; + int count; +}; + +static int convert_to_cvarr_count(PyObject *o, cvarr_count *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->cvarr = new CvArr*[dst->count]; + for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) { + if (!convert_to_CvArr(PySequence_Fast_GET_ITEM(fi, i), &dst->cvarr[i], name)) + return 0; + } + Py_DECREF(fi); + return 1; +} + +struct intpair +{ + int *pairs; + int count; +}; + +static int convert_to_intpair(PyObject *o, intpair *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->pairs = new int[2 * dst->count]; + for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) { + PyObject *item = PySequence_Fast_GET_ITEM(fi, i); + if (!PyArg_ParseTuple(item, "ii", &dst->pairs[2 * i], &dst->pairs[2 * i + 1])) { + return 0; + } + } + Py_DECREF(fi); + return 1; +} + +struct cvpoint2d32f_count { + CvPoint2D32f* points; + int count; +}; + +static int convert_to_cvpoint2d32f_count(PyObject *o, cvpoint2d32f_count *dst, const char *name = "no_name") +{ + if (PyInt_Check(o)) { + dst->count = PyInt_AsLong(o); + dst->points = new CvPoint2D32f[dst->count]; + return 1; + } else { + return failmsg("Expected integer for CvPoint2D32f count"); + } +} + +struct floats { + float *f; + int count; +}; +static int convert_to_floats(PyObject *o, floats *dst, const char *name = "no_name") +{ + 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] = (float)PyFloat_AsDouble(o); + } else { + return failmsg("Expected list of floats, or float for argument '%s'", name); + } + return 1; +} + +struct chars { + char *f; + int count; +}; +/// convert_to_chars not used + +struct CvPoints { + CvPoint *p; + int count; +}; +static int convert_to_CvPoints(PyObject *o, CvPoints *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->p = new CvPoint[dst->count]; + for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) { + PyObject *item = PySequence_Fast_GET_ITEM(fi, i); + convert_to_CvPoint(item, &dst->p[i], name); + } + Py_DECREF(fi); + return 1; +} + +struct CvPoint3D32fs { + CvPoint3D32f *p; + int count; +}; +static int convert_to_CvPoint3D32fs(PyObject *o, CvPoint3D32fs *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->p = new CvPoint3D32f[dst->count]; + for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) { + PyObject *item = PySequence_Fast_GET_ITEM(fi, i); + convert_to_CvPoint3D32f(item, &dst->p[i], name); + } + Py_DECREF(fi); + return 1; +} + +struct CvPoint2D32fs { + CvPoint2D32f *p; + int count; +}; +static int convert_to_CvPoint2D32fs(PyObject *o, CvPoint2D32fs *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->p = new CvPoint2D32f[dst->count]; + for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) { + PyObject *item = PySequence_Fast_GET_ITEM(fi, i); + convert_to_CvPoint2D32f(item, &dst->p[i], name); + } + Py_DECREF(fi); + return 1; +} + +struct ints { + int *i; + int count; +}; +static int convert_to_ints(PyObject *o, ints *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->i = new int[dst->count]; + for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) { + PyObject *item = PySequence_Fast_GET_ITEM(fi, i); + dst->i[i] = PyInt_AsLong(item); + } + Py_DECREF(fi); + return 1; +} + +struct ints0 { + int *i; + int count; +}; +static int convert_to_ints0(PyObject *o, ints0 *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->i = new int[dst->count + 1]; + for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) { + PyObject *item = PySequence_Fast_GET_ITEM(fi, i); + dst->i[i] = PyInt_AsLong(item); + } + dst->i[dst->count] = 0; + Py_DECREF(fi); + return 1; +} + +struct dims +{ + int count; + int i[CV_MAX_DIM]; + int step[CV_MAX_DIM]; + int length[CV_MAX_DIM]; +}; + +static int convert_to_dim(PyObject *item, int i, dims *dst, CvArr *cva, const char *name = "no_name") +{ + if (PySlice_Check(item)) { + Py_ssize_t start, stop, step, slicelength; + PySlice_GetIndicesEx((PySliceObject*)item, cvGetDimSize(cva, i), &start, &stop, &step, &slicelength); + dst->i[i] = start; + dst->step[i] = step; + dst->length[i] = slicelength; + } else { + int index = PyInt_AsLong(item); + if (0 <= index) + dst->i[i] = index; + else + dst->i[i] = cvGetDimSize(cva, i) + index; + dst->step[i] = 0; + dst->length[i] = 1; + } + return 1; +} + +static int convert_to_dims(PyObject *o, dims *dst, CvArr *cva, const char *name = "no_name") +{ + if (!PyTuple_Check(o)) { + dst->count = 1; + return convert_to_dim(o, 0, dst, cva, name); + } else { + PyObject *fi = PySequence_Fast(o, name); + if (fi == NULL) { + PyErr_SetString(PyExc_TypeError, "Expected tuple for index"); + return 0; + } + dst->count = PySequence_Fast_GET_SIZE(fi); + for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) { + if (i >= cvGetDims(cva)) { + return failmsg("Access specifies %d dimensions, but array only has %d", PySequence_Fast_GET_SIZE(fi), cvGetDims(cva)); + } + PyObject *item = PySequence_Fast_GET_ITEM(fi, i); + if (!convert_to_dim(item, i, dst, cva, name)) + return 0; + } + Py_DECREF(fi); + return 1; + } +} + +struct IplImages { + IplImage **ims; + int count; +}; +static int convert_to_IplImages(PyObject *o, IplImages *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->ims = new IplImage*[dst->count]; + for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) { + PyObject *item = PySequence_Fast_GET_ITEM(fi, i); + if (!convert_to_IplImage(item, &dst->ims[i])) + return 0; + } + Py_DECREF(fi); + return 1; +} + +struct CvArrs { + CvArr **ims; + int count; +}; +static int convert_to_CvArrs(PyObject *o, CvArrs *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->ims = new CvArr*[dst->count]; + for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) { + PyObject *item = PySequence_Fast_GET_ITEM(fi, i); + if (!convert_to_CvArr(item, &dst->ims[i])) + return 0; + } + Py_DECREF(fi); + return 1; +} + +/*static int convert_to_floatPTRPTR(PyObject *o, float*** dst, const char *name = "no_name") +{ + PyObject *fi = PySequence_Fast(o, name); + if (fi == NULL) + return 0; + Py_ssize_t sz = PySequence_Fast_GET_SIZE(fi); + float **r = new float*[sz]; + for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) { + PyObject *item = PySequence_Fast_GET_ITEM(fi, i); + floats ff; + if (!convert_to_floats(item, &ff)) + return 0; + r[i] = ff.f; + } + *dst = r; + return 1; +}*/ + +static int convert_to_CvFontPTR(PyObject *o, CvFont** dst, const char *name = "no_name") +{ + if (PyType_IsSubtype(o->ob_type, &cvfont_Type)) { + (*dst) = &(((cvfont_t*)o)->a); + return 1; + } else { + (*dst) = (CvFont*)NULL; + return failmsg("Expected CvFont for argument '%s'", name); + } +} + +/*static int convert_to_CvContourTreePTR(PyObject *o, CvContourTree** dst, const char *name = "no_name") +{ + if (PyType_IsSubtype(o->ob_type, &cvcontourtree_Type)) { + (*dst) = ((cvcontourtree_t*)o)->a; + return 1; + } else { + (*dst) = NULL; + return failmsg("Expected CvContourTree for argument '%s'", name); + } +}*/ + +static int convert_to_CvRNGPTR(PyObject *o, CvRNG** dst, const char *name = "no_name") +{ + if (PyType_IsSubtype(o->ob_type, &cvrng_Type)) { + (*dst) = &(((cvrng_t*)o)->a); + return 1; + } else { + (*dst) = (CvRNG*)NULL; + return failmsg("Expected CvRNG for argument '%s'", name); + } +} + +typedef void* generic; +static int convert_to_generic(PyObject *o, generic *dst, const char *name = "no_name") +{ + if (PyType_IsSubtype(o->ob_type, &iplimage_Type)) + return convert_to_IplImage(o, (IplImage**)dst, name); + else if (PyType_IsSubtype(o->ob_type, &cvmat_Type)) + return convert_to_CvMat(o, (CvMat**)dst, name); + else if (PyType_IsSubtype(o->ob_type, &cvmatnd_Type)) + return convert_to_CvMatND(o, (CvMatND**)dst, name); + else { + return failmsg("Cannot identify type of '%s'", name); + } +} + +static int convert_to_CvTermCriteria(PyObject *o, CvTermCriteria* dst, const char *name = "no_name") +{ + if (!PyArg_ParseTuple(o, "iid", &dst->type, &dst->max_iter, &dst->epsilon)) + return 0; + return 1; +} + +static int convert_to_CvBox2D(PyObject *o, CvBox2D* dst, const char *name = "no_name") +{ + if (!PyArg_ParseTuple(o, "(ff)(ff)f", &dst->center.x, &dst->center.y, &dst->size.width, &dst->size.height, &dst->angle)) + return 0; + return 1; +} + +static int convert_to_CvSubdiv2DPTR(PyObject *o, CvSubdiv2D** dst, const char *name = "no_name") +{ + if (PyType_IsSubtype(o->ob_type, &cvsubdiv2d_Type)) { + (*dst) = (((cvsubdiv2d_t*)o)->a); + return 1; + } else { + (*dst) = (CvSubdiv2D*)NULL; + return failmsg("Expected CvSubdiv2D for argument '%s'", name); + } +} + +static int convert_to_CvNextEdgeType(PyObject *o, CvNextEdgeType *dst, const char *name = "no_name") +{ + if (!PyInt_Check(o)) { + *dst = (CvNextEdgeType)NULL; + return failmsg("Expected number for CvNextEdgeType argument '%s'", name); + } else { + *dst = (CvNextEdgeType)PyInt_AsLong(o); + return 1; + } +} + +static int convert_to_CvSubdiv2DEdge(PyObject *o, CvSubdiv2DEdge *dst, const char *name = "no_name") +{ + if (PyType_IsSubtype(o->ob_type, &cvsubdiv2dedge_Type)) { + (*dst) = (((cvsubdiv2dedge_t*)o)->a); + return 1; + } else { + *dst = 0L; + return failmsg("Expected CvSubdiv2DEdge for argument '%s'", name); + } +} + +/************************************************************************/ + +static PyObject *pythonize_CvMat(cvmat_t *m) +{ + // Need to make this CvMat look like any other, with a Python + // buffer object as its data. + CvMat *mat = m->a; + assert(mat->step != 0); +#if 0 + PyObject *data = PyString_FromStringAndSize((char*)(mat->data.ptr), mat->rows * mat->step); +#else + memtrack_t *o = PyObject_NEW(memtrack_t, &memtrack_Type); + size_t gap = mat->data.ptr - (uchar*)mat->refcount; + o->ptr = mat->refcount; + o->owner = __LINE__; + o->freeptr = true; + o->size = gap + mat->rows * mat->step; + o->backing = NULL; + o->backingmat = NULL; + PyObject *data = PyBuffer_FromReadWriteObject((PyObject*)o, (size_t)gap, mat->rows * mat->step); + if (data == NULL) + return NULL; +#endif + m->data = data; + m->offset = 0; + Py_DECREF(o); + + // Now m has a reference to data, which has a reference to o. + + return (PyObject*)m; +} + +static PyObject *pythonize_foreign_CvMat(cvmat_t *m) +{ + // Need to make this CvMat look like any other, with a Python + // buffer object as its data. + // Difference here is that the buffer is 'foreign' (from NumPy, for example) + CvMat *mat = m->a; + assert(mat->step != 0); +#if 0 + PyObject *data = PyString_FromStringAndSize((char*)(mat->data.ptr), mat->rows * mat->step); +#else + memtrack_t *o = PyObject_NEW(memtrack_t, &memtrack_Type); + o->ptr = mat->data.ptr; + o->owner = __LINE__; + o->freeptr = false; + o->size = mat->rows * mat->step; + o->backing = NULL; + o->backingmat = mat; + PyObject *data = PyBuffer_FromReadWriteObject((PyObject*)o, (size_t)0, mat->rows * mat->step); + if (data == NULL) + return NULL; +#endif + m->data = data; + m->offset = 0; + Py_DECREF(o); + + // Now m has a reference to data, which has a reference to o. + + return (PyObject*)m; +} + +static PyObject *pythonize_IplImage(iplimage_t *cva) +{ + // Need to make this iplimage look like any other, with a Python + // string as its data. + // So copy the image data into a Python string object, then release + // it. + + IplImage *ipl = (IplImage*)(cva->a); + // PyObject *data = PyString_FromStringAndSize(ipl->imageData, ipl->imageSize); + + memtrack_t *o = PyObject_NEW(memtrack_t, &memtrack_Type); + assert(ipl->imageDataOrigin == ipl->imageData); + o->ptr = ipl->imageDataOrigin; + o->owner = __LINE__; + o->freeptr = true; + o->size = ipl->height * ipl->widthStep; + o->backing = NULL; + o->backingmat = NULL; + PyObject *data = PyBuffer_FromReadWriteObject((PyObject*)o, (size_t)0, o->size); + if (data == NULL) + return NULL; + Py_DECREF(o); + cva->data = data; + cva->offset = 0; + + return (PyObject*)cva; +} + +static PyObject *pythonize_CvMatND(cvmatnd_t *m, PyObject *backing = NULL) +{ + // + // Need to make this CvMatND look like any other, with a Python + // buffer object as its data. + // + + CvMatND *mat = m->a; + assert(mat->dim[0].step != 0); +#if 0 + PyObject *data = PyString_FromStringAndSize((char*)(mat->data.ptr), mat->dim[0].size * mat->dim[0].step); +#else + memtrack_t *o = PyObject_NEW(memtrack_t, &memtrack_Type); + o->ptr = mat->data.ptr; + o->owner = __LINE__; + o->freeptr = false; + o->size = cvmatnd_size(mat); + Py_XINCREF(backing); + o->backing = backing; + o->backingmat = mat; + PyObject *data = PyBuffer_FromReadWriteObject((PyObject*)o, (size_t)0, o->size); + Py_DECREF(o); // Now 'data' holds the only reference to 'o' + if (data == NULL) + return NULL; +#endif + m->data = data; + m->offset = 0; + + return (PyObject*)m; +} + +/************************************************************************/ +/* FROM_xxx: C -> Python converters. + * + * Turn various OpenCV types (and some aggregate types above) + * into Python objects. Used by the generated code. + * + * All these functions and macros return a new reference. + */ + + +static PyObject *_FROM_CvSeqPTR(CvSeq *s, PyObject *storage) +{ + cvseq_t *ps = PyObject_NEW(cvseq_t, &cvseq_Type); + ps->a = s; + ps->container = storage; + Py_INCREF(ps->container); + return (PyObject*)ps; +} + +static PyObject *_FROM_CvSubdiv2DPTR(CvSubdiv2D *s, PyObject *storage) +{ + cvsubdiv2d_t *ps = PyObject_NEW(cvsubdiv2d_t, &cvsubdiv2d_Type); + ps->a = s; + ps->container = storage; + Py_INCREF(ps->container); + return (PyObject*)ps; +} + +static PyObject *FROM_floats(floats r) +{ + PyObject *pr; + + pr = PyList_New(r.count); + for (Py_ssize_t i = 0; i < (Py_ssize_t)r.count; i++) { + PyList_SetItem(pr, i, PyFloat_FromDouble(r.f[i])); + } + return pr; +} + +static PyObject *FROM_chars(chars r) +{ + PyObject *pr; + + pr = PyList_New(r.count); + for (Py_ssize_t i = 0; i < (Py_ssize_t)r.count; i++) { + PyList_SetItem(pr, i, PyInt_FromLong(r.f[i])); + } + return pr; +} + +static PyObject *FROM_cvpoint2d32f_count(cvpoint2d32f_count r) +{ + PyObject *pr; + + pr = PyList_New(r.count); + for (Py_ssize_t i = 0; i < (Py_ssize_t)r.count; i++) { + PyList_SetItem(pr, i, FROM_CvPoint2D32f(r.points[i])); + } + return pr; +} + +static PyObject *FROM_CvPoint2D32fs(CvPoint2D32fs r) +{ + PyObject *pr; + + pr = PyList_New(r.count); + for (Py_ssize_t i = 0; i < (Py_ssize_t)r.count; i++) { + PyList_SetItem(pr, i, FROM_CvPoint2D32f(r.p[i])); + } + return pr; +} + +typedef CvSeq CvSeqOfCvConvexityDefect; +static PyObject *FROM_CvSeqOfCvConvexityDefectPTR(CvSeqOfCvConvexityDefect *r) +{ + PyObject *pr; + pr = PyList_New(r->total); + for (int i = 0; i < r->total; i++) { + CvConvexityDefect *pd = CV_GET_SEQ_ELEM(CvConvexityDefect, r, i); + PyList_SetItem(pr, i, Py_BuildValue("(ii)(ii)(ii)f", + pd->start->x, pd->start->y, + pd->end->x, pd->end->y, + pd->depth_point->x, pd->depth_point->y, + pd->depth)); + } + // This function has copied the CvSeq data into a list. Hence the + // CvSeq is not being returned to the caller. Hence, no reference + // count increase for the storage, unlike _FROM_CvSeqPTR. + return pr; +} + +typedef CvSeq CvSeqOfCvAvgComp; +static PyObject *FROM_CvSeqOfCvAvgCompPTR(CvSeqOfCvAvgComp *r) +{ + PyObject *pr; + pr = PyList_New(r->total); + for (int i = 0; i < r->total; i++) { + CvAvgComp *pd = CV_GET_SEQ_ELEM(CvAvgComp, r, i); + PyList_SetItem(pr, i, Py_BuildValue("(iiii)i", + pd->rect.x, pd->rect.y, + pd->rect.width, pd->rect.height, + pd->neighbors)); + } + // This function has copied the CvSeq data into a list. Hence the + // CvSeq is not being returned to the caller. Hence, no reference + // count increase for the storage, unlike _FROM_CvSeqPTR. + return pr; +} + +typedef CvSeq CvSeqOfCvStarKeypoint; +static PyObject *FROM_CvSeqOfCvStarKeypointPTR(CvSeqOfCvStarKeypoint *r) +{ + PyObject *pr; + pr = PyList_New(r->total); + for (int i = 0; i < r->total; i++) { + CvStarKeypoint *pd = CV_GET_SEQ_ELEM(CvStarKeypoint, r, i); + PyList_SetItem(pr, i, Py_BuildValue("(ii)if", + pd->pt.x, pd->pt.y, + pd->size, + pd->response)); + } + // This function has copied the CvSeq data into a list. Hence the + // CvSeq is not being returned to the caller. Hence, no reference + // count increase for the storage, unlike _FROM_CvSeqPTR. + return pr; +} + +typedef CvSeq CvSeqOfCvSURFPoint; +static PyObject *FROM_CvSeqOfCvSURFPointPTR(CvSeqOfCvSURFPoint *r) +{ + PyObject *pr; + pr = PyList_New(r->total); + for (int i = 0; i < r->total; i++) { + CvSURFPoint *pd = CV_GET_SEQ_ELEM(CvSURFPoint, r, i); + PyList_SetItem(pr, i, Py_BuildValue("(ff)iiff", + pd->pt.x, pd->pt.y, + pd->laplacian, + pd->size, + pd->dir, + pd->hessian)); + } + // This function has copied the CvSeq data into a list. Hence the + // CvSeq is not being returned to the caller. Hence, no reference + // count increase for the storage, unlike _FROM_CvSeqPTR. + return pr; +} + +typedef CvSeq CvSeqOfCvSURFDescriptor; +static PyObject *FROM_CvSeqOfCvSURFDescriptorPTR(CvSeqOfCvSURFDescriptor *r) +{ + PyObject *pr; + pr = PyList_New(r->total); + for (int i = 0; i < r->total; i++) { + float *pd = (float*)cvGetSeqElem(r, i); + int count = r->elem_size / sizeof(float); + PyObject *oi = PyList_New(count); + for (int j = 0; j < count; j++) { + PyList_SetItem(oi, j, PyFloat_FromDouble(pd[j])); + } + PyList_SetItem(pr, i, oi); + } + // This function has copied the CvSeq data into a list. Hence the + // CvSeq is not being returned to the caller. Hence, no reference + // count increase for the storage, unlike _FROM_CvSeqPTR. + return pr; +} + +typedef CvPoint2D32f CvPoint2D32f_4[4]; +static PyObject *FROM_CvPoint2D32f_4(CvPoint2D32f* r) +{ + return Py_BuildValue("(ff)(ff)(ff)(ff)", + r[0].x, r[0].y, + r[1].x, r[1].y, + r[2].x, r[2].y, + r[3].x, r[3].y); +} + +typedef float CvMatr32f_i[9]; + +static PyObject *FROM_CvMatr32f_i(CvMatr32f_i r) +{ + return Py_BuildValue("(fff)(fff)(fff)", + r[0], r[1], r[2], + r[3], r[4], r[5], + r[6], r[7], r[8]); +} + +typedef float CvVect32f_i[3]; +static PyObject *FROM_CvVect32f_i(CvVect32f_i r) +{ + return Py_BuildValue("fff", + r[0], r[1], r[2]); +} + +static PyObject *FROM_CvFont(CvFont r) +{ + cvfont_t *cf = PyObject_NEW(cvfont_t, &cvfont_Type); + cf->a = r; + return (PyObject*)cf; +} + +static PyObject *FROM_CvSubdiv2DPointPTR(CvSubdiv2DPoint* r) +{ + if (r != NULL) { + cvsubdiv2dpoint_t *cf = PyObject_NEW(cvsubdiv2dpoint_t, &cvsubdiv2dpoint_Type); + cf->a = r; + return (PyObject*)cf; + } else { + Py_INCREF(Py_None); + return Py_None; + } +} + +static PyObject *FROM_IplImagePTR(IplImage *r) +{ + iplimage_t *cva = PyObject_NEW(iplimage_t, &iplimage_Type); + cva->a = r; + return pythonize_IplImage(cva); +} + +static PyObject *FROM_ROIplImagePTR(ROIplImage *r) +{ + if (r != NULL) { + iplimage_t *cva = PyObject_NEW(iplimage_t, &iplimage_Type); + cva->a = cvCreateImageHeader(cvSize(100,100), 8, 1); + *(cva->a) = *r; + cva->data = PyBuffer_FromReadWriteMemory(r->imageData, r->height * r->widthStep); + cva->offset = 0; + return (PyObject*)cva; + } else { + Py_RETURN_NONE; + } +} + +static PyObject *FROM_ROCvMatPTR(ROCvMat *r) +{ + if (r != NULL) { + cvmat_t *cva = PyObject_NEW(cvmat_t, &cvmat_Type); + cva->a = cvCreateMatHeader(100, 100, CV_8U); + *(cva->a) = *r; + cva->data = PyBuffer_FromReadWriteMemory(r->data.ptr, r->rows * r->step); + cva->offset = 0; + return (PyObject*)cva; + } else { + Py_RETURN_NONE; + } +} + +static PyObject *FROM_CvMatPTR(CvMat *r) +{ + cvmat_t *cvm = PyObject_NEW(cvmat_t, &cvmat_Type); + cvm->a = r; + + return pythonize_CvMat(cvm); +} + +static PyObject *FROM_CvMat(CvMat *r) +{ + cvmat_t *m = PyObject_NEW(cvmat_t, &cvmat_Type); + m->a = r; + return pythonize_CvMat(m); +} + +static PyObject *FROM_CvMatNDPTR(CvMatND *r) +{ + cvmatnd_t *m = PyObject_NEW(cvmatnd_t, &cvmatnd_Type); + m->a = r; + return pythonize_CvMatND(m); +} + +static PyObject *FROM_CvRNG(CvRNG r) +{ + cvrng_t *m = PyObject_NEW(cvrng_t, &cvrng_Type); + m->a = r; + return (PyObject*)m; +} + +/*static PyObject *FROM_CvContourTreePTR(CvContourTree *r) +{ + cvcontourtree_t *m = PyObject_NEW(cvcontourtree_t, &cvcontourtree_Type); + m->a = r; + return (PyObject*)m; +}*/ + +static PyObject *FROM_generic(generic r) +{ + CvTypeInfo* t = cvTypeOf(r); + if (r == NULL) { + failmsg("OpenCV returned NULL"); + return NULL; + } if (strcmp(t->type_name, "opencv-image") == 0) + return FROM_IplImagePTR((IplImage*)r); + else if (strcmp(t->type_name, "opencv-matrix") == 0) + return FROM_CvMat((CvMat*)r); + else if (strcmp(t->type_name, "opencv-nd-matrix") == 0) + return FROM_CvMatNDPTR((CvMatND*)r); + else if (strcmp(t->type_name, "opencv-haar-classifier") == 0) + return FROM_CvHaarClassifierCascadePTR((CvHaarClassifierCascade*)r); + else { + failmsg("Unknown OpenCV type '%s'", t->type_name); + return NULL; + } +} + +static PyObject *FROM_CvSubdiv2DEdge(CvSubdiv2DEdge r) +{ + cvsubdiv2dedge_t *m = PyObject_NEW(cvsubdiv2dedge_t, &cvsubdiv2dedge_Type); + m->a = r; + m->container = Py_None; // XXX + Py_INCREF(m->container); + 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, + * so are handwritten here */ + +static PyObject *pycvWaitKey(PyObject *self, PyObject *args, PyObject *kw) +{ + int delay = 0; + + const char *keywords[] = { "delay", NULL }; + if (!PyArg_ParseTupleAndKeywords(args, kw, "|i", (char**)keywords, &delay)) + return NULL; + int r; + Py_BEGIN_ALLOW_THREADS + r = cvWaitKey(delay); + Py_END_ALLOW_THREADS + return FROM_int(r); +} + +static PyObject *pycvLoadImage(PyObject *self, PyObject *args, PyObject *kw) +{ + const char *keywords[] = { "filename", "iscolor", NULL }; + char *filename; + int iscolor = CV_LOAD_IMAGE_COLOR; + + if (!PyArg_ParseTupleAndKeywords(args, kw, "s|i", (char**)keywords, &filename, &iscolor)) + return NULL; + + // Inside ALLOW_THREADS, must not reference 'filename' because it might move. + // So make a local copy 'filename_copy'. + char filename_copy[2048]; + strncpy(filename_copy, filename, sizeof(filename_copy)); + + IplImage *r; + Py_BEGIN_ALLOW_THREADS + r = cvLoadImage(filename_copy, iscolor); + Py_END_ALLOW_THREADS + + if (r == NULL) { + PyErr_SetFromErrnoWithFilename(PyExc_IOError, filename); + return NULL; + } else { + return FROM_IplImagePTR(r); + } +} + +static PyObject *pycvLoadImageM(PyObject *self, PyObject *args, PyObject *kw) +{ + const char *keywords[] = { "filename", "iscolor", NULL }; + char *filename; + int iscolor = CV_LOAD_IMAGE_COLOR; + + if (!PyArg_ParseTupleAndKeywords(args, kw, "s|i", (char**)keywords, &filename, &iscolor)) + return NULL; + + // Inside ALLOW_THREADS, must not reference 'filename' because it might move. + // So make a local copy 'filename_copy'. + char filename_copy[2048]; + strncpy(filename_copy, filename, sizeof(filename_copy)); + + CvMat *r; + Py_BEGIN_ALLOW_THREADS + r = cvLoadImageM(filename_copy, iscolor); + Py_END_ALLOW_THREADS + + if (r == NULL) { + PyErr_SetFromErrnoWithFilename(PyExc_IOError, filename); + return NULL; + } else { + return FROM_CvMatPTR(r); + } +} + +static PyObject *pycvCreateImageHeader(PyObject *self, PyObject *args) +{ + int w, h, depth, channels; + if (!PyArg_ParseTuple(args, "(ii)Ii", &w, &h, &depth, &channels)) + return NULL; + iplimage_t *cva = PyObject_NEW(iplimage_t, &iplimage_Type); + cva->a = cvCreateImageHeader(cvSize(w, h), depth, channels); + if (cva->a == NULL) { + PyErr_SetString(PyExc_TypeError, "CreateImage failed"); + return NULL; + } else { + cva->data = Py_None; + Py_INCREF(cva->data); + cva->offset = 0; + + return (PyObject*)cva; + } +} + +static PyObject *pycvCreateImage(PyObject *self, PyObject *args) +{ + int w, h, depth, channels; + if (!PyArg_ParseTuple(args, "(ii)Ii:CreateImage", &w, &h, &depth, &channels)) + return NULL; + iplimage_t *cva = PyObject_NEW(iplimage_t, &iplimage_Type); + ERRWRAP(cva->a = cvCreateImage(cvSize(w, h), depth, channels)); + if (cva->a == NULL) { + PyErr_SetString(PyExc_TypeError, "CreateImage failed"); + return NULL; + } else { + return pythonize_IplImage(cva); + } +} + +static PyObject *pycvCreateMatHeader(PyObject *self, PyObject *args) +{ + int rows, cols, type; + if (!PyArg_ParseTuple(args, "iii", &rows, &cols, &type)) + return NULL; + cvmat_t *m = PyObject_NEW(cvmat_t, &cvmat_Type); + ERRWRAP(m->a = cvCreateMatHeader(rows, cols, type)); + if (m->a == NULL) { + PyErr_SetString(PyExc_TypeError, "CreateMat failed"); + return NULL; + } else { + m->data = Py_None; + Py_INCREF(m->data); + m->offset = 0; + return (PyObject*)m; + } +} + +static PyObject *pycvCreateMat(PyObject *self, PyObject *args) +{ + int rows, cols, type; + if (!PyArg_ParseTuple(args, "iii", &rows, &cols, &type)) + return NULL; + cvmat_t *m = PyObject_NEW(cvmat_t, &cvmat_Type); + ERRWRAP(m->a = cvCreateMat(rows, cols, type)); + if (m->a == NULL) { + PyErr_SetString(PyExc_TypeError, "CreateMat failed"); + return NULL; + } else { + return pythonize_CvMat(m); + } +} + +static PyObject *pycvCreateMatNDHeader(PyObject *self, PyObject *args) +{ + ints dims; + int type; + + if (!PyArg_ParseTuple(args, "O&i", convert_to_ints, (void*)&dims, &type)) + return NULL; + cvmatnd_t *m = PyObject_NEW(cvmatnd_t, &cvmatnd_Type); + ERRWRAP(m->a = cvCreateMatNDHeader(dims.count, dims.i, type)); + + m->data = Py_None; + Py_INCREF(m->data); + delete [] dims.i; + return (PyObject*)m; +} + + +static PyObject *pycvCreateMatND(PyObject *self, PyObject *args) +{ + ints dims; + int type; + + if (!PyArg_ParseTuple(args, "O&i", convert_to_ints, (void*)&dims, &type)) + return NULL; + cvmatnd_t *m = PyObject_NEW(cvmatnd_t, &cvmatnd_Type); + ERRWRAP(m->a = cvCreateMatND(dims.count, dims.i, type)); + delete [] dims.i; + return pythonize_CvMatND(m); +} + +#if PYTHON_USE_NUMPY +static PyObject *pycvfromarray(PyObject *self, PyObject *args, PyObject *kw) +{ + const char *keywords[] = { "arr", "allowND", NULL }; + PyObject *o; + int allowND = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kw, "O|i", (char**)keywords, &o, &allowND)) + return NULL; + return fromarray(o, allowND); +} + +static PyObject *fromarray(PyObject *o, int allowND) +{ + PyObject *ao = PyObject_GetAttrString(o, "__array_struct__"); + PyObject *retval; + + if ((ao == NULL) || !PyCObject_Check(ao)) { + PyErr_SetString(PyExc_TypeError, "object does not have array interface"); + return NULL; + } + PyArrayInterface *pai = (PyArrayInterface*)PyCObject_AsVoidPtr(ao); + if (pai->two != 2) { + PyErr_SetString(PyExc_TypeError, "object does not have array interface"); + return NULL; + } + + int type = -1; + + switch (pai->typekind) { + case 'i': + if (pai->itemsize == 1) + type = CV_8SC1; + else if (pai->itemsize == 2) + type = CV_16SC1; + else if (pai->itemsize == 4) + type = CV_32SC1; + else if (pai->itemsize == 8) { + PyErr_SetString(PyExc_TypeError, "OpenCV cannot handle 64-bit integer arrays"); + return NULL; + } + break; + + case 'u': + if (pai->itemsize == 1) + type = CV_8UC1; + else if (pai->itemsize == 2) + type = CV_16UC1; + break; + + case 'f': + if (pai->itemsize == 4) + type = CV_32FC1; + else if (pai->itemsize == 8) + type = CV_64FC1; + break; + + } + assert(type != -1); + + if (!allowND) { + cvmat_t *m = PyObject_NEW(cvmat_t, &cvmat_Type); + if (pai->nd == 2) { + if (pai->strides[1] != pai->itemsize) { + return (PyObject*)failmsg("cv.fromarray array can only accept arrays with contiguous data"); + } + ERRWRAP(m->a = cvCreateMatHeader(pai->shape[0], pai->shape[1], type)); + m->a->step = pai->strides[0]; + } else if (pai->nd == 3) { + if (pai->shape[2] > CV_CN_MAX) + return (PyObject*)failmsg("cv.fromarray too many channels, see allowND argument"); + ERRWRAP(m->a = cvCreateMatHeader(pai->shape[0], pai->shape[1], type + ((pai->shape[2] - 1) << CV_CN_SHIFT))); + m->a->step = pai->strides[0]; + } else { + return (PyObject*)failmsg("cv.fromarray array can be 2D or 3D only, see allowND argument"); + } + m->a->data.ptr = (uchar*)pai->data; + retval = pythonize_foreign_CvMat(m); + } else { + int dims[CV_MAX_DIM]; + int i; + for (i = 0; i < pai->nd; i++) + dims[i] = pai->shape[i]; + cvmatnd_t *m = PyObject_NEW(cvmatnd_t, &cvmatnd_Type); + ERRWRAP(m->a = cvCreateMatND(pai->nd, dims, type)); + m->a->data.ptr = (uchar*)pai->data; + + retval = pythonize_CvMatND(m, ao); + } + Py_DECREF(ao); + return retval; +} +#endif + +class ranges { +public: + Py_ssize_t len; + float **rr; + ranges() { + len = 0; + rr = NULL; + } + int fromobj(PyObject *o, const char *name = "no_name") { + PyObject *fi = PySequence_Fast(o, name); + if (fi == NULL) + return 0; + len = PySequence_Fast_GET_SIZE(fi); + rr = new float*[len]; + for (Py_ssize_t i = 0; i < len; i++) { + PyObject *item = PySequence_Fast_GET_ITEM(fi, i); + floats ff; + if (!convert_to_floats(item, &ff)) + return 0; + rr[i] = ff.f; + } + Py_DECREF(fi); + return 1; + } + ~ranges() { + for (Py_ssize_t i = 0; i < len; i++) + delete rr[i]; + delete rr; + } +}; + +static int ranges_converter(PyObject *o, ranges* dst) +{ + return dst->fromobj(o); +} + +static PyObject *pycvCreateHist(PyObject *self, PyObject *args, PyObject *kw) +{ + const char *keywords[] = { "dims", "type", "ranges", "uniform", NULL }; + PyObject *dims; + int type; + int uniform = 1; + ranges r; + if (!PyArg_ParseTupleAndKeywords(args, kw, "Oi|O&i", (char**)keywords, &dims, &type, ranges_converter, (void*)&r, &uniform)) { + return NULL; + } + cvhistogram_t *h = PyObject_NEW(cvhistogram_t, &cvhistogram_Type); + args = Py_BuildValue("Oi", dims, CV_32FC1); + h->bins = pycvCreateMatND(self, args); + Py_DECREF(args); + if (h->bins == NULL) { + return NULL; + } + h->h.type = CV_HIST_MAGIC_VAL; + if (!convert_to_CvArr(h->bins, &(h->h.bins), "bins")) + return NULL; + + ERRWRAP(cvSetHistBinRanges(&(h->h), r.rr, uniform)); + + return (PyObject*)h; +} + +static PyObject *pycvInitLineIterator(PyObject *self, PyObject *args, PyObject *kw) +{ + const char *keywords[] = { "image", "pt1", "pt2", "connectivity", "left_to_right", NULL }; + CvArr *image; + CvPoint pt1; + CvPoint pt2; + int connectivity = 8; + int left_to_right = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kw, "O&O&O&|ii", (char**)keywords, + convert_to_CvArr, &image, + convert_to_CvPoint, &pt1, + convert_to_CvPoint, &pt2, + &connectivity, + &left_to_right)) + return NULL; + + cvlineiterator_t *pi = PyObject_NEW(cvlineiterator_t, &cvlineiterator_Type); + pi->count = cvInitLineIterator(image, pt1, pt2, &pi->iter, connectivity, left_to_right); + ERRWRAP(pi->type = cvGetElemType(image)); + return (PyObject*)pi; +} + +static PyObject *pycvCreateMemStorage(PyObject *self, PyObject *args) +{ + int block_size = 0; + if (!PyArg_ParseTuple(args, "|i", &block_size)) + return NULL; + cvmemstorage_t *pm = PyObject_NEW(cvmemstorage_t, &cvmemstorage_Type); + pm->a = cvCreateMemStorage(block_size); + return (PyObject*)pm; +} + +// single index: return row +// 2 indices: row, column +// both row and column can be slices. column slice must have a step of 1. +// +// returns a scalar when all dimensions are specified and all are integers. Otherwise returns a CvMat. +// +static PyObject *cvarr_GetItem(PyObject *o, PyObject *key) +{ + dims dd; + + CvArr *cva; + if (!convert_to_CvArr(o, &cva, "src")) + return NULL; + + if (!convert_to_dims(key, &dd, cva, "key")) { + return NULL; + } + + // Figure out if all supplied indices have a stride of zero - means they are not slices + // and if all indices are positive + int all0 = 1; + for (int i = 0; i < dd.count; i++) { + all0 &= (dd.step[i] == 0) && (0 <= dd.i[i]); + } + + // if every dimension supplied, and none are slices, return the scalar + if ((cvGetDims(cva) == dd.count) && all0) { + CvScalar s; + ERRWRAP(s = cvGetND(cva, dd.i)); + return PyObject_FromCvScalar(s, cvGetElemType(cva)); + } else { + // pad missing dimensions + for (int i = dd.count; i < cvGetDims(cva); i++) { + dd.i[i] = 0; + dd.step[i] = 1; + dd.length[i] = cvGetDimSize(cva, i); + } + dd.count = cvGetDims(cva); + + // negative steps are illegal for OpenCV + for (int i = 0; i < dd.count; i++) { + if (dd.step[i] < 0) + return (PyObject*)failmsg("Negative step is illegal"); + } + + // zero length illegal for OpenCV + for (int i = 0; i < dd.count; i++) { + if (dd.length[i] == 0) + return (PyObject*)failmsg("Zero sized dimension is illegal"); + } + + // column step can only be 0 or 1 + if ((dd.step[dd.count-1] != 0) && (dd.step[dd.count-1] != 1)) + return (PyObject*)failmsg("Column step is illegal"); + + if (is_cvmat(o) || is_iplimage(o)) { + cvmat_t *sub = PyObject_NEW(cvmat_t, &cvmat_Type); + sub->a = cvCreateMatHeader(dd.length[0], dd.length[1], cvGetElemType(cva)); + uchar *old0; // pointer to first element in old mat + int oldstep; + cvGetRawData(cva, &old0, &oldstep); + uchar *new0; // pointer to first element in new mat + ERRWRAP(new0 = cvPtrND(cva, dd.i)); + + sub->a->step = oldstep * dd.step[0]; + sub->data = what_data(o); + Py_INCREF(sub->data); + sub->offset = new0 - old0; + return (PyObject*)sub; + } else { + cvmatnd_t *sub = PyObject_NEW(cvmatnd_t, &cvmatnd_Type); + sub->a = cvCreateMatNDHeader(dd.count, dd.length, cvGetElemType(cva)); + uchar *old0; // pointer to first element in old mat + cvGetRawData(cva, &old0); + uchar *new0; // pointer to first element in new mat + ERRWRAP(new0 = cvPtrND(cva, dd.i)); + + for (int d = 0; d < dd.count; d++) { + int stp = dd.step[d]; + sub->a->dim[d].step = ((CvMatND*)cva)->dim[d].step * ((stp == 0) ? 1 : stp); + sub->a->dim[d].size = dd.length[d]; + } + sub->data = what_data(o); + Py_INCREF(sub->data); + sub->offset = new0 - old0; + return (PyObject*)sub; + } + } +} + +static int cvarr_SetItem(PyObject *o, PyObject *key, PyObject *v) +{ + dims dd; + + CvArr *cva; + if (!convert_to_CvArr(o, &cva, "src")) + return -1; + + if (!convert_to_dims(key, &dd, cva, "key")) { + return -1; + } + + if (cvGetDims(cva) != dd.count) { + PyErr_SetString(PyExc_TypeError, "key length does not match array dimension"); + return -1; + } + + CvScalar s; + if (PySequence_Check(v)) { + PyObject *fi = PySequence_Fast(v, "v"); + if (fi == NULL) + return -1; + if (PySequence_Fast_GET_SIZE(fi) != CV_MAT_CN(cvGetElemType(cva))) { + PyErr_SetString(PyExc_TypeError, "sequence size must be same as channel count"); + return -1; + } + for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) + s.val[i] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(fi, i)); + Py_DECREF(fi); + } else { + if (1 != CV_MAT_CN(cvGetElemType(cva))) { + PyErr_SetString(PyExc_TypeError, "scalar supplied but channel count does not equal 1"); + return -1; + } + s.val[0] = PyFloat_AsDouble(v); + } + switch (dd.count) { + case 1: + ERRWRAPN(cvSet1D(cva, dd.i[0], s), -1); + break; + case 2: + ERRWRAPN(cvSet2D(cva, dd.i[0], dd.i[1], s), -1); + break; + case 3: + ERRWRAPN(cvSet3D(cva, dd.i[0], dd.i[1], dd.i[2], s), -1); + break; + default: + ERRWRAPN(cvSetND(cva, dd.i, s), -1); + // XXX - OpenCV bug? - seems as if an error in cvSetND does not set error status? + break; + } + if (cvGetErrStatus() != 0) { + translate_error_to_exception(); + return -1; + } + + return 0; +} + + +static PyObject *pycvSetData(PyObject *self, PyObject *args) +{ + PyObject *o, *s; + int step = CV_AUTO_STEP; + + if (!PyArg_ParseTuple(args, "OO|i", &o, &s, &step)) + return NULL; + if (is_iplimage(o)) { + iplimage_t *ipl = (iplimage_t*)o; + ipl->a->widthStep = step; + Py_DECREF(ipl->data); + ipl->data = s; + Py_INCREF(ipl->data); + } else if (is_cvmat(o)) { + cvmat_t *m = (cvmat_t*)o; + m->a->step = step; + Py_DECREF(m->data); + m->data = s; + Py_INCREF(m->data); + } else if (is_cvmatnd(o)) { + cvmatnd_t *m = (cvmatnd_t*)o; + Py_DECREF(m->data); + m->data = s; + Py_INCREF(m->data); + } else { + PyErr_SetString(PyExc_TypeError, "SetData argument must be either IplImage, CvMat or CvMatND"); + return NULL; + } + + Py_RETURN_NONE; +} + +static PyObject *what_data(PyObject *o) +{ + if (is_iplimage(o)) { + iplimage_t *ipl = (iplimage_t*)o; + return ipl->data; + } else if (is_cvmat(o)) { + cvmat_t *m = (cvmat_t*)o; + return m->data; + } else if (is_cvmatnd(o)) { + cvmatnd_t *m = (cvmatnd_t*)o; + return m->data; + } else { + assert(0); + return NULL; + } +} + +static PyObject *pycvCreateData(PyObject *self, PyObject *args) +{ + PyObject *o; + + if (!PyArg_ParseTuple(args, "O", &o)) + return NULL; + + CvArr *a; + if (!convert_to_CvArr(o, &a, "arr")) + return NULL; + ERRWRAP(cvCreateData(a)); + + Py_DECREF(what_data(o)); + if (is_iplimage(o)) { + iplimage_t *ipl = (iplimage_t*)o; + pythonize_IplImage(ipl); + } else if (is_cvmat(o)) { + cvmat_t *m = (cvmat_t*)o; + pythonize_CvMat(m); + } else if (is_cvmatnd(o)) { + cvmatnd_t *m = (cvmatnd_t*)o; + pythonize_CvMatND(m); + } else { + PyErr_SetString(PyExc_TypeError, "CreateData argument must be either IplImage, CvMat or CvMatND"); + return NULL; + } + + Py_RETURN_NONE; +} + +static PyObject *pycvGetDims(PyObject *self, PyObject *args) +{ + PyObject *o; + + if (!PyArg_ParseTuple(args, "O", &o)) + return NULL; + CvArr *cva; + if (!convert_to_CvArr(o, &cva, "src")) + return NULL; + + int i, nd; + ERRWRAP(nd = cvGetDims(cva)); + PyObject *r = PyTuple_New(nd); + for (i = 0; i < nd; i++) + PyTuple_SetItem(r, i, PyInt_FromLong(cvGetDimSize(cva, i))); + return r; +} + +static PyObject *pycvGetImage(PyObject *self, PyObject *args) +{ + PyObject *o, *r; + + if (!PyArg_ParseTuple(args, "O", &o)) + return NULL; + if (is_iplimage(o)) { + r = o; + Py_INCREF(o); + } else { + IplImage *ipl = cvCreateImageHeader(cvSize(100,100), 8, 1); // these args do not matter, because overwritten + CvArr *cva; + if (!convert_to_CvArr(o, &cva, "src")) + return NULL; + ERRWRAP(cvGetImage(cva, ipl)); + + iplimage_t *oipl = PyObject_NEW(iplimage_t, &iplimage_Type); + oipl->a = ipl; + oipl->data = what_data(o); + Py_INCREF(oipl->data); + oipl->offset = 0; + + r = (PyObject*)oipl; + } + return r; +} + +static PyObject *pycvGetMat(PyObject *self, PyObject *args, PyObject *kw) +{ + const char *keywords[] = { "arr", "allowND", NULL }; + PyObject *o, *r; + int allowND = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kw, "O|i", (char**)keywords, &o, &allowND)) + return NULL; + if (is_cvmat(o)) { + r = o; + Py_INCREF(o); + } else { + CvMat *m = cvCreateMatHeader(100,100, 1); // these args do not matter, because overwritten + CvArr *cva; + if (!convert_to_CvArr(o, &cva, "src")) + return NULL; + ERRWRAP(cvGetMat(cva, m, NULL, allowND)); + + cvmat_t *om = PyObject_NEW(cvmat_t, &cvmat_Type); + om->a = m; + om->data = what_data(o); + Py_INCREF(om->data); + om->offset = 0; + + r = (PyObject*)om; + } + return r; +} + +static PyObject *pycvReshape(PyObject *self, PyObject *args) +{ + PyObject *o; + int new_cn; + int new_rows = 0; + + if (!PyArg_ParseTuple(args, "Oi|i", &o, &new_cn, &new_rows)) + return NULL; + + CvMat *m = cvCreateMatHeader(100,100, 1); // these args do not matter, because overwritten + CvArr *cva; + if (!convert_to_CvArr(o, &cva, "src")) + return NULL; + ERRWRAP(cvReshape(cva, m, new_cn, new_rows)); + + cvmat_t *om = PyObject_NEW(cvmat_t, &cvmat_Type); + om->a = m; + om->data = what_data(o); + Py_INCREF(om->data); + om->offset = 0; + + return (PyObject*)om; +} + +static PyObject *pycvReshapeMatND(PyObject *self, PyObject *args) +{ + PyObject *o; + int new_cn = 0; + PyObject *new_dims = NULL; + + if (!PyArg_ParseTuple(args, "OiO", &o, &new_cn, &new_dims)) + return NULL; + + CvMatND *cva; + if (!convert_to_CvMatND(o, &cva, "src")) + return NULL; + ints dims; + if (new_dims != NULL) { + if (!convert_to_ints(new_dims, &dims, "new_dims")) + return NULL; + } + + if (new_cn == 0) + new_cn = CV_MAT_CN(cvGetElemType(cva)); + + int i; + int count = CV_MAT_CN(cvGetElemType(cva)); + for (i = 0; i < cva->dims; i++) + count *= cva->dim[i].size; + + int newcount = new_cn; + for (i = 0; i < dims.count; i++) + newcount *= dims.i[i]; + + if (count != newcount) { + PyErr_SetString(PyExc_TypeError, "Total number of elements must be unchanged"); + return NULL; + } + + CvMatND *pn = cvCreateMatNDHeader(dims.count, dims.i, CV_MAKETYPE(CV_MAT_TYPE(cva->type), new_cn)); + return shareDataND(o, cva, pn); +} + +static void OnMouse(int event, int x, int y, int flags, void* param) +{ + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); + + PyObject *o = (PyObject*)param; + PyObject *args = Py_BuildValue("iiiiO", event, x, y, flags, PyTuple_GetItem(o, 1)); + + PyObject *r = PyObject_Call(PyTuple_GetItem(o, 0), args, NULL); + if (r == NULL) + PyErr_Print(); + else + Py_DECREF(r); + Py_DECREF(args); + PyGILState_Release(gstate); +} + +static PyObject *pycvSetMouseCallback(PyObject *self, PyObject *args, PyObject *kw) +{ + const char *keywords[] = { "window_name", "on_mouse", "param", NULL }; + char* name; + PyObject *on_mouse; + PyObject *param = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|O", (char**)keywords, &name, &on_mouse, ¶m)) + return NULL; + if (!PyCallable_Check(on_mouse)) { + PyErr_SetString(PyExc_TypeError, "on_mouse must be callable"); + return NULL; + } + if (param == NULL) { + param = Py_None; + } + ERRWRAP(cvSetMouseCallback(name, OnMouse, Py_BuildValue("OO", on_mouse, param))); + Py_RETURN_NONE; +} + +void OnChange(int pos, void *param) +{ + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); + + PyObject *o = (PyObject*)param; + PyObject *args = Py_BuildValue("(i)", pos); + PyObject *r = PyObject_Call(PyTuple_GetItem(o, 0), args, NULL); + if (r == NULL) + PyErr_Print(); + Py_DECREF(args); + PyGILState_Release(gstate); +} + +static PyObject *pycvCreateTrackbar(PyObject *self, PyObject *args) +{ + PyObject *on_change; + char* trackbar_name; + char* window_name; + int *value = new int; + int count; + + if (!PyArg_ParseTuple(args, "ssiiO", &trackbar_name, &window_name, value, &count, &on_change)) + return NULL; + if (!PyCallable_Check(on_change)) { + PyErr_SetString(PyExc_TypeError, "on_change must be callable"); + return NULL; + } + ERRWRAP(cvCreateTrackbar2(trackbar_name, window_name, value, count, OnChange, Py_BuildValue("OO", on_change, Py_None))); + Py_RETURN_NONE; +} + +static PyObject *pycvFindContours(PyObject *self, PyObject *args, PyObject *kw) +{ + CvArr* image; + PyObject *pyobj_image = NULL; + CvMemStorage* storage; + PyObject *pyobj_storage = NULL; + CvSeq* first_contour; + int header_size = sizeof(CvContour); + int mode = CV_RETR_LIST; + int method = CV_CHAIN_APPROX_SIMPLE; + CvPoint offset = cvPoint(0,0); + PyObject *pyobj_offset = NULL; + + const char *keywords[] = { "image", "storage", "mode", "method", "offset", NULL }; + if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|iiO", (char**)keywords, &pyobj_image, &pyobj_storage, &mode, &method, &pyobj_offset)) + return NULL; + if (!convert_to_CvArr(pyobj_image, &image, "image")) return NULL; + if (!convert_to_CvMemStorage(pyobj_storage, &storage, "storage")) return NULL; + if ((pyobj_offset != NULL) && !convert_to_CvPoint(pyobj_offset, &offset, "offset")) return NULL; + ERRWRAP(cvFindContours(image, storage, &first_contour, header_size, mode, method, offset)); + cvseq_t *ps = PyObject_NEW(cvseq_t, &cvseq_Type); + ps->a = first_contour; + ps->container = PyTuple_GetItem(args, 1); // storage + Py_INCREF(ps->container); + return (PyObject*)ps; +} + +static PyObject *pycvApproxPoly(PyObject *self, PyObject *args, PyObject *kw) +{ + cvarrseq src_seq; + PyObject *pyobj_src_seq = NULL; + int header_size = sizeof(CvContour); + CvMemStorage* storage; + PyObject *pyobj_storage = NULL; + int method; + double parameter = 0; + int parameter2 = 0; + + const char *keywords[] = { "src_seq", "storage", "method", "parameter", "parameter2", NULL }; + if (!PyArg_ParseTupleAndKeywords(args, kw, "OOi|di", (char**)keywords, &pyobj_src_seq, &pyobj_storage, &method, ¶meter, ¶meter2)) + return NULL; + if (!convert_to_cvarrseq(pyobj_src_seq, &src_seq, "src_seq")) return NULL; + if (!convert_to_CvMemStorage(pyobj_storage, &storage, "storage")) return NULL; + CvSeq* r; + ERRWRAP(r = cvApproxPoly(src_seq.mat, header_size, storage, method, parameter, parameter2)); + return FROM_CvSeqPTR(r); +} + +static float distance_function_glue( const float* a, const float* b, void* user_param ) +{ + PyObject *o = (PyObject*)user_param; + PyObject *args = Py_BuildValue("(ff)(ff)O", a[0], a[1], b[0], b[1], PyTuple_GetItem(o, 1)); + PyObject *r = PyObject_Call(PyTuple_GetItem(o, 0), args, NULL); + Py_DECREF(args); + return (float)PyFloat_AsDouble(r); +} + +static PyObject *pycvCalcEMD2(PyObject *self, PyObject *args, PyObject *kw) +{ + const char *keywords[] = { "signature1", "signature2", "distance_type", "distance_func", "cost_matrix", "flow", "lower_bound", "userdata", NULL }; + CvArr* signature1; + PyObject *pyobj_signature1; + CvArr* signature2; + PyObject *pyobj_signature2; + int distance_type; + PyObject *distance_func = NULL; + CvArr* cost_matrix=NULL; + PyObject *pyobj_cost_matrix = NULL; + CvArr* flow=NULL; + PyObject *pyobj_flow = NULL; + float lower_bound = 0.0; + PyObject *userdata = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kw, "OOi|OOOfO", (char**)keywords, + &pyobj_signature1, + &pyobj_signature2, + &distance_type, + &distance_func, + &pyobj_cost_matrix, + &pyobj_flow, + &lower_bound, + &userdata)) + return NULL; + if (!convert_to_CvArr(pyobj_signature1, &signature1, "signature1")) return NULL; + if (!convert_to_CvArr(pyobj_signature2, &signature2, "signature2")) return NULL; + if (pyobj_cost_matrix && !convert_to_CvArr(pyobj_cost_matrix, &cost_matrix, "cost_matrix")) return NULL; + if (pyobj_flow && !convert_to_CvArr(pyobj_flow, &flow, "flow")) return NULL; + + if (distance_func == NULL) { + distance_func = Py_None; + } + if (userdata == NULL) { + userdata = Py_None; + } + + PyObject *ud = Py_BuildValue("OO", distance_func, userdata); + float r; + ERRWRAP(r = cvCalcEMD2(signature1, signature2, distance_type, distance_function_glue, cost_matrix, flow, &lower_bound, (void*)ud)); + Py_DECREF(ud); + + return PyFloat_FromDouble(r); +} + +static PyObject *pycvSubdiv2DLocate(PyObject *self, PyObject *args) +{ + PyObject *pyobj_subdiv; + PyObject *pyobj_pt; + CvSubdiv2D *subdiv; + CvPoint2D32f pt; + CvSubdiv2DEdge edge; + CvSubdiv2DPoint* vertex; + + if (!PyArg_ParseTuple(args, "OO", &pyobj_subdiv, &pyobj_pt)) + return NULL; + if (!convert_to_CvSubdiv2DPTR(pyobj_subdiv, &subdiv, "subdiv")) + return NULL; + if (!convert_to_CvPoint2D32f(pyobj_pt, &pt, "pt")) + return NULL; + + CvSubdiv2DPointLocation loc = cvSubdiv2DLocate(subdiv, pt, &edge, &vertex); + PyObject *r; + switch (loc) { + case CV_PTLOC_INSIDE: + case CV_PTLOC_ON_EDGE: + r = FROM_CvSubdiv2DEdge(edge); + break; + case CV_PTLOC_VERTEX: + r = FROM_CvSubdiv2DPointPTR(vertex); + break; + case CV_PTLOC_OUTSIDE_RECT: + r = Py_None; + Py_INCREF(Py_None); + break; + default: + return (PyObject*)failmsg("Unexpected loc from cvSubdiv2DLocate"); + } + return Py_BuildValue("iO", (int)loc, r); +} + +static PyObject *pycvCalcOpticalFlowPyrLK(PyObject *self, PyObject *args) +{ + CvArr* prev; + PyObject *pyobj_prev = NULL; + CvArr* curr; + PyObject *pyobj_curr = NULL; + CvArr* prev_pyr; + PyObject *pyobj_prev_pyr = NULL; + CvArr* curr_pyr; + PyObject *pyobj_curr_pyr = NULL; + CvPoint2D32f* prev_features; + PyObject *pyobj_prev_features = NULL; + PyObject *pyobj_curr_features = NULL; + CvPoint2D32f* curr_features; + CvSize win_size; + int level; + CvTermCriteria criteria; + int flags; + + if (!PyArg_ParseTuple(args, "OOOOO(ii)i(iif)i|O", + &pyobj_prev, &pyobj_curr, &pyobj_prev_pyr, &pyobj_curr_pyr, + &pyobj_prev_features, + &win_size.width, &win_size.height, &level, + &criteria.type, &criteria.max_iter, &criteria.epsilon, + &flags, + &pyobj_curr_features)) + return NULL; + if (!convert_to_CvArr(pyobj_prev, &prev, "prev")) return NULL; + if (!convert_to_CvArr(pyobj_curr, &curr, "curr")) return NULL; + if (!convert_to_CvArr(pyobj_prev_pyr, &prev_pyr, "prev_pyr")) return NULL; + if (!convert_to_CvArr(pyobj_curr_pyr, &curr_pyr, "curr_pyr")) return NULL; + if (!convert_to_CvPoint2D32fPTR(pyobj_prev_features, &prev_features, "prev_features")) return NULL; + int count = (int)PySequence_Length(pyobj_prev_features); + if (flags & CV_LKFLOW_INITIAL_GUESSES) { + failmsg("flag CV_LKFLOW_INITIAL_GUESSES is determined automatically from function arguments - it is not required"); + return NULL; + } + if (!pyobj_curr_features) { + curr_features = new CvPoint2D32f[count]; + } else { + if (PySequence_Length(pyobj_curr_features) != count) { + failmsg("curr_features must have same length as prev_features"); + return NULL; + } + if (!convert_to_CvPoint2D32fPTR(pyobj_curr_features, &curr_features, "curr_features")) return NULL; + flags |= CV_LKFLOW_INITIAL_GUESSES; + } + float *track_error = new float[count]; + char* status = new char[count]; + ERRWRAP(cvCalcOpticalFlowPyrLK(prev, curr, prev_pyr, curr_pyr, prev_features, curr_features, count, win_size, level, status, track_error, criteria, flags)); + + cvpoint2d32f_count r0; + r0.points = curr_features; + r0.count = count; + + chars r1; + r1.f = status; + r1.count = count; + + floats r2; + r2.f = track_error; + r2.count = count; + + return Py_BuildValue("NNN", FROM_cvpoint2d32f_count(r0), FROM_chars(r1), FROM_floats(r2)); +} + +// pt1,pt2 are input and output arguments here + +static PyObject *pycvClipLine(PyObject *self, PyObject *args) +{ + CvSize img_size; + PyObject *pyobj_img_size = NULL; + CvPoint pt1; + PyObject *pyobj_pt1 = NULL; + CvPoint pt2; + PyObject *pyobj_pt2 = NULL; + + if (!PyArg_ParseTuple(args, "OOO", &pyobj_img_size, &pyobj_pt1, &pyobj_pt2)) + return NULL; + if (!convert_to_CvSize(pyobj_img_size, &img_size, "img_size")) return NULL; + if (!convert_to_CvPoint(pyobj_pt1, &pt1, "pt1")) return NULL; + if (!convert_to_CvPoint(pyobj_pt2, &pt2, "pt2")) return NULL; + int r; + ERRWRAP(r = cvClipLine(img_size, &pt1, &pt2)); + if (r == 0) { + Py_RETURN_NONE; + } else { + return Py_BuildValue("NN", FROM_CvPoint(pt1), FROM_CvPoint(pt2)); + } +} + +static PyObject *pyfinddatamatrix(PyObject *self, PyObject *args) +{ + PyObject *pyim; + if (!PyArg_ParseTuple(args, "O", &pyim)) + return NULL; + + CvMat *image; + if (!convert_to_CvMat(pyim, &image, "image")) return NULL; + + std::deque codes; + ERRWRAP(codes = cvFindDataMatrix(image)); + + PyObject *pycodes = PyList_New(codes.size()); + for (size_t i = 0; i < codes.size(); i++) { + DataMatrixCode *pc = &codes[i]; + PyList_SetItem(pycodes, i, Py_BuildValue("(sOO)", pc->msg, FROM_CvMat(pc->corners), FROM_CvMat(pc->original))); + } + + return pycodes; +} + +static PyObject *temp_test(PyObject *self, PyObject *args) +{ +#if 0 + CvArr *im = cvLoadImage("../samples/c/lena.jpg", 0); + printf("im=%p\n", im); + CvMat *m = cvEncodeImage(".jpeg", im); +#endif +#if 0 + CvArr *im = cvLoadImage("lena.jpg", 0); + float r0[] = { 0, 255 }; + float *ranges[] = { r0 }; + int hist_size[] = { 256 }; + CvHistogram *hist = cvCreateHist(1, hist_size, CV_HIST_ARRAY, ranges, 1); + cvCalcHist(im, hist, 0, 0); +#endif + +#if 0 + CvMat* mat = cvCreateMat( 3, 3, CV_32F ); + CvMat row_header, *row; + row = cvReshape( mat, &row_header, 0, 1 ); + printf("%d,%d\n", row_header.rows, row_header.cols); + printf("ge %08x\n", cvGetElemType(mat)); +#endif + +#if 0 + CvMat *m = cvCreateMat(1, 10, CV_8UC1); + printf("CvMat stride ===> %d\n", m->step); +#endif + +#if 0 + CvPoint2D32f src[3] = { { 0,0 }, { 1,0 }, { 0,1 } }; + CvPoint2D32f dst[3] = { { 0,0 }, { 17,0 }, { 0,17 } }; + + CvMat* mapping = cvCreateMat(2, 3, CV_32FC1); + cvGetAffineTransform(src, dst, mapping); + printf("===> %f\n", cvGetReal2D(mapping, 0, 0)); +#endif + +#if 0 + CvArr *im = cvLoadImage("checker77.png"); + CvPoint2D32f corners[49]; + int count; + cvFindChessboardCorners(im, cvSize(7,7), corners, &count, 0); + printf("count=%d\n", count); +#endif + +#if 0 + CvMat *src = cvCreateMat(512, 512, CV_8UC3); + CvMat *dst = cvCreateMat(512, 512, CV_8UC3); + cvPyrMeanShiftFiltering(src, dst, 5, 5); + return FROM_CvMat(src); +#endif + + return PyFloat_FromDouble(0.0); +} + +static PyObject *pycvFindChessboardCorners(PyObject *self, PyObject *args, PyObject *kw) +{ + CvArr* image; + PyObject *pyobj_image = NULL; + CvSize pattern_size; + PyObject *pyobj_pattern_size = NULL; + cvpoint2d32f_count corners; + int flags = CV_CALIB_CB_ADAPTIVE_THRESH; + + const char *keywords[] = { "image", "pattern_size", "flags", NULL }; + if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|i", (char**)keywords, &pyobj_image, &pyobj_pattern_size, &flags)) + return NULL; + if (!convert_to_CvArr(pyobj_image, &image, "image")) return NULL; + if (!convert_to_CvSize(pyobj_pattern_size, &pattern_size, "pattern_size")) return NULL; + int r; + corners.points = new CvPoint2D32f[pattern_size.width * pattern_size.height]; + ERRWRAP(r = cvFindChessboardCorners(image, pattern_size, corners.points,&corners.count, flags)); + return Py_BuildValue("NN", FROM_int(r), FROM_cvpoint2d32f_count(corners)); +} + +// For functions GetSubRect, GetRow, GetCol. +// recipient has a view into donor's data, and needs to share it. +// make recipient use the donor's data, compute the offset, +// and manage reference counts. + +static void preShareData(CvArr *donor, CvMat **recipient) +{ + *recipient = cvCreateMatHeader(4, 4, cvGetElemType(donor)); +} + +static PyObject *shareData(PyObject *donor, CvArr *pdonor, CvMat *precipient) +{ + PyObject *recipient = (PyObject*)PyObject_NEW(cvmat_t, &cvmat_Type); + ((cvmat_t*)recipient)->a = precipient; + ((cvmat_t*)recipient)->offset = cvPtr1D(precipient, 0) - cvPtr1D(pdonor, 0); + + PyObject *arr_data; + if (is_cvmat(donor)) { + arr_data = ((cvmat_t*)donor)->data; + ((cvmat_t*)recipient)->offset += ((cvmat_t*)donor)->offset; + } else if (is_iplimage(donor)) { + arr_data = ((iplimage_t*)donor)->data; + ((cvmat_t*)recipient)->offset += ((iplimage_t*)donor)->offset; + } else { + return (PyObject*)failmsg("Argument 'mat' must be either IplImage or CvMat"); + } + ((cvmat_t*)recipient)->data = arr_data; + Py_INCREF(arr_data); + return recipient; +} + +static PyObject *shareDataND(PyObject *donor, CvMatND *pdonor, CvMatND *precipient) +{ + PyObject *recipient = (PyObject*)PyObject_NEW(cvmatnd_t, &cvmatnd_Type); + ((cvmatnd_t*)recipient)->a = precipient; + ((cvmatnd_t*)recipient)->offset = 0; + + PyObject *arr_data; + arr_data = ((cvmatnd_t*)donor)->data; + ((cvmatnd_t*)recipient)->data = arr_data; + Py_INCREF(arr_data); + return recipient; +} + +static PyObject *pycvGetHuMoments(PyObject *self, PyObject *args) +{ + CvMoments* moments; + PyObject *pyobj_moments = NULL; + + if (!PyArg_ParseTuple(args, "O", &pyobj_moments)) + return NULL; + if (!convert_to_CvMomentsPTR(pyobj_moments, &moments, "moments")) return NULL; + CvHuMoments r; + ERRWRAP(cvGetHuMoments(moments, &r)); + return Py_BuildValue("ddddddd", r.hu1, r.hu2, r.hu3, r.hu4, r.hu5, r.hu6, r.hu7); +} + +static PyObject *pycvFitLine(PyObject *self, PyObject *args) +{ + cvarrseq points; + PyObject *pyobj_points = NULL; + int dist_type; + float param; + float reps; + float aeps; + float r[6]; + + if (!PyArg_ParseTuple(args, "Oifff", &pyobj_points, &dist_type, ¶m, &reps, &aeps)) + return NULL; + if (!convert_to_cvarrseq(pyobj_points, &points, "points")) return NULL; + ERRWRAP(cvFitLine(points.mat, dist_type, param, reps, aeps, r)); + int dimension; + if (strcmp("opencv-matrix", cvTypeOf(points.mat)->type_name) == 0) + dimension = CV_MAT_CN(cvGetElemType(points.mat)); + else { + // sequence case... don't think there is a sequence of 3d points, + // so assume 2D + dimension = 2; + } + if (dimension == 2) + return Py_BuildValue("dddd", r[0], r[1], r[2], r[3]); + else + return Py_BuildValue("dddddd", r[0], r[1], r[2], r[3], r[4], r[5]); +} + +static PyObject *pycvGetMinMaxHistValue(PyObject *self, PyObject *args) +{ + CvHistogram* hist; + PyObject *pyobj_hist = NULL; + float min_val; + float max_val; + int min_loc[CV_MAX_DIM]; + int max_loc[CV_MAX_DIM]; + + if (!PyArg_ParseTuple(args, "O", &pyobj_hist)) + return NULL; + if (!convert_to_CvHistogram(pyobj_hist, &hist, "hist")) return NULL; + ERRWRAP(cvGetMinMaxHistValue(hist, &min_val, &max_val, min_loc, max_loc)); + int d = cvGetDims(hist->bins); + PyObject *pminloc = PyTuple_New(d), *pmaxloc = PyTuple_New(d); + for (int i = 0; i < d; i++) { + PyTuple_SetItem(pminloc, i, PyInt_FromLong(min_loc[i])); + PyTuple_SetItem(pmaxloc, i, PyInt_FromLong(max_loc[i])); + } + return Py_BuildValue("ffNN", min_val, max_val, pminloc, pmaxloc); +} + +static CvSeq* cvHOGDetectMultiScale( const CvArr* image, CvMemStorage* storage, + const CvArr* svm_classifier=NULL, CvSize win_stride=cvSize(0,0), + double hit_threshold=0, double scale=1.05, + int group_threshold=2, CvSize padding=cvSize(0,0), + CvSize win_size=cvSize(64,128), CvSize block_size=cvSize(16,16), + CvSize block_stride=cvSize(8,8), CvSize cell_size=cvSize(8,8), + int nbins=9, int gammaCorrection=1 ) +{ + cv::HOGDescriptor hog(win_size, block_size, block_stride, cell_size, nbins, 1, -1, cv::HOGDescriptor::L2Hys, 0.2, gammaCorrection!=0); + if(win_stride.width == 0 && win_stride.height == 0) + win_stride = block_stride; + cv::Mat img = cv::cvarrToMat(image); + std::vector found; + if(svm_classifier) + { + CvMat stub, *m = cvGetMat(svm_classifier, &stub); + int sz = m->cols*m->rows; + CV_Assert(CV_IS_MAT_CONT(m->type) && (m->cols == 1 || m->rows == 1) && CV_MAT_TYPE(m->type) == CV_32FC1); + std::vector w(sz); + std::copy(m->data.fl, m->data.fl + sz, w.begin()); + hog.setSVMDetector(w); + } + else + hog.setSVMDetector(cv::HOGDescriptor::getDefaultPeopleDetector()); + hog.detectMultiScale(img, found, hit_threshold, win_stride, padding, scale, group_threshold); + CvSeq* seq = cvCreateSeq(cv::DataType::type, sizeof(CvSeq), sizeof(cv::Rect), storage); + if(found.size()) + cvSeqPushMulti(seq, &found[0], (int)found.size()); + return seq; +} + +static void cvGrabCut(CvArr *image, + CvArr *mask, + CvRect rect, + CvArr *bgdModel, + CvArr *fgdModel, + int iterCount, + int mode) +{ + cv::Mat _image = cv::cvarrToMat(image); + cv::Mat _mask = cv::cvarrToMat(mask); + cv::Mat _bgdModel = cv::cvarrToMat(bgdModel); + cv::Mat _fgdModel = cv::cvarrToMat(fgdModel); + grabCut(_image, _mask, rect, _bgdModel, _fgdModel, iterCount, mode); +} + +static int zero = 0; + +/************************************************************************/ +/* Custom Validators */ + +#define CVPY_VALIDATE_DrawChessboardCorners() do { \ + if ((patternSize.width * patternSize.height) != corners.count) \ + return (PyObject*)failmsg("Size is %dx%d, but corner list is length %d", patternSize.width, patternSize.height, corners.count); \ + } while (0) + +#define cvGetRotationMatrix2D cv2DRotationMatrix + +/************************************************************************/ +/* Generated functions */ + +#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) + +static double cppKMeans(const CvArr* _samples, int cluster_count, CvArr* _labels, + CvTermCriteria termcrit, int attempts, int flags, CvArr* _centers) +{ + cv::Mat data = cv::cvarrToMat(_samples), labels = cv::cvarrToMat(_labels), centers; + if( _centers ) + centers = cv::cvarrToMat(_centers); + CV_Assert( labels.isContinuous() && labels.type() == CV_32S && + (labels.cols == 1 || labels.rows == 1) && + labels.cols + labels.rows - 1 == data.rows ); + return cv::kmeans(data, cluster_count, labels, termcrit, attempts, + flags, _centers ? cv::OutputArray(centers) : cv::OutputArray() ); +} + +#define cvKMeans2(samples, nclusters, labels, termcrit, attempts, flags, centers) \ + cppKMeans(samples, nclusters, labels, termcrit, attempts, flags, centers) + +#include "generated0.i" + +static PyMethodDef methods[] = { + +#if PYTHON_USE_NUMPY + {"fromarray", (PyCFunction)pycvfromarray, METH_KEYWORDS, "fromarray(array) -> cvmatnd"}, +#endif + + //{"CalcOpticalFlowFarneback", (PyCFunction)pycvCalcOpticalFlowFarneback, METH_KEYWORDS, "CalcOpticalFlowFarneback(prev, next, flow, pyr_scale=0.5, levels=3, win_size=15, iterations=3, poly_n=7, poly_sigma=1.5, flags=0) -> None"}, + //{"_HOGComputeDescriptors", (PyCFunction)pycvHOGComputeDescriptors, METH_KEYWORDS, "_HOGComputeDescriptors(image, win_stride=block_stride, locations=None, 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_descriptors"}, + //{"_HOGDetect", (PyCFunction)pycvHOGDetect, METH_KEYWORDS, "_HOGDetect(image, svm_classifier, win_stride=block_stride, locations=None, 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"}, + //{"_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"}, + + {"FindDataMatrix", pyfinddatamatrix, METH_VARARGS}, + {"temp_test", temp_test, METH_VARARGS}, + +#include "generated1.i" + + {NULL, NULL}, +}; + +/************************************************************************/ +/* Module init */ + +static int to_ok(PyTypeObject *to) +{ + to->tp_alloc = PyType_GenericAlloc; + to->tp_new = PyType_GenericNew; + to->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE; + return (PyType_Ready(to) == 0); +} + +#define MKTYPE(NAME) NAME##_specials(); if (!to_ok(&NAME##_Type)) return + +using namespace cv; + +extern "C" +#if defined WIN32 || defined _WIN32 +__declspec(dllexport) +#endif + +void initcv() +{ +#if PYTHON_USE_NUMPY + import_array(); +#endif + + PyObject *m, *d; + + cvSetErrMode(CV_ErrModeParent); + + MKTYPE(cvcontourtree); + MKTYPE(cvfont); + MKTYPE(cvhistogram); + MKTYPE(cvlineiterator); + MKTYPE(cvmat); + MKTYPE(cvmatnd); + MKTYPE(cvmemstorage); + MKTYPE(cvsubdiv2dedge); + MKTYPE(cvrng); + MKTYPE(cvseq); + MKTYPE(cvset); + MKTYPE(cvsubdiv2d); + MKTYPE(cvsubdiv2dpoint); + MKTYPE(iplimage); + MKTYPE(memtrack); + +#include "generated4.i" + + m = Py_InitModule(MODULESTR"", methods); + d = PyModule_GetDict(m); + + PyDict_SetItemString(d, "__version__", PyString_FromString("$Rev: 4557 $")); + + opencv_error = PyErr_NewException((char*)MODULESTR".error", NULL, NULL); + PyDict_SetItemString(d, "error", opencv_error); + + // Couple of warnings about strict aliasing here. Not clear how to fix. + union { + PyObject *o; + PyTypeObject *to; + } convert; + convert.to = &iplimage_Type; + PyDict_SetItemString(d, "iplimage", convert.o); + convert.to = &cvmat_Type; + PyDict_SetItemString(d, "cvmat", convert.o); + + // AFAIK the only floating-point constant + PyDict_SetItemString(d, "CV_PI", PyFloat_FromDouble(CV_PI)); + +#define PUBLISH(I) PyDict_SetItemString(d, #I, PyInt_FromLong(I)) +#define PUBLISHU(I) PyDict_SetItemString(d, #I, PyLong_FromUnsignedLong(I)) +#define PUBLISH2(I, value) PyDict_SetItemString(d, #I, PyLong_FromLong(value)) + + PUBLISHU(IPL_DEPTH_8U); + PUBLISHU(IPL_DEPTH_8S); + PUBLISHU(IPL_DEPTH_16U); + PUBLISHU(IPL_DEPTH_16S); + PUBLISHU(IPL_DEPTH_32S); + PUBLISHU(IPL_DEPTH_32F); + PUBLISHU(IPL_DEPTH_64F); + + PUBLISH(CV_LOAD_IMAGE_COLOR); + PUBLISH(CV_LOAD_IMAGE_GRAYSCALE); + PUBLISH(CV_LOAD_IMAGE_UNCHANGED); + PUBLISH(CV_HIST_ARRAY); + PUBLISH(CV_HIST_SPARSE); + PUBLISH(CV_8U); + PUBLISH(CV_8UC1); + PUBLISH(CV_8UC2); + PUBLISH(CV_8UC3); + PUBLISH(CV_8UC4); + PUBLISH(CV_8S); + PUBLISH(CV_8SC1); + PUBLISH(CV_8SC2); + PUBLISH(CV_8SC3); + PUBLISH(CV_8SC4); + PUBLISH(CV_16U); + PUBLISH(CV_16UC1); + PUBLISH(CV_16UC2); + PUBLISH(CV_16UC3); + PUBLISH(CV_16UC4); + PUBLISH(CV_16S); + PUBLISH(CV_16SC1); + PUBLISH(CV_16SC2); + PUBLISH(CV_16SC3); + PUBLISH(CV_16SC4); + PUBLISH(CV_32S); + PUBLISH(CV_32SC1); + PUBLISH(CV_32SC2); + PUBLISH(CV_32SC3); + PUBLISH(CV_32SC4); + PUBLISH(CV_32F); + PUBLISH(CV_32FC1); + PUBLISH(CV_32FC2); + PUBLISH(CV_32FC3); + PUBLISH(CV_32FC4); + PUBLISH(CV_64F); + PUBLISH(CV_64FC1); + PUBLISH(CV_64FC2); + PUBLISH(CV_64FC3); + PUBLISH(CV_64FC4); + PUBLISH(CV_NEXT_AROUND_ORG); + PUBLISH(CV_NEXT_AROUND_DST); + PUBLISH(CV_PREV_AROUND_ORG); + PUBLISH(CV_PREV_AROUND_DST); + PUBLISH(CV_NEXT_AROUND_LEFT); + PUBLISH(CV_NEXT_AROUND_RIGHT); + PUBLISH(CV_PREV_AROUND_LEFT); + PUBLISH(CV_PREV_AROUND_RIGHT); + + PUBLISH(CV_WINDOW_AUTOSIZE); + + PUBLISH(CV_PTLOC_INSIDE); + PUBLISH(CV_PTLOC_ON_EDGE); + PUBLISH(CV_PTLOC_VERTEX); + PUBLISH(CV_PTLOC_OUTSIDE_RECT); + + PUBLISH(GC_BGD); + PUBLISH(GC_FGD); + PUBLISH(GC_PR_BGD); + PUBLISH(GC_PR_FGD); + PUBLISH(GC_INIT_WITH_RECT); + PUBLISH(GC_INIT_WITH_MASK); + PUBLISH(GC_EVAL); + +#include "generated2.i" +} + diff --git a/modules/python/src1/defs b/modules/python/src1/defs new file mode 100644 index 0000000000..38b5753c00 --- /dev/null +++ b/modules/python/src1/defs @@ -0,0 +1,339 @@ +#define CV_BLUR_NO_SCALE 0 +#define CV_BLUR 1 +#define CV_GAUSSIAN 2 +#define CV_MEDIAN 3 +#define CV_BILATERAL 4 +#define CV_INPAINT_NS 0 +#define CV_INPAINT_TELEA 1 +#define CV_SCHARR -1 +#define CV_MAX_SOBEL_KSIZE 7 +#define CV_BGR2BGRA 0 +#define CV_RGB2RGBA CV_BGR2BGRA +#define CV_BGRA2BGR 1 +#define CV_RGBA2RGB CV_BGRA2BGR +#define CV_BGR2RGBA 2 +#define CV_RGB2BGRA CV_BGR2RGBA +#define CV_RGBA2BGR 3 +#define CV_BGRA2RGB CV_RGBA2BGR +#define CV_BGR2RGB 4 +#define CV_RGB2BGR CV_BGR2RGB +#define CV_BGRA2RGBA 5 +#define CV_RGBA2BGRA CV_BGRA2RGBA +#define CV_BGR2GRAY 6 +#define CV_RGB2GRAY 7 +#define CV_GRAY2BGR 8 +#define CV_GRAY2RGB CV_GRAY2BGR +#define CV_GRAY2BGRA 9 +#define CV_GRAY2RGBA CV_GRAY2BGRA +#define CV_BGRA2GRAY 10 +#define CV_RGBA2GRAY 11 +#define CV_BGR2BGR565 12 +#define CV_RGB2BGR565 13 +#define CV_BGR5652BGR 14 +#define CV_BGR5652RGB 15 +#define CV_BGRA2BGR565 16 +#define CV_RGBA2BGR565 17 +#define CV_BGR5652BGRA 18 +#define CV_BGR5652RGBA 19 +#define CV_GRAY2BGR565 20 +#define CV_BGR5652GRAY 21 +#define CV_BGR2BGR555 22 +#define CV_RGB2BGR555 23 +#define CV_BGR5552BGR 24 +#define CV_BGR5552RGB 25 +#define CV_BGRA2BGR555 26 +#define CV_RGBA2BGR555 27 +#define CV_BGR5552BGRA 28 +#define CV_BGR5552RGBA 29 +#define CV_GRAY2BGR555 30 +#define CV_BGR5552GRAY 31 +#define CV_BGR2XYZ 32 +#define CV_RGB2XYZ 33 +#define CV_XYZ2BGR 34 +#define CV_XYZ2RGB 35 +#define CV_BGR2YCrCb 36 +#define CV_RGB2YCrCb 37 +#define CV_YCrCb2BGR 38 +#define CV_YCrCb2RGB 39 +#define CV_BGR2HSV 40 +#define CV_RGB2HSV 41 +#define CV_BGR2Lab 44 +#define CV_RGB2Lab 45 +#define CV_BayerBG2BGR 46 +#define CV_BayerGB2BGR 47 +#define CV_BayerRG2BGR 48 +#define CV_BayerGR2BGR 49 +#define CV_BayerBG2RGB CV_BayerRG2BGR +#define CV_BayerGB2RGB CV_BayerGR2BGR +#define CV_BayerRG2RGB CV_BayerBG2BGR +#define CV_BayerGR2RGB CV_BayerGB2BGR +#define CV_BayerBG2BGR_VNG 62 +#define CV_BayerGB2BGR_VNG 63 +#define CV_BayerRG2BGR_VNG 64 +#define CV_BayerGR2BGR_VNG 65 +#define CV_BGR2Luv 50 +#define CV_RGB2Luv 51 +#define CV_BGR2HLS 52 +#define CV_RGB2HLS 53 +#define CV_HSV2BGR 54 +#define CV_HSV2RGB 55 +#define CV_Lab2BGR 56 +#define CV_Lab2RGB 57 +#define CV_Luv2BGR 58 +#define CV_Luv2RGB 59 +#define CV_HLS2BGR 60 +#define CV_HLS2RGB 61 +#define CV_COLORCVT_MAX 100 +#define CV_INTER_NN 0 +#define CV_INTER_LINEAR 1 +#define CV_INTER_CUBIC 2 +#define CV_INTER_AREA 3 +#define CV_WARP_FILL_OUTLIERS 8 +#define CV_WARP_INVERSE_MAP 16 +#define CV_SHAPE_RECT 0 +#define CV_SHAPE_CROSS 1 +#define CV_SHAPE_ELLIPSE 2 +#define CV_SHAPE_CUSTOM 100 +#define CV_MOP_OPEN 2 +#define CV_MOP_CLOSE 3 +#define CV_MOP_GRADIENT 4 +#define CV_MOP_TOPHAT 5 +#define CV_MOP_BLACKHAT 6 +#define CV_TM_SQDIFF 0 +#define CV_TM_SQDIFF_NORMED 1 +#define CV_TM_CCORR 2 +#define CV_TM_CCORR_NORMED 3 +#define CV_TM_CCOEFF 4 +#define CV_TM_CCOEFF_NORMED 5 +#define CV_LKFLOW_PYR_A_READY 1 +#define CV_LKFLOW_PYR_B_READY 2 +#define CV_LKFLOW_INITIAL_GUESSES 4 +#define CV_LKFLOW_GET_MIN_EIGENVALS 8 +#define CV_POLY_APPROX_DP 0 +#define CV_CONTOURS_MATCH_I1 1 +#define CV_CONTOURS_MATCH_I2 2 +#define CV_CONTOURS_MATCH_I3 3 +#define CV_CLOCKWISE 1 +#define CV_COUNTER_CLOCKWISE 2 +#define CV_COMP_CORREL 0 +#define CV_COMP_CHISQR 1 +#define CV_COMP_INTERSECT 2 +#define CV_COMP_BHATTACHARYYA 3 +#define CV_DIST_MASK_3 3 +#define CV_DIST_MASK_5 5 +#define CV_DIST_MASK_PRECISE 0 +#define CV_THRESH_BINARY 0 /* value = value > threshold ? max_value : 0 */ +#define CV_THRESH_BINARY_INV 1 /* value = value > threshold ? 0 : max_value */ +#define CV_THRESH_TRUNC 2 /* value = value > threshold ? threshold : value */ +#define CV_THRESH_TOZERO 3 /* value = value > threshold ? value : 0 */ +#define CV_THRESH_TOZERO_INV 4 /* value = value > threshold ? 0 : value */ +#define CV_THRESH_MASK 7 +#define CV_THRESH_OTSU 8 /* use Otsu algorithm to choose the optimal threshold value; +#define CV_ADAPTIVE_THRESH_MEAN_C 0 +#define CV_ADAPTIVE_THRESH_GAUSSIAN_C 1 +#define CV_FLOODFILL_FIXED_RANGE (1 << 16) +#define CV_FLOODFILL_MASK_ONLY (1 << 17) +#define CV_CANNY_L2_GRADIENT (1 << 31) +#define CV_HOUGH_STANDARD 0 +#define CV_HOUGH_PROBABILISTIC 1 +#define CV_HOUGH_MULTI_SCALE 2 +#define CV_HOUGH_GRADIENT 3 +#define CV_HAAR_DO_CANNY_PRUNING 1 +#define CV_HAAR_SCALE_IMAGE 2 +#define CV_HAAR_FIND_BIGGEST_OBJECT 4 +#define CV_HAAR_DO_ROUGH_SEARCH 8 +#define CV_LMEDS 4 +#define CV_RANSAC 8 +#define CV_CALIB_CB_ADAPTIVE_THRESH 1 +#define CV_CALIB_CB_NORMALIZE_IMAGE 2 +#define CV_CALIB_CB_FILTER_QUADS 4 +#define CV_CALIB_USE_INTRINSIC_GUESS 1 +#define CV_CALIB_FIX_ASPECT_RATIO 2 +#define CV_CALIB_FIX_PRINCIPAL_POINT 4 +#define CV_CALIB_ZERO_TANGENT_DIST 8 +#define CV_CALIB_FIX_FOCAL_LENGTH 16 +#define CV_CALIB_FIX_K1 32 +#define CV_CALIB_FIX_K2 64 +#define CV_CALIB_FIX_K3 128 +#define CV_CALIB_FIX_INTRINSIC 256 +#define CV_CALIB_SAME_FOCAL_LENGTH 512 +#define CV_CALIB_ZERO_DISPARITY 1024 +#define CV_FM_7POINT 1 +#define CV_FM_8POINT 2 +#define CV_FM_LMEDS_ONLY CV_LMEDS +#define CV_FM_RANSAC_ONLY CV_RANSAC +#define CV_FM_LMEDS CV_LMEDS +#define CV_FM_RANSAC CV_RANSAC +#define CV_STEREO_BM_NORMALIZED_RESPONSE 0 +#define CV_STEREO_BM_BASIC 0 +#define CV_STEREO_BM_FISH_EYE 1 +#define CV_STEREO_BM_NARROW 2 +#define CV_STEREO_GC_OCCLUDED SHRT_MAX +#define CV_AUTOSTEP 0x7fffffff +#define CV_MAX_ARR 10 +#define CV_NO_DEPTH_CHECK 1 +#define CV_NO_CN_CHECK 2 +#define CV_NO_SIZE_CHECK 4 +#define CV_CMP_EQ 0 +#define CV_CMP_GT 1 +#define CV_CMP_GE 2 +#define CV_CMP_LT 3 +#define CV_CMP_LE 4 +#define CV_CMP_NE 5 +#define CV_CHECK_RANGE 1 +#define CV_CHECK_QUIET 2 +#define CV_RAND_UNI 0 +#define CV_RAND_NORMAL 1 +#define CV_SORT_EVERY_ROW 0 +#define CV_SORT_EVERY_COLUMN 1 +#define CV_SORT_ASCENDING 0 +#define CV_SORT_DESCENDING 16 +#define CV_GEMM_A_T 1 +#define CV_GEMM_B_T 2 +#define CV_GEMM_C_T 4 +#define CV_SVD_MODIFY_A 1 +#define CV_SVD_U_T 2 +#define CV_SVD_V_T 4 +#define CV_LU 0 +#define CV_SVD 1 +#define CV_SVD_SYM 2 +#define CV_CHOLESKY 3 +#define CV_QR 4 +#define CV_NORMAL 16 +#define CV_COVAR_SCRAMBLED 0 +#define CV_COVAR_NORMAL 1 +#define CV_COVAR_USE_AVG 2 +#define CV_COVAR_SCALE 4 +#define CV_COVAR_ROWS 8 +#define CV_COVAR_COLS 16 +#define CV_PCA_DATA_AS_ROW 0 +#define CV_PCA_DATA_AS_COL 1 +#define CV_PCA_USE_AVG 2 +#define CV_C 1 +#define CV_L1 2 +#define CV_L2 4 +#define CV_NORM_MASK 7 +#define CV_RELATIVE 8 +#define CV_DIFF 16 +#define CV_MINMAX 32 +#define CV_DIFF_C (CV_DIFF | CV_C) +#define CV_DIFF_L1 (CV_DIFF | CV_L1) +#define CV_DIFF_L2 (CV_DIFF | CV_L2) +#define CV_RELATIVE_C (CV_RELATIVE | CV_C) +#define CV_RELATIVE_L1 (CV_RELATIVE | CV_L1) +#define CV_RELATIVE_L2 (CV_RELATIVE | CV_L2) +#define CV_REDUCE_SUM 0 +#define CV_REDUCE_AVG 1 +#define CV_REDUCE_MAX 2 +#define CV_REDUCE_MIN 3 +#define CV_DXT_FORWARD 0 +#define CV_DXT_INVERSE 1 +#define CV_DXT_SCALE 2 /* divide result by size of array */ +#define CV_DXT_INV_SCALE (CV_DXT_INVERSE + CV_DXT_SCALE) +#define CV_DXT_INVERSE_SCALE CV_DXT_INV_SCALE +#define CV_DXT_ROWS 4 /* transform each row individually */ +#define CV_DXT_MUL_CONJ 8 /* conjugate the second argument of cvMulSpectrums */ +#define CV_FRONT 1 +#define CV_BACK 0 +#define CV_GRAPH_VERTEX 1 +#define CV_GRAPH_TREE_EDGE 2 +#define CV_GRAPH_BACK_EDGE 4 +#define CV_GRAPH_FORWARD_EDGE 8 +#define CV_GRAPH_CROSS_EDGE 16 +#define CV_GRAPH_ANY_EDGE 30 +#define CV_GRAPH_NEW_TREE 32 +#define CV_GRAPH_BACKTRACKING 64 +#define CV_GRAPH_OVER -1 +#define CV_GRAPH_ALL_ITEMS -1 +#define CV_GRAPH_ITEM_VISITED_FLAG (1 << 30) +#define CV_GRAPH_SEARCH_TREE_NODE_FLAG (1 << 29) +#define CV_GRAPH_FORWARD_EDGE_FLAG (1 << 28) +#define CV_FILLED -1 +#define CV_AA 16 +#define CV_FONT_HERSHEY_SIMPLEX 0 +#define CV_FONT_HERSHEY_PLAIN 1 +#define CV_FONT_HERSHEY_DUPLEX 2 +#define CV_FONT_HERSHEY_COMPLEX 3 +#define CV_FONT_HERSHEY_TRIPLEX 4 +#define CV_FONT_HERSHEY_COMPLEX_SMALL 5 +#define CV_FONT_HERSHEY_SCRIPT_SIMPLEX 6 +#define CV_FONT_HERSHEY_SCRIPT_COMPLEX 7 +#define CV_FONT_ITALIC 16 +#define CV_FONT_VECTOR0 CV_FONT_HERSHEY_SIMPLEX +#define CV_KMEANS_USE_INITIAL_LABELS 1 +#define CV_ErrModeLeaf 0 /* Print error and exit program */ +#define CV_ErrModeParent 1 /* Print error and continue */ +#define CV_ErrModeSilent 2 /* Don't print and continue */ +#define CV_RETR_EXTERNAL 0 +#define CV_RETR_LIST 1 +#define CV_RETR_CCOMP 2 +#define CV_RETR_TREE 3 +#define CV_CHAIN_CODE 0 +#define CV_CHAIN_APPROX_NONE 1 +#define CV_CHAIN_APPROX_SIMPLE 2 +#define CV_CHAIN_APPROX_TC89_L1 3 +#define CV_CHAIN_APPROX_TC89_KCOS 4 +#define CV_LINK_RUNS 5 +#define CV_SUBDIV2D_VIRTUAL_POINT_FLAG (1 << 30) +#define CV_DIST_USER -1 /* User defined distance */ +#define CV_DIST_L1 1 /* distance = |x1-x2| + |y1-y2| */ +#define CV_DIST_L2 2 /* the simple euclidean distance */ +#define CV_DIST_C 3 /* distance = max(|x1-x2|,|y1-y2|) */ +#define CV_DIST_L12 4 /* L1-L2 metric: distance = 2(sqrt(1+x*x/2) - 1)) */ +#define CV_DIST_FAIR 5 /* distance = c^2(|x|/c-log(1+|x|/c)), c = 1.3998 */ +#define CV_DIST_WELSCH 6 /* distance = c^2/2(1-exp(-(x/c)^2)), c = 2.9846 */ +#define CV_DIST_HUBER 7 /* distance = |x| 2: + if fields[2][0] == '/': + self.flags = fields[2][1:].split(",") + else: + self.init = fields[2] + +api = [] +for l in open("%s/api" % sys.argv[1]): + if l[0] == '#': + continue + l = l.rstrip() + if (not l.startswith(' ')) and ('/' in l): + (l, flags) = l.split('/') + else: + flags = "" + f = l.split() + if len(f) != 0: + if l[0] != ' ': + if len(f) > 1: + ty = f[1] + else: + ty = None + api.append((f[0], [], ty, flags)) + else: + api[-1][1].append(argument(f)) + +# Validation: check that any optional arguments are last +had_error = False +for (f, args, ty, flags) in api: + if f == 'PolarToCart': + print f, [(a.init != None) for a in args] + has_init = [(a.init != None) for a in args if not 'O' in a.flags] + if True in has_init and not all(has_init[has_init.index(True):]): + print 'Error in definition for "%s", optional arguments must be last' % f + had_error = True + +if had_error: + sys.exit(1) + +def cname(n): + if n.startswith("CV"): + return '_' + n + elif n[0].isdigit(): + return '_' + n + else: + return n + +# RHS is how the aggregate gets expanded in the C call +aggregate = { + 'pts_npts_contours' : '!.pts,!.npts,!.contours', + 'cvarr_count' : '!.cvarr,!.count', + 'cvarr_plane_count' : '!.cvarr,!.count', + 'floats' : '!.f', + 'ints' : '!.i', + 'ints0' : '!.i', + 'CvPoints' : '!.p,!.count', + 'CvPoint2D32fs' : '!.p,!.count', + 'CvPoint3D32fs' : '!.p,!.count', + 'cvarrseq' : '!.seq', + 'CvArrs' : '!.ims', + 'IplImages' : '!.ims', + 'intpair' : '!.pairs,!.count', + 'cvpoint2d32f_count' : '!.points,&!.count' +} +conversion_types = [ +'char', +'CvArr', +'CvArrSeq', +'CvBox2D', # '((ff)(ff)f)', +'CvBox2D*', +'CvCapture*', +'CvStereoBMState*', +'CvStereoGCState*', +'CvKalman*', +'CvVideoWriter*', +'CvContourTree*', +'CvFont', +'CvFont*', +'CvHaarClassifierCascade*', +'CvHistogram', +'CvMat', +'CvMatND', +'CvMemStorage', +'CvMoments', +'CvMoments*', +'CvNextEdgeType', +'CvPoint', +'CvPoint*', +'CvPoint2D32f', # '(ff)', +'CvPoint2D32f*', +'CvPoint3D32f*', +'CvPoint2D64f', +'CvPOSITObject*', +'CvRect', +'CvRect*', +'CvRNG*', +'CvScalar', +'CvSeq', +'CvSeqOfCvConvexityDefect', +'CvSize', +'CvSlice', +'CvStarDetectorParams', +'CvSubdiv2D*', +'CvSubdiv2DEdge', +'CvTermCriteria', +'generic', +'IplConvKernel*', +'IplImage', +'PyObject*', +'PyCallableObject*' +] + +def safename(s): + return s.replace('*', 'PTR').replace('[', '_').replace(']', '_') + +def has_optional(al): + """ return true if any argument is optional """ + return any([a.init for a in al]) + +def gen(name, args, ty, flags): + yield "" + if has_optional(args): + yield "static PyObject *pycv%s(PyObject *self, PyObject *args, PyObject *kw)" % cname(name) + else: + yield "static PyObject *pycv%s(PyObject *self, PyObject *args)" % cname(name) + if 'doconly' in flags: + yield ";" + else: + yield "{" + + destinations = [] + for a in args: + remap = { + 'CvArr' : 'CvArr*', + 'CvMat' : 'CvMat*', + 'CvMatND' : 'CvMatND*', + 'IplImage' : 'IplImage*', + 'CvMemStorage' : 'CvMemStorage*', + 'CvHistogram':'CvHistogram*', + 'CvSeq':'CvSeq*', + 'CvHaarClassifierCascade' : 'CvHaarClassifierCascade*' + } + ctype = remap.get(a.ty, a.ty) + if a.init: + init = " = %s" % a.init + else: + init = '' + yield " %s %s%s;" % (ctype, a.nm, init) + if 'O' in a.flags: + continue + if a.ty in (conversion_types + aggregate.keys()): + yield ' PyObject *pyobj_%s = NULL;' % (a.nm) + destinations.append('&pyobj_%s' % (a.nm)) + elif a.ty in [ 'CvPoint2D32f' ]: + destinations.append('&%s.x, &%s.y' % (a.nm, a.nm)) + elif a.ty in [ 'CvTermCriteria' ]: + destinations.append('&%s.type, &%s.max_iter, &%s.epsilon' % ((a.nm,)*3)) + elif a.ty in [ 'CvSURFParams' ]: + destinations.append('&%s.extended, &%s.hessianThreshold, &%s.nOctaves, &%s.nOctaveLayers' % ((a.nm,)*4)) + elif a.nm in [ 'CvBox2D' ]: + s = ", ".join([('&' + a.nm +'.' + fld) for fld in [ 'center.x', 'center.y', 'size.width', 'size.height', 'angle' ] ]) + destinations.append(s) + else: + destinations.append('&%s' % a.nm) + fmap = { + 'CvSURFParams' : '(idii)', + 'double' : 'd', + 'float' : 'f', + 'int' : 'i', + 'int64' : 'L', + 'char*' : 's', + } + for k in (conversion_types + aggregate.keys()): + fmap[k] = 'O' + in_args = [ a for a in args if not 'O' in a.flags ] + fmt0 = "".join([ fmap[a.ty] for a in in_args if not a.init]) + fmt1 = "".join([ fmap[a.ty] for a in in_args if a.init]) + + yield '' + if len(fmt0 + fmt1) > 0: + if len(fmt1) > 0: + yield ' const char *keywords[] = { %s };' % (", ".join([ '"%s"' % arg.nm for arg in args if not 'O' in arg.flags ] + ['NULL'])) + yield ' if (!PyArg_ParseTupleAndKeywords(args, kw, "%s|%s", %s))' % (fmt0, fmt1, ", ".join(['(char**)keywords'] + destinations)) + if '(' in (fmt0 + fmt1): + print "Tuple with kwargs is not allowed, function", name + sys.exit(1) + else: + yield ' if (!PyArg_ParseTuple(args, "%s", %s))' % (fmt0, ", ".join(destinations)) + yield ' return NULL;' + + # Do the conversions: + for a in args: + joinwith = [f[2:] for f in a.flags if f.startswith("J:")] + if len(joinwith) > 0: + yield 'preShareData(%s, &%s);' % (joinwith[0], a.nm) + if 'O' in a.flags: + continue + if a.ty in (conversion_types + aggregate.keys()): + if a.init: + pred = '(pyobj_%s != NULL) && ' % a.nm + else: + pred = '' + yield ' if (%s!convert_to_%s(pyobj_%s, &%s, "%s")) return NULL;' % (pred, safename(a.ty), a.nm, a.nm, a.nm) + + yield '#ifdef CVPY_VALIDATE_%s' % name + yield 'CVPY_VALIDATE_%s();' % name + yield '#endif' + + def invokename(a): + if 'K' in a.flags: + prefix = "(const CvArr **)" + elif 'O' in a.flags and not 'A' in a.flags: + prefix = "&" + else: + prefix = "" + if a.ty in aggregate: + return prefix + aggregate[a.ty].replace('!', a.nm) + else: + return prefix + a.nm + + def funcname(s): + # The name by which the function is called, in C + if s.startswith("CV"): + return s + else: + return "cv" + s + tocall = '%s(%s)' % (funcname(name), ", ".join(invokename(a) for a in args)) + if 'stub' in flags: + yield ' return stub%s(%s);' % (name, ", ".join(invokename(a) for a in args)) + elif ty == None: + yield ' ERRWRAP(%s);' % tocall + yield ' Py_RETURN_NONE;' + else: + Rtypes = [ + 'int', + 'int64', + 'double', + 'CvCapture*', + 'CvVideoWriter*', + 'CvPOSITObject*', + 'CvScalar', + 'CvSize', + 'CvRect', + 'CvSeq*', + 'CvBox2D', + 'CvSeqOfCvAvgComp*', + 'CvSeqOfCvConvexityDefect*', + 'CvSeqOfCvStarKeypoint*', + 'CvSeqOfCvSURFPoint*', + 'CvSeqOfCvSURFDescriptor*', + 'CvContourTree*', + 'IplConvKernel*', + 'IplImage*', + 'CvMat*', + 'constCvMat*', + 'ROCvMat*', + 'CvMatND*', + 'CvPoint2D32f_4', + 'CvRNG', + 'CvSubdiv2D*', + 'CvSubdiv2DPoint*', + 'CvSubdiv2DEdge', + 'ROIplImage*', + 'CvStereoBMState*', + 'CvStereoGCState*', + 'CvKalman*', + 'float', + 'generic', + 'unsigned' ] + + if ty in Rtypes: + yield ' %s r;' % (ty) + yield ' ERRWRAP(r = %s);' % (tocall) + yield ' return FROM_%s(r);' % safename(ty) + else: + all_returns = ty.split(",") + return_value_from_call = len(set(Rtypes) & set(all_returns)) != 0 + if return_value_from_call: + yield ' %s r;' % list(set(Rtypes) & set(all_returns))[0] + yield ' ERRWRAP(r = %s);' % (tocall) + else: + yield ' ERRWRAP(%s);' % (tocall) + typed = dict([ (a.nm,a.ty) for a in args]) + for i in range(len(all_returns)): + if all_returns[i] in Rtypes: + typed['r'] = all_returns[i] + all_returns[i] = "r" + if len(all_returns) == 1: + af = dict([ (a.nm,a.flags) for a in args]) + joinwith = [f[2:] for f in af.get(all_returns[0], []) if f.startswith("J:")] + if len(joinwith) > 0: + yield ' return shareData(pyobj_%s, %s, %s);' % (joinwith[0], joinwith[0], all_returns[0]) + else: + yield ' return FROM_%s(%s);' % (safename(typed[all_returns[0]]), all_returns[0]) + else: + yield ' return Py_BuildValue("%s", %s);' % ("N" * len(all_returns), ", ".join(["FROM_%s(%s)" % (safename(typed[n]), n) for n in all_returns])) + + yield '}' + +gen_c = [ open("generated%d.i" % i, "w") for i in range(5) ] + +print "Generated %d functions" % len(api) +for nm,args,ty,flags in sorted(api): + + # Figure out docstring into ds_* + ds_args = [] + mandatory = [a.nm for a in args if not ('O' in a.flags) and not a.init] + optional = [a.nm for a in args if not ('O' in a.flags) and a.init] + ds_args = ", ".join(mandatory) + def o2s(o): + if o == []: + return "" + else: + return ' [, %s%s]' % (o[0], o2s(o[1:])) + ds_args += o2s(optional) + + ds = "%s(%s) -> %s" % (nm, ds_args, str(ty)) + print ds + + if has_optional(args): + entry = '{"%%s", (PyCFunction)pycv%s, METH_KEYWORDS, "%s"},' % (cname(nm), ds) + else: + entry = '{"%%s", pycv%s, METH_VARARGS, "%s"},' % (cname(nm), ds) + print >>gen_c[1], entry % (nm) + if nm.startswith('CV_'): + print >>gen_c[1], entry % (nm[3:]) + for l in gen(nm,args,ty,flags): + print >>gen_c[0], l + +for l in open("%s/defs" % sys.argv[1]): + print >>gen_c[2], "PUBLISH(%s);" % l.split()[1] + +######################################################################## +# Generated objects. +######################################################################## + +# gen_c[3] is the code, gen_c[4] initializers + +gensimple = Template(""" +/* + ${cvtype} is the OpenCV C struct + ${ourname}_t is the Python object +*/ + +struct ${ourname}_t { + PyObject_HEAD + ${cvtype} v; +}; + +static PyObject *${ourname}_repr(PyObject *self) +{ + ${ourname}_t *p = (${ourname}_t*)self; + char str[1000]; + sprintf(str, "<${ourname} %p>", p); + return PyString_FromString(str); +} + +${getset_funcs} + +static PyGetSetDef ${ourname}_getseters[] = { + + ${getset_inits} + {NULL} /* Sentinel */ +}; + +static PyTypeObject ${ourname}_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, /*size*/ + MODULESTR".${ourname}", /*name*/ + sizeof(${ourname}_t), /*basicsize*/ +}; + +static void ${ourname}_specials(void) +{ + ${ourname}_Type.tp_repr = ${ourname}_repr; + ${ourname}_Type.tp_getset = ${ourname}_getseters; +} + +static PyObject *FROM_${cvtype}(${cvtype} r) +{ + ${ourname}_t *m = PyObject_NEW(${ourname}_t, &${ourname}_Type); + m->v = r; + return (PyObject*)m; +} + +static int convert_to_${cvtype}PTR(PyObject *o, ${cvtype}** dst, const char *name = "no_name") +{ + ${allownull} + if (PyType_IsSubtype(o->ob_type, &${ourname}_Type)) { + *dst = &(((${ourname}_t*)o)->v); + return 1; + } else { + (*dst) = (${cvtype}*)NULL; + return failmsg("Expected ${cvtype} for argument '%s'", name); + } +} + +""") + +genptr = Template(""" +/* + ${cvtype} is the OpenCV C struct + ${ourname}_t is the Python object +*/ + +struct ${ourname}_t { + PyObject_HEAD + ${cvtype} *v; +}; + +static void ${ourname}_dealloc(PyObject *self) +{ + ${ourname}_t *p = (${ourname}_t*)self; + cvRelease${ourname}(&p->v); + PyObject_Del(self); +} + +static PyObject *${ourname}_repr(PyObject *self) +{ + ${ourname}_t *p = (${ourname}_t*)self; + char str[1000]; + sprintf(str, "<${ourname} %p>", p); + return PyString_FromString(str); +} + +${getset_funcs} + +static PyGetSetDef ${ourname}_getseters[] = { + + ${getset_inits} + {NULL} /* Sentinel */ +}; + +static PyTypeObject ${ourname}_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, /*size*/ + MODULESTR".${ourname}", /*name*/ + sizeof(${ourname}_t), /*basicsize*/ +}; + +static void ${ourname}_specials(void) +{ + ${ourname}_Type.tp_dealloc = ${ourname}_dealloc; + ${ourname}_Type.tp_repr = ${ourname}_repr; + ${ourname}_Type.tp_getset = ${ourname}_getseters; +} + +static PyObject *FROM_${cvtype}PTR(${cvtype} *r) +{ + ${ourname}_t *m = PyObject_NEW(${ourname}_t, &${ourname}_Type); + m->v = r; + return (PyObject*)m; +} + +static int convert_to_${cvtype}PTR(PyObject *o, ${cvtype}** dst, const char *name = "no_name") +{ + ${allownull} + if (PyType_IsSubtype(o->ob_type, &${ourname}_Type)) { + *dst = ((${ourname}_t*)o)->v; + return 1; + } else { + (*dst) = (${cvtype}*)NULL; + return failmsg("Expected ${cvtype} for argument '%s'", name); + } +} + +""") + +getset_func_template = Template(""" +static PyObject *${ourname}_get_${member}(${ourname}_t *p, void *closure) +{ + return ${rconverter}(p->v${accessor}${member}); +} + +static int ${ourname}_set_${member}(${ourname}_t *p, PyObject *value, void *closure) +{ + if (value == NULL) { + PyErr_SetString(PyExc_TypeError, "Cannot delete the ${member} attribute"); + return -1; + } + + if (! ${checker}(value)) { + PyErr_SetString(PyExc_TypeError, "The ${member} attribute value must be a ${typename}"); + return -1; + } + + p->v${accessor}${member} = ${converter}(value); + return 0; +} + +""") + +getset_init_template = Template(""" + {(char*)"${member}", (getter)${ourname}_get_${member}, (setter)${ourname}_set_${member}, (char*)"${member}", NULL}, +""") + +objects = [ + ( 'IplConvKernel', ['allownull'], { + "nCols" : 'i', + "nRows" : 'i', + "anchorX" : 'i', + "anchorY" : 'i', + }), + ( 'CvCapture', [], {}), + ( 'CvHaarClassifierCascade', [], {}), + ( 'CvPOSITObject', [], {}), + ( 'CvVideoWriter', [], {}), + ( 'CvStereoBMState', [], { + "preFilterType" : 'i', + "preFilterSize" : 'i', + "preFilterCap" : 'i', + "SADWindowSize" : 'i', + "minDisparity" : 'i', + "numberOfDisparities" : 'i', + "textureThreshold" : 'i', + "uniquenessRatio" : 'i', + "speckleWindowSize" : 'i', + "speckleRange" : 'i', + }), + ( 'CvStereoGCState', [], { + "Ithreshold" : 'i', + "interactionRadius" : 'i', + "K" : 'f', + "lambda" : 'f', + "lambda1" : 'f', + "lambda2" : 'f', + "occlusionCost" : 'i', + "minDisparity" : 'i', + "numberOfDisparities" : 'i', + "maxIters" : 'i', + }), + ( 'CvKalman', [], { + "MP" : 'i', + "DP" : 'i', + "CP" : 'i', + "state_pre" : 'mr', + "state_post" : 'mr', + "transition_matrix" : 'mr', + "control_matrix" : 'mr', + "measurement_matrix" : 'mr', + "control_matrix" : 'mr', + "process_noise_cov" : 'mr', + "measurement_noise_cov" : 'mr', + "error_cov_pre" : 'mr', + "gain" : 'mr', + "error_cov_post" : 'mr', + }), + ( 'CvMoments', ['copy'], { + "m00" : 'f', + "m10" : 'f', + "m01" : 'f', + "m20" : 'f', + "m11" : 'f', + "m02" : 'f', + "m30" : 'f', + "m21" : 'f', + "m12" : 'f', + "m03" : 'f', + "mu20" : 'f', + "mu11" : 'f', + "mu02" : 'f', + "mu30" : 'f', + "mu21" : 'f', + "mu12" : 'f', + "mu03" : 'f', + "inv_sqrt_m00" : 'f', + }), +] + +checkers = { + 'i' : 'PyNumber_Check', + 'f' : 'PyNumber_Check', + 'm' : 'is_cvmat', + 'mr' : 'is_cvmat' +} +# Python -> C +converters = { + 'i' : 'PyInt_AsLong', + 'f' : 'PyFloat_AsDouble', + 'm' : 'PyCvMat_AsCvMat', + 'mr' : 'PyCvMat_AsCvMat' +} +# C -> Python +rconverters = { + 'i' : 'PyInt_FromLong', + 'f' : 'PyFloat_FromDouble', + 'm' : 'FROM_CvMat', + 'mr' : 'FROM_ROCvMatPTR' +} +# Human-readable type names +typenames = { + 'i' : 'integer', + 'f' : 'float', + 'm' : 'list of CvMat', + 'mr' : 'list of CvMat', +} + +for (t, flags, members) in objects: + map = {'cvtype' : t, + 'ourname' : t.replace('Cv', '')} + # gsf is all the generated code for the member accessors + if 'copy' in flags: + a = '.' + else: + a = '->' + gsf = "".join([getset_func_template.substitute(map, accessor = a, member = m, checker = checkers[t], converter = converters[t], rconverter = rconverters[t], typename = typenames[t]) for (m, t) in members.items()]) + # gsi is the generated code for the initializer for each accessor + gsi = "".join([getset_init_template.substitute(map, member = m) for (m, t) in members.items()]) + # s is the template that pulls everything together + if 'allownull' in flags: + nullcode = """if (o == Py_None) { *dst = (%s*)NULL; return 1; }""" % map['cvtype'] + else: + nullcode = "" + if 'copy' in flags: + print >>gen_c[3], gensimple.substitute(map, getset_funcs = gsf, getset_inits = gsi, allownull = nullcode) + else: + print >>gen_c[3], genptr.substitute(map, getset_funcs = gsf, getset_inits = gsi, allownull = nullcode) + print >>gen_c[4], "MKTYPE(%s);" % map['ourname'] + +for f in gen_c: + f.close() diff --git a/modules/python/src1/hdr_parser.pyc b/modules/python/src1/hdr_parser.pyc new file mode 100755 index 0000000000000000000000000000000000000000..cc852e4137f1961bbf6c1cc1a12009d2c018b92a GIT binary patch literal 17939 zcmcIsTW}oNSw20ZyLGW-*|Kb}-Imv@kyk6Ny_}znntRXL8gJA0l`5Ai;mT|NGo_mG$zPS4N!wZt zO7T`Bh%P)^uq7#bRPm{__;%*3n^+E(~X$!2`=SEYv0qFu^ju!B()OZAWmF(qKG zUVk?z`9Wi`)QEycD(N|-y^Y`K5rP0xC%J}rQm7ruDJ3_j2S|5b50LRTJwSHb^#FPA z&;z8tQxA~+EEiDz_xq0P!+|P(RZ{NHzS6sR_cl*Y|yo$`-yn-B8ug%>ou%(#w zM?qzkyUZwvD6rFaFyGPic76I$t?_WWR^CoF-1J7x->L-Bbp3I>UaL+=jq>!m-ze6# zLQ{zCLh)iTtcG#1cmmH6J8qorGH!|P18fTy z%20v>p@0THa{b*nN3nnqQEy6Fwwv8{v-4F76J!N7qB=KEO@ zI--IRbn0}d^8!z+Ijkk8XKJX zf%w=x>+6Kjj!^{@5tU_Dc7tmIrRa`NjJsjAr8M+&#a5xMr(LibR(%OdC9DS3T1+{O z9!E+GcEVU1iJ6L3XsTjddx&mvJ)^i0)(c!+D|~!Hw~L5Z;cC5RWswgTRD@5j#mu-; zs+6kbK>d%OuSl*1aZ!_1L~mHNPDcZA>~jX3L8rsXJ7<&UKBpf~J^1a-NmvgfKjm7& z`imImn&G~rutF$0OzjL-KF=MBC8sn}n632XlkF<`luYi;kLAzuOFi4|&HNDXWb31? z4rWZ`s?$7ZH?_cL*GMgW7UU35P`6E_E4*=t$BGvbf9%b>D49PK`j5NQlv4 zG}7~9H*(;IYy`u=++l7y&2E?G5l2g}_U%7u&va{JaR*}n$k#`33*yny1Fk=UhI`GXmtz9Df6=~G z7aWI^aZtsNtC)XOsZaVfEuD6x<2K(A^VR#14}}I*=#TNzZ|YRQqtcSyO$FRT;EKVd zQ-wEGP@|T_n2*_R{7=56y3eUPtp6x}sUKPK@gGnz=8Ofp&4V`6to(#3=fq<>qKD|n z#3q`mzONQ)C)I~!Dr|Z=r%Ep7XR8;LT05&h{tMm+As7YX+DlzDPU(!%Wy z$sFbYn}?D617@SISs2BdGCydZV0+{>qdn-tY4%N0*=Fio_f#1SnwAZq9IDU7P^nLb zY^gp|r{wjT5IgV?JI~#L1`w5lY$5k%q22Mv4A2$NYzG2}iU8{HA?k*(0HX0R7!E+vyyN%1a@=_(N=lgEk*8FZ7Z&C#pzK# zHtCM7BfbpV12_z?Q&UqDX+x!|¶lcuV{Bb?rTu*3FBRs7Vdk2h*t8il~YR9g7< zI)FhKO}gP~f*yDbv!(}I=rBtsfWqY*xsO7i*p|Mzb}EQ7(u|B^4N(xgaV>3X3>n7U zmtE9fP=6;dbLczDsueo`n5&I|04DIWUJ7Q+y;oegb2}o`pI(R&nz$PQqHoMAg#cvw z#zHf8?uzGK`K-lAO1k1&=yTAPn!B@fd*N2mW{Zffr{|D`Mzqj{tMDa-=M>H=ysU6i zxE+>QqZHQ~5qr{naRph*wQ3X#&y?3o4dpI#Zh@~O&MxMi0WoBKp}PLLxuMhE=QyL zt3kU#vi>i#>WN)&ipQBC#j##Z3bi1LWXJQ~aDWhJP3tiu~(aEQ@t z;6W{{%F2skEKx+^wlEe*lue*1MS4Vb1yxDQ$UA~S%}b7jOOx%c=P)WY8l}hH2(wW# zQdH@2TGb-VL@XAYRSvyUM|j7XgZ9`Xbpb6%@uV-@UGV{=m#S-(fK`+q;(S5=P%~6- z1lz?&%8@7xN}Vn4CrvVY{k%%mFFZdG&7sP!C4ipAOZ4{$Om|1V4?y`y&W0TT(|rKb zM{|SDv0UqOFJke3dmh0073UCg9e3Ih4(hiP&j8#xn}=bi=@0}z?2P7moKEEGLEd9{ zB3!o+eNfMXfa^nu?{S9l{~@Ox`Fm6od(Z^|e-2zfq*b1*d`Srza`0&HLd0IefJCv!L91z|ntLdM}B2Tq_FfHSn+ zi~?Ca1$zK9fmL+S>;-AVgVSaKXtG&&JOkALDe=eJ%$rl75IS&va&70mafI5DnVNhv zvnOB1crYQH8SQx28jDg7^-36fq{}?gC3bthjwe}(w7mRU44tpzx4`+ewjp<+ACxPS zVeX2Gq_$F#KugxQOBInf&6lDdRN|8MH%sb)tcDf$ZEbLrd46Kg-deE_s#_a>i?`@S z1O^g1U?p0TIsm!rq0~Yahar2z&g+h(iBuG)SJE_(L0W0TA|wVRID*80Yzi1{NQea1 z9gqzogC$N(5fWzm^NYpUli!+@5+76vJZ4Qtlto@^I?h484w_T6k??{rZ&vdVU25y-y9iP!l0d(5 zr4&We(2iT>*rlwLaF~a+Dj*8^N1IMTYeU0W`)mBy0cBln3WBp%V|gA1jZyy7w;Bt zU0KxLv{>d=sUGv7%X)__OE+#U-n4)1Su#u=>_TWWGdjbjBA!(5N9XQO&Md!$zhY`FI`|w?vIE}({oC^TOsy6bQ27EA z{51ZE2on(Ss7HhW?9tB=Nx^8xHv(^g**Og96z?;9@)*3yfTy(g76Ts6-Vy@ojN<+C z%U0P0I-<2WI(@0oxG1`6c|IgC7t`txD+83qe?gq!oax|c*M}2~ry4_^nn!uoJYYS=cwIPdeAm<6+jsGuc)wmZtVInjuc}2z4DNh&mAp4IC3@8)gQW zM9?$Ttk7|wqjO@qtrgy)*fGJjJW8GhJ2ry6tfV>RY!=Nldy!y?mNqPt^Ml)P6HShs z2TTZ(<(Q`EUOJM)&7N>17%#e&jpRpfMLosnEdz!T<7fi75#O-ePuh$enUzfPJXpal zNU>-F&}1a9NaBGr0Ht)$j1X;+x4;}{yv6784hV>3k`H{`B!d*PlurF1Y6NWq0XeSG zw{9b}+^4k$BVm^WybGzAF7SUsV`PUQZilqdh7}%WGRCrVE)V8|!vXp`0hUY!E|T@d z9H1VpA*2QLk$=kgu2}=F!zQxq=Mk~LM@)SRBRri9$X<@1Vb7&yP9P1_4~?gi6hX-LsM$ScszmO#-7`N@IV#6dki06N={1 zplFi6P~GP^2&amx1m<};T?@QSruDp{ddQR_dMd3)(R=IRDA8MpFUC4!{7c54HU68% zzij-s$lPNt(=~Wxq)?PVleb$x$E#?Fx->UKAqKa<83N>{u{~0Kr17ONCGKO#TiqdWypmEJ+4zb*owy zegtI$BYnN*??IKxjoMy3dB3n1KjOw!WaNbV#GQNZ%HoYe5;Kv(MG~0zKU|(|wrAmH z+9M_xQd$#uQ_n;$=P%!XbJh=5OIww=2peb%G0TLbY3>Uxxi37E`vP) ztb^!HSb$L(cZ^(%2wg5jLEx5FYTH59ac>zb=@Em9vH`%o>s?uFVp~2F3X=@nkB14K zw_#3hl`0l)6K}#|h{G~W2404Whp~@>wYu6)T5v5!Cf-ZRAmPUR%^UOAn#5)DMl;%G zv3w$p71eAF53e8TN|Bg&^#6!1AZVc!r^xq#GTsQQ=pLB62^uw4tR`HsQZw$^C_1sX zSo0z|V(#&?(YQxr*_&nypWK^uO5}D^5T_HV=Q@!A-UuTShBK-pu?sARaF!Lm#0trG zWmnKmijgi`q3PthJW^_xDG?6sGHXMLzjUsEN?e!7aWDwbG zv&eQ?Ex!4xZFtFAMwGbBGK!v&uPn_29&F9J-&V_V%Bv(Z<606(vFs5}YifOzgl45Y zc*?aj?Cs!n|IqAU9)E1g2Opb4c0Wp%$kwv;OblI_(mW!1X=<)iYUPKP6m78xWgwIn>~(K(bzmRF@nj*kh`rL?4P1 zW2@YM*0`Nzi#`HXLNZyUykm@FCoGHH^s1l?t6?@^T{-xgkKW#3aim&aC71A?GBRwjSpk zINl!Q0FRqk(5J;O!!&M_cv}mb&_O!iLC2w~=AAaZFDgwBysKUO1W9|A(9xoI|;jV7%MG zJ&#)EnR8D1f%6=F69KUl<_CZV*k_5(pfJ~WzLdmYUH&{tL;@J(bIfS+ggfpW31L|Z zz)Iv7JK=hC%Ay{?=mWZ&ehJtJHZaQC8cfp=Y9mGiUKTVYqyq~ugg*ep*296OKnG_0o2BFPq|!tj_Yb`#~CQYq`=AW67-ykP!2%7O*cT zE~TY*TOQNM^kEOwc@)Bz3Ip5@z%hOik5T#??h>Yb{v<&`;~o4S#b|26bcpvd&~;MNHm1UF5`v1@t9bQt@!6B^PaVS`}5fsM#KFti0_%OJf?W)odqkPTZ7o(tBA5p+9}MY~yt zBD`fbF&upg}-l{CBghMcI-NpSz* zLr%*>Lp+V0nV*2+ZgcBeqNTJ9`P$c{?BIj*6bBHwe>-2W)ig)%-YE!yvM<54jAG#$JwH*Ff z!5YHCgKPvhU{~{>MO@Qq4qSnaBF!h$9z0!oQlT$$^8>5npGiE1QUSJ$ka%KYa*!G9 zC4B3!8r*@FY8<2s6r>BB7s#qLhho-77cFG$GpDXDA2Pcrh6wN%+8aZg?QI_pszurK0zOoQlj+N@d3fUj310=c5`~B-EJj3=pP)p7Nunu z7_4?5aBsImef}%t?{jeHpp(q#t?07aaTvU_p8ju za~GyZfQ888acpi(jqWPEq{?~h0`FVmfvv%6#3vLfX~O5CcUR@7y}L5>fg2N$;Qc0^ zyx(H*RRr_auKPW{(@)60{%-opORN^WFvwS0<#OJ!rrlw_%3{O0Yci`&@L|4IwHJTh zDidY8(O~oLG5940#L@QdP^KYGyn-$RQw+j2(JW)%Bo6F6?1hW)UiUtaH)UW>>!-sE z2Q%Ss{{Fb|rz#R7lV!+eP9iwo8qsDXDekyGnAA`65ij zw)sNQJ@3u3u@yE(aR?P|KR2MHUS^{EEwmARh;~dD+yX8**yE`6Wby z;{|HoI_N+h6FSi}N|<;Y@bJ$;94~yVn~gpdK|1r?#R-cH`ci|UAN?JIRI|MUw@j;( z`AGzTKR$_YR~xkrX{+&=E1G_J5t71k$D{E{0`Z3UJLQF3g`%0q>*FovLE@<@TSI!U zRtB7hi>YmfIxECyAvegK|u6$f+x6j4Mr$O+Ic4tTtFnw`-$$ja5_!8Ts*LRNWqm^T-5 zNCW%~fklN~>GNVe!gw`?3s%%&VKA_IL@}n2<=ZCHIb!5h9^1yffW@kgN(T))k zfiF6+=CFJ0h3o(?<&q0(6s5Tb@P|q1Y?^!aA~u^eX148s<+0-jYHY*3YQNcB$YtY4 zEV^Ll0OKRJ#5-54*<(#5O&85oB4YrpLo#d*(jG{J-C|!z?E%1ST(rRr3yT1Zik=Rd z(OQTh;}LPliQ8=pjDdTH34NIt?)slbCRi2LF=7nn=_I2Cj{$vgKZlXa?ZMfs=I?I) z25z@)q?|0A&2QzMD!vDRj{-JNJZ$ngAa2_N?F;)wb<&9a_yxj_e7Fj(LT6(S@=_Sx zgohcL!jB+1?`#3vTYM!@nf;Px-43fml1CSemW83fLs8iJFfS9yn#X|pS}h(6*avoc zIrXEEamq*XsS9>DWNb5TllWMDkY!HR2|JX8*;0W#arCnYQUy%Ny#ZP*xm=ub7x@vX zJy7gvL0;ygj|3hq{2rhMF$49+bpJ2I%YP+sfgQp8Y{|o0&$vbd37lbE>rNHx1Q5cM zGne=hx&;=&s8GM_;>kMcq=t`o% z1IjwU5~QvZ&*>D^is)2b6%1sL)I}bwOLJG|1=QyjZr!>ze_N>X>J5)yGrxCD*MyS^@#fmHvDG@Giq$OFC%Edfvd2})H&Zee}p=T>G)Q$DLB(T-h78zv9z(8T>pG@cVq6FL`m;qVc{$vErUJZCubX z=K#VJ&H;P_P|&4&7m|uHvWi8Cf04EszVa^?J=(?kT*UgK(x|j1r_4~>!l9< zfm!|$K{g;gMRb(^@&8=`52X#S`64Qlj$C(VcYF76_ZRVdy!&hTE%qMlw%?eb`#4pK zMg0>E+V4Q