a big patch; use special proxy types (Input/OutputArray, Input/OutputArrayOfArrays...
authorVadim Pisarevsky <no@email>
Sun, 17 Apr 2011 13:14:45 +0000 (13:14 +0000)
committerVadim Pisarevsky <no@email>
Sun, 17 Apr 2011 13:14:45 +0000 (13:14 +0000)
94 files changed:
modules/calib3d/include/opencv2/calib3d/calib3d.hpp
modules/calib3d/src/calibinit.cpp
modules/calib3d/src/calibration.cpp
modules/calib3d/src/circlesgrid.cpp
modules/calib3d/src/fundam.cpp
modules/calib3d/src/modelest.cpp
modules/calib3d/src/quadsubpix.cpp
modules/calib3d/src/solvepnp.cpp
modules/calib3d/src/stereobm.cpp
modules/calib3d/src/stereosgbm.cpp
modules/calib3d/test/test_cameracalibration.cpp
modules/calib3d/test/test_solvepnp_ransac.cpp
modules/core/include/opencv2/core/core.hpp
modules/core/include/opencv2/core/mat.hpp
modules/core/include/opencv2/core/operations.hpp
modules/core/src/arithm.cpp
modules/core/src/array.cpp
modules/core/src/convert.cpp
modules/core/src/copy.cpp
modules/core/src/datastructs.cpp
modules/core/src/drawing.cpp
modules/core/src/dxt.cpp
modules/core/src/lapack.cpp
modules/core/src/mathfuncs.cpp
modules/core/src/matmul.cpp
modules/core/src/matop.cpp
modules/core/src/matrix.cpp
modules/core/src/precomp.hpp
modules/core/src/rand.cpp
modules/core/src/stat.cpp
modules/core/src/system.cpp
modules/core/test/test_arithm.cpp
modules/core/test/test_dxt.cpp
modules/core/test/test_mat.cpp
modules/features2d/src/bagofwords.cpp
modules/features2d/test/test_nearestneighbors.cpp
modules/gpu/test/test_filters.cpp
modules/gpu/test/test_hog.cpp
modules/gpu/test/test_operator_async_call.cpp
modules/gpu/test/test_operator_convert_to.cpp
modules/gpu/test/test_operator_copy_to.cpp
modules/gpu/test/test_operator_set_to.cpp
modules/gpu/test/test_stereo_bm.cpp
modules/gpu/test/test_stereo_bm_async.cpp
modules/gpu/test/test_stereo_bp.cpp
modules/gpu/test/test_stereo_csbp.cpp
modules/highgui/include/opencv2/highgui/highgui.hpp
modules/highgui/src/loadsave.cpp
modules/highgui/src/window.cpp
modules/imgproc/include/opencv2/imgproc/imgproc.hpp
modules/imgproc/src/accum.cpp
modules/imgproc/src/canny.cpp
modules/imgproc/src/color.cpp
modules/imgproc/src/contours.cpp
modules/imgproc/src/corner.cpp
modules/imgproc/src/cornersubpix.cpp
modules/imgproc/src/deriv.cpp
modules/imgproc/src/distransform.cpp
modules/imgproc/src/emd.cpp
modules/imgproc/src/featureselect.cpp
modules/imgproc/src/filter.cpp
modules/imgproc/src/floodfill.cpp
modules/imgproc/src/grabcut.cpp
modules/imgproc/src/histogram.cpp
modules/imgproc/src/hough.cpp
modules/imgproc/src/imgwarp.cpp
modules/imgproc/src/inpaint.cpp
modules/imgproc/src/moments.cpp
modules/imgproc/src/morph.cpp
modules/imgproc/src/pyramids.cpp
modules/imgproc/src/samplers.cpp
modules/imgproc/src/segmentation.cpp
modules/imgproc/src/smooth.cpp
modules/imgproc/src/sumpixels.cpp
modules/imgproc/src/templmatch.cpp
modules/imgproc/src/thresh.cpp
modules/imgproc/src/undistort.cpp
modules/imgproc/src/utils.cpp
modules/imgproc/test/test_imgwarp.cpp
modules/ml/src/ann_mlp.cpp
modules/ml/src/knearest.cpp
modules/ml/test/test_emknearestkmeans.cpp
modules/objdetect/src/planardetect.cpp
modules/ts/include/opencv2/ts/ts.hpp
modules/ts/src/ts_func.cpp
modules/video/include/opencv2/video/background_segm.hpp
modules/video/include/opencv2/video/tracking.hpp
modules/video/src/bgfg_gaussmix.cpp
modules/video/src/bgfg_gaussmix2.cpp
modules/video/src/camshift.cpp
modules/video/src/lkpyramid.cpp
modules/video/src/motempl.cpp
modules/video/src/optflowgf.cpp
modules/video/test/test_motiontemplates.cpp

index 16fcd2b..47a4e12 100644 (file)
@@ -432,10 +432,7 @@ namespace cv
 {
 
 //! converts rotation vector to rotation matrix or vice versa using Rodrigues transformation
-CV_EXPORTS_W void Rodrigues(const Mat& src, CV_OUT Mat& dst);
-    
-//! converts rotation vector to rotation matrix or vice versa using Rodrigues transformation. Also computes the Jacobian matrix
-CV_EXPORTS_AS(RodriguesJ) void Rodrigues(const Mat& src, CV_OUT Mat& dst, CV_OUT Mat& jacobian);
+CV_EXPORTS_W void Rodrigues(const InputArray& src, OutputArray dst, OutputArray jacobian=OutputArray());
 
 //! type of the robust estimation algorithm
 enum
@@ -445,128 +442,93 @@ enum
 };
 
 //! computes the best-fit perspective transformation mapping srcPoints to dstPoints.
-CV_EXPORTS_AS(findHomographyAndOutliers) Mat findHomography( const Mat& srcPoints,
-                               const Mat& dstPoints,
-                               vector<uchar>& mask, int method=0,
-                               double ransacReprojThreshold=3 );
-
-//! computes the best-fit perspective transformation mapping srcPoints to dstPoints.
-CV_EXPORTS_W Mat findHomography( const Mat& srcPoints,
-                               const Mat& dstPoints,
-                               int method=0, double ransacReprojThreshold=3 );
-
-//! computes the best-fit affine transformation that maps one 3D point set to another (RANSAC algorithm is used)
-CV_EXPORTS int estimateAffine3D(const Mat& from, const Mat& to, CV_OUT Mat& dst,
-                                CV_OUT vector<uchar>& outliers,
-                                double param1 = 3.0, double param2 = 0.99);    
+CV_EXPORTS_W Mat findHomography( const InputArray& srcPoints,
+                                 const InputArray& dstPoints,
+                                 int method=0, double ransacReprojThreshold=3,
+                                 OutputArray mask=OutputArray());
     
 //! Computes RQ decomposition of 3x3 matrix
-CV_EXPORTS void RQDecomp3x3( const Mat& M, Mat& R, Mat& Q );
-    
-//! Computes RQ decomposition of 3x3 matrix. Also, decomposes the output orthogonal matrix into the 3 primitive rotation matrices
-CV_EXPORTS_W Vec3d RQDecomp3x3( const Mat& M, Mat& R, Mat& Q,
-                              CV_OUT Mat& Qx, CV_OUT Mat& Qy, CV_OUT Mat& Qz );
+CV_EXPORTS_W Vec3d RQDecomp3x3( const InputArray& src, OutputArray mtxR, OutputArray mtxQ,
+                                OutputArray Qx=OutputArray(),
+                                OutputArray Qy=OutputArray(),
+                                OutputArray Qz=OutputArray());
 
 //! Decomposes the projection matrix into camera matrix and the rotation martix and the translation vector
-CV_EXPORTS void decomposeProjectionMatrix( const Mat& projMatrix, Mat& cameraMatrix,
-                                           Mat& rotMatrix, Mat& transVect );
-    
-//! Decomposes the projection matrix into camera matrix and the rotation martix and the translation vector. The rotation matrix is further decomposed
-CV_EXPORTS_W void decomposeProjectionMatrix( const Mat& projMatrix, CV_OUT Mat& cameraMatrix,
-                                           CV_OUT Mat& rotMatrix, CV_OUT Mat& transVect,
-                                           CV_OUT Mat& rotMatrixX, CV_OUT Mat& rotMatrixY,
-                                           CV_OUT Mat& rotMatrixZ, CV_OUT Vec3d& eulerAngles );
+CV_EXPORTS_W void decomposeProjectionMatrix( const InputArray& projMatrix, OutputArray cameraMatrix,
+                                             OutputArray rotMatrix, OutputArray transVect,
+                                             OutputArray rotMatrixX=OutputArray(),
+                                             OutputArray rotMatrixY=OutputArray(),
+                                             OutputArray rotMatrixZ=OutputArray(),
+                                             OutputArray eulerAngles=OutputArray() );   
 
 //! computes derivatives of the matrix product w.r.t each of the multiplied matrix coefficients
-CV_EXPORTS_W void matMulDeriv( const Mat& A, const Mat& B, CV_OUT Mat& dABdA, CV_OUT Mat& dABdB );
-
-//! composes 2 [R|t] transformations together
-CV_EXPORTS_W void composeRT( const Mat& rvec1, const Mat& tvec1,
-                           const Mat& rvec2, const Mat& tvec2,
-                           CV_OUT Mat& rvec3, CV_OUT Mat& tvec3 );
+CV_EXPORTS_W void matMulDeriv( const InputArray& A, const InputArray& B,
+                               OutputArray dABdA,
+                               OutputArray dABdB );
 
 //! composes 2 [R|t] transformations together. Also computes the derivatives of the result w.r.t the arguments
-CV_EXPORTS_AS(composeRT_J) void composeRT( const Mat& rvec1, const Mat& tvec1,
-                           const Mat& rvec2, const Mat& tvec2,
-                           CV_OUT Mat& rvec3, CV_OUT Mat& tvec3,
-                           CV_OUT Mat& dr3dr1, CV_OUT Mat& dr3dt1,
-                           CV_OUT Mat& dr3dr2, CV_OUT Mat& dr3dt2,
-                           CV_OUT Mat& dt3dr1, CV_OUT Mat& dt3dt1,
-                           CV_OUT Mat& dt3dr2, CV_OUT Mat& dt3dt2 );
-
-//! projects points from the model coordinate space to the image coordinates. Takes the intrinsic and extrinsic camera parameters into account
-CV_EXPORTS_W void projectPoints( const Mat& objectPoints,
-                               const Mat& rvec, const Mat& tvec,
-                               const Mat& cameraMatrix,
-                               const Mat& distCoeffs,
-                               CV_OUT vector<Point2f>& imagePoints );
+CV_EXPORTS_W void composeRT( const InputArray& rvec1, const InputArray& tvec1,
+                             const InputArray& rvec2, const InputArray& tvec2,
+                             OutputArray rvec3, OutputArray tvec3,
+                             OutputArray dr3dr1=OutputArray(), OutputArray dr3dt1=OutputArray(),
+                             OutputArray dr3dr2=OutputArray(), OutputArray dr3dt2=OutputArray(),
+                             OutputArray dt3dr1=OutputArray(), OutputArray dt3dt1=OutputArray(),
+                             OutputArray dt3dr2=OutputArray(), OutputArray dt3dt2=OutputArray() );
 
 //! projects points from the model coordinate space to the image coordinates. Also computes derivatives of the image coordinates w.r.t the intrinsic and extrinsic camera parameters
-CV_EXPORTS_AS(projectPointsJ) void projectPoints( const Mat& objectPoints,
-                               const Mat& rvec, const Mat& tvec,
-                               const Mat& cameraMatrix,
-                               const Mat& distCoeffs,
-                               CV_OUT vector<Point2f>& imagePoints,
-                               CV_OUT Mat& dpdrot, CV_OUT Mat& dpdt, CV_OUT Mat& dpdf,
-                               CV_OUT Mat& dpdc, CV_OUT Mat& dpddist,
-                               double aspectRatio=0 );
+CV_EXPORTS_W void projectPoints( const InputArray& objectPoints,
+                                 const InputArray& rvec, const InputArray& tvec,
+                                 const InputArray& cameraMatrix, const InputArray& distCoeffs,
+                                 OutputArray imagePoints,
+                                 OutputArray jacobian=OutputArray(),
+                                 double aspectRatio=0 );
 
 //! computes the camera pose from a few 3D points and the corresponding projections. The outliers are not handled.
-CV_EXPORTS_W void solvePnP( const Mat& objectPoints,
-                            const Mat& imagePoints,
-                            const Mat& cameraMatrix,
-                            const Mat& distCoeffs,
-                            CV_OUT Mat& rvec, CV_OUT Mat& tvec,
+CV_EXPORTS_W void solvePnP( const InputArray& objectPoints, const InputArray& imagePoints,
+                            const InputArray& cameraMatrix, const InputArray& distCoeffs,
+                            OutputArray rvec, OutputArray tvec,
                             bool useExtrinsicGuess=false );
 
 //! computes the camera pose from a few 3D points and the corresponding projections. The outliers are possible.
-CV_EXPORTS_W void solvePnPRansac( const Mat& objectPoints,
-                                  const Mat& imagePoints,
-                                  const Mat& cameraMatrix,
-                                  const Mat& distCoeffs,
-                                  CV_OUT Mat& rvec,
-                                  CV_OUT Mat& tvec,
+CV_EXPORTS_W void solvePnPRansac( const InputArray& objectPoints,
+                                  const InputArray& imagePoints,
+                                  const InputArray& cameraMatrix,
+                                  const InputArray& distCoeffs,
+                                  OutputArray rvec,
+                                  OutputArray tvec,
                                   bool useExtrinsicGuess = false,
                                   int iterationsCount = 100,
                                   float reprojectionError = 8.0,
                                   int minInliersCount = 100,
-                                  CV_OUT vector<int>* inliers = NULL );
+                                  OutputArray inliers = OutputArray() );
 
 //! initializes camera matrix from a few 3D points and the corresponding projections.
-CV_EXPORTS_W Mat initCameraMatrix2D( const vector<vector<Point3f> >& objectPoints,
-                                   const vector<vector<Point2f> >& imagePoints,
-                                   Size imageSize, double aspectRatio=1. );
-
+CV_EXPORTS_W Mat initCameraMatrix2D( const InputArrayOfArrays& objectPoints,
+                                     const InputArrayOfArrays& imagePoints,
+                                     Size imageSize, double aspectRatio=1. );
 
 enum { CALIB_CB_ADAPTIVE_THRESH = 1, CALIB_CB_NORMALIZE_IMAGE = 2,
        CALIB_CB_FILTER_QUADS = 4, CALIB_CB_FAST_CHECK = 8 };
 
 //! finds checkerboard pattern of the specified size in the image
-CV_EXPORTS_W bool findChessboardCorners( const Mat& image, Size patternSize,
-                                         CV_OUT vector<Point2f>& corners,
+CV_EXPORTS_W bool findChessboardCorners( const InputArray& image, Size patternSize,
+                                         OutputArray corners,
                                          int flags=CALIB_CB_ADAPTIVE_THRESH+
                                               CALIB_CB_NORMALIZE_IMAGE );
 
 //! finds subpixel-accurate positions of the chessboard corners                                              
-CV_EXPORTS bool find4QuadCornerSubpix(const Mat& img, std::vector<Point2f>& corners,
-                                      Size region_size);
+CV_EXPORTS bool find4QuadCornerSubpix(const InputArray& img, InputOutputArray corners, Size region_size);
 
 //! draws the checkerboard pattern (found or partly found) in the image
-CV_EXPORTS_W void drawChessboardCorners( Mat& image, Size patternSize,
-                                         const Mat& corners,
-                                         bool patternWasFound );
-
-CV_EXPORTS void drawChessboardCorners( Mat& image, Size patternSize,
-                                       const vector<Point2f>& corners,
-                                       bool patternWasFound );    
+CV_EXPORTS_W void drawChessboardCorners( InputOutputArray image, Size patternSize,
+                                         const InputArray& corners, bool patternWasFound );
 
 enum { CALIB_CB_SYMMETRIC_GRID = 1, CALIB_CB_ASYMMETRIC_GRID = 2,
        CALIB_CB_CLUSTERING = 4, CALIB_CB_WHITE_CIRCLES = 8 };
 
 //! finds circles' grid pattern of the specified size in the image
-CV_EXPORTS_W bool findCirclesGrid( const Mat& image, Size patternSize,
-                                   CV_OUT vector<Point2f>& centers,
-                                   int flags=CALIB_CB_SYMMETRIC_GRID );
+CV_EXPORTS_W bool findCirclesGrid( const InputArray& image, Size patternSize,
+                                   OutputArray centers, int flags=CALIB_CB_SYMMETRIC_GRID );
 
 enum
 {
@@ -590,16 +552,16 @@ enum
 };
 
 //! finds intrinsic and extrinsic camera parameters from several fews of a known calibration pattern.
-CV_EXPORTS_W double calibrateCamera( const vector<vector<Point3f> >& objectPoints,
-                                     const vector<vector<Point2f> >& imagePoints,
+CV_EXPORTS_W double calibrateCamera( const InputArrayOfArrays& objectPoints,
+                                     const InputArrayOfArrays& imagePoints,
                                      Size imageSize,
-                                     CV_IN_OUT Mat& cameraMatrix,
-                                     CV_IN_OUT Mat& distCoeffs,
-                                     CV_OUT vector<Mat>& rvecs, CV_OUT vector<Mat>& tvecs,
+                                     CV_IN_OUT InputOutputArray cameraMatrix,
+                                     CV_IN_OUT InputOutputArray distCoeffs,
+                                     OutputArray rvecs, OutputArray tvecs,
                                      int flags=0 );
 
 //! computes several useful camera characteristics from the camera matrix, camera frame resolution and the physical sensor size.
-CV_EXPORTS_W void calibrationMatrixValues( const Mat& cameraMatrix,
+CV_EXPORTS_W void calibrationMatrixValues( const InputArray& cameraMatrix,
                                 Size imageSize,
                                 double apertureWidth,
                                 double apertureHeight,
@@ -610,64 +572,58 @@ CV_EXPORTS_W void calibrationMatrixValues( const Mat& cameraMatrix,
                                 CV_OUT double& aspectRatio );
 
 //! finds intrinsic and extrinsic parameters of a stereo camera
-CV_EXPORTS_W double stereoCalibrate( const vector<vector<Point3f> >& objectPoints,
-                                     const vector<vector<Point2f> >& imagePoints1,
-                                     const vector<vector<Point2f> >& imagePoints2,
-                                     CV_IN_OUT Mat& cameraMatrix1, CV_IN_OUT Mat& distCoeffs1,
-                                     CV_IN_OUT Mat& cameraMatrix2, CV_IN_OUT Mat& distCoeffs2,
-                                     Size imageSize, CV_OUT Mat& R, CV_OUT Mat& T,
-                                     CV_OUT Mat& E, CV_OUT Mat& F,
+CV_EXPORTS_W double stereoCalibrate( const InputArrayOfArrays& objectPoints,
+                                     const InputArrayOfArrays& imagePoints1,
+                                     const InputArrayOfArrays& imagePoints2,
+                                     CV_IN_OUT InputOutputArray cameraMatrix1,
+                                     CV_IN_OUT InputOutputArray distCoeffs1,
+                                     CV_IN_OUT InputOutputArray cameraMatrix2,
+                                     CV_IN_OUT InputOutputArray distCoeffs2,
+                                     Size imageSize, OutputArray R,
+                                     OutputArray T, OutputArray E, OutputArray F,
                                      TermCriteria criteria = TermCriteria(TermCriteria::COUNT+
                                          TermCriteria::EPS, 30, 1e-6),
                                      int flags=CALIB_FIX_INTRINSIC );
 
     
 //! computes the rectification transformation for a stereo camera from its intrinsic and extrinsic parameters
-CV_EXPORTS void stereoRectify( const Mat& cameraMatrix1, const Mat& distCoeffs1,
-                               const Mat& cameraMatrix2, const Mat& distCoeffs2,
-                               Size imageSize, const Mat& R, const Mat& T,
-                               CV_OUT Mat& R1, CV_OUT Mat& R2,
-                               CV_OUT Mat& P1, CV_OUT Mat& P2, CV_OUT Mat& Q,
-                               int flags=CALIB_ZERO_DISPARITY );
-
-//! computes the rectification transformation for a stereo camera from its intrinsic and extrinsic parameters
-CV_EXPORTS_W void stereoRectify( const Mat& cameraMatrix1, const Mat& distCoeffs1,
-                                 const Mat& cameraMatrix2, const Mat& distCoeffs2,
-                                 Size imageSize, const Mat& R, const Mat& T,
-                                 CV_OUT Mat& R1, CV_OUT Mat& R2,
-                                 CV_OUT Mat& P1, CV_OUT Mat& P2, CV_OUT Mat& Q,
-                                 double alpha, Size newImageSize=Size(),
-                                 CV_OUT Rect* validPixROI1=0, CV_OUT Rect* validPixROI2=0,
-                                 int flags=CALIB_ZERO_DISPARITY );
+CV_EXPORTS void stereoRectify( const InputArray& cameraMatrix1, const InputArray& distCoeffs1,
+                               const InputArray& cameraMatrix2, const InputArray& distCoeffs2,
+                               Size imageSize, const InputArray& R, const InputArray& T,
+                               OutputArray R1, OutputArray R2,
+                               OutputArray P1, OutputArray P2,
+                               OutputArray Q, int flags=CALIB_ZERO_DISPARITY,
+                               double alpha=-1, Size newImageSize=Size(),
+                               CV_OUT Rect* validPixROI1=0, CV_OUT Rect* validPixROI2=0 );
 
 //! computes the rectification transformation for an uncalibrated stereo camera (zero distortion is assumed)
-CV_EXPORTS_W bool stereoRectifyUncalibrated( const Mat& points1, const Mat& points2,
-                                             const Mat& F, Size imgSize,
-                                             CV_OUT Mat& H1, CV_OUT Mat& H2,
+CV_EXPORTS_W bool stereoRectifyUncalibrated( const InputArray& points1, const InputArray& points2,
+                                             const InputArray& F, Size imgSize,
+                                             OutputArray H1, OutputArray H2,
                                              double threshold=5 );
 
 //! computes the rectification transformations for 3-head camera, where all the heads are on the same line.
-CV_EXPORTS_W float rectify3Collinear( const Mat& cameraMatrix1, const Mat& distCoeffs1,
-                                      const Mat& cameraMatrix2, const Mat& distCoeffs2,
-                                      const Mat& cameraMatrix3, const Mat& distCoeffs3,
-                                      const vector<vector<Point2f> >& imgpt1,
-                                      const vector<vector<Point2f> >& imgpt3,
-                                      Size imageSize, const Mat& R12, const Mat& T12,
-                                      const Mat& R13, const Mat& T13,
-                                      CV_OUT Mat& R1, CV_OUT Mat& R2, CV_OUT Mat& R3,
-                                      CV_OUT Mat& P1, CV_OUT Mat& P2, CV_OUT Mat& P3, CV_OUT Mat& Q,
-                                      double alpha, Size newImgSize,
+CV_EXPORTS_W float rectify3Collinear( const InputArray& cameraMatrix1, const InputArray& distCoeffs1,
+                                      const InputArray& cameraMatrix2, const InputArray& distCoeffs2,
+                                      const InputArray& cameraMatrix3, const InputArray& distCoeffs3,
+                                      const InputArrayOfArrays& imgpt1, const InputArrayOfArrays& imgpt3,
+                                      Size imageSize, const InputArray& R12, const InputArray& T12,
+                                      const InputArray& R13, const InputArray& T13,
+                                      OutputArray R1, OutputArray R2, OutputArray R3,
+                                      OutputArray P1, OutputArray P2, OutputArray P3,
+                                      OutputArray Q, double alpha, Size newImgSize,
                                       CV_OUT Rect* roi1, CV_OUT Rect* roi2, int flags );
     
 //! returns the optimal new camera matrix
-CV_EXPORTS_W Mat getOptimalNewCameraMatrix( const Mat& cameraMatrix, const Mat& distCoeffs,
+CV_EXPORTS_W Mat getOptimalNewCameraMatrix( const InputArray& cameraMatrix, const InputArray& distCoeffs,
                                             Size imageSize, double alpha, Size newImgSize=Size(),
                                             CV_OUT Rect* validPixROI=0);
 
 //! converts point coordinates from normal pixel coordinates to homogeneous coordinates ((x,y)->(x,y,1))
-CV_EXPORTS void convertPointsHomogeneous( const Mat& src, CV_OUT vector<Point3f>& dst );
+CV_EXPORTS void convertPointsToHomogeneous( const InputArray& src, OutputArray dst );
+    
 //! converts point coordinates from homogeneous to normal pixel coordinates ((x,y,z)->(x/z, y/z))
-CV_EXPORTS void convertPointsHomogeneous( const Mat& src, CV_OUT vector<Point2f>& dst );
+CV_EXPORTS void convertPointsFromHomogeneous( const InputArray& src, OutputArray dst );
 
 //! the algorithm for finding fundamental matrix
 enum
@@ -679,19 +635,15 @@ enum
 };
 
 //! finds fundamental matrix from a set of corresponding 2D points
-CV_EXPORTS Mat findFundamentalMat( const Mat& points1, const Mat& points2,
-                                     CV_OUT vector<uchar>& mask, int method=FM_RANSAC,
-                                     double param1=3., double param2=0.99 );
-
-//! finds fundamental matrix from a set of corresponding 2D points
-CV_EXPORTS_W Mat findFundamentalMat( const Mat& points1, const Mat& points2,
+CV_EXPORTS_W Mat findFundamentalMat( const InputArray& points1, const InputArray& points2,
                                      int method=FM_RANSAC,
-                                     double param1=3., double param2=0.99 );
+                                     double param1=3., double param2=0.99,
+                                     OutputArray mask=OutputArray());
 
 //! finds coordinates of epipolar lines corresponding the specified points
-CV_EXPORTS void computeCorrespondEpilines( const Mat& points1,
-                                             int whichImage, const Mat& F,
-                                             CV_OUT vector<Vec3f>& lines );
+CV_EXPORTS void computeCorrespondEpilines( const InputArray& points1,
+                                           int whichImage, const InputArray& F,
+                                           OutputArray lines );
 
 template<> CV_EXPORTS void Ptr<CvStereoBMState>::delete_obj();
 
@@ -713,7 +665,8 @@ public:
     //! the method that reinitializes the state. The previous content is destroyed
     void init(int preset, int ndisparities=0, int SADWindowSize=21);
     //! the stereo correspondence operator. Finds the disparity for the specified rectified stereo pair
-    CV_WRAP_AS(compute) void operator()( const Mat& left, const Mat& right, Mat& disparity, int disptype=CV_16S );
+    CV_WRAP_AS(compute) void operator()( const InputArray& left, const InputArray& right,
+                                         OutputArray disparity, int disptype=CV_16S );
 
     //! pointer to the underlying CvStereoBMState
     Ptr<CvStereoBMState> state;
@@ -743,7 +696,8 @@ public:
     virtual ~StereoSGBM();
 
     //! the stereo correspondence operator that computes disparity map for the specified rectified stereo pair
-    CV_WRAP_AS(compute) virtual void operator()(const Mat& left, const Mat& right, Mat& disp);
+    CV_WRAP_AS(compute) virtual void operator()(const InputArray& left, const InputArray& right,
+                                                OutputArray disp);
 
     CV_PROP_RW int minDisparity;
     CV_PROP_RW int numberOfDisparities;
@@ -762,7 +716,8 @@ protected:
 };
 
 //! filters off speckles (small regions of incorrectly computed disparity)
-CV_EXPORTS_W void filterSpeckles( Mat& img, double newVal, int maxSpeckleSize, double maxDiff, Mat& buf );
+CV_EXPORTS_W void filterSpeckles( InputOutputArray img, double newVal, int maxSpeckleSize, double maxDiff,
+                                  InputOutputArray buf=InputOutputArray() );
 
 //! computes valid disparity ROI from the valid ROIs of the rectified images (that are returned by cv::stereoRectify())
 CV_EXPORTS_W Rect getValidDisparityROI( Rect roi1, Rect roi2,
@@ -770,16 +725,20 @@ CV_EXPORTS_W Rect getValidDisparityROI( Rect roi1, Rect roi2,
                                         int SADWindowSize );
 
 //! validates disparity using the left-right check. The matrix "cost" should be computed by the stereo correspondence algorithm
-CV_EXPORTS_W void validateDisparity( Mat& disparity, const Mat& cost,
+CV_EXPORTS_W void validateDisparity( InputOutputArray disparity, const InputArray& cost,
                                      int minDisparity, int numberOfDisparities,
                                      int disp12MaxDisp=1 );
 
 //! reprojects disparity image to 3D: (x,y,d)->(X,Y,Z) using the matrix Q returned by cv::stereoRectify
-CV_EXPORTS_W void reprojectImageTo3D( const Mat& disparity,
-                                      CV_OUT Mat& _3dImage, const Mat& Q,
+CV_EXPORTS_W void reprojectImageTo3D( const InputArray& disparity,
+                                      OutputArray _3dImage, const InputArray& Q,
                                       bool handleMissingValues=false,
                                       int ddepth=-1 );
     
+CV_EXPORTS_W  int estimateAffine3D(const InputArray& _from, const InputArray& _to,
+                                   OutputArray _out, OutputArray _outliers,
+                                   double param1=3, double param2=0.99);
+    
 }
 
 #endif
index afb2231..15645b8 100644 (file)
@@ -1894,49 +1894,43 @@ cvDrawChessboardCorners( CvArr* _image, CvSize pattern_size,
     }
 }
 
-namespace cv
-{
-
-bool findChessboardCorners( const Mat& image, Size patternSize,
-                            vector<Point2f>& corners, int flags )
+bool cv::findChessboardCorners( const InputArray& _image, Size patternSize,
+                            OutputArray corners, int flags )
 {
     int count = patternSize.area()*2;
-    corners.resize(count);
-    CvMat _image = image;
-    bool ok = cvFindChessboardCorners(&_image, patternSize,
-        (CvPoint2D32f*)&corners[0], &count, flags ) > 0;
-    if(count >= 0)
-        corners.resize(count);
+    vector<Point2f> tmpcorners(count+1);
+    CvMat c_image = _image.getMat();
+    bool ok = cvFindChessboardCorners(&c_image, patternSize,
+        (CvPoint2D32f*)&tmpcorners[0], &count, flags ) > 0;
+    if( count > 0 )
+    {
+        tmpcorners.resize(count);
+        Mat(tmpcorners).copyTo(corners);
+    }
+    else
+        corners.release();
     return ok;
 }
 
-void drawChessboardCorners( Mat& image, Size patternSize,
-                            const Mat& corners,
+void cv::drawChessboardCorners( InputOutputArray _image, Size patternSize,
+                            const InputArray& _corners,
                             bool patternWasFound )
 {
-    if( corners.cols == 0 || corners.rows == 0 )
+    Mat corners = _corners.getMat();
+    if( !corners.empty() )
         return;
-    CvMat _image = image;
+    CvMat c_image = _image.getMat();
     int nelems = corners.checkVector(2, CV_32F, true);
     CV_Assert(nelems >= 0);
-    cvDrawChessboardCorners( &_image, patternSize, (CvPoint2D32f*)corners.data,
+    cvDrawChessboardCorners( &c_image, patternSize, (CvPoint2D32f*)corners.data,
                              nelems, patternWasFound );
 }
-    
-void drawChessboardCorners( Mat& image, Size patternSize,
-                            const vector<Point2f>& corners,
-                            bool patternWasFound )
-{
-    if( corners.empty() )
-        return;
-    CvMat _image = image;
-    cvDrawChessboardCorners( &_image, patternSize, (CvPoint2D32f*)&corners[0],
-                            (int)corners.size(), patternWasFound );
-}
 
-bool findCirclesGrid( const Mat& image, Size patternSize,
-                      vector<Point2f>& centers, int flags )
+bool cv::findCirclesGrid( const InputArray& _image, Size patternSize,
+                          OutputArray _centers, int flags )
 {
+    Mat image = _image.getMat();
+    vector<Point2f> centers;
     SimpleBlobDetector::Params params;
     if(flags & CALIB_CB_WHITE_CIRCLES)
     {
@@ -1957,6 +1951,7 @@ bool findCirclesGrid( const Mat& image, Size patternSize,
     {
       CirclesGridClusterFinder circlesGridClusterFinder;
       circlesGridClusterFinder.findGrid(points, patternSize, centers);
+      Mat(centers).copyTo(_centers);
       return !centers.empty();
     }
 
@@ -2005,10 +2000,10 @@ bool findCirclesGrid( const Mat& image, Size patternSize,
         if (i != 0)
         {
           Mat orgPointsMat;
-          transform(Mat(centers), orgPointsMat, H.inv());
-          convertPointsHomogeneous(orgPointsMat, centers);
+          transform(centers, orgPointsMat, H.inv());
+          convertPointsFromHomogeneous(orgPointsMat, centers);
         }
-
+        Mat(centers).copyTo(_centers);
         return true;
       }
       
@@ -2020,10 +2015,8 @@ bool findCirclesGrid( const Mat& image, Size patternSize,
         H = CirclesGridFinder::rectifyGrid(boxFinder.getDetectedGridSize(), centers, points, points);
       }
     }
-
+    Mat(centers).copyTo(_centers);
     return false;
 }
 
-}
-
 /* End of file. */
index 695664e..bb364f0 100644 (file)
@@ -2753,10 +2753,11 @@ CV_IMPL int cvStereoRectifyUncalibrated(
 }
 
 
-void cv::reprojectImageTo3D( const Mat& disparity,
-                             Mat& _3dImage, const Mat& Q,
+void cv::reprojectImageTo3D( const InputArray& _disparity,
+                             OutputArray __3dImage, const InputArray& _Qmat,
                              bool handleMissingValues, int dtype )
 {
+    Mat disparity = _disparity.getMat(), Q = _Qmat.getMat();
     int stype = disparity.type();
     
     CV_Assert( stype == CV_8UC1 || stype == CV_16SC1 ||
@@ -2771,7 +2772,8 @@ void cv::reprojectImageTo3D( const Mat& disparity,
         CV_Assert( dtype == CV_16SC3 || dtype == CV_32SC3 || dtype == CV_32FC3 );
     }
     
-    _3dImage.create(disparity.size(), CV_MAKETYPE(dtype, 3));
+    __3dImage.create(disparity.size(), CV_MAKETYPE(dtype, 3));
+    Mat _3dImage = __3dImage.getMat();
     
     const double bigZ = 10000.;
     double q[4][4];
@@ -3092,45 +3094,56 @@ cvDecomposeProjectionMatrix( const CvMat *projMatr, CvMat *calibMatr,
 namespace cv
 {
 
-static void collectCalibrationData( const vector<vector<Point3f> >& objectPoints,
-                                    const vector<vector<Point2f> >& imagePoints,
-                                    const vector<vector<Point2f> >& imagePoints2,
-                                    Mat& objPtMat, Mat& imgPtMat, Mat* imgPtMat2,
+static void collectCalibrationData( const InputArrayOfArrays& objectPoints,
+                                    const InputArrayOfArrays& imagePoints1,
+                                    const InputArrayOfArrays& imagePoints2,
+                                    Mat& objPtMat, Mat& imgPtMat1, Mat* imgPtMat2,
                                     Mat& npoints )
 {
-    size_t i, j = 0, ni = 0, nimages = objectPoints.size(), total = 0;
-    CV_Assert(nimages > 0 && nimages == imagePoints.size() &&
-        (!imgPtMat2 || nimages == imagePoints2.size()));
+    int nimages = (int)objectPoints.total();
+    int i, j = 0, ni = 0, total = 0;
+    CV_Assert(nimages > 0 && nimages == (int)imagePoints1.total() &&
+        (!imgPtMat2 || nimages == (int)imagePoints2.total()));
 
     for( i = 0; i < nimages; i++ )
     {
-        ni = objectPoints[i].size();
-        CV_Assert(ni == imagePoints[i].size() && (!imgPtMat2 || ni == imagePoints2[i].size()));
+        ni = objectPoints.getMat(i).checkVector(3, CV_32F);
+        CV_Assert( ni >= 0 );
         total += ni;
     }
 
     npoints.create(1, (int)nimages, CV_32S);
-    objPtMat.create(1, (int)total, DataType<Point3f>::type);
-    imgPtMat.create(1, (int)total, DataType<Point2f>::type);
+    objPtMat.create(1, (int)total, CV_32FC3);
+    imgPtMat1.create(1, (int)total, CV_32FC2);
     Point2f* imgPtData2 = 0;
     
     if( imgPtMat2 )
     {
-        imgPtMat2->create(1, (int)total, DataType<Point2f>::type);
+        imgPtMat2->create(1, (int)total, CV_32FC2);
         imgPtData2 = imgPtMat2->ptr<Point2f>();
     }
 
     Point3f* objPtData = objPtMat.ptr<Point3f>();
-    Point2f* imgPtData = imgPtMat.ptr<Point2f>();
+    Point2f* imgPtData1 = imgPtMat1.ptr<Point2f>();
     
     for( i = 0; i < nimages; i++, j += ni )
     {
-        ni = objectPoints[i].size();
-        ((int*)npoints.data)[i] = (int)ni;
-        std::copy(objectPoints[i].begin(), objectPoints[i].end(), objPtData + j);
-        std::copy(imagePoints[i].begin(), imagePoints[i].end(), imgPtData + j);
-        if( imgPtMat2 )
-            std::copy(imagePoints2[i].begin(), imagePoints2[i].end(), imgPtData2 + j);
+        Mat objpt = objectPoints.getMat(i);
+        Mat imgpt1 = imagePoints1.getMat(i);
+        ni = objpt.checkVector(3, CV_32F);
+        int ni1 = imgpt1.checkVector(2, CV_32F);
+        CV_Assert( ni > 0 && ni == ni1 );
+        npoints.at<int>(i) = ni;
+        memcpy( objPtData + j, objpt.data, ni*sizeof(objPtData[0]) );
+        memcpy( imgPtData1 + j, imgpt1.data, ni*sizeof(imgPtData1[0]) );
+        
+        if( imgPtData2 )
+        {
+            Mat imgpt2 = imagePoints2.getMat(i);
+            int ni2 = imgpt2.checkVector(2, CV_32F);
+            CV_Assert( ni == ni2 );
+            memcpy( imgPtData2 + j, imgpt2.data, ni*sizeof(imgPtData2[0]) );
+        }
     }
 }
 
@@ -3162,126 +3175,153 @@ static Mat prepareDistCoeffs(Mat& distCoeffs0, int rtype)
 }
 
 
-void cv::Rodrigues(const Mat& src, Mat& dst)
+void cv::Rodrigues(const InputArray& _src, OutputArray _dst, OutputArray _jacobian)
 {
+    Mat src = _src.getMat();
     bool v2m = src.cols == 1 || src.rows == 1;
-    dst.create(3, v2m ? 3 : 1, src.depth());
-    CvMat _src = src, _dst = dst;
-    bool ok = cvRodrigues2(&_src, &_dst, 0) > 0;
-    if( !ok )
-        dst = Scalar(0);
-}
-
-void cv::Rodrigues(const Mat& src, Mat& dst, Mat& jacobian)
-{
-    bool v2m = src.cols == 1 || src.rows == 1;
-    dst.create(3, v2m ? 3 : 1, src.depth());
-    jacobian.create(v2m ? Size(9, 3) : Size(3, 9), src.depth());
-    CvMat _src = src, _dst = dst, _jacobian = jacobian;
-    bool ok = cvRodrigues2(&_src, &_dst, &_jacobian) > 0;
+    _dst.create(3, v2m ? 3 : 1, src.depth());
+    Mat dst = _dst.getMat();
+    CvMat _csrc = src, _cdst = dst, _cjacobian;
+    if( _jacobian.needed() )
+    {
+        _jacobian.create(v2m ? Size(9, 3) : Size(3, 9), src.depth());
+        _cjacobian = _jacobian.getMat();
+    }
+    bool ok = cvRodrigues2(&_csrc, &_cdst, _jacobian.needed() ? &_cjacobian : 0) > 0;
     if( !ok )
         dst = Scalar(0);
 }
 
-void cv::matMulDeriv( const Mat& A, const Mat& B, Mat& dABdA, Mat& dABdB )
-{
-    dABdA.create(A.rows*B.cols, A.rows*A.cols, A.type());
-    dABdB.create(A.rows*B.cols, B.rows*B.cols, A.type());
-    CvMat matA = A, matB = B, _dABdA = dABdA, _dABdB = dABdB;
-    cvCalcMatMulDeriv(&matA, &matB, &_dABdA, &_dABdB);
-}
-
-void cv::composeRT( const Mat& rvec1, const Mat& tvec1,
-                    const Mat& rvec2, const Mat& tvec2,
-                    Mat& rvec3, Mat& tvec3 )
+void cv::matMulDeriv( const InputArray& _Amat, const InputArray& _Bmat,
+                      OutputArray _dABdA, OutputArray _dABdB )
 {
-    rvec3.create(rvec1.size(), rvec1.type());
-    tvec3.create(tvec1.size(), tvec1.type());
-    CvMat _rvec1 = rvec1, _tvec1 = tvec1, _rvec2 = rvec2,
-    _tvec2 = tvec2, _rvec3 = rvec3, _tvec3 = tvec3;
-    cvComposeRT(&_rvec1, &_tvec1, &_rvec2, &_tvec2, &_rvec3, &_tvec3, 0, 0, 0, 0, 0, 0, 0, 0);
+    Mat A = _Amat.getMat(), B = _Bmat.getMat();
+    _dABdA.create(A.rows*B.cols, A.rows*A.cols, A.type());
+    _dABdB.create(A.rows*B.cols, B.rows*B.cols, A.type());
+    CvMat matA = A, matB = B, c_dABdA = _dABdA.getMat(), c_dABdB = _dABdB.getMat();
+    cvCalcMatMulDeriv(&matA, &matB, &c_dABdA, &c_dABdB);
 }
 
 
-void cv::composeRT( const Mat& rvec1, const Mat& tvec1,
-                    const Mat& rvec2, const Mat& tvec2,
-                    Mat& rvec3, Mat& tvec3,
-                    Mat& dr3dr1, Mat& dr3dt1,
-                    Mat& dr3dr2, Mat& dr3dt2,
-                    Mat& dt3dr1, Mat& dt3dt1,
-                    Mat& dt3dr2, Mat& dt3dt2 )
+void cv::composeRT( const InputArray& _rvec1, const InputArray& _tvec1,
+                    const InputArray& _rvec2, const InputArray& _tvec2,
+                    OutputArray _rvec3, OutputArray _tvec3,
+                    OutputArray _dr3dr1, OutputArray _dr3dt1,
+                    OutputArray _dr3dr2, OutputArray _dr3dt2,
+                    OutputArray _dt3dr1, OutputArray _dt3dt1,
+                    OutputArray _dt3dr2, OutputArray _dt3dt2 )
 {
+    Mat rvec1 = _rvec1.getMat(), tvec1 = _tvec1.getMat();
+    Mat rvec2 = _rvec2.getMat(), tvec2 = _tvec2.getMat();
     int rtype = rvec1.type();
-    rvec3.create(rvec1.size(), rtype);
-    tvec3.create(tvec1.size(), rtype);
-    dr3dr1.create(3, 3, rtype); dr3dt1.create(3, 3, rtype);
-    dr3dr2.create(3, 3, rtype); dr3dt2.create(3, 3, rtype);
-    dt3dr1.create(3, 3, rtype); dt3dt1.create(3, 3, rtype);
-    dt3dr2.create(3, 3, rtype); dt3dt2.create(3, 3, rtype);
-    
-    CvMat _rvec1 = rvec1, _tvec1 = tvec1, _rvec2 = rvec2,
-    _tvec2 = tvec2, _rvec3 = rvec3, _tvec3 = tvec3;
-    CvMat _dr3dr1 = dr3dr1, _dr3dt1 = dr3dt1, _dr3dr2 = dr3dr2, _dr3dt2 = dr3dt2;
-    CvMat _dt3dr1 = dt3dr1, _dt3dt1 = dt3dt1, _dt3dr2 = dt3dr2, _dt3dt2 = dt3dt2;
-    cvComposeRT(&_rvec1, &_tvec1, &_rvec2, &_tvec2, &_rvec3, &_tvec3,
-                &_dr3dr1, &_dr3dt1, &_dr3dr2, &_dr3dt2,
-                &_dt3dr1, &_dt3dt1, &_dt3dr2, &_dt3dt2);
-}
-
-
-void cv::projectPoints( const Mat& opoints,
-                        const Mat& rvec, const Mat& tvec,
-                        const Mat& cameraMatrix,
-                        const Mat& distCoeffs,
-                        vector<Point2f>& ipoints )
-{
-    CV_Assert(opoints.isContinuous() && opoints.depth() == CV_32F &&
-              ((opoints.rows == 1 && opoints.channels() == 3) ||
-               opoints.cols*opoints.channels() == 3));
+    _rvec3.create(rvec1.size(), rtype);
+    _tvec3.create(tvec1.size(), rtype);
+    Mat rvec3 = _rvec3.getMat(), tvec3 = _tvec3.getMat();
+    
+    CvMat c_rvec1 = rvec1, c_tvec1 = tvec1, c_rvec2 = rvec2,
+          c_tvec2 = tvec2, c_rvec3 = rvec3, c_tvec3 = tvec3;
+    CvMat c_dr3dr1, c_dr3dt1, c_dr3dr2, c_dr3dt2, c_dt3dr1, c_dt3dt1, c_dt3dr2, c_dt3dt2;
+    CvMat *p_dr3dr1=0, *p_dr3dt1=0, *p_dr3dr2=0, *p_dr3dt2=0, *p_dt3dr1=0, *p_dt3dt1=0, *p_dt3dr2=0, *p_dt3dt2=0;
+    
+    if( _dr3dr1.needed() )
+    {
+        _dr3dr1.create(3, 3, rtype);
+        p_dr3dr1 = &(c_dr3dr1 = _dr3dr1.getMat());
+    }
+    
+    if( _dr3dt1.needed() )
+    {
+        _dr3dt1.create(3, 3, rtype);
+        p_dr3dt1 = &(c_dr3dt1 = _dr3dt1.getMat());
+    }
+    
+    if( _dr3dr2.needed() )
+    {
+        _dr3dr2.create(3, 3, rtype);
+        p_dr3dr2 = &(c_dr3dr2 = _dr3dr2.getMat());
+    }
+    
+    if( _dr3dt2.needed() )
+    {
+        _dr3dt2.create(3, 3, rtype);
+        p_dr3dt2 = &(c_dr3dt2 = _dr3dt2.getMat());
+    }
+    
+    if( _dt3dr1.needed() )
+    {
+        _dt3dr1.create(3, 3, rtype);
+        p_dt3dr1 = &(c_dt3dr1 = _dt3dr1.getMat());
+    }
+    
+    if( _dt3dt1.needed() )
+    {
+        _dt3dt1.create(3, 3, rtype);
+        p_dt3dt1 = &(c_dt3dt1 = _dt3dt1.getMat());
+    }
+    
+    if( _dt3dr2.needed() )
+    {
+        _dt3dr2.create(3, 3, rtype);
+        p_dt3dr2 = &(c_dt3dr2 = _dt3dr2.getMat());
+    }
     
-    ipoints.resize(opoints.cols*opoints.rows*opoints.channels()/3);
-    CvMat _objectPoints = opoints, _imagePoints = Mat(ipoints);
-    CvMat _rvec = rvec, _tvec = tvec, _cameraMatrix = cameraMatrix, _distCoeffs = distCoeffs;
+    if( _dt3dt2.needed() )
+    {
+        _dt3dt2.create(3, 3, rtype);
+        p_dt3dt2 = &(c_dt3dt2 = _dt3dt2.getMat());
+    }
     
-    cvProjectPoints2( &_objectPoints, &_rvec, &_tvec, &_cameraMatrix,
-                     distCoeffs.data ? &_distCoeffs : 0,
-                     &_imagePoints, 0, 0, 0, 0, 0, 0 );
+    cvComposeRT(&c_rvec1, &c_tvec1, &c_rvec2, &c_tvec2, &c_rvec3, &c_tvec3,
+                p_dr3dr1, p_dr3dt1, p_dr3dr2, p_dr3dt2,
+                p_dt3dr1, p_dt3dt1, p_dt3dr2, p_dt3dt2);
 }
 
-void cv::projectPoints( const Mat& opoints,
-                        const Mat& rvec, const Mat& tvec,
-                        const Mat& cameraMatrix,
-                        const Mat& distCoeffs,
-                        vector<Point2f>& ipoints,
-                        Mat& dpdrot, Mat& dpdt, Mat& dpdf,
-                        Mat& dpdc, Mat& dpddist,
+
+void cv::projectPoints( const InputArray& _opoints,
+                        const InputArray& _rvec,
+                        const InputArray& _tvec,
+                        const InputArray& _cameraMatrix,
+                        const InputArray& _distCoeffs,
+                        OutputArray _ipoints,
+                        OutputArray _jacobian,
                         double aspectRatio )
 {
-    CV_Assert(opoints.isContinuous() && opoints.depth() == CV_32F &&
-              ((opoints.rows == 1 && opoints.channels() == 3) ||
-               opoints.cols*opoints.channels() == 3));
-    
-    int npoints = opoints.cols*opoints.rows*opoints.channels()/3;
-    ipoints.resize(npoints);
-    dpdrot.create(npoints*2, 3, CV_64F);
-    dpdt.create(npoints*2, 3, CV_64F);
-    dpdf.create(npoints*2, 2, CV_64F);
-    dpdc.create(npoints*2, 2, CV_64F);
-    dpddist.create(npoints*2, distCoeffs.rows + distCoeffs.cols - 1, CV_64F);
-    CvMat _objectPoints = opoints, _imagePoints = Mat(ipoints);
-    CvMat _rvec = rvec, _tvec = tvec, _cameraMatrix = cameraMatrix, _distCoeffs = distCoeffs;
-    CvMat _dpdrot = dpdrot, _dpdt = dpdt, _dpdf = dpdf, _dpdc = dpdc, _dpddist = dpddist;
-    
-    cvProjectPoints2( &_objectPoints, &_rvec, &_tvec, &_cameraMatrix, &_distCoeffs,
-                      &_imagePoints, &_dpdrot, &_dpdt, &_dpdf, &_dpdc, &_dpddist, aspectRatio );
+    Mat opoints = _opoints.getMat();
+    int npoints = opoints.checkVector(3), depth = opoints.depth();
+    CV_Assert(npoints >= 0 && (depth == CV_32F || depth == CV_64F));
+    
+    CvMat dpdrot, dpdt, dpdf, dpdc, dpddist;
+    CvMat *pdpdrot=0, *pdpdt=0, *pdpdf=0, *pdpdc=0, *pdpddist=0;
+    
+    _ipoints.create(npoints, 1, CV_MAKETYPE(depth, 2), -1, true);
+    CvMat imagePoints = _ipoints.getMat();
+    CvMat objectPoints = opoints;
+    CvMat cameraMatrix = _cameraMatrix.getMat();
+    CvMat rvec = _rvec.getMat(), tvec = _tvec.getMat();
+    CvMat distCoeffs = _distCoeffs.getMat();
+    int ndistCoeffs = distCoeffs.rows + distCoeffs.cols - 1;
+    
+    if( _jacobian.needed() )
+    {
+        _jacobian.create(npoints*2, 3+3+2+2+ndistCoeffs, CV_64F);
+        Mat jacobian = _jacobian.getMat();
+        pdpdrot = &(dpdrot = jacobian.colRange(0, 3));
+        pdpdt = &(dpdt = jacobian.colRange(3, 6));
+        pdpdf = &(dpdf = jacobian.colRange(6, 8));
+        pdpdc = &(dpdc = jacobian.colRange(8, 10));
+        pdpddist = &(dpddist = jacobian.colRange(10, 10+ndistCoeffs));
+    }
+        
+    cvProjectPoints2( &objectPoints, &rvec, &tvec, &cameraMatrix, &distCoeffs,
+                      &imagePoints, pdpdrot, pdpdt, pdpdf, pdpdc, pdpddist, aspectRatio );
 }
 
-cv::Mat cv::initCameraMatrix2D( const vector<vector<Point3f> >& objectPoints,
-                                const vector<vector<Point2f> >& imagePoints,
+cv::Mat cv::initCameraMatrix2D( const InputArrayOfArrays& objectPoints,
+                                const InputArrayOfArrays& imagePoints,
                                 Size imageSize, double aspectRatio )
 {
     Mat objPt, imgPt, npoints, cameraMatrix(3, 3, CV_64F);
-    collectCalibrationData( objectPoints, imagePoints, vector<vector<Point2f> >(),
+    collectCalibrationData( objectPoints, imagePoints, InputArrayOfArrays(),
                             objPt, imgPt, 0, npoints );
     CvMat _objPt = objPt, _imgPt = imgPt, _npoints = npoints, _cameraMatrix = cameraMatrix;
     cvInitIntrinsicParams2D( &_objPt, &_imgPt, &_npoints,
@@ -3290,60 +3330,73 @@ cv::Mat cv::initCameraMatrix2D( const vector<vector<Point3f> >& objectPoints,
 }
 
 
-double cv::calibrateCamera( const vector<vector<Point3f> >& objectPoints,
-                          const vector<vector<Point2f> >& imagePoints,
-                          Size imageSize, Mat& cameraMatrix, Mat& distCoeffs,
-                          vector<Mat>& rvecs, vector<Mat>& tvecs, int flags )
+double cv::calibrateCamera( const InputArrayOfArrays& _objectPoints,
+                            const InputArrayOfArrays& _imagePoints,
+                            Size imageSize, InputOutputArray _cameraMatrix, InputOutputArray _distCoeffs,
+                            OutputArray _rvecs, OutputArray _tvecs, int flags )
 {
     int rtype = CV_64F;
+    Mat cameraMatrix = _cameraMatrix.getMat();
     cameraMatrix = prepareCameraMatrix(cameraMatrix, rtype);
+    Mat distCoeffs = _distCoeffs.getMat();
     distCoeffs = prepareDistCoeffs(distCoeffs, rtype);
     if( !(flags & CALIB_RATIONAL_MODEL) )
         distCoeffs = distCoeffs.rows == 1 ? distCoeffs.colRange(0, 5) : distCoeffs.rowRange(0, 5);
 
-    size_t i, nimages = objectPoints.size();
+    size_t i, nimages = _objectPoints.total();
     CV_Assert( nimages > 0 );
     Mat objPt, imgPt, npoints, rvecM((int)nimages, 3, CV_64FC1), tvecM((int)nimages, 3, CV_64FC1);
-    collectCalibrationData( objectPoints, imagePoints, vector<vector<Point2f> >(),
+    collectCalibrationData( _objectPoints, _imagePoints, InputArrayOfArrays(),
                             objPt, imgPt, 0, npoints );
-    CvMat _objPt = objPt, _imgPt = imgPt, _npoints = npoints;
-    CvMat _cameraMatrix = cameraMatrix, _distCoeffs = distCoeffs;
-    CvMat _rvecM = rvecM, _tvecM = tvecM;
-
-    double reprojErr = cvCalibrateCamera2(&_objPt, &_imgPt, &_npoints, imageSize,
-                                          &_cameraMatrix, &_distCoeffs, &_rvecM,
-                                          &_tvecM, flags );
-    rvecs.resize(nimages);
-    tvecs.resize(nimages);
+    CvMat c_objPt = objPt, c_imgPt = imgPt, c_npoints = npoints;
+    CvMat c_cameraMatrix = cameraMatrix, c_distCoeffs = distCoeffs;
+    CvMat c_rvecM = rvecM, c_tvecM = tvecM;
+
+    double reprojErr = cvCalibrateCamera2(&c_objPt, &c_imgPt, &c_npoints, imageSize,
+                                          &c_cameraMatrix, &c_distCoeffs, &c_rvecM,
+                                          &c_tvecM, flags );
+    _rvecs.create(nimages, 1, CV_64FC3);
+    _tvecs.create(nimages, 1, CV_64FC3);
+    
     for( i = 0; i < nimages; i++ )
     {
-        rvecM.row((int)i).copyTo(rvecs[i]);
-        tvecM.row((int)i).copyTo(tvecs[i]);
+        _rvecs.create(3, 1, CV_64F, i, true);
+        _tvecs.create(3, 1, CV_64F, i, true);
+        Mat rv = _rvecs.getMat(i), tv = _tvecs.getMat(i);
+        memcpy(rv.data, rvecM.ptr<double>(i), 3*sizeof(double));
+        memcpy(tv.data, tvecM.ptr<double>(i), 3*sizeof(double));
     }
+    cameraMatrix.copyTo(_cameraMatrix);
+    distCoeffs.copyTo(_distCoeffs);
+    
     return reprojErr;
 }
 
 
-void cv::calibrationMatrixValues( const Mat& cameraMatrix, Size imageSize,
+void cv::calibrationMatrixValues( const InputArray& _cameraMatrix, Size imageSize,
                                   double apertureWidth, double apertureHeight,
                                   double& fovx, double& fovy, double& focalLength,
                                   Point2d& principalPoint, double& aspectRatio )
 {
-    CvMat _cameraMatrix = cameraMatrix;
-    cvCalibrationMatrixValues( &_cameraMatrix, imageSize, apertureWidth, apertureHeight,
+    CvMat c_cameraMatrix = _cameraMatrix.getMat();
+    cvCalibrationMatrixValues( &c_cameraMatrix, imageSize, apertureWidth, apertureHeight,
         &fovx, &fovy, &focalLength, (CvPoint2D64f*)&principalPoint, &aspectRatio );
 }
 
-double cv::stereoCalibrate( const vector<vector<Point3f> >& objectPoints,
-                          const vector<vector<Point2f> >& imagePoints1,
-                          const vector<vector<Point2f> >& imagePoints2,
-                          Mat& cameraMatrix1, Mat& distCoeffs1,
-                          Mat& cameraMatrix2, Mat& distCoeffs2,
-                          Size imageSize, Mat& R, Mat& T,
-                          Mat& E, Mat& F, TermCriteria criteria,
+double cv::stereoCalibrate( const InputArrayOfArrays& _objectPoints,
+                          const InputArrayOfArrays& _imagePoints1,
+                          const InputArrayOfArrays& _imagePoints2,
+                          InputOutputArray _cameraMatrix1, InputOutputArray _distCoeffs1,
+                          InputOutputArray _cameraMatrix2, InputOutputArray _distCoeffs2,
+                          Size imageSize, OutputArray _Rmat, OutputArray _Tmat,
+                          OutputArray _Emat, OutputArray _Fmat, TermCriteria criteria,
                           int flags )
 {
     int rtype = CV_64F;
+    Mat cameraMatrix1 = _cameraMatrix1.getMat();
+    Mat cameraMatrix2 = _cameraMatrix2.getMat();
+    Mat distCoeffs1 = _distCoeffs1.getMat();
+    Mat distCoeffs2 = _distCoeffs2.getMat();
     cameraMatrix1 = prepareCameraMatrix(cameraMatrix1, rtype);
     cameraMatrix2 = prepareCameraMatrix(cameraMatrix2, rtype);
     distCoeffs1 = prepareDistCoeffs(distCoeffs1, rtype);
@@ -3355,176 +3408,210 @@ double cv::stereoCalibrate( const vector<vector<Point3f> >& objectPoints,
         distCoeffs2 = distCoeffs2.rows == 1 ? distCoeffs2.colRange(0, 5) : distCoeffs2.rowRange(0, 5);
     }
     
-    R.create(3, 3, rtype);
-    T.create(3, 1, rtype);
-    E.create(3, 3, rtype);
-    F.create(3, 3, rtype);
+    _Rmat.create(3, 3, rtype);
+    _Tmat.create(3, 1, rtype);
 
     Mat objPt, imgPt, imgPt2, npoints;
 
-    collectCalibrationData( objectPoints, imagePoints1, imagePoints2,
+    collectCalibrationData( _objectPoints, _imagePoints1, _imagePoints2,
                             objPt, imgPt, &imgPt2, npoints );
-    CvMat _objPt = objPt, _imgPt = imgPt, _imgPt2 = imgPt2, _npoints = npoints;
-    CvMat _cameraMatrix1 = cameraMatrix1, _distCoeffs1 = distCoeffs1;
-    CvMat _cameraMatrix2 = cameraMatrix2, _distCoeffs2 = distCoeffs2;
-    CvMat matR = R, matT = T, matE = E, matF = F;
-
-    return cvStereoCalibrate(&_objPt, &_imgPt, &_imgPt2, &_npoints, &_cameraMatrix1,
-        &_distCoeffs1, &_cameraMatrix2, &_distCoeffs2, imageSize,
-        &matR, &matT, &matE, &matF, criteria, flags );
-}
-
+    CvMat c_objPt = objPt, c_imgPt = imgPt, c_imgPt2 = imgPt2, c_npoints = npoints;
+    CvMat c_cameraMatrix1 = cameraMatrix1, c_distCoeffs1 = distCoeffs1;
+    CvMat c_cameraMatrix2 = cameraMatrix2, c_distCoeffs2 = distCoeffs2;
+    CvMat c_matR = _Rmat.getMat(), c_matT = _Tmat.getMat(), c_matE, c_matF, *p_matE = 0, *p_matF = 0;
+    
+    if( _Emat.needed() )
+    {
+        _Emat.create(3, 3, rtype);
+        p_matE = &(c_matE = _Emat.getMat());
+    }
+    if( _Fmat.needed() )
+    {
+        _Fmat.create(3, 3, rtype);
+        p_matF = &(c_matF = _Fmat.getMat());
+    }
 
-void cv::stereoRectify( const Mat& cameraMatrix1, const Mat& distCoeffs1,
-                        const Mat& cameraMatrix2, const Mat& distCoeffs2,
-                        Size imageSize, const Mat& R, const Mat& T,
-                        Mat& R1, Mat& R2, Mat& P1, Mat& P2, Mat& Q,
-                        int flags )
-{
-    int rtype = CV_64F;
-    R1.create(3, 3, rtype);
-    R2.create(3, 3, rtype);
-    P1.create(3, 4, rtype);
-    P2.create(3, 4, rtype);
-    Q.create(4, 4, rtype);
-    CvMat _cameraMatrix1 = cameraMatrix1, _distCoeffs1 = distCoeffs1;
-    CvMat _cameraMatrix2 = cameraMatrix2, _distCoeffs2 = distCoeffs2;
-    CvMat matR = R, matT = T, _R1 = R1, _R2 = R2, _P1 = P1, _P2 = P2, matQ = Q;
-    cvStereoRectify( &_cameraMatrix1, &_cameraMatrix2, &_distCoeffs1, &_distCoeffs2,
-        imageSize, &matR, &matT, &_R1, &_R2, &_P1, &_P2, &matQ, flags );
+    double err = cvStereoCalibrate(&c_objPt, &c_imgPt, &c_imgPt2, &c_npoints, &c_cameraMatrix1,
+        &c_distCoeffs1, &c_cameraMatrix2, &c_distCoeffs2, imageSize,
+        &c_matR, &c_matT, p_matE, p_matF, criteria, flags );
+    
+    cameraMatrix1.copyTo(_cameraMatrix1);
+    cameraMatrix2.copyTo(_cameraMatrix2);
+    distCoeffs1.copyTo(_distCoeffs1);
+    distCoeffs2.copyTo(_distCoeffs2);
+    
+    return err;
 }
 
-void cv::stereoRectify( const Mat& cameraMatrix1, const Mat& distCoeffs1,
-                        const Mat& cameraMatrix2, const Mat& distCoeffs2,
-                        Size imageSize, const Mat& R, const Mat& T,
-                        Mat& R1, Mat& R2, Mat& P1, Mat& P2, Mat& Q,
+
+void cv::stereoRectify( const InputArray& _cameraMatrix1, const InputArray& _distCoeffs1,
+                        const InputArray& _cameraMatrix2, const InputArray& _distCoeffs2,
+                        Size imageSize, const InputArray& _Rmat, const InputArray& _Tmat,
+                        OutputArray _Rmat1, OutputArray _Rmat2,
+                        OutputArray _Pmat1, OutputArray _Pmat2,
+                        OutputArray _Qmat, int flags,
                         double alpha, Size newImageSize,
-                        Rect* validPixROI1, Rect* validPixROI2,
-                        int flags )
+                        Rect* validPixROI1, Rect* validPixROI2 )
 {
+    CvMat c_cameraMatrix1 = _cameraMatrix1.getMat();
+    CvMat c_cameraMatrix2 = _cameraMatrix2.getMat();
+    CvMat c_distCoeffs1 = _distCoeffs1.getMat();
+    CvMat c_distCoeffs2 = _distCoeffs2.getMat();
+    CvMat c_R = _Rmat.getMat(), c_T = _Tmat.getMat();
+    
     int rtype = CV_64F;
-    R1.create(3, 3, rtype);
-    R2.create(3, 3, rtype);
-    P1.create(3, 4, rtype);
-    P2.create(3, 4, rtype);
-    Q.create(4, 4, rtype);
-    CvMat _cameraMatrix1 = cameraMatrix1, _distCoeffs1 = distCoeffs1;
-    CvMat _cameraMatrix2 = cameraMatrix2, _distCoeffs2 = distCoeffs2;
-    CvMat matR = R, matT = T, _R1 = R1, _R2 = R2, _P1 = P1, _P2 = P2, matQ = Q;
-    cvStereoRectify( &_cameraMatrix1, &_cameraMatrix2, &_distCoeffs1, &_distCoeffs2,
-                    imageSize, &matR, &matT, &_R1, &_R2, &_P1, &_P2, &matQ, flags,
-                    alpha, newImageSize, (CvRect*)validPixROI1, (CvRect*)validPixROI2);
+    _Rmat1.create(3, 3, rtype);
+    _Rmat2.create(3, 3, rtype);
+    _Pmat1.create(3, 4, rtype);
+    _Pmat2.create(3, 4, rtype);
+    CvMat c_R1 = _Rmat1.getMat(), c_R2 = _Rmat2.getMat(), c_P1 = _Pmat1.getMat(), c_P2 = _Pmat2.getMat();
+    CvMat c_Q, *p_Q = 0;
+    
+    if( _Qmat.needed() )
+    {
+        _Qmat.create(4, 4, rtype);
+        p_Q = &(c_Q = _Qmat.getMat());
+    }
+    
+    cvStereoRectify( &c_cameraMatrix1, &c_cameraMatrix2, &c_distCoeffs1, &c_distCoeffs2,
+        imageSize, &c_R, &c_T, &c_R1, &c_R2, &c_P1, &c_P2, p_Q, flags, alpha,
+        newImageSize, (CvRect*)validPixROI1, (CvRect*)validPixROI2);
 }
 
-bool cv::stereoRectifyUncalibrated( const Mat& points1, const Mat& points2,
-                                    const Mat& F, Size imgSize,
-                                    Mat& H1, Mat& H2, double threshold )
+bool cv::stereoRectifyUncalibrated( const InputArray& _points1, const InputArray& _points2,
+                                    const InputArray& _Fmat, Size imgSize,
+                                    OutputArray _Hmat1, OutputArray _Hmat2, double threshold )
 {
     int rtype = CV_64F;
-    H1.create(3, 3, rtype);
-    H2.create(3, 3, rtype);
-    CvMat _pt1 = points1, _pt2 = points2, matF, *pF=0, _H1 = H1, _H2 = H2;
+    _Hmat1.create(3, 3, rtype);
+    _Hmat2.create(3, 3, rtype);
+    Mat F = _Fmat.getMat();
+    CvMat c_pt1 = _points1.getMat(), c_pt2 = _points2.getMat();
+    CvMat c_F, *p_F=0, c_H1 = _Hmat1.getMat(), c_H2 = _Hmat2.getMat();
     if( F.size() == Size(3, 3) )
-        pF = &(matF = F);
-    return cvStereoRectifyUncalibrated(&_pt1, &_pt2, pF, imgSize, &_H1, &_H2, threshold) > 0;
+        p_F = &(c_F = F);
+    return cvStereoRectifyUncalibrated(&c_pt1, &c_pt2, p_F, imgSize, &c_H1, &c_H2, threshold) > 0;
 }
 
-cv::Mat cv::getOptimalNewCameraMatrix( const Mat& cameraMatrix, const Mat& distCoeffs,
-                                   Size imgSize, double alpha, Size newImgSize,
-                                   Rect* validPixROI )
+cv::Mat cv::getOptimalNewCameraMatrix( const InputArray& _cameraMatrix,
+                                       const InputArray& _distCoeffs,
+                                       Size imgSize, double alpha, Size newImgSize,
+                                       Rect* validPixROI )
 {
-    Mat newCameraMatrix(3, 3, cameraMatrix.type());
-    CvMat _cameraMatrix = cameraMatrix,
-        _distCoeffs = distCoeffs,
-        _newCameraMatrix = newCameraMatrix;
-    cvGetOptimalNewCameraMatrix(&_cameraMatrix, &_distCoeffs, imgSize,
-                                alpha, &_newCameraMatrix,
+    CvMat c_cameraMatrix = _cameraMatrix.getMat(), c_distCoeffs = _distCoeffs.getMat();
+    
+    Mat newCameraMatrix(3, 3, CV_MAT_TYPE(c_cameraMatrix.type));
+    CvMat c_newCameraMatrix = newCameraMatrix;
+    
+    cvGetOptimalNewCameraMatrix(&c_cameraMatrix, &c_distCoeffs, imgSize,
+                                alpha, &c_newCameraMatrix,
                                 newImgSize, (CvRect*)validPixROI);
     return newCameraMatrix;
 }
 
 
-void cv::RQDecomp3x3( const Mat& M, Mat& R, Mat& Q )
+cv::Vec3d cv::RQDecomp3x3( const InputArray& _Mmat,
+                           OutputArray _Rmat,
+                           OutputArray _Qmat,
+                           OutputArray _Qx,
+                           OutputArray _Qy,
+                           OutputArray _Qz )
 {
-    R.create(3, 3, M.type());
-    Q.create(3, 3, M.type());
-
-    CvMat matM = M, matR = R, matQ = Q;
-    cvRQDecomp3x3(&matM, &matR, &matQ, 0, 0, 0, 0);
-}
-
-
-cv::Vec3d cv::RQDecomp3x3( const Mat& M, Mat& R, Mat& Q,
-                           Mat& Qx, Mat& Qy, Mat& Qz )
-{
-    R.create(3, 3, M.type());
-    Q.create(3, 3, M.type());
+    Mat M = _Mmat.getMat();
+    _Rmat.create(3, 3, M.type());
+    _Qmat.create(3, 3, M.type());
     Vec3d eulerAngles;
 
-    CvMat matM = M, matR = R, matQ = Q, _Qx = Qx, _Qy = Qy, _Qz = Qz;
-    cvRQDecomp3x3(&matM, &matR, &matQ, &_Qx, &_Qy, &_Qz, (CvPoint3D64f*)&eulerAngles[0]);
+    CvMat matM = M, matR = _Rmat.getMat(), matQ = _Qmat.getMat(), Qx, Qy, Qz, *pQx=0, *pQy=0, *pQz=0;
+    if( _Qx.needed() )
+    {
+        _Qx.create(3, 3, M.type());
+        pQx = &(Qx = _Qx.getMat());
+    }
+    if( _Qy.needed() )
+    {
+        _Qy.create(3, 3, M.type());
+        pQy = &(Qy = _Qy.getMat());
+    }
+    if( _Qz.needed() )
+    {
+        _Qz.create(3, 3, M.type());
+        pQz = &(Qz = _Qz.getMat());
+    }
+    cvRQDecomp3x3(&matM, &matR, &matQ, pQx, pQy, pQz, (CvPoint3D64f*)&eulerAngles[0]);
     return eulerAngles;
 }
 
 
-void cv::decomposeProjectionMatrix( const Mat& projMatrix, Mat& cameraMatrix,
-                                Mat& rotMatrix, Mat& transVect )
+void cv::decomposeProjectionMatrix( const InputArray& _projMatrix, OutputArray _cameraMatrix,
+                                    OutputArray _rotMatrix, OutputArray _transVect,
+                                    OutputArray _rotMatrixX, OutputArray _rotMatrixY,
+                                    OutputArray _rotMatrixZ, OutputArray _eulerAngles )
 {
+    Mat projMatrix = _projMatrix.getMat();
     int type = projMatrix.type();
-    cameraMatrix.create(3, 3, type);
-    rotMatrix.create(3, 3, type);
-    transVect.create(4, 1, type);
-    CvMat _projMatrix = projMatrix, _cameraMatrix = cameraMatrix;
-    CvMat _rotMatrix = rotMatrix, _transVect = transVect;
-    cvDecomposeProjectionMatrix(&_projMatrix, &_cameraMatrix, &_rotMatrix,
-                                &_transVect, 0, 0, 0, 0);
-}
-
-
-void cv::decomposeProjectionMatrix( const Mat& projMatrix, Mat& cameraMatrix,
-                                Mat& rotMatrix, Mat& transVect,
-                                Mat& rotMatrixX, Mat& rotMatrixY,
-                                Mat& rotMatrixZ, Vec3d& eulerAngles )
-{
-    int type = projMatrix.type();
-    cameraMatrix.create(3, 3, type);
-    rotMatrix.create(3, 3, type);
-    transVect.create(4, 1, type);
-    rotMatrixX.create(3, 3, type);
-    rotMatrixY.create(3, 3, type);
-    rotMatrixZ.create(3, 3, type);
-    CvMat _projMatrix = projMatrix, _cameraMatrix = cameraMatrix;
-    CvMat _rotMatrix = rotMatrix, _transVect = transVect;
-    CvMat _rotMatrixX = rotMatrixX, _rotMatrixY = rotMatrixY;
-    CvMat _rotMatrixZ = rotMatrixZ;
-    cvDecomposeProjectionMatrix(&_projMatrix, &_cameraMatrix, &_rotMatrix,
-                                &_transVect, &_rotMatrixX, &_rotMatrixY,
-                                &_rotMatrixZ, (CvPoint3D64f*)&eulerAngles[0]);
+    _cameraMatrix.create(3, 3, type);
+    _rotMatrix.create(3, 3, type);
+    _transVect.create(4, 1, type);
+    CvMat c_projMatrix = projMatrix, c_cameraMatrix = _cameraMatrix.getMat();
+    CvMat c_rotMatrix = _rotMatrix.getMat(), c_transVect = _transVect.getMat();
+    CvMat c_rotMatrixX, *p_rotMatrixX = 0;
+    CvMat c_rotMatrixY, *p_rotMatrixY = 0;
+    CvMat c_rotMatrixZ, *p_rotMatrixZ = 0;
+    CvPoint3D64f *p_eulerAngles = 0;
+    
+    if( _rotMatrixX.needed() )
+    {
+        _rotMatrixX.create(3, 3, type);
+        p_rotMatrixX = &(c_rotMatrixX = _rotMatrixX.getMat());
+    }
+    if( _rotMatrixY.needed() )
+    {
+        _rotMatrixY.create(3, 3, type);
+        p_rotMatrixY = &(c_rotMatrixY = _rotMatrixY.getMat());
+    }
+    if( _rotMatrixZ.needed() )
+    {
+        _rotMatrixZ.create(3, 3, type);
+        p_rotMatrixZ = &(c_rotMatrixZ = _rotMatrixZ.getMat());
+    }
+    if( _eulerAngles.needed() )
+    {
+        _eulerAngles.create(3, 1, CV_64F, -1, true);
+        p_eulerAngles = (CvPoint3D64f*)_eulerAngles.getMat().data;
+    }
+    
+    cvDecomposeProjectionMatrix(&c_projMatrix, &c_cameraMatrix, &c_rotMatrix,
+                                &c_transVect, p_rotMatrixX, p_rotMatrixY,
+                                p_rotMatrixZ, p_eulerAngles);
 }
 
 
 namespace cv
 {
     
-static void adjust3rdMatrix(const vector<vector<Point2f> >& imgpt1_0,
-                            const vector<vector<Point2f> >& imgpt3_0, 
+static void adjust3rdMatrix(const InputArrayOfArrays& _imgpt1_0,
+                            const InputArrayOfArrays& _imgpt3_0, 
                             const Mat& cameraMatrix1, const Mat& distCoeffs1,
                             const Mat& cameraMatrix3, const Mat& distCoeffs3,
                             const Mat& R1, const Mat& R3, const Mat& P1, Mat& P3 )
 {
+    size_t n1 = _imgpt1_0.total(), n3 = _imgpt3_0.total();
     vector<Point2f> imgpt1, imgpt3;
     
-    for( int i = 0; i < (int)std::min(imgpt1_0.size(), imgpt3_0.size()); i++ )
+    for( int i = 0; i < (int)std::min(n1, n3); i++ )
     {
-        if( !imgpt1_0[i].empty() && !imgpt3_0[i].empty() )
-        {
-            std::copy(imgpt1_0[i].begin(), imgpt1_0[i].end(), std::back_inserter(imgpt1));
-            std::copy(imgpt3_0[i].begin(), imgpt3_0[i].end(), std::back_inserter(imgpt3));
-        }
+        Mat pt1 = _imgpt1_0.getMat(i), pt3 = _imgpt3_0.getMat(i);
+        int ni1 = pt1.checkVector(2, CV_32F), ni3 = pt3.checkVector(2, CV_32F);
+        CV_Assert( ni1 > 0 && ni1 == ni3 );
+        const Point2f* pt1data = pt1.ptr<Point2f>();
+        const Point2f* pt3data = pt3.ptr<Point2f>();
+        std::copy(pt1data, pt1data + ni1, std::back_inserter(imgpt1));
+        std::copy(pt3data, pt3data + ni3, std::back_inserter(imgpt3));
     }
     
-    undistortPoints(Mat(imgpt1), imgpt1, cameraMatrix1, distCoeffs1, R1, P1);
-    undistortPoints(Mat(imgpt3), imgpt3, cameraMatrix3, distCoeffs3, R3, P3);
+    undistortPoints(imgpt1, imgpt1, cameraMatrix1, distCoeffs1, R1, P1);
+    undistortPoints(imgpt3, imgpt3, cameraMatrix3, distCoeffs3, R3, P3);
     
     double y1_ = 0, y2_ = 0, y1y1_ = 0, y1y2_ = 0;
     size_t n = imgpt1.size();
@@ -3555,20 +3642,31 @@ static void adjust3rdMatrix(const vector<vector<Point2f> >& imgpt1_0,
 
 }
 
-float cv::rectify3Collinear( const Mat& cameraMatrix1, const Mat& distCoeffs1,
-                   const Mat& cameraMatrix2, const Mat& distCoeffs2,
-                   const Mat& cameraMatrix3, const Mat& distCoeffs3,
-                   const vector<vector<Point2f> >& imgpt1,
-                   const vector<vector<Point2f> >& imgpt3,
-                   Size imageSize, const Mat& R12, const Mat& T12, const Mat& R13, const Mat& T13,
-                   Mat& R1, Mat& R2, Mat& R3, Mat& P1, Mat& P2, Mat& P3, Mat& Q,
+float cv::rectify3Collinear( const InputArray& _cameraMatrix1, const InputArray& _distCoeffs1,
+                   const InputArray& _cameraMatrix2, const InputArray& _distCoeffs2,
+                   const InputArray& _cameraMatrix3, const InputArray& _distCoeffs3,
+                   const InputArrayOfArrays& _imgpt1,
+                   const InputArrayOfArrays& _imgpt3,
+                   Size imageSize, const InputArray& _Rmat12, const InputArray& _Tmat12,
+                   const InputArray& _Rmat13, const InputArray& _Tmat13,
+                   OutputArray _Rmat1, OutputArray _Rmat2, OutputArray _Rmat3,
+                   OutputArray _Pmat1, OutputArray _Pmat2, OutputArray _Pmat3,
+                   OutputArray _Qmat,
                    double alpha, Size /*newImgSize*/,
                    Rect* roi1, Rect* roi2, int flags )
 {
     // first, rectify the 1-2 stereo pair
-    stereoRectify( cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2,
-                  imageSize, R12, T12, R1, R2, P1, P2, Q,
-                  alpha, imageSize, roi1, roi2, flags );
+    stereoRectify( _cameraMatrix1, _distCoeffs1, _cameraMatrix2, _distCoeffs2,
+                   imageSize, _Rmat12, _Tmat12, _Rmat1, _Rmat2, _Pmat1, _Pmat2, _Qmat,
+                   flags, alpha, imageSize, roi1, roi2 );
+    
+    Mat R12 = _Rmat12.getMat(), R13 = _Rmat13.getMat(), T12 = _Tmat12.getMat(), T13 = _Tmat13.getMat();
+    
+    _Rmat3.create(3, 3, CV_64F);
+    _Pmat3.create(3, 4, CV_64F);
+    
+    Mat P1 = _Pmat1.getMat(), P2 = _Pmat2.getMat();
+    Mat R3 = _Rmat3.getMat(), P3 = _Pmat3.getMat();
     
     // recompute rectification transforms for cameras 1 & 2.
     Mat om, r_r, r_r13;
@@ -3608,8 +3706,9 @@ float cv::rectify3Collinear( const Mat& cameraMatrix1, const Mat& distCoeffs1,
     P3.at<double>(0,3) *= P3.at<double>(0,0);
     P3.at<double>(1,3) *= P3.at<double>(1,1);
     
-    if( !imgpt1.empty() && imgpt3.empty() )
-        adjust3rdMatrix(imgpt1, imgpt3, cameraMatrix1, distCoeffs1, cameraMatrix3, distCoeffs3, R1, R3, P1, P3);
+    if( !_imgpt1.empty() && _imgpt3.empty() )
+        adjust3rdMatrix(_imgpt1, _imgpt3, _cameraMatrix1.getMat(), _distCoeffs1.getMat(),
+                        _cameraMatrix3.getMat(), _distCoeffs3.getMat(), _Rmat1.getMat(), R3, P1, P3);
     
     return (float)((P3.at<double>(idx,3)/P3.at<double>(idx,idx))/
                    (P2.at<double>(idx,3)/P2.at<double>(idx,idx)));
index 40e174b..42cd520 100644 (file)
@@ -280,9 +280,9 @@ void CirclesGridClusterFinder::rectifyPatternPoints(const cv::Size &patternSize,
 
   Mat homography = findHomography(Mat(sortedCorners), Mat(idealPoints), 0);
   Mat rectifiedPointsMat;
-  transform(Mat(patternPoints), rectifiedPointsMat, homography);
+  transform(patternPoints, rectifiedPointsMat, homography);
   rectifiedPatternPoints.clear();
-  convertPointsHomogeneous(rectifiedPointsMat, rectifiedPatternPoints);
+  convertPointsFromHomogeneous(rectifiedPointsMat, rectifiedPatternPoints);
 }
 
 void CirclesGridClusterFinder::parsePatternPoints(const cv::Size &patternSize, const std::vector<cv::Point2f> &patternPoints, const std::vector<cv::Point2f> &rectifiedPatternPoints, std::vector<cv::Point2f> &centers)
@@ -727,7 +727,7 @@ Mat CirclesGridFinder::rectifyGrid(Size detectedGridSize, const vector<Point2f>&
   Mat dstKeypointsMat;
   transform(Mat(srcKeypoints), dstKeypointsMat, H);
   vector<Point2f> dstKeypoints;
-  convertPointsHomogeneous(dstKeypointsMat, dstKeypoints);
+  convertPointsFromHomogeneous(dstKeypointsMat, dstKeypoints);
 
   warpedKeypoints.clear();
   for (size_t i = 0; i < dstKeypoints.size(); i++)
@@ -969,7 +969,7 @@ void CirclesGridFinder::findBasis(const vector<Point2f> &samples, vector<Point2f
   Mat centers;
   const int clustersCount = 4;
   kmeans(Mat(samples).reshape(1, 0), clustersCount, bestLabels, termCriteria, parameters.kmeansAttempts,
-         KMEANS_RANDOM_CENTERS, &centers);
+         KMEANS_RANDOM_CENTERS, centers);
   assert( centers.type() == CV_32FC1 );
 
   vector<int> basisIndices;
index 41e648f..fab93bf 100644 (file)
@@ -1044,114 +1044,95 @@ CV_IMPL void cvConvertPointsHomogeneous( const CvMat* src, CvMat* dst )
     }
 }
 
-namespace cv
+cv::Mat cv::findHomography( const InputArray& _points1, const InputArray& _points2,
+                            int method, double ransacReprojThreshold, OutputArray _mask )
 {
-
-static Mat _findHomography( const Mat& points1, const Mat& points2,
-                            int method, double ransacReprojThreshold,
-                            vector<uchar>* mask )
-{
-    CV_Assert(points1.isContinuous() && points2.isContinuous() &&
-              points1.type() == points2.type() &&
-              ((points1.rows == 1 && points1.channels() == 2) ||
-               points1.cols*points1.channels() == 2) &&
-              ((points2.rows == 1 && points2.channels() == 2) ||
-               points2.cols*points2.channels() == 2));
+    Mat points1 = _points1.getMat(), points2 = _points2.getMat();
+    int npoints = points1.checkVector(2);
+    CV_Assert( npoints >= 0 && points2.checkVector(2) == npoints &&
+               points1.type() == points2.type());
     
     Mat H(3, 3, CV_64F);
-    CvMat _pt1 = Mat(points1), _pt2 = Mat(points2);
-    CvMat matH = H, _mask, *pmask = 0;
-    if( mask )
+    CvMat _pt1 = points1, _pt2 = points2;
+    CvMat matH = H, c_mask, *p_mask = 0;
+    if( _mask.needed() )
     {
-        mask->resize(points1.cols*points1.rows*points1.channels()/2);
-        pmask = &(_mask = cvMat(1, (int)mask->size(), CV_8U, (void*)&(*mask)[0]));
+        _mask.create(npoints, 1, CV_8U, -1, true);
+        p_mask = &(c_mask = _mask.getMat());
     }
-    bool ok = cvFindHomography( &_pt1, &_pt2, &matH, method, ransacReprojThreshold, pmask ) > 0;
+    bool ok = cvFindHomography( &_pt1, &_pt2, &matH, method, ransacReprojThreshold, p_mask ) > 0;
     if( !ok )
         H = Scalar(0);
     return H;
 }
     
-static Mat _findFundamentalMat( const Mat& points1, const Mat& points2,
+cv::Mat cv::findFundamentalMat( const InputArray& _points1, const InputArray& _points2,
                                int method, double param1, double param2,
-                               vector<uchar>* mask )
+                               OutputArray _mask )
 {
-    CV_Assert(points1.checkVector(2) >= 0 && points2.checkVector(2) >= 0 &&
-              (points1.depth() == CV_32F || points1.depth() == CV_32S) &&
-              points1.depth() == points2.depth());
+    Mat points1 = _points1.getMat(), points2 = _points2.getMat();
+    int npoints = points1.checkVector(2);
+    CV_Assert( npoints >= 0 && points2.checkVector(2) == npoints &&
+              points1.type() == points2.type());
     
     Mat F(3, 3, CV_64F);
-    CvMat _pt1 = Mat(points1), _pt2 = Mat(points2);
-    CvMat matF = F, _mask, *pmask = 0;
-    if( mask )
+    CvMat _pt1 = points1, _pt2 = points2;
+    CvMat matF = F, c_mask, *p_mask = 0;
+    if( _mask.needed() )
     {
-        mask->resize(points1.cols*points1.rows*points1.channels()/2);
-        pmask = &(_mask = cvMat(1, (int)mask->size(), CV_8U, (void*)&(*mask)[0]));
+        _mask.create(npoints, 1, CV_8U, -1, true);
+        p_mask = &(c_mask = _mask.getMat());
     }
-    int n = cvFindFundamentalMat( &_pt1, &_pt2, &matF, method, param1, param2, pmask );
+    int n = cvFindFundamentalMat( &_pt1, &_pt2, &matF, method, param1, param2, p_mask );
     if( n <= 0 )
         F = Scalar(0);
     return F;
 }
-    
-}    
-
-
-cv::Mat cv::findHomography( const Mat& srcPoints, const Mat& dstPoints,
-                            vector<uchar>& mask, int method,
-                            double ransacReprojThreshold )
-{
-    return _findHomography(srcPoints, dstPoints, method, ransacReprojThreshold, &mask);
-}
 
-cv::Mat cv::findHomography( const Mat& srcPoints, const Mat& dstPoints,
-                            int method, double ransacReprojThreshold )
+void cv::computeCorrespondEpilines( const InputArray& _points, int whichImage,
+                                    const InputArray& _Fmat, OutputArray _lines )
 {
-    return _findHomography(srcPoints, dstPoints, method, ransacReprojThreshold, 0);
-}
-
+    Mat points = _points.getMat();
+    int npoints = points.checkVector(2);
+    CV_Assert( npoints >= 0 && (points.depth() == CV_32F || points.depth() == CV_32S));
     
-cv::Mat cv::findFundamentalMat( const Mat& points1, const Mat& points2,
-                                vector<uchar>& mask, int method, double param1, double param2 )
-{
-    return _findFundamentalMat( points1, points2, method, param1, param2, &mask );
+    _lines.create(npoints, 1, CV_32FC3, -1, true);
+    CvMat c_points = points, c_lines = _lines.getMat(), c_F = _Fmat.getMat();
+    cvComputeCorrespondEpilines(&c_points, whichImage, &c_F, &c_lines);
 }
 
-cv::Mat cv::findFundamentalMat( const Mat& points1, const Mat& points2,
-                                int method, double param1, double param2 )
+void cv::convertPointsFromHomogeneous( const InputArray& _src, OutputArray _dst )
 {
-    return _findFundamentalMat( points1, points2, method, param1, param2, 0 );
-}
-
-void cv::computeCorrespondEpilines( const Mat& points, int whichImage,
-                                    const Mat& F, vector<Vec3f>& lines )
-{
-    CV_Assert(points.checkVector(2) >= 0 &&
-              (points.depth() == CV_32F || points.depth() == CV_32S));
-    
-    lines.resize(points.cols*points.rows*points.channels()/2);
-    CvMat _points = points, _lines = Mat(lines), matF = F;
-    cvComputeCorrespondEpilines(&_points, whichImage, &matF, &_lines);
-}
-
-void cv::convertPointsHomogeneous( const Mat& src, vector<Point3f>& dst )
-{
-    int srccn = src.checkVector(2) >= 0 ? 2 : src.checkVector(4) >= 0 ? 4 : -1;
-    CV_Assert( srccn > 0 && (src.depth() == CV_32F || src.depth() == CV_32S));
+    Mat src = _src.getMat();
+    int npoints = src.checkVector(3), cn = 3;
+    if( npoints < 0 )
+    {
+        npoints = src.checkVector(4);
+        if( npoints >= 0 )
+            cn = 4;
+    }
+    CV_Assert( npoints >= 0 && (src.depth() == CV_32F || src.depth() == CV_32S));
     
-    dst.resize(src.cols*src.rows*src.channels()/srccn);
-    CvMat _src = src, _dst = Mat(dst);
-    cvConvertPointsHomogeneous(&_src, &_dst);
+    _dst.create(npoints, 1, CV_MAKETYPE(CV_32F, cn-1));
+    CvMat c_src = src, c_dst = _dst.getMat();
+    cvConvertPointsHomogeneous(&c_src, &c_dst);
 }
 
-void cv::convertPointsHomogeneous( const Mat& src, vector<Point2f>& dst )
+void cv::convertPointsToHomogeneous( const InputArray& _src, OutputArray _dst )
 {
-    CV_Assert(src.checkVector(3) >= 0 &&
-              (src.depth() == CV_32F || src.depth() == CV_32S));
+    Mat src = _src.getMat();
+    int npoints = src.checkVector(2), cn = 2;
+    if( npoints < 0 )
+    {
+        npoints = src.checkVector(3);
+        if( npoints >= 0 )
+            cn = 3;
+    }
+    CV_Assert( npoints >= 0 && (src.depth() == CV_32F || src.depth() == CV_32S));
     
-    dst.resize(src.cols*src.rows*src.channels()/3);
-    CvMat _src = Mat(src), _dst = Mat(dst);
-    cvConvertPointsHomogeneous(&_src, &_dst);
+    _dst.create(npoints, 1, CV_MAKETYPE(CV_32F, cn+1));
+    CvMat c_src = src, c_dst = _dst.getMat();
+    cvConvertPointsHomogeneous(&c_src, &c_dst);
 }
 
 /* End of file. */
index c21a071..33f451c 100644 (file)
@@ -452,34 +452,34 @@ bool cv::Affine3DEstimator::checkSubset( const CvMat* ms1, int count )
     return j == i;
 }
 
-int cv::estimateAffine3D(const Mat& from, const Mat& to, Mat& out, vector<uchar>& outliers, double param1, double param2)
+int cv::estimateAffine3D(const InputArray& _from, const InputArray& _to,
+                         OutputArray _out, OutputArray _outliers,
+                         double param1, double param2)
 {
-    int count = from.cols*from.rows*from.channels()/3;
+    Mat from = _from.getMat(), to = _to.getMat();
+    int count = from.checkVector(3, CV_32F);
     
-    CV_Assert( count >= 4 && from.isContinuous() && to.isContinuous() &&
-               from.depth() == CV_32F && to.depth() == CV_32F &&
-               ((from.rows == 1 && from.channels() == 3) || from.cols*from.channels() == 3) &&
-               ((to.rows == 1 && to.channels() == 3) || to.cols*to.channels() == 3) &&
-               count == to.cols*to.rows*to.channels()/3);
+    CV_Assert( count >= 0 && to.checkVector(3, CV_32F) == count );
 
-    out.create(3, 4, CV_64F); 
-    outliers.resize(count);
-    fill(outliers.begin(), outliers.end(), (uchar)1);
-
-    vector<Point3d> dFrom;
-    vector<Point3d> dTo;    
+    _out.create(3, 4, CV_64F);
+    Mat out = _out.getMat();
+    
+    _outliers.create(count, 1, CV_8U, -1, true);
+    Mat outliers = _outliers.getMat();
+    outliers = Scalar::all(1);
 
-    copy(from.ptr<Point3f>(), from.ptr<Point3f>() + count, back_inserter(dFrom));
-    copy(to.ptr<Point3f>(), to.ptr<Point3f>() + count, back_inserter(dTo));
+    Mat dFrom, dTo;
+    from.convertTo(dFrom, CV_64F);
+    to.convertTo(dTo, CV_64F);
     
     CvMat F3x4 = out;
-    CvMat mask  = cvMat( 1, count, CV_8U, &outliers[0] );           
-    CvMat m1 = cvMat( 1, count, CV_64FC3, &dFrom[0] );    
-    CvMat m2 = cvMat( 1, count, CV_64FC3, &dTo[0] );
+    CvMat mask  = outliers;
+    CvMat m1 = dFrom;
+    CvMat m2 = dTo;
     
     const double epsilon = numeric_limits<double>::epsilon();        
     param1 = param1 <= 0 ? 3 : param1;
     param2 = (param2 < epsilon) ? 0.99 : (param2 > 1 - epsilon) ? 0.99 : param2;
             
-    return Affine3DEstimator().runRANSAC(&m1,m2, &F3x4, &mask, param1, param2 );    
+    return Affine3DEstimator().runRANSAC(&m1, &m2, &F3x4, &mask, param1, param2 );    
 }
index d995bf7..bd32d64 100644 (file)
@@ -223,9 +223,15 @@ int segment_hist_max(const Mat& hist, int& low_thresh, int& high_thresh)
         return 1;
     }
 }
+}
     
-bool find4QuadCornerSubpix(const Mat& img, std::vector<Point2f>& corners, Size region_size)
+bool cv::find4QuadCornerSubpix(const InputArray& _img, InputOutputArray _corners, Size region_size)
 {
+    Mat img = _img.getMat(), cornersM = _corners.getMat();
+    int ncorners = cornersM.checkVector(2, CV_32F);
+    CV_Assert( ncorners >= 0 );
+    Point2f* corners = cornersM.ptr<Point2f>();
     const int nbins = 256;
     float ranges[] = {0, 256};
     const float* _ranges = ranges;
@@ -238,7 +244,7 @@ bool find4QuadCornerSubpix(const Mat& img, std::vector<Point2f>& corners, Size r
     
     
     Mat black_comp, white_comp;
-    for(size_t i = 0; i < corners.size(); i++)
+    for(int i = 0; i < ncorners; i++)
     {        
         int channels = 0;
         Rect roi(cvRound(corners[i].x - region_size.width), cvRound(corners[i].y - region_size.height),
@@ -362,5 +368,3 @@ bool find4QuadCornerSubpix(const Mat& img, std::vector<Point2f>& corners, Size r
     
     return true;
 }
-    
-}; // namespace std
index ab0ed91..c121892 100644 (file)
 /*M///////////////////////////////////////////////////////////////////////////////////////
-//
-//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
-//
-//  By downloading, copying, installing or using the software you agree to this license.
-//  If you do not agree to this license, do not download, install,
-//  copy or use the software.
-//
-//
-//                           License Agreement
-//                For Open Source Computer Vision Library
-//
-// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
-// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
-// Third party copyrights are property of their respective owners.
-//
-// Redistribution and use in source and binary forms, with or without modification,
-// are permitted provided that the following conditions are met:
-//
-//   * Redistribution's of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//
-//   * Redistribution's in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//
-//   * The name of the copyright holders may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// This software is provided by the copyright holders and contributors "as is" and
-// any express or implied warranties, including, but not limited to, the implied
-// warranties of merchantability and fitness for a particular purpose are disclaimed.
-// In no event shall the Intel Corporation or contributors be liable for any direct,
-// indirect, incidental, special, exemplary, or consequential damages
-// (including, but not limited to, procurement of substitute goods or services;
-// loss of use, data, or profits; or business interruption) however caused
-// and on any theory of liability, whether in contract, strict liability,
-// or tort (including negligence or otherwise) arising in any way out of
-// the use of this software, even if advised of the possibility of such damage.
-//
-//M*/
+ //
+ //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+ //
+ //  By downloading, copying, installing or using the software you agree to this license.
+ //  If you do not agree to this license, do not download, install,
+ //  copy or use the software.
+ //
+ //
+ //                           License Agreement
+ //                For Open Source Computer Vision Library
+ //
+ // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+ // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+ // Third party copyrights are property of their respective owners.
+ //
+ // Redistribution and use in source and binary forms, with or without modification,
+ // are permitted provided that the following conditions are met:
+ //
+ //   * Redistribution's of source code must retain the above copyright notice,
+ //     this list of conditions and the following disclaimer.
+ //
+ //   * Redistribution's in binary form must reproduce the above copyright notice,
+ //     this list of conditions and the following disclaimer in the documentation
+ //     and/or other materials provided with the distribution.
+ //
+ //   * The name of the copyright holders may not be used to endorse or promote products
+ //     derived from this software without specific prior written permission.
+ //
+ // This software is provided by the copyright holders and contributors "as is" and
+ // any express or implied warranties, including, but not limited to, the implied
+ // warranties of merchantability and fitness for a particular purpose are disclaimed.
+ // In no event shall the Intel Corporation or contributors be liable for any direct,
+ // indirect, incidental, special, exemplary, or consequential damages
+ // (including, but not limited to, procurement of substitute goods or services;
+ // loss of use, data, or profits; or business interruption) however caused
+ // and on any theory of liability, whether in contract, strict liability,
+ // or tort (including negligence or otherwise) arising in any way out of
+ // the use of this software, even if advised of the possibility of such damage.
+ //
+ //M*/
 
 #include "precomp.hpp"
 using namespace cv;
 
-void cv::solvePnP( const Mat& opoints, const Mat& ipoints,
-                   const Mat& cameraMatrix, const Mat& distCoeffs,
-                   Mat& rvec, Mat& tvec, bool useExtrinsicGuess )
+void cv::solvePnP( const InputArray& _opoints, const InputArray& _ipoints,
+                  const InputArray& _cameraMatrix, const InputArray& _distCoeffs,
+                  OutputArray _rvec, OutputArray _tvec, bool useExtrinsicGuess )
 {
-    CV_Assert(opoints.isContinuous() && opoints.depth() == CV_32F &&
-              ((opoints.rows == 1 && opoints.channels() == 3) ||
-               opoints.cols*opoints.channels() == 3) &&
-              ipoints.isContinuous() && ipoints.depth() == CV_32F &&
-              ((ipoints.rows == 1 && ipoints.channels() == 2) ||
-              ipoints.cols*ipoints.channels() == 2));
-
-    rvec.create(3, 1, CV_64F);
-    tvec.create(3, 1, CV_64F);
-    CvMat _objectPoints = opoints, _imagePoints = ipoints;
-    CvMat _cameraMatrix = cameraMatrix, _distCoeffs = distCoeffs;
-    CvMat _rvec = rvec, _tvec = tvec;
-    cvFindExtrinsicCameraParams2(&_objectPoints, &_imagePoints, &_cameraMatrix,
-                                 distCoeffs.data ? &_distCoeffs : 0,
-                                 &_rvec, &_tvec, useExtrinsicGuess );
+    Mat opoints = _opoints.getMat(), ipoints = _ipoints.getMat();
+    int npoints = opoints.checkVector(3, CV_32F);
+    CV_Assert( npoints >= 0 && npoints == ipoints.checkVector(2, CV_32F) );
+    
+    _rvec.create(3, 1, CV_64F);
+    _tvec.create(3, 1, CV_64F);
+    CvMat c_objectPoints = opoints, c_imagePoints = ipoints;
+    CvMat c_cameraMatrix = _cameraMatrix.getMat(), c_distCoeffs = _distCoeffs.getMat();
+    CvMat c_rvec = _rvec.getMat(), c_tvec = _tvec.getMat();
+    cvFindExtrinsicCameraParams2(&c_objectPoints, &c_imagePoints, &c_cameraMatrix,
+                                 c_distCoeffs.rows*c_distCoeffs.cols ? &c_distCoeffs : 0,
+                                 &c_rvec, &c_tvec, useExtrinsicGuess );
 }
 
 namespace cv
 {
-  namespace pnpransac
-  {
-    const int MIN_POINTS_COUNT = 4;
-
-    void project3dPoints(const Mat& points, const Mat& rvec, const Mat& tvec, Mat& modif_points)
-    {
-      modif_points.create(1, points.cols, CV_32FC3);
-      Mat R(3, 3, CV_64FC1);
-      Rodrigues(rvec, R);
-      Mat transformation(3, 4, CV_64F);
-      Mat r = transformation.colRange(0, 2);
-      R.copyTo(r);
-      Mat t = transformation.colRange(3, 4);
-      tvec.copyTo(t);
-      transform(points, modif_points, transformation);
-    }
-
-    class Mutex
+    namespace pnpransac
     {
-    public:
-        Mutex() {}
-        void lock()
+        const int MIN_POINTS_COUNT = 4;
+        
+        void project3dPoints(const Mat& points, const Mat& rvec, const Mat& tvec, Mat& modif_points)
         {
-        #ifdef HAVE_TBB
-          slock.acquire(resultsMutex);
-        #endif
+            modif_points.create(1, points.cols, CV_32FC3);
+            Mat R(3, 3, CV_64FC1);
+            Rodrigues(rvec, R);
+            Mat transformation(3, 4, CV_64F);
+            Mat r = transformation.colRange(0, 2);
+            R.copyTo(r);
+            Mat t = transformation.colRange(3, 4);
+            tvec.copyTo(t);
+            transform(points, modif_points, transformation);
         }
-
-        void unlock()
+        
+        class Mutex
         {
-        #ifdef HAVE_TBB
-          slock.release();
-        #endif
-        }
-
-    private:
-    #ifdef HAVE_TBB
-      tbb::mutex resultsMutex;
-      tbb::mutex::scoped_lock slock;
-    #endif
-    };
-
-    struct CameraParameters
-    {
-        void init(Mat _intrinsics, Mat _distCoeffs)
-        {
-            _intrinsics.copyTo(intrinsics);
-            _distCoeffs.copyTo(distortion);
-        }
-
-        Mat intrinsics;
-        Mat distortion;
-    };
-
-    struct Parameters
-    {
-        int iterationsCount;
-        float reprojectionError;
-        int minInliersCount;
-        bool useExtrinsicGuess;
-        CameraParameters camera;
-    };
-
-    void pnpTask(const vector<char>& pointsMask, const Mat& objectPoints, const Mat& imagePoints,
-                 const Parameters& params, vector<int>& inliers, Mat& rvec, Mat& tvec,
-                 const Mat& rvecInit, const Mat& tvecInit, Mutex& resultsMutex)
-    {
-      Mat modelObjectPoints(1, MIN_POINTS_COUNT, CV_32FC3), modelImagePoints(1, MIN_POINTS_COUNT, CV_32FC2);
-      for (size_t i = 0, colIndex = 0; i < pointsMask.size(); i++)
-      {
-        if (pointsMask[i])
-        {
-          Mat colModelImagePoints = modelImagePoints(Rect(colIndex, 0, 1, 1));
-          imagePoints.col(i).copyTo(colModelImagePoints);
-          Mat colModelObjectPoints = modelObjectPoints(Rect(colIndex, 0, 1, 1));
-          objectPoints.col(i).copyTo(colModelObjectPoints);
-          colIndex = colIndex+1;
-        }
-      }
-
-      //filter same 3d points, hang in solvePnP
-      double eps = 1e-10;
-      int num_same_points = 0;
-      for (int i = 0; i < MIN_POINTS_COUNT; i++)
-        for (int j = i + 1; j < MIN_POINTS_COUNT; j++)
+        public:
+            Mutex() {}
+            void lock()
+            {
+#ifdef HAVE_TBB
+                slock.acquire(resultsMutex);
+#endif
+            }
+            
+            void unlock()
+            {
+#ifdef HAVE_TBB
+                slock.release();
+#endif
+            }
+            
+        private:
+#ifdef HAVE_TBB
+            tbb::mutex resultsMutex;
+            tbb::mutex::scoped_lock slock;
+#endif
+        };
+        
+        struct CameraParameters
         {
-          if (norm(modelObjectPoints.at<Vec3f>(0, i) - modelObjectPoints.at<Vec3f>(0, j)) < eps)
-            num_same_points++;
-        }
-      if (num_same_points > 0)
-        return;
-
-      Mat localRvec, localTvec;
-      rvecInit.copyTo(localRvec);
-      tvecInit.copyTo(localTvec);
-
-      solvePnP(modelObjectPoints, modelImagePoints, params.camera.intrinsics, params.camera.distortion, localRvec, localTvec, params.useExtrinsicGuess);
-
-      vector<Point2f> projected_points;
-      projected_points.resize(objectPoints.cols);
-      projectPoints(objectPoints, localRvec, localTvec, params.camera.intrinsics, params.camera.distortion, projected_points);
-
-      Mat rotatedPoints;
-      project3dPoints(objectPoints, localRvec, localTvec, rotatedPoints);
-
-      vector<int> localInliers;
-      for (size_t i = 0; i < objectPoints.cols; i++)
-      {
-        Point2f p(imagePoints.at<Vec2f>(0, i)[0], imagePoints.at<Vec2f>(0, i)[1]);
-        if ((norm(p - projected_points[i]) < params.reprojectionError)
-            && (rotatedPoints.at<Vec3f>(0, i)[2] > 0)) //hack
+            void init(Mat _intrinsics, Mat _distCoeffs)
+            {
+                _intrinsics.copyTo(intrinsics);
+                _distCoeffs.copyTo(distortion);
+            }
+            
+            Mat intrinsics;
+            Mat distortion;
+        };
+        
+        struct Parameters
         {
-          localInliers.push_back(i);
-        }
-      }
-
-      if (localInliers.size() > inliers.size())
-      {
-        resultsMutex.lock();
-
-        inliers.clear();
-        inliers.resize(localInliers.size());
-        memcpy(&inliers[0], &localInliers[0], sizeof(int) * localInliers.size());
-        localRvec.copyTo(rvec);
-        localTvec.copyTo(tvec);
-
-        resultsMutex.unlock();
-      }
-    }
-
-    class PnPSolver
-    {
-    public:
-        void operator()( const BlockedRange& r ) const
+            int iterationsCount;
+            float reprojectionError;
+            int minInliersCount;
+            bool useExtrinsicGuess;
+            CameraParameters camera;
+        };
+        
+        void pnpTask(const vector<char>& pointsMask, const Mat& objectPoints, const Mat& imagePoints,
+                     const Parameters& params, vector<int>& inliers, Mat& rvec, Mat& tvec,
+                     const Mat& rvecInit, const Mat& tvecInit, Mutex& resultsMutex)
         {
-            vector<char> pointsMask(objectPoints.cols, 0);
-            memset(&pointsMask[0], 1, MIN_POINTS_COUNT );
-            for( size_t i=r.begin(); i!=r.end(); ++i )
+            Mat modelObjectPoints(1, MIN_POINTS_COUNT, CV_32FC3), modelImagePoints(1, MIN_POINTS_COUNT, CV_32FC2);
+            for (size_t i = 0, colIndex = 0; i < pointsMask.size(); i++)
+            {
+                if (pointsMask[i])
+                {
+                    Mat colModelImagePoints = modelImagePoints(Rect(colIndex, 0, 1, 1));
+                    imagePoints.col(i).copyTo(colModelImagePoints);
+                    Mat colModelObjectPoints = modelObjectPoints(Rect(colIndex, 0, 1, 1));
+                    objectPoints.col(i).copyTo(colModelObjectPoints);
+                    colIndex = colIndex+1;
+                }
+            }
+            
+            //filter same 3d points, hang in solvePnP
+            double eps = 1e-10;
+            int num_same_points = 0;
+            for (int i = 0; i < MIN_POINTS_COUNT; i++)
+                for (int j = i + 1; j < MIN_POINTS_COUNT; j++)
+                {
+                    if (norm(modelObjectPoints.at<Vec3f>(0, i) - modelObjectPoints.at<Vec3f>(0, j)) < eps)
+                        num_same_points++;
+                }
+            if (num_same_points > 0)
+                return;
+            
+            Mat localRvec, localTvec;
+            rvecInit.copyTo(localRvec);
+            tvecInit.copyTo(localTvec);
+            
+            solvePnP(modelObjectPoints, modelImagePoints, params.camera.intrinsics, params.camera.distortion, localRvec, localTvec, params.useExtrinsicGuess);
+            
+            vector<Point2f> projected_points;
+            projected_points.resize(objectPoints.cols);
+            projectPoints(objectPoints, localRvec, localTvec, params.camera.intrinsics, params.camera.distortion, projected_points);
+            
+            Mat rotatedPoints;
+            project3dPoints(objectPoints, localRvec, localTvec, rotatedPoints);
+            
+            vector<int> localInliers;
+            for (int i = 0; i < objectPoints.cols; i++)
+            {
+                Point2f p(imagePoints.at<Vec2f>(0, i)[0], imagePoints.at<Vec2f>(0, i)[1]);
+                if ((norm(p - projected_points[i]) < params.reprojectionError)
+                    && (rotatedPoints.at<Vec3f>(0, i)[2] > 0)) //hack
+                {
+                    localInliers.push_back(i);
+                }
+            }
+            
+            if (localInliers.size() > inliers.size())
             {
-               generateVar(pointsMask);
-               pnpTask(pointsMask, objectPoints, imagePoints, parameters,
-                       inliers, rvec, tvec, initRvec, initTvec, syncMutex);
-               if ((int)inliers.size() > parameters.minInliersCount)
-               {
-                    #ifdef HAVE_TBB
-                      tbb::task::self().cancel_group_execution();
-                    #else
-                      break;
-                     #endif
-               }
+                resultsMutex.lock();
+                
+                inliers.clear();
+                inliers.resize(localInliers.size());
+                memcpy(&inliers[0], &localInliers[0], sizeof(int) * localInliers.size());
+                localRvec.copyTo(rvec);
+                localTvec.copyTo(tvec);
+                
+                resultsMutex.unlock();
             }
         }
-        PnPSolver(const Mat& objectPoints, const Mat& imagePoints, const Parameters& parameters,
-                  Mat& rvec, Mat& tvec, vector<int>& inliers):
-                    objectPoints(objectPoints), imagePoints(imagePoints), parameters(parameters),
-                    rvec(rvec), tvec(tvec), inliers(inliers)
+        
+        class PnPSolver
         {
-          rvec.copyTo(initRvec);
-          tvec.copyTo(initTvec);
-        }
-    private:
-        const Mat& objectPoints;
-        const Mat& imagePoints;
-        const Parameters& parameters;
-        vector<int>& inliers;
-        Mat &rvec, &tvec;
-        Mat initRvec, initTvec;
-
-        static RNG generator;
-        static Mutex syncMutex;
-
-        void generateVar(vector<char>& mask) const
-        {
-          size_t size = mask.size();
-          for (size_t i = 0; i < size; i++)
-          {
-                int i1 = generator.uniform(0, size);
-                int i2 = generator.uniform(0, size);
-                char curr = mask[i1];
-                mask[i1] = mask[i2];
-                mask[i2] = curr;
-          }
-        }
-    };
-
-    Mutex PnPSolver::syncMutex;
-    RNG PnPSolver::generator;
-
-  }
+        public:
+            void operator()( const BlockedRange& r ) const
+            {
+                vector<char> pointsMask(objectPoints.cols, 0);
+                memset(&pointsMask[0], 1, MIN_POINTS_COUNT );
+                for( int i=r.begin(); i!=r.end(); ++i )
+                {
+                    generateVar(pointsMask);
+                    pnpTask(pointsMask, objectPoints, imagePoints, parameters,
+                            inliers, rvec, tvec, initRvec, initTvec, syncMutex);
+                    if ((int)inliers.size() > parameters.minInliersCount)
+                    {
+#ifdef HAVE_TBB
+                        tbb::task::self().cancel_group_execution();
+#else
+                        break;
+#endif
+                    }
+                }
+            }
+            PnPSolver(const Mat& objectPoints, const Mat& imagePoints, const Parameters& parameters,
+                      Mat& rvec, Mat& tvec, vector<int>& inliers):
+            objectPoints(objectPoints), imagePoints(imagePoints), parameters(parameters),
+            rvec(rvec), tvec(tvec), inliers(inliers)
+            {
+                rvec.copyTo(initRvec);
+                tvec.copyTo(initTvec);
+            }
+        private:
+            const Mat& objectPoints;
+            const Mat& imagePoints;
+            const Parameters& parameters;
+            Mat &rvec, &tvec;
+            vector<int>& inliers;
+            Mat initRvec, initTvec;
+            
+            static RNG generator;
+            static Mutex syncMutex;
+            
+            void generateVar(vector<char>& mask) const
+            {
+                size_t size = mask.size();
+                for (size_t i = 0; i < size; i++)
+                {
+                    int i1 = generator.uniform(0, size);
+                    int i2 = generator.uniform(0, size);
+                    char curr = mask[i1];
+                    mask[i1] = mask[i2];
+                    mask[i2] = curr;
+                }
+            }
+        };
+        
+        Mutex PnPSolver::syncMutex;
+        RNG PnPSolver::generator;
+        
+    }
 }
 
-void cv::solvePnPRansac(const Mat& opoints, const Mat& ipoints,
-                    const Mat& cameraMatrix, const Mat& distCoeffs, Mat& rvec, Mat& tvec, bool useExtrinsicGuess,
-                    int iterationsCount, float reprojectionError, int minInliersCount, vector<int>* inliers)
+void cv::solvePnPRansac(const InputArray& _opoints, const InputArray& _ipoints,
+                        const InputArray& _cameraMatrix, const InputArray& _distCoeffs,
+                        OutputArray _rvec, OutputArray _tvec, bool useExtrinsicGuess,
+                        int iterationsCount, float reprojectionError, int minInliersCount,
+                        OutputArray _inliers)
 {
-
-  CV_Assert(opoints.isContinuous());
-  CV_Assert(opoints.depth() == CV_32F);
-  CV_Assert((opoints.rows == 1 && opoints.channels() == 3) || opoints.cols*opoints.channels() == 3);
-  CV_Assert(ipoints.isContinuous());
-  CV_Assert(ipoints.depth() == CV_32F);
-  CV_Assert((ipoints.rows == 1 && ipoints.channels() == 2) || ipoints.cols*ipoints.channels() == 2);
-
-  rvec.create(3, 1, CV_64FC1);
-  tvec.create(3, 1, CV_64FC1);
-
-  Mat objectPoints = opoints.reshape(3, 1), imagePoints = ipoints.reshape(2, 1);
-
-  if (minInliersCount <= 0)
-    minInliersCount = objectPoints.cols;
-  cv::pnpransac::Parameters params;
-  params.iterationsCount = iterationsCount;
-  params.minInliersCount = minInliersCount;
-  params.reprojectionError = reprojectionError;
-  params.useExtrinsicGuess = useExtrinsicGuess;
-  params.camera.init(cameraMatrix, distCoeffs);
-
-  vector<int> localInliers;
-  Mat localRvec, localTvec;
-  rvec.copyTo(localRvec);
-  tvec.copyTo(localTvec);
-
-  if (objectPoints.cols >= pnpransac::MIN_POINTS_COUNT)
-  {
-     parallel_for(BlockedRange(0,iterationsCount), cv::pnpransac::PnPSolver(objectPoints, imagePoints, params,
-        localRvec, localTvec, localInliers));
-  }
-
-  if (localInliers.size() >= pnpransac::MIN_POINTS_COUNT)
-  {
-    size_t pointsCount = localInliers.size();
-    Mat inlierObjectPoints(1, pointsCount, CV_32FC3), inlierImagePoints(1, pointsCount, CV_32FC2);
-    int index;
-    for (size_t i = 0; i < localInliers.size(); i++)
+    Mat opoints = _opoints.getMat(), ipoints = _ipoints.getMat();
+    Mat cameraMatrix = _cameraMatrix.getMat(), distCoeffs = _distCoeffs.getMat();
+    
+    CV_Assert(opoints.isContinuous());
+    CV_Assert(opoints.depth() == CV_32F);
+    CV_Assert((opoints.rows == 1 && opoints.channels() == 3) || opoints.cols*opoints.channels() == 3);
+    CV_Assert(ipoints.isContinuous());
+    CV_Assert(ipoints.depth() == CV_32F);
+    CV_Assert((ipoints.rows == 1 && ipoints.channels() == 2) || ipoints.cols*ipoints.channels() == 2);
+    
+    _rvec.create(3, 1, CV_64FC1);
+    _tvec.create(3, 1, CV_64FC1);
+    Mat rvec = _rvec.getMat();
+    Mat tvec = _tvec.getMat();
+    
+    Mat objectPoints = opoints.reshape(3, 1), imagePoints = ipoints.reshape(2, 1);
+    
+    if (minInliersCount <= 0)
+        minInliersCount = objectPoints.cols;
+    cv::pnpransac::Parameters params;
+    params.iterationsCount = iterationsCount;
+    params.minInliersCount = minInliersCount;
+    params.reprojectionError = reprojectionError;
+    params.useExtrinsicGuess = useExtrinsicGuess;
+    params.camera.init(cameraMatrix, distCoeffs);
+    
+    vector<int> localInliers;
+    Mat localRvec, localTvec;
+    rvec.copyTo(localRvec);
+    tvec.copyTo(localTvec);
+    
+    if (objectPoints.cols >= pnpransac::MIN_POINTS_COUNT)
+    {
+        parallel_for(BlockedRange(0,iterationsCount), cv::pnpransac::PnPSolver(objectPoints, imagePoints, params,
+                                                                               localRvec, localTvec, localInliers));
+    }
+    
+    if (localInliers.size() >= (size_t)pnpransac::MIN_POINTS_COUNT)
+    {
+        size_t pointsCount = localInliers.size();
+        Mat inlierObjectPoints(1, pointsCount, CV_32FC3), inlierImagePoints(1, pointsCount, CV_32FC2);
+        int index;
+        for (size_t i = 0; i < localInliers.size(); i++)
+        {
+            index = localInliers[i];
+            Mat colInlierImagePoints = inlierImagePoints(Rect(i, 0, 1, 1));
+            imagePoints.col(index).copyTo(colInlierImagePoints);
+            Mat colInlierObjectPoints = inlierObjectPoints(Rect(i, 0, 1, 1));
+            objectPoints.col(index).copyTo(colInlierObjectPoints);
+        }
+        solvePnP(inlierObjectPoints, inlierImagePoints, params.camera.intrinsics, params.camera.distortion, localRvec, localTvec, true);
+        localRvec.copyTo(rvec);
+        localTvec.copyTo(tvec);
+        if (_inliers.needed())
+            Mat(localInliers).copyTo(_inliers);
+    }
+    else
     {
-      index = localInliers[i];
-      Mat colInlierImagePoints = inlierImagePoints(Rect(i, 0, 1, 1));
-      imagePoints.col(index).copyTo(colInlierImagePoints);
-      Mat colInlierObjectPoints = inlierObjectPoints(Rect(i, 0, 1, 1));
-      objectPoints.col(index).copyTo(colInlierObjectPoints);
+        tvec.setTo(Scalar(0));
+        Mat R = Mat::eye(3, 3, CV_64F);
+        Rodrigues(R, rvec);
+        if( _inliers.needed() )
+            _inliers.release();
     }
-    solvePnP(inlierObjectPoints, inlierImagePoints, params.camera.intrinsics, params.camera.distortion, localRvec, localTvec, true);
-    localRvec.copyTo(rvec);
-    localTvec.copyTo(tvec);
-    if (inliers)
-       *inliers = localInliers;
-  }
-  else
-  {
-    tvec.setTo(Scalar(0));
-    Mat R = Mat::ones(3, 3, CV_64F);
-    Rodrigues(R, rvec);
-  }
-  return;
+    return;
 }
 
index 485d73d..8f9fe00 100644 (file)
@@ -920,10 +920,13 @@ void StereoBM::init(int _preset, int _ndisparities, int _SADWindowSize)
     state->SADWindowSize = _SADWindowSize;
 }
 
-void StereoBM::operator()( const Mat& left, const Mat& right, Mat& disparity, int disptype )
+void StereoBM::operator()( const InputArray& _left, const InputArray& _right,
+                           OutputArray _disparity, int disptype )
 {
+    Mat left = _left.getMat(), right = _right.getMat();
     CV_Assert( disptype == CV_16S || disptype == CV_32F );
-    disparity.create(left.size(), disptype);
+    _disparity.create(left.size(), disptype);
+    Mat disparity = _disparity.getMat();
     
     findStereoCorrespondenceBM(left, right, disparity, state);
 }
index 275cd36..fd0ffcd 100644 (file)
@@ -819,8 +819,49 @@ static void computeDisparitySGBM( const Mat& img1, const Mat& img2,
 
 typedef cv::Point_<short> Point2s;
 
-void filterSpeckles( Mat& img, double _newval, int maxSpeckleSize, double _maxDiff, Mat& _buf )
+void StereoSGBM::operator ()( const InputArray& _left, const InputArray& _right,
+                             OutputArray _disp )
 {
+    Mat left = _left.getMat(), right = _right.getMat();
+    CV_Assert( left.size() == right.size() && left.type() == right.type() &&
+              left.depth() == DataType<PixType>::depth );
+    
+    _disp.create( left.size(), CV_16S );
+    Mat disp = _disp.getMat();
+    
+    computeDisparitySGBM( left, right, disp, *this, buffer );
+    medianBlur(disp, disp, 3);
+    
+    if( speckleWindowSize > 0 )
+        filterSpeckles(disp, (minDisparity - 1)*DISP_SCALE, speckleWindowSize, DISP_SCALE*speckleRange, buffer);
+}
+
+
+Rect getValidDisparityROI( Rect roi1, Rect roi2,
+                          int minDisparity,
+                          int numberOfDisparities,
+                          int SADWindowSize )
+{
+    int SW2 = SADWindowSize/2;
+    int minD = minDisparity, maxD = minDisparity + numberOfDisparities - 1;
+    
+    int xmin = max(roi1.x, roi2.x + maxD) + SW2;
+    int xmax = min(roi1.x + roi1.width, roi2.x + roi2.width - minD) - SW2;
+    int ymin = max(roi1.y, roi2.y) + SW2;
+    int ymax = min(roi1.y + roi1.height, roi2.y + roi2.height) - SW2;
+    
+    Rect r(xmin, ymin, xmax - xmin, ymax - ymin);
+    
+    return r.width > 0 && r.height > 0 ? r : Rect();
+}    
+    
+}
+    
+void cv::filterSpeckles( InputOutputArray _img, double _newval, int maxSpeckleSize,
+                         double _maxDiff, InputOutputArray __buf )
+{
+    Mat img = _img.getMat();
+    Mat temp, &_buf = __buf.needed() ? __buf.getMatRef() : temp;
     CV_Assert( img.type() == CV_16SC1 );
     
     int newVal = cvRound(_newval);
@@ -916,44 +957,11 @@ void filterSpeckles( Mat& img, double _newval, int maxSpeckleSize, double _maxDi
         }
     }
 }    
-
-
-void StereoSGBM::operator ()( const Mat& left, const Mat& right, Mat& disp )
-{
-    CV_Assert( left.size() == right.size() && left.type() == right.type() &&
-              left.depth() == DataType<PixType>::depth );
-    
-    disp.create( left.size(), CV_16S );
-    
-    computeDisparitySGBM( left, right, disp, *this, buffer );
-    medianBlur(disp, disp, 3);
     
-    if( speckleWindowSize > 0 )
-        filterSpeckles(disp, (minDisparity - 1)*DISP_SCALE, speckleWindowSize, DISP_SCALE*speckleRange, buffer);
-}
-    
-    
-Rect getValidDisparityROI( Rect roi1, Rect roi2,
-                           int minDisparity,
-                           int numberOfDisparities,
-                           int SADWindowSize )
-{
-    int SW2 = SADWindowSize/2;
-    int minD = minDisparity, maxD = minDisparity + numberOfDisparities - 1;
-    
-    int xmin = max(roi1.x, roi2.x + maxD) + SW2;
-    int xmax = min(roi1.x + roi1.width, roi2.x + roi2.width - minD) - SW2;
-    int ymin = max(roi1.y, roi2.y) + SW2;
-    int ymax = min(roi1.y + roi1.height, roi2.y + roi2.height) - SW2;
-    
-    Rect r(xmin, ymin, xmax - xmin, ymax - ymin);
-    
-    return r.width > 0 && r.height > 0 ? r : Rect();
-}
-    
-    
-void validateDisparity( Mat& disp, const Mat& cost, int minDisparity, int numberOfDisparities, int disp12MaxDiff )
+void cv::validateDisparity( InputOutputArray _disp, const InputArray& _cost, int minDisparity,
+                            int numberOfDisparities, int disp12MaxDiff )
 {
+    Mat disp = _disp.getMat(), cost = _cost.getMat();
     int cols = disp.cols, rows = disp.rows;
     int minD = minDisparity, maxD = minDisparity + numberOfDisparities;
     int x, minX1 = max(maxD, 0), maxX1 = cols + min(minD, 0);
@@ -1030,8 +1038,6 @@ void validateDisparity( Mat& disp, const Mat& cost, int minDisparity, int number
         }
     }
 }
-    
-}
 
 CvRect cvGetValidDisparityROI( CvRect roi1, CvRect roi2, int minDisparity,
                                int numberOfDisparities, int SADWindowSize )
index c14b70b..eb24c5c 100644 (file)
@@ -1244,8 +1244,13 @@ void CV_ProjectPointsTest_CPP::project( const Mat& objectPoints, const Mat& rvec
                                                                           const Mat& cameraMatrix, const Mat& distCoeffs, vector<Point2f>& imagePoints,
                                                                           Mat& dpdrot, Mat& dpdt, Mat& dpdf, Mat& dpdc, Mat& dpddist, double aspectRatio)
 {
-       projectPoints( objectPoints, rvec, tvec, cameraMatrix, distCoeffs, imagePoints,
-               dpdrot, dpdt, dpdf, dpdc, dpddist, aspectRatio );
+    Mat J;
+       projectPoints( objectPoints, rvec, tvec, cameraMatrix, distCoeffs, imagePoints, J, aspectRatio);
+    J.colRange(0, 3).copyTo(dpdrot);
+    J.colRange(3, 6).copyTo(dpdt);
+    J.colRange(6, 8).copyTo(dpdf);
+    J.colRange(8, 10).copyTo(dpdc);
+    J.colRange(10, J.cols).copyTo(dpddist);
 }
 
 ///////////////////////////////// Stereo Calibration /////////////////////////////////////
@@ -1696,7 +1701,7 @@ void CV_StereoCalibrationTest_CPP::rectify( const Mat& cameraMatrix1, const Mat&
                                                                                 Rect* validPixROI1, Rect* validPixROI2, int flags )
 {
        stereoRectify( cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2,
-                               imageSize, R, T, R1, R2, P1, P2, Q, alpha, newImageSize,validPixROI1, validPixROI2, flags );
+                               imageSize, R, T, R1, R2, P1, P2, Q, flags, alpha, newImageSize,validPixROI1, validPixROI2 );
 }
 
 bool CV_StereoCalibrationTest_CPP::rectifyUncalibrated( const Mat& points1,
index ea306dd..b2e8c1c 100644 (file)
@@ -104,8 +104,8 @@ protected:
                 Mat rvec, tvec;
                 vector<int> inliers;
 
-                solvePnPRansac(Mat(points), Mat(points1), intrinsics, dist_coeffs, rvec, tvec,
-                                false, 1000, 2.0, -1, &inliers);
+                solvePnPRansac(points, points1, intrinsics, dist_coeffs, rvec, tvec,
+                                false, 1000, 2.0, -1, inliers);
 
                 bool isTestSuccess = inliers.size() == 475;
 
index a4edcb1..9751a5a 100644 (file)
@@ -14,7 +14,7 @@
 //                For Open Source Computer Vision Library
 //
 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
-// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
 // Third party copyrights are property of their respective owners.
 //
 // Redistribution and use in source and binary forms, with or without modification,
@@ -121,7 +121,7 @@ enum { DFT_INVERSE=1, DFT_SCALE=2, DFT_ROWS=4, DFT_COMPLEX_OUTPUT=16, DFT_REAL_O
 class CV_EXPORTS Exception : public std::exception
 {
 public:
-       /*!
+    /*!
      Default constructor
      */
     Exception() { code = 0; line = 0; }
@@ -129,16 +129,16 @@ public:
      Full constructor. Normally the constuctor is not called explicitly.
      Instead, the macros CV_Error(), CV_Error_() and CV_Assert() are used.
     */
-       Exception(int _code, const string& _err, const string& _func, const string& _file, int _line)
-               : code(_code), err(_err), func(_func), file(_file), line(_line)
+    Exception(int _code, const string& _err, const string& _func, const string& _file, int _line)
+        : code(_code), err(_err), func(_func), file(_file), line(_line)
     { formatMessage(); }
     
-       virtual ~Exception() throw() {}
+    virtual ~Exception() throw() {}
 
     /*!
      \return the error description and the context as a text string.
     */ 
-       virtual const char *what() const throw() { return msg.c_str(); }
+    virtual const char *what() const throw() { return msg.c_str(); }
 
     void formatMessage()
     {
@@ -148,13 +148,13 @@ public:
             msg = format("%s:%d: error: (%d) %s\n", file.c_str(), line, code, err.c_str());
     }
     
-       string msg; ///< the formatted error message
+    string msg; ///< the formatted error message
 
-       int code; ///< error code @see CVStatus
-       string err; ///< error description
-       string func; ///< function name. Available only when the compiler supports __func__ macro
-       string file; ///< source file name where the error has occured
-       int line; ///< line number in the source file where the error has occured 
+    int code; ///< error code @see CVStatus
+    string err; ///< error description
+    string func; ///< function name. Available only when the compiler supports __func__ macro
+    string file; ///< source file name where the error has occured
+    int line; ///< line number in the source file where the error has occured 
 };
 
 
@@ -641,6 +641,8 @@ typedef Vec<ushort, 4> Vec4w;
 typedef Vec<int, 2> Vec2i;
 typedef Vec<int, 3> Vec3i;
 typedef Vec<int, 4> Vec4i;
+typedef Vec<int, 6> Vec6i;
+typedef Vec<int, 8> Vec8i;
 
 typedef Vec<float, 2> Vec2f;
 typedef Vec<float, 3> Vec3f;
@@ -748,7 +750,7 @@ public:
     Point3_();
     Point3_(_Tp _x, _Tp _y, _Tp _z);
     Point3_(const Point3_& pt);
-       explicit Point3_(const Point_<_Tp>& pt);
+    explicit Point3_(const Point_<_Tp>& pt);
     Point3_(const CvPoint3D32f& pt);
     Point3_(const Vec<_Tp, 3>& v);
 
@@ -1252,10 +1254,90 @@ public:
     
 protected:
     _Tp* obj; //< the object pointer.
-    int* refcount; //< the associated                         bbbbbbbbbbbbbbbbbb reference counter
+    int* refcount; //< the associated reference counter
+};
+
+    
+//////////////////////// Input/Output Array Arguments /////////////////////////////////
+    
+/*!
+ Proxy datatype for passing Mat's and vector<>'s as input parameters 
+ */
+class CV_EXPORTS InputArray
+{
+public:
+    enum { KIND_SHIFT=16, NONE=0<<KIND_SHIFT, MAT=1<<KIND_SHIFT,
+        MATX=2<<KIND_SHIFT, STD_VECTOR=3<<KIND_SHIFT,
+        STD_VECTOR_VECTOR=4<<KIND_SHIFT,
+        STD_VECTOR_MAT=5<<KIND_SHIFT, EXPR=6<<KIND_SHIFT };
+    InputArray();
+    InputArray(const Mat& m);
+    InputArray(const MatExpr& expr);
+    template<typename _Tp> InputArray(const vector<_Tp>& vec);
+    template<typename _Tp> InputArray(const vector<vector<_Tp> >& vec);
+    InputArray(const vector<Mat>& vec);
+    template<typename _Tp, int m, int n> InputArray(const Matx<_Tp, m, n>& matx);
+    InputArray(const double& val);
+    Mat getMat(int i=-1) const;
+    void getMatVector(vector<Mat>& mv) const;
+    int kind() const;
+    Size size(int i=-1) const;
+    size_t total(int i=-1) const;
+    int type(int i=-1) const;
+    int depth(int i=-1) const;
+    int channels(int i=-1) const;
+    bool empty() const;
+
+    int flags;
+    void* obj;
+    Size sz;
+};
+
+
+enum
+{
+    DEPTH_MASK_8U = 1 << CV_8U,
+    DEPTH_MASK_8S = 1 << CV_8S,
+    DEPTH_MASK_16U = 1 << CV_16U,
+    DEPTH_MASK_16S = 1 << CV_16S,
+    DEPTH_MASK_32S = 1 << CV_32S,
+    DEPTH_MASK_32F = 1 << CV_32F,
+    DEPTH_MASK_64F = 1 << CV_64F,
+    DEPTH_MASK_ALL = (DEPTH_MASK_64F<<1)-1,
+    DEPTH_MASK_ALL_BUT_8S = DEPTH_MASK_ALL & ~DEPTH_MASK_8S,
+    DEPTH_MASK_FLT = DEPTH_MASK_32F + DEPTH_MASK_64F
+};
+
+
+/*!
+ Proxy datatype for passing Mat's and vector<>'s as input parameters 
+ */
+class CV_EXPORTS OutputArray : public InputArray
+{
+public:
+    OutputArray();
+    OutputArray(Mat& m);
+    template<typename _Tp> OutputArray(vector<_Tp>& vec);
+    template<typename _Tp> OutputArray(vector<vector<_Tp> >& vec);
+    OutputArray(vector<Mat>& vec);
+    template<typename _Tp, int m, int n> OutputArray(Matx<_Tp, m, n>& matx);
+    bool fixedSize() const;
+    bool fixedType() const;
+    bool needed() const;
+    Mat& getMatRef(int i=-1);
+    void create(Size sz, int type, int i=-1, bool allocateVector=false, int fixedDepthMask=0);
+    void create(int rows, int cols, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0);
+    void create(int dims, const int* size, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0);
+    void release();
+    void clear();
 };
 
-//////////////////////////////// Mat ////////////////////////////////
+typedef InputArray InputArrayOfArrays;
+typedef OutputArray OutputArrayOfArrays;
+
+typedef OutputArray InputOutputArray;    
+    
+/////////////////////////////////////// Mat ///////////////////////////////////////////
 
 enum { MAGIC_MASK=0xFFFF0000, TYPE_MASK=0x00000FFF, DEPTH_MASK=7 };
 
@@ -1563,19 +1645,18 @@ public:
     Mat clone() const;
     //! copies the matrix content to "m".
     // It calls m.create(this->size(), this->type()).
-    void copyTo( Mat& m ) const;
-    template<typename _Tp> void copyTo( vector<_Tp>& v ) const;
+    void copyTo( OutputArray m ) const;
     //! copies those matrix elements to "m" that are marked with non-zero mask elements.
-    void copyTo( Mat& m, const Mat& mask ) const;
+    void copyTo( OutputArray m, const InputArray& mask ) const;
     //! converts matrix to another datatype with optional scalng. See cvConvertScale.
-    void convertTo( Mat& m, int rtype, double alpha=1, double beta=0 ) const;
+    void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const;
 
     void assignTo( Mat& m, int type=-1 ) const;
 
     //! sets every matrix element to s
     Mat& operator = (const Scalar& s);
     //! sets some of the matrix elements to s, according to the mask
-    Mat& setTo(const Scalar& s, const Mat& mask=Mat());
+    Mat& setTo(const Scalar& s, const InputArray& mask=InputArray());
     //! creates alternative matrix header for the same data, with different
     // number of channels and/or different number of rows. see cvReshape.
     Mat reshape(int _cn, int _rows=0) const;
@@ -1586,13 +1667,13 @@ public:
     //! matrix inversion by means of matrix expressions
     MatExpr inv(int method=DECOMP_LU) const;
     //! per-element matrix multiplication by means of matrix expressions
-    MatExpr mul(const Mat& m, double scale=1) const;
+    MatExpr mul(const InputArray& m, double scale=1) const;
     MatExpr mul(const MatExpr& m, double scale=1) const;
     
     //! computes cross-product of 2 3D vectors
-    Mat cross(const Mat& m) const;
+    Mat cross(const InputArray& m) const;
     //! computes dot-product
-    double dot(const Mat& m) const;
+    double dot(const InputArray& m) const;
 
     //! Matlab-style matrix initialization
     static MatExpr zeros(int rows, int cols, int type);
@@ -1809,7 +1890,7 @@ public:
     MStep step;
 };
 
+
 /*!
    Random Number Generator
  
@@ -1830,9 +1911,9 @@ public:
     operator ushort();
     operator short();
     operator unsigned();
-       //! returns a random integer sampled uniformly from [0, N).
-       unsigned operator()(unsigned N);
-       unsigned operator ()();
+    //! returns a random integer sampled uniformly from [0, N).
+    unsigned operator()(unsigned N);
+    unsigned operator ()();
     operator int();
     operator float();
     operator double();
@@ -1842,14 +1923,12 @@ public:
     float uniform(float a, float b);
     //! returns uniformly distributed double-precision floating-point random number from [a,b) range
     double uniform(double a, double b);
-    void fill( Mat& mat, int distType, const Scalar& a, const Scalar& b );
-       //! returns Gaussian random variate with mean zero.
-       double gaussian(double sigma);
+    void fill( InputOutputArray mat, int distType, const InputArray& a, const InputArray& b );
+    //! returns Gaussian random variate with mean zero.
+    double gaussian(double sigma);
 
     uint64 state;
 };
-    
-    
 
 
 /*!
@@ -1879,6 +1958,7 @@ public:
     double epsilon; // the desired accuracy
 };
 
+    
 //! swaps two matrices
 CV_EXPORTS void swap(Mat& a, Mat& b);
     
@@ -1886,79 +1966,75 @@ CV_EXPORTS void swap(Mat& a, Mat& b);
 CV_EXPORTS Mat cvarrToMat(const CvArr* arr, bool copyData=false,
                           bool allowND=true, int coiMode=0);
 //! extracts Channel of Interest from CvMat or IplImage and makes cv::Mat out of it.
-CV_EXPORTS void extractImageCOI(const CvArr* arr, CV_OUT Mat& coiimg, int coi=-1);
+CV_EXPORTS void extractImageCOI(const CvArr* arr, OutputArray coiimg, int coi=-1);
 //! inserts single-channel cv::Mat into a multi-channel CvMat or IplImage
-CV_EXPORTS void insertImageCOI(const Mat& coiimg, CvArr* arr, int coi=-1);
-
+CV_EXPORTS void insertImageCOI(const InputArray& coiimg, CvArr* arr, int coi=-1);  
+    
 //! adds one matrix to another (dst = src1 + src2)
-CV_EXPORTS_W void add(const Mat& src1, const Mat& src2, CV_OUT Mat& dst, const Mat& mask CV_WRAP_DEFAULT(Mat()));
+CV_EXPORTS_W void add(const InputArray& src1, const InputArray& src2, OutputArray dst,
+                      const InputArray& mask=InputArray(), int dtype=-1);
 //! subtracts one matrix from another (dst = src1 - src2) 
-CV_EXPORTS_W void subtract(const Mat& src1, const Mat& src2, CV_OUT Mat& dst, const Mat& mask CV_WRAP_DEFAULT(Mat()));
-//! adds one matrix to another (dst = src1 + src2)    
-CV_EXPORTS void add(const Mat& src1, const Mat& src2, CV_OUT Mat& dst);
-//! subtracts one matrix from another (dst = src1 - src2) 
-CV_EXPORTS void subtract(const Mat& src1, const Mat& src2, CV_OUT Mat& dst);
-//! adds scalar to a matrix (dst = src1 + src2)
-CV_EXPORTS_W void add(const Mat& src1, const Scalar& src2, CV_OUT Mat& dst, const Mat& mask=Mat());
-//! subtracts scalar from a matrix (dst = src1 - src2)    
-CV_EXPORTS_W void subtract(const Mat& src1, const Scalar& src2, CV_OUT Mat& dst, const Mat& mask=Mat());
-//! subtracts matrix from scalar (dst = src1 - src2)    
-CV_EXPORTS_W void subtract(const Scalar& src1, const Mat& src2, CV_OUT Mat& dst, const Mat& mask=Mat());
+CV_EXPORTS_W void subtract(const InputArray& src1, const InputArray& src2, OutputArray dst,
+                           const InputArray& mask=InputArray(), int dtype=-1);
 
 //! computes element-wise weighted product of the two arrays (dst = scale*src1*src2)
-CV_EXPORTS_W void multiply(const Mat& src1, const Mat& src2, CV_OUT Mat& dst, double scale=1);
+CV_EXPORTS_W void multiply(const InputArray& src1, const InputArray& src2,
+                           OutputArray dst, double scale=1, int dtype=-1);
+    
 //! computes element-wise weighted quotient of the two arrays (dst = scale*src1/src2)
-CV_EXPORTS_W void divide(const Mat& src1, const Mat& src2, CV_OUT Mat& dst, double scale=1);
+CV_EXPORTS_W void divide(const InputArray& src1, const InputArray& src2, OutputArray dst,
+                         double scale=1, int dtype=-1);
+    
 //! computes element-wise weighted reciprocal of an array (dst = scale/src2)
-CV_EXPORTS_W void divide(double scale, const Mat& src2, CV_OUT Mat& dst);
+CV_EXPORTS_W void divide(double scale, const InputArray& src2,
+                         OutputArray dst, int dtype=-1);
 
 //! adds scaled array to another one (dst = alpha*src1 + src2)
-CV_EXPORTS_W void scaleAdd(const Mat& src1, double alpha, const Mat& src2, CV_OUT Mat& dst);
+CV_EXPORTS_W void scaleAdd(const InputArray& src1, double alpha, const InputArray& src2, OutputArray dst);
+    
 //! computes weighted sum of two arrays (dst = alpha*src1 + beta*src2 + gamma)
-CV_EXPORTS_W void addWeighted(const Mat& src1, double alpha, const Mat& src2,
-                            double beta, double gamma, CV_OUT Mat& dst);
+CV_EXPORTS_W void addWeighted(const InputArray& src1, double alpha, const InputArray& src2,
+                              double beta, double gamma, OutputArray dst, int dtype=-1);
+
 //! scales array elements, computes absolute values and converts the results to 8-bit unsigned integers: dst(i)=saturate_cast<uchar>abs(src(i)*alpha+beta)
-CV_EXPORTS_W void convertScaleAbs(const Mat& src, CV_OUT Mat& dst, double alpha=1, double beta=0);
-//! transforms 8-bit unsigned integers using lookup table: dst(i)=lut(src(i))
-CV_EXPORTS_W void LUT(const Mat& src, const Mat& lut, CV_OUT Mat& dst);
+CV_EXPORTS_W void convertScaleAbs(const InputArray& src, OutputArray dst,
+                                  double alpha=1, double beta=0);
+//! transforms array of numbers using a lookup table: dst(i)=lut(src(i))
+CV_EXPORTS_W void LUT(const InputArray& src, const InputArray& lut, OutputArray dst,
+                      int interpolation=0);
 
 //! computes sum of array elements
-CV_EXPORTS_W Scalar sum(const Mat& src);
+CV_EXPORTS_W Scalar sum(const InputArray& src); 
 //! computes the number of nonzero array elements
-CV_EXPORTS_W int countNonZero( const Mat& src );
-
-//! computes mean value of array elements
-CV_EXPORTS Scalar mean(const Mat& src);
+CV_EXPORTS_W int countNonZero( const InputArray& src );
 //! computes mean value of selected array elements
-CV_EXPORTS_W Scalar mean(const Mat& src, const Mat& mask CV_WRAP_DEFAULT(Mat()));
+CV_EXPORTS_W Scalar mean(const InputArray& src, const InputArray& mask=InputArray());
 //! computes mean value and standard deviation of all or selected array elements
-CV_EXPORTS_W void meanStdDev(const Mat& src, CV_OUT Scalar& mean, CV_OUT Scalar& stddev, const Mat& mask=Mat());
-//! computes norm of array
-CV_EXPORTS double norm(const Mat& src1, int normType=NORM_L2);
-//! computes norm of the difference between two arrays
-CV_EXPORTS double norm(const Mat& src1, const Mat& src2, int normType=NORM_L2);
+CV_EXPORTS_W void meanStdDev(const InputArray& src, OutputArray mean, OutputArray stddev,
+                             const InputArray& mask=InputArray());
 //! computes norm of the selected array part
-CV_EXPORTS_W double norm(const Mat& src1, int normType, const Mat& mask CV_WRAP_DEFAULT(Mat()));
+CV_EXPORTS_W double norm(const InputArray& src1, int normType=NORM_L2, const InputArray& mask=InputArray());
 //! computes norm of selected part of the difference between two arrays
-CV_EXPORTS_W double norm(const Mat& src1, const Mat& src2,
-                       int normType, const Mat& mask CV_WRAP_DEFAULT(Mat()));
+CV_EXPORTS_W double norm(const InputArray& src1, const InputArray& src2,
+                         int normType=NORM_L2, const InputArray& mask=InputArray());
 //! scales and shifts array elements so that either the specified norm (alpha) or the minimum (alpha) and maximum (beta) array values get the specified values 
-CV_EXPORTS_W void normalize( const Mat& src, CV_OUT Mat& dst, double alpha=1, double beta=0,
-                           int norm_type=NORM_L2, int rtype=-1, const Mat& mask=Mat());
+CV_EXPORTS_W void normalize( const InputArray& src, OutputArray dst, double alpha=1, double beta=0,
+                             int norm_type=NORM_L2, int dtype=-1, const InputArray& mask=InputArray());
 
 //! finds global minimum and maximum array elements and returns their values and their locations
-CV_EXPORTS_W void minMaxLoc(const Mat& src, CV_OUT double* minVal,
-                          CV_OUT double* maxVal=0, CV_OUT Point* minLoc=0,
-                          CV_OUT Point* maxLoc=0, const Mat& mask=Mat());
-CV_EXPORTS void minMaxIdx(const Mat& src, double* minVal, double* maxVal,
-                          int* minIdx=0, int* maxIdx=0, const Mat& mask=Mat());
+CV_EXPORTS_W void minMaxLoc(const InputArray& src, CV_OUT double* minVal,
+                           CV_OUT double* maxVal=0, CV_OUT Point* minLoc=0,
+                           CV_OUT Point* maxLoc=0, const InputArray& mask=InputArray());
+CV_EXPORTS void minMaxIdx(const InputArray& src, double* minVal, double* maxVal,
+                          int* minIdx=0, int* maxIdx=0, const InputArray& mask=InputArray());
     
 //! transforms 2D matrix to 1D row or column vector by taking sum, minimum, maximum or mean value over all the rows
-CV_EXPORTS_W void reduce(const Mat& src, CV_OUT Mat& dst, int dim, int rtype, int dtype=-1);
+CV_EXPORTS_W void reduce(const InputArray& src, OutputArray dst, int dim, int rtype, int dtype=-1);
+
 //! makes multi-channel array out of several single-channel arrays
-CV_EXPORTS void merge(const Mat* mv, size_t count, CV_OUT Mat& dst);
+CV_EXPORTS void merge(const Mat* mv, size_t count, OutputArray dst);
 //! makes multi-channel array out of several single-channel arrays
-CV_EXPORTS_W void merge(const vector<Mat>& mv, Mat& dst);
+CV_EXPORTS_W void merge(const vector<Mat>& mv, OutputArray dst);
     
 //! copies each plane of a multi-channel array to a dedicated array
 CV_EXPORTS void split(const Mat& src, Mat* mvbegin);
@@ -1969,133 +2045,131 @@ CV_EXPORTS_W void split(const Mat& m, vector<Mat>& mv);
 CV_EXPORTS void mixChannels(const Mat* src, size_t nsrcs, Mat* dst, size_t ndsts,
                             const int* fromTo, size_t npairs);
 CV_EXPORTS void mixChannels(const vector<Mat>& src, vector<Mat>& dst,
-                            const int* fromTo, int npairs);
+                            const int* fromTo, size_t npairs);
 
 //! reverses the order of the rows, columns or both in a matrix
-CV_EXPORTS_W void flip(const Mat& src, CV_OUT Mat& dst, int flipCode);
+CV_EXPORTS_W void flip(const InputArray& src, OutputArray dst, int flipCode);
 
 //! replicates the input matrix the specified number of times in the horizontal and/or vertical direction
-CV_EXPORTS_W void repeat(const Mat& src, int ny, int nx, CV_OUT Mat& dst);
+CV_EXPORTS_W void repeat(const InputArray& src, int ny, int nx, OutputArray dst);
 CV_EXPORTS Mat repeat(const Mat& src, int ny, int nx);
         
-CV_EXPORTS void hconcat(const Mat* src, size_t nsrc, Mat& dst);
-CV_EXPORTS void hconcat(const Mat& src1, const Mat& src2, Mat& dst);
-CV_EXPORTS_W void hconcat(const vector<Mat>& src, CV_OUT Mat& dst);
+CV_EXPORTS void hconcat(const Mat* src, size_t nsrc, OutputArray dst);
+CV_EXPORTS void hconcat(const InputArray& src1, const InputArray& src2, OutputArray dst);
+CV_EXPORTS_W void hconcat(const InputArray& src, OutputArray dst);
 
-CV_EXPORTS void vconcat(const Mat* src, size_t nsrc, Mat& dst);
-CV_EXPORTS void vconcat(const Mat& src1, const Mat& src2, Mat& dst);
-CV_EXPORTS_W void vconcat(const vector<Mat>& src, CV_OUT Mat& dst);
+CV_EXPORTS void vconcat(const Mat* src, size_t nsrc, OutputArray dst);
+CV_EXPORTS void vconcat(const InputArray& src1, const InputArray& src2, OutputArray dst);
+CV_EXPORTS_W void vconcat(const InputArray& src, OutputArray dst);
     
 //! computes bitwise conjunction of the two arrays (dst = src1 & src2)
-CV_EXPORTS_W void bitwise_and(const Mat& src1, const Mat& src2, CV_OUT Mat& dst, const Mat& mask=Mat());
+CV_EXPORTS_W void bitwise_and(const InputArray& src1, const InputArray& src2,
+                              OutputArray dst, const InputArray& mask=InputArray());
 //! computes bitwise disjunction of the two arrays (dst = src1 | src2)
-CV_EXPORTS_W void bitwise_or(const Mat& src1, const Mat& src2, CV_OUT Mat& dst, const Mat& mask=Mat());
+CV_EXPORTS_W void bitwise_or(const InputArray& src1, const InputArray& src2,
+                             OutputArray dst, const InputArray& mask=InputArray());
 //! computes bitwise exclusive-or of the two arrays (dst = src1 ^ src2)
-CV_EXPORTS_W void bitwise_xor(const Mat& src1, const Mat& src2, CV_OUT Mat& dst, const Mat& mask=Mat());
-//! computes bitwise conjunction of an array and scalar (dst = src1 & src2)
-CV_EXPORTS_W void bitwise_and(const Mat& src1, const Scalar& src2, CV_OUT Mat& dst, const Mat& mask=Mat());
-//! computes bitwise disjunction of an array and scalar (dst = src1 | src2)
-CV_EXPORTS_W void bitwise_or(const Mat& src1, const Scalar& src2, CV_OUT Mat& dst, const Mat& mask=Mat());
-//! computes bitwise exclusive-or of an array and scalar (dst = src1 ^ src2)
-CV_EXPORTS_W void bitwise_xor(const Mat& src1, const Scalar& src2, CV_OUT Mat& dst, const Mat& mask=Mat());
+CV_EXPORTS_W void bitwise_xor(const InputArray& src1, const InputArray& src2,
+                              OutputArray dst, const InputArray& mask=InputArray());
 //! inverts each bit of array (dst = ~src)
-CV_EXPORTS_W void bitwise_not(const Mat& src, CV_OUT Mat& dst);
+CV_EXPORTS_W void bitwise_not(const InputArray& src, OutputArray dst,
+                              const InputArray& mask=InputArray());
 //! computes element-wise absolute difference of two arrays (dst = abs(src1 - src2))
-CV_EXPORTS_W void absdiff(const Mat& src1, const Mat& src2, CV_OUT Mat& dst);
-//! computes element-wise absolute difference of array and scalar (dst = abs(src1 - src2))
-CV_EXPORTS_W void absdiff(const Mat& src1, const Scalar& src2, CV_OUT Mat& dst);
+CV_EXPORTS_W void absdiff(const InputArray& src1, const InputArray& src2, OutputArray dst);
 //! set mask elements for those array elements which are within the element-specific bounding box (dst = lowerb <= src && src < upperb)    
-CV_EXPORTS_W void inRange(const Mat& src, const Mat& lowerb,
-                        const Mat& upperb, CV_OUT Mat& dst);
-//! set mask elements for those array elements which are within the fixed bounding box (dst = lowerb <= src && src < upperb)    
-CV_EXPORTS_W void inRange(const Mat& src, const Scalar& lowerb,
-                        const Scalar& upperb, CV_OUT Mat& dst);
+CV_EXPORTS_W void inRange(const InputArray& src, const InputArray& lowerb,
+                          const InputArray& upperb, OutputArray dst);    
 //! compares elements of two arrays (dst = src1 <cmpop> src2)
-CV_EXPORTS_W void compare(const Mat& src1, const Mat& src2, CV_OUT Mat& dst, int cmpop);
-//! compares elements of array with scalar (dst = src1 <cmpop> src2)
-CV_EXPORTS_W void compare(const Mat& src1, double s, CV_OUT Mat& dst, int cmpop);
+CV_EXPORTS_W void compare(const InputArray& src1, const InputArray& src2, OutputArray dst, int cmpop);
 //! computes per-element minimum of two arrays (dst = min(src1, src2))
-CV_EXPORTS_W void min(const Mat& src1, const Mat& src2, CV_OUT Mat& dst);
+CV_EXPORTS_W void min(const InputArray& src1, const InputArray& src2, OutputArray dst);
+//! computes per-element maximum of two arrays (dst = max(src1, src2))
+CV_EXPORTS_W void max(const InputArray& src1, const InputArray& src2, OutputArray dst);
+
+//! computes per-element minimum of two arrays (dst = min(src1, src2))
+CV_EXPORTS void min(const Mat& src1, const Mat& src2, Mat& dst);
 //! computes per-element minimum of array and scalar (dst = min(src1, src2))
-CV_EXPORTS_W void min(const Mat& src1, double src2, CV_OUT Mat& dst);
+CV_EXPORTS void min(const Mat& src1, double src2, Mat& dst);
 //! computes per-element maximum of two arrays (dst = max(src1, src2))
-CV_EXPORTS_W void max(const Mat& src1, const Mat& src2, CV_OUT Mat& dst);
+CV_EXPORTS void max(const Mat& src1, const Mat& src2, Mat& dst);
 //! computes per-element maximum of array and scalar (dst = max(src1, src2))
-CV_EXPORTS_W void max(const Mat& src1, double src2, CV_OUT Mat& dst);
-
+CV_EXPORTS void max(const Mat& src1, double src2, Mat& dst);    
+    
 //! computes square root of each matrix element (dst = src**0.5)
-CV_EXPORTS_W void sqrt(const Mat& src, CV_OUT Mat& dst);
+CV_EXPORTS_W void sqrt(const InputArray& src, OutputArray dst);
 //! raises the input matrix elements to the specified power (b = a**power) 
-CV_EXPORTS_W void pow(const Mat& src, double power, CV_OUT Mat& dst);
+CV_EXPORTS_W void pow(const InputArray& src, double power, OutputArray dst);
 //! computes exponent of each matrix element (dst = e**src)
-CV_EXPORTS_W void exp(const Mat& src, CV_OUT Mat& dst);
+CV_EXPORTS_W void exp(const InputArray& src, OutputArray dst);
 //! computes natural logarithm of absolute value of each matrix element: dst = log(abs(src))
-CV_EXPORTS_W void log(const Mat& src, CV_OUT Mat& dst);
+CV_EXPORTS_W void log(const InputArray& src, OutputArray dst);
 //! computes cube root of the argument
 CV_EXPORTS_W float cubeRoot(float val);
 //! computes the angle in degrees (0..360) of the vector (x,y)
 CV_EXPORTS_W float fastAtan2(float y, float x);
 //! converts polar coordinates to Cartesian
-CV_EXPORTS_W void polarToCart(const Mat& magnitude, const Mat& angle,
-                            CV_OUT Mat& x, CV_OUT Mat& y, bool angleInDegrees=false);
+CV_EXPORTS_W void polarToCart(const InputArray& magnitude, const InputArray& angle,
+                              OutputArray x, OutputArray y, bool angleInDegrees=false);
 //! converts Cartesian coordinates to polar
-CV_EXPORTS_W void cartToPolar(const Mat& x, const Mat& y,
-                            CV_OUT Mat& magnitude, CV_OUT Mat& angle,
-                            bool angleInDegrees=false);
+CV_EXPORTS_W void cartToPolar(const InputArray& x, const InputArray& y,
+                              OutputArray magnitude, OutputArray angle,
+                              bool angleInDegrees=false);
 //! computes angle (angle(i)) of each (x(i), y(i)) vector
-CV_EXPORTS_W void phase(const Mat& x, const Mat& y, CV_OUT Mat& angle,
+CV_EXPORTS_W void phase(const InputArray& x, const InputArray& y, OutputArray angle,
                         bool angleInDegrees=false);
 //! computes magnitude (magnitude(i)) of each (x(i), y(i)) vector
-CV_EXPORTS_W void magnitude(const Mat& x, const Mat& y, CV_OUT Mat& magnitude);
+CV_EXPORTS_W void magnitude(const InputArray& x, const InputArray& y, OutputArray magnitude);
 //! checks that each matrix element is within the specified range.
-CV_EXPORTS_W bool checkRange(const Mat& a, bool quiet=true, CV_OUT Point* pt=0,
+CV_EXPORTS_W bool checkRange(const InputArray& a, bool quiet=true, CV_OUT Point* pt=0,
                             double minVal=-DBL_MAX, double maxVal=DBL_MAX);
 //! implements generalized matrix product algorithm GEMM from BLAS
-CV_EXPORTS_W void gemm(const Mat& src1, const Mat& src2, double alpha,
-                       const Mat& src3, double gamma, CV_OUT Mat& dst, int flags=0);
+CV_EXPORTS_W void gemm(const InputArray& src1, const InputArray& src2, double alpha,
+                       const InputArray& src3, double gamma, OutputArray dst, int flags=0);
 //! multiplies matrix by its transposition from the left or from the right
-CV_EXPORTS_W void mulTransposed( const Mat& src, CV_OUT Mat& dst, bool aTa,
-                                 const Mat& delta=Mat(),
-                                 double scale=1, int rtype=-1 );
+CV_EXPORTS_W void mulTransposed( const InputArray& src, OutputArray dst, bool aTa,
+                                 const InputArray& delta=InputArray(),
+                                 double scale=1, int dtype=-1 );
 //! transposes the matrix
-CV_EXPORTS_W void transpose(const Mat& src, CV_OUT Mat& dst);
+CV_EXPORTS_W void transpose(const InputArray& src, OutputArray dst);
 //! performs affine transformation of each element of multi-channel input matrix
-CV_EXPORTS_W void transform(const Mat& src, CV_OUT Mat& dst, const Mat& m );
+CV_EXPORTS_W void transform(const InputArray& src, OutputArray dst, const InputArray& m );
 //! performs perspective transformation of each element of multi-channel input matrix
-CV_EXPORTS_W void perspectiveTransform(const Mat& src, CV_OUT Mat& dst, const Mat& m );
+CV_EXPORTS_W void perspectiveTransform(const InputArray& src, OutputArray dst, const InputArray& m );
 
 //! extends the symmetrical matrix from the lower half or from the upper half 
-CV_EXPORTS_W void completeSymm(Mat& mtx, bool lowerToUpper=false);
+CV_EXPORTS_W void completeSymm(InputOutputArray mtx, bool lowerToUpper=false);
 //! initializes scaled identity matrix
-CV_EXPORTS_W void setIdentity(Mat& mtx, const Scalar& s=Scalar(1));
+CV_EXPORTS_W void setIdentity(InputOutputArray mtx, const Scalar& s=Scalar(1));
 //! computes determinant of a square matrix
-CV_EXPORTS_W double determinant(const Mat& mtx);
+CV_EXPORTS_W double determinant(const InputArray& mtx);
 //! computes trace of a matrix
-CV_EXPORTS_W Scalar trace(const Mat& mtx);
+CV_EXPORTS_W Scalar trace(const InputArray& mtx);
 //! computes inverse or pseudo-inverse matrix
-CV_EXPORTS_W double invert(const Mat& src, CV_OUT Mat& dst, int flags=DECOMP_LU);
+CV_EXPORTS_W double invert(const InputArray& src, OutputArray dst, int flags=DECOMP_LU);
 //! solves linear system or a least-square problem
-CV_EXPORTS_W bool solve(const Mat& src1, const Mat& src2, CV_OUT Mat& dst, int flags=DECOMP_LU);
+CV_EXPORTS_W bool solve(const InputArray& src1, const InputArray& src2,
+                        OutputArray dst, int flags=DECOMP_LU);
 //! sorts independently each matrix row or each matrix column
-CV_EXPORTS_W void sort(const Mat& src, CV_OUT Mat& dst, int flags);
+CV_EXPORTS_W void sort(const InputArray& src, OutputArray dst, int flags);
 //! sorts independently each matrix row or each matrix column
-CV_EXPORTS_W void sortIdx(const Mat& src, CV_OUT Mat& dst, int flags);
+CV_EXPORTS_W void sortIdx(const InputArray& src, OutputArray dst, int flags);
 //! finds real roots of a cubic polynomial
-CV_EXPORTS_W int solveCubic(const Mat& coeffs, CV_OUT Mat& roots);
+CV_EXPORTS_W int solveCubic(const InputArray& coeffs, OutputArray roots);
 //! finds real and complex roots of a polynomial
-CV_EXPORTS_W double solvePoly(const Mat& coeffs, CV_OUT Mat& roots, int maxIters=300);
+CV_EXPORTS_W double solvePoly(const InputArray& coeffs, OutputArray roots, int maxIters=300);
 //! finds eigenvalues of a symmetric matrix
-CV_EXPORTS bool eigen(const Mat& src, CV_OUT Mat& eigenvalues, int lowindex=-1,
+CV_EXPORTS bool eigen(const InputArray& src, OutputArray eigenvalues, int lowindex=-1,
                       int highindex=-1);
 //! finds eigenvalues and eigenvectors of a symmetric matrix
-CV_EXPORTS bool eigen(const Mat& src, CV_OUT Mat& eigenvalues, CV_OUT Mat& eigenvectors,
+CV_EXPORTS bool eigen(const InputArray& src, OutputArray eigenvalues,
+                      OutputArray eigenvectors,
                       int lowindex=-1, int highindex=-1);
 //! computes covariation matrix of a set of samples
 CV_EXPORTS void calcCovarMatrix( const Mat* samples, int nsamples, Mat& covar, Mat& mean,
                                  int flags, int ctype=CV_64F);
 //! computes covariation matrix of a set of samples
-CV_EXPORTS_W void calcCovarMatrix( const Mat& samples, CV_OUT Mat& covar, CV_OUT Mat& mean,
-                                 int flags, int ctype=CV_64F);
+CV_EXPORTS_W void calcCovarMatrix( const InputArray& samples, OutputArray covar,
+                                   OutputArray mean, int flags, int ctype=CV_64F);
 
 /*!
     Principal Component Analysis
@@ -2157,17 +2231,17 @@ public:
     //! default constructor
     PCA();
     //! the constructor that performs PCA
-    PCA(const Mat& data, const Mat& mean, int flags, int maxComponents=0);
+    PCA(const InputArray& data, const InputArray& mean, int flags, int maxComponents=0);
     //! operator that performs PCA. The previously stored data, if any, is released
-    PCA& operator()(const Mat& data, const Mat& mean, int flags, int maxComponents=0);
+    PCA& operator()(const InputArray& data, const InputArray& mean, int flags, int maxComponents=0);
     //! projects vector from the original space to the principal components subspace
-    Mat project(const Mat& vec) const;
+    Mat project(const InputArray& vec) const;
     //! projects vector from the original space to the principal components subspace
-    void project(const Mat& vec, CV_OUT Mat& result) const;
+    void project(const InputArray& vec, OutputArray result) const;
     //! reconstructs the original vector from the projection
-    Mat backProject(const Mat& vec) const;
+    Mat backProject(const InputArray& vec) const;
     //! reconstructs the original vector from the projection
-    void backProject(const Mat& vec, CV_OUT Mat& result) const;
+    void backProject(const InputArray& vec, OutputArray result) const;
 
     Mat eigenvectors; //!< eigenvectors of the covariation matrix
     Mat eigenvalues; //!< eigenvalues of the covariation matrix
@@ -2194,17 +2268,19 @@ public:
     //! the default constructor
     SVD();
     //! the constructor that performs SVD
-    SVD( const Mat& src, int flags=0 );
+    SVD( const InputArray& src, int flags=0 );
     //! the operator that performs SVD. The previously allocated SVD::u, SVD::w are SVD::vt are released.
-    SVD& operator ()( const Mat& src, int flags=0 );
+    SVD& operator ()( const InputArray& src, int flags=0 );
 
     //! decomposes matrix and stores the results to user-provided matrices
-    static void compute( const Mat& src, CV_OUT Mat& w, CV_OUT Mat& u, CV_OUT Mat& vt, int flags=0 );
+    static void compute( const InputArray& src, OutputArray w,
+                         OutputArray u, OutputArray vt, int flags=0 );
     //! computes singular values of a matrix
-    static void compute( const Mat& src, CV_OUT Mat& w, int flags=0 );
+    static void compute( const InputArray& src, OutputArray w, int flags=0 );
     //! performs back substitution
-    static void backSubst( const Mat& w, const Mat& u, const Mat& vt,
-                           const Mat& rhs, CV_OUT Mat& dst );
+    static void backSubst( const InputArray& w, const InputArray& u,
+                           const InputArray& vt, const InputArray& rhs,
+                           OutputArray dst );
     
     template<typename _Tp, int m, int n, int nm> static void compute( const Matx<_Tp, m, n>& a,
         Matx<_Tp, nm, 1>& w, Matx<_Tp, m, nm>& u, Matx<_Tp, n, nm>& vt );
@@ -2214,29 +2290,29 @@ public:
         const Matx<_Tp, m, nm>& u, const Matx<_Tp, n, nm>& vt, const Matx<_Tp, m, nb>& rhs, Matx<_Tp, n, nb>& dst );
     
     //! finds dst = arg min_{|dst|=1} |m*dst|
-    static void solveZ( const Mat& src, CV_OUT Mat& dst );
+    static void solveZ( const InputArray& src, OutputArray dst );
     //! performs back substitution, so that dst is the solution or pseudo-solution of m*dst = rhs, where m is the decomposed matrix 
-    void backSubst( const Mat& rhs, CV_OUT Mat& dst ) const;
+    void backSubst( const InputArray& rhs, OutputArray dst ) const;
 
     Mat u, w, vt;
 };
 
 //! computes Mahalanobis distance between two vectors: sqrt((v1-v2)'*icovar*(v1-v2)), where icovar is the inverse covariation matrix
-CV_EXPORTS_W double Mahalanobis(const Mat& v1, const Mat& v2, const Mat& icovar);
+CV_EXPORTS_W double Mahalanobis(const InputArray& v1, const InputArray& v2, const InputArray& icovar);
 //! a synonym for Mahalanobis
-CV_EXPORTS double Mahalonobis(const Mat& v1, const Mat& v2, const Mat& icovar);
+CV_EXPORTS double Mahalonobis(const InputArray& v1, const InputArray& v2, const InputArray& icovar);
 
 //! performs forward or inverse 1D or 2D Discrete Fourier Transformation
-CV_EXPORTS_W void dft(const Mat& src, CV_OUT Mat& dst, int flags=0, int nonzeroRows=0);
+CV_EXPORTS_W void dft(const InputArray& src, OutputArray dst, int flags=0, int nonzeroRows=0);
 //! performs inverse 1D or 2D Discrete Fourier Transformation
-CV_EXPORTS_W void idft(const Mat& src, CV_OUT Mat& dst, int flags=0, int nonzeroRows=0);
+CV_EXPORTS_W void idft(const InputArray& src, OutputArray dst, int flags=0, int nonzeroRows=0);
 //! performs forward or inverse 1D or 2D Discrete Cosine Transformation
-CV_EXPORTS_W void dct(const Mat& src, CV_OUT Mat& dst, int flags=0);
+CV_EXPORTS_W void dct(const InputArray& src, OutputArray dst, int flags=0);
 //! performs inverse 1D or 2D Discrete Cosine Transformation
-CV_EXPORTS_W void idct(const Mat& src, CV_OUT Mat& dst, int flags=0);
+CV_EXPORTS_W void idct(const InputArray& src, OutputArray dst, int flags=0);
 //! computes element-wise product of the two Fourier spectrums. The second spectrum can optionally be conjugated before the multiplication
-CV_EXPORTS_W void mulSpectrums(const Mat& a, const Mat& b, CV_OUT Mat& c,
-                             int flags, bool conjB=false);
+CV_EXPORTS_W void mulSpectrums(const InputArray& a, const InputArray& b, OutputArray c,
+                               int flags, bool conjB=false);
 //! computes the minimal vector size vecsize1 >= vecsize so that the dft() of the vector of length vecsize1 can be computed efficiently
 CV_EXPORTS_W int getOptimalDFTSize(int vecsize);
 
@@ -2250,9 +2326,9 @@ enum
     KMEANS_USE_INITIAL_LABELS=1 // Uses the user-provided labels for K-Means initialization
 };
 //! clusters the input data using k-Means algorithm
-CV_EXPORTS_W double kmeans( const Mat& data, int K, CV_OUT Mat& bestLabels,
-                          TermCriteria criteria, int attempts,
-                          int flags, CV_OUT Mat* centers=0 );
+CV_EXPORTS_W double kmeans( const InputArray& data, int K, CV_OUT InputOutputArray bestLabels,
+                            TermCriteria criteria, int attempts,
+                            int flags, OutputArray centers=OutputArray() );
 
 //! returns the thread-local Random number generator
 CV_EXPORTS RNG& theRNG();
@@ -2261,13 +2337,13 @@ CV_EXPORTS RNG& theRNG();
 template<typename _Tp> static inline _Tp randu() { return (_Tp)theRNG(); }
 
 //! fills array with uniformly-distributed random numbers from the range [low, high)
-CV_EXPORTS_W void randu(CV_OUT Mat& dst, const Scalar& low, const Scalar& high);
+CV_EXPORTS_W void randu(CV_IN_OUT OutputArray dst, const InputArray& low, const InputArray& high);
     
 //! fills array with normally-distributed random numbers with the specified mean and the standard deviation
-CV_EXPORTS_W void randn(CV_OUT Mat& dst, const Scalar& mean, const Scalar& stddev);
+CV_EXPORTS_W void randn(CV_IN_OUT OutputArray dst, const InputArray& mean, const InputArray& stddev);
 
 //! shuffles the input array elements
-CV_EXPORTS void randShuffle(Mat& dst, double iterFactor=1., RNG* rng=0);
+CV_EXPORTS void randShuffle(InputOutputArray dst, double iterFactor=1., RNG* rng=0);
 
 //! draws the line segment (pt1, pt2) in the image
 CV_EXPORTS_W void line(Mat& img, Point pt1, Point pt2, const Scalar& color,
@@ -2351,8 +2427,8 @@ public:
 
 //! converts elliptic arc to a polygonal curve
 CV_EXPORTS_W void ellipse2Poly( Point center, Size axes, int angle,
-                              int arcStart, int arcEnd, int delta,
-                              CV_OUT vector<Point>& pts );
+                                int arcStart, int arcEnd, int delta,
+                                CV_OUT vector<Point>& pts );
 
 enum
 {
@@ -2828,6 +2904,7 @@ template<typename _Tp, size_t fixed_size=4096/sizeof(_Tp)+8> class CV_EXPORTS Au
 {
 public:
     typedef _Tp value_type;
+    enum { buffer_padding = (int)((16 + sizeof(_Tp) - 1)/sizeof(_Tp)) };
 
     //! the default contructor
     AutoBuffer();
@@ -2851,7 +2928,7 @@ protected:
     //! size of the real buffer
     size_t size;
     //! pre-allocated buffer
-    _Tp buf[fixed_size];
+    _Tp buf[fixed_size+buffer_padding];
 };
 
 /////////////////////////// multi-dimensional dense matrix //////////////////////////
@@ -2912,9 +2989,11 @@ public:
     //! the default constructor
     NAryMatIterator();
     //! the full constructor taking arbitrary number of n-dim matrices
+    NAryMatIterator(const Mat** arrays, uchar** ptrs, int narrays=-1);
+    //! the full constructor taking arbitrary number of n-dim matrices
     NAryMatIterator(const Mat** arrays, Mat* planes, int narrays=-1);
     //! the separate iterator initialization method
-    void init(const Mat** arrays, Mat* planes, int narrays=-1);
+    void init(const Mat** arrays, Mat* planes, uchar** ptrs, int narrays=-1);
 
     //! proceeds to the next plane of every iterated matrix 
     NAryMatIterator& operator ++();
@@ -2925,12 +3004,17 @@ public:
     const Mat** arrays;
     //! the current planes
     Mat* planes;
+    //! data pointers
+    uchar** ptrs;
     //! the number of arrays
     int narrays;
-    //! the number of planes in each array
-    int nplanes;
+    //! the number of hyper-planes that the iterator steps through
+    size_t nplanes;
+    //! the size of each segment (in elements)
+    size_t size;
 protected:
-    int iterdepth, idx;
+    int iterdepth;
+    size_t idx;
 };
     
 //typedef NAryMatIterator NAryMatNDIterator;
@@ -3081,7 +3165,7 @@ public:
      \param try1d if true and m is a single-column matrix (Nx1),
             then the sparse matrix will be 1-dimensional.
     */ 
-    SparseMat(const Mat& m);
+    explicit SparseMat(const Mat& m);
     //! converts old-style sparse matrix to the new-style. All the data is copied
     SparseMat(const CvSparseMat* m);
     //! the destructor
@@ -3563,39 +3647,30 @@ public:
     //! the default constructor
     CV_WRAP KDTree();
     //! the full constructor that builds the search tree
-    CV_WRAP KDTree(const Mat& _points, bool copyAndReorderPoints=false);
+    CV_WRAP KDTree(const InputArray& points, bool copyAndReorderPoints=false);
     //! the full constructor that builds the search tree
-    CV_WRAP KDTree(const Mat& _points, const Mat& _labels, bool copyAndReorderPoints=false);
+    CV_WRAP KDTree(const InputArray& points, const InputArray& _labels,
+                   bool copyAndReorderPoints=false);
     //! builds the search tree
-    CV_WRAP void build(const Mat& _points, bool copyAndReorderPoints=false);
+    CV_WRAP void build(const InputArray& points, bool copyAndReorderPoints=false);
     //! builds the search tree
-    CV_WRAP void build(const Mat& _points, const Mat& _labels, bool copyAndReorderPoints=false);
+    CV_WRAP void build(const InputArray& points, const InputArray& labels,
+                       bool copyAndReorderPoints=false);
     //! finds the K nearest neighbors of "vec" while looking at Emax (at most) leaves
-    int findNearest(const float* vec,
-                    int K, int Emax, int* neighborsIdx,
-                    Mat* neighbors=0, float* dist=0, int* labels=0) const;
-    //! finds the K nearest neighbors while looking at Emax (at most) leaves
-    int findNearest(const float* vec, int K, int Emax,
-                    vector<int>* neighborsIdx,
-                    Mat* neighbors=0,
-                    vector<float>* dist=0,
-                    vector<int>* labels=0) const;
-    CV_WRAP int findNearest(const vector<float>& vec, int K, int Emax,
-                    CV_OUT vector<int>* neighborsIdx,
-                    CV_OUT Mat* neighbors=0,
-                    CV_OUT vector<float>* dist=0,
-                    CV_OUT vector<int>* labels=0) const;
+    CV_WRAP int findNearest(const InputArray& vec, int K, int Emax,
+                            OutputArray neighborsIdx,
+                            OutputArray neighbors=OutputArray(),
+                            OutputArray dist=OutputArray(),
+                            OutputArray labels=OutputArray()) const;
     //! finds all the points from the initial set that belong to the specified box 
-    void findOrthoRange(const float* minBounds, const float* maxBounds,
-                        vector<int>* neighborsIdx, Mat* neighbors=0,
-                        vector<int>* labels=0) const;
-    CV_WRAP void findOrthoRange(const vector<float>& minBounds, const vector<float>& maxBounds,
-                                CV_OUT vector<int>* neighborsIdx, CV_OUT Mat* neighbors=0,
-                                CV_OUT vector<int>* labels=0) const;
+    CV_WRAP void findOrthoRange(const InputArray& minBounds,
+                                const InputArray& maxBounds,
+                                OutputArray neighborsIdx,
+                                OutputArray neighbors=OutputArray(),
+                                OutputArray labels=OutputArray()) const;
     //! returns vectors with the specified indices
-    void getPoints(const int* idx, size_t nidx, Mat& pts, vector<int>* labels=0) const;
-    //! returns vectors with the specified indices
-    CV_WRAP void getPoints(const vector<int>& idxs, Mat& pts, CV_OUT vector<int>* labels=0) const;
+    CV_WRAP void getPoints(const InputArray& idx, OutputArray pts,
+                           OutputArray labels=OutputArray()) const;
     //! return a vector with the specified index
     const float* getPoint(int ptidx, int* label=0) const;
     //! returns the search space dimensionality
@@ -4042,7 +4117,7 @@ public:
     int index;
 };
 
-#if 0    
+    
 class CV_EXPORTS AlgorithmImpl;
 
 /*!
@@ -4088,7 +4163,6 @@ protected:
     
     Ptr<AlgorithmImpl> impl;
 };
-#endif
     
 }
 
index 22b65fa..41cd458 100644 (file)
@@ -608,21 +608,6 @@ template<typename _Tp> inline MatIterator_<_Tp> Mat::end()
     return it;
 }
 
-    
-template<typename _Tp> inline void Mat::copyTo(vector<_Tp>& v) const
-{
-    int n = checkVector(DataType<_Tp>::channels);
-    if( empty() || n == 0 )
-    {
-        v.clear();
-        return;
-    }
-    CV_Assert( n > 0 );
-    v.resize(n);
-    Mat temp(dims, size.p, DataType<_Tp>::type, &v[0]);
-    convertTo(temp, DataType<_Tp>::type);
-}    
-    
 template<typename _Tp> inline Mat::operator vector<_Tp>() const
 {
     vector<_Tp> v;
@@ -726,10 +711,12 @@ static inline Mat cvarrToMatND(const CvArr* arr, bool copyData=false, int coiMod
 ///////////////////////////////////////////// SVD //////////////////////////////////////////////////////
 
 inline SVD::SVD() {}
-inline SVD::SVD( const Mat& m, int flags ) { operator ()(m, flags); }
-inline void SVD::solveZ( const Mat& m, Mat& dst )
+inline SVD::SVD( const InputArray& m, int flags ) { operator ()(m, flags); }
+inline void SVD::solveZ( const InputArray& m, OutputArray _dst )
 {
     SVD svd(m);
+    _dst.create(svd.vt.cols, 1, svd.vt.type());
+    Mat dst = _dst.getMat();
     svd.vt.row(svd.vt.rows-1).reshape(1,svd.vt.cols).copyTo(dst);
 }
 
@@ -1075,6 +1062,22 @@ process( const Mat_<T1>& m1, const Mat_<T2>& m2, Mat_<T3>& m3, Op op )
     }
 }
 
+    
+/////////////////////////////// Input/Output Arrays /////////////////////////////////
+    
+template<typename _Tp> InputArray::InputArray(const vector<_Tp>& vec)
+    : flags(STD_VECTOR + DataType<_Tp>::type), obj((void*)&vec) {}
+
+template<typename _Tp> InputArray::InputArray(const vector<vector<_Tp> >& vec)
+    : flags(STD_VECTOR_VECTOR + DataType<_Tp>::type), obj((void*)&vec) {}
+
+template<typename _Tp, int m, int n> InputArray::InputArray(const Matx<_Tp, m, n>& mtx)
+    : flags(MATX + DataType<_Tp>::type), obj((void*)&mtx), sz(n, m) {}
+
+template<typename _Tp> OutputArray::OutputArray(vector<_Tp>& vec) : InputArray(vec) {}
+template<typename _Tp> OutputArray::OutputArray(vector<vector<_Tp> >& vec) : InputArray(vec) {}
+template<typename _Tp, int m, int n> OutputArray::OutputArray(Matx<_Tp, m, n>& mtx) : InputArray(mtx) {}
+    
 //////////////////////////////////// Matrix Expressions /////////////////////////////////////////
 
 class CV_EXPORTS MatOp
@@ -1113,6 +1116,9 @@ public:
     virtual void transpose(const MatExpr& expr, MatExpr& res) const;
     virtual void matmul(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const;
     virtual void invert(const MatExpr& expr, int method, MatExpr& res) const;
+    
+    virtual Size size(const MatExpr& expr) const;
+    virtual int type(const MatExpr& expr) const;
 };
 
     
@@ -1152,6 +1158,9 @@ public:
     MatExpr mul(const MatExpr& e, double scale=1) const;
     MatExpr mul(const Mat& m, double scale=1) const;
     
+    Size size() const;
+    int type() const;
+    
     const MatOp* op;
     int flags;
     
index 10c94f3..45a6c6e 100644 (file)
@@ -2298,10 +2298,17 @@ inline Point LineIterator::pos() const
 /////////////////////////////// AutoBuffer ////////////////////////////////////////
 
 template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::AutoBuffer()
-: ptr(buf), size(fixed_size) {}
+{
+    ptr = alignPtr(buf, 16);
+    size = fixed_size;
+}
 
 template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::AutoBuffer(size_t _size)
-: ptr(buf), size(fixed_size) { allocate(_size); }
+{
+    ptr = alignPtr(buf, 16);
+    size = fixed_size;
+    allocate(_size);
+}
 
 template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::~AutoBuffer()
 { deallocate(); }
@@ -2320,10 +2327,11 @@ template<typename _Tp, size_t fixed_size> inline void AutoBuffer<_Tp, fixed_size
 
 template<typename _Tp, size_t fixed_size> inline void AutoBuffer<_Tp, fixed_size>::deallocate()
 {
-    if( ptr != buf )
+    _Tp* buf0 = alignPtr(buf, 16);
+    if( ptr != buf0 )
     {
         cv::deallocate<_Tp>(ptr, size);
-        ptr = buf;
+        ptr = buf0;
         size = fixed_size;
     }
 }
@@ -3550,7 +3558,6 @@ template<typename _Tp> static inline std::ostream& operator << (std::ostream& ou
     return out;
 }
     
-#if 0
 template<typename _Tp> struct AlgorithmParamType {};
 template<> struct AlgorithmParamType<int> { enum { type = CV_PARAM_TYPE_INT }; };
 template<> struct AlgorithmParamType<double> { enum { type = CV_PARAM_TYPE_REAL }; };
@@ -3594,7 +3601,6 @@ template<typename _Tp> void Algorithm::setParamRange(int propId, const _Tp& minV
 {
     setParamRange_(propId, AlgorithmParamType<_Tp>::type, &minVal, &maxVal);
 }
-#endif
     
 }
 
index 8675ddd..0101896 100644 (file)
@@ -11,7 +11,7 @@
 //                For Open Source Computer Vision Library
 //
 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
-// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
 // Third party copyrights are property of their respective owners.
 //
 // Redistribution and use in source and binary forms, with or without modification,
 
 /* ////////////////////////////////////////////////////////////////////
 //
-//  Matrix arithmetic and logical operations: +, -, *, /, &, |, ^, ~, abs ...
+//  Arithmetic and logical operations: +, -, *, /, &, |, ^, ~, abs ...
 //
 // */
 
 #include "precomp.hpp"
 
-#ifdef HAVE_IPP
-#include "ippversion.h"
-#endif
-
 namespace cv
 {
 
-#if CV_SSE2
+#if ARITHM_USE_IPP
+struct IPPArithmInitializer
+{
+    IPPArithmInitializer(void)
+    {
+        IppStatus status = ippStaticInit();
+    }
+};
 
-enum { ARITHM_SIMD = CV_CPU_SSE2 };
+IPPArithmInitializer ippArithmInitializer;
+#endif
 
-template<class Op8> struct VBinOp8
+struct NOP {};
+    
+template<typename T, class Op, class Op8>
+void vBinOp8(const T* src1, size_t step1, const T* src2, size_t step2, T* dst, size_t step, Size sz)
 {
-    int operator()(const uchar* src1, const uchar* src2, uchar* dst, int len) const
+    Op8 op8;
+    Op op;
+    
+    for( ; sz.height--; src1 += step1/sizeof(src1[0]),
+                        src2 += step2/sizeof(src2[0]),
+                        dst += step/sizeof(dst[0]) )
     {
         int x = 0;
-        for( ; x <= len - 32; x += 32 )
+        
+    #if CV_SSE2
+        if( USE_SSE2 )
         {
-            __m128i r0 = _mm_loadu_si128((const __m128i*)(src1 + x));
-            __m128i r1 = _mm_loadu_si128((const __m128i*)(src1 + x + 16));
-            r0 = op(r0,_mm_loadu_si128((const __m128i*)(src2 + x)));
-            r1 = op(r1,_mm_loadu_si128((const __m128i*)(src2 + x + 16)));
-            _mm_storeu_si128((__m128i*)(dst + x), r0);
-            _mm_storeu_si128((__m128i*)(dst + x + 16), r1);
+            for( ; x <= sz.width - 32; x += 32 )
+            {
+                __m128i r0 = _mm_loadu_si128((const __m128i*)(src1 + x));
+                __m128i r1 = _mm_loadu_si128((const __m128i*)(src1 + x + 16));
+                r0 = op8(r0,_mm_loadu_si128((const __m128i*)(src2 + x)));
+                r1 = op8(r1,_mm_loadu_si128((const __m128i*)(src2 + x + 16)));
+                _mm_storeu_si128((__m128i*)(dst + x), r0);
+                _mm_storeu_si128((__m128i*)(dst + x + 16), r1);
+            }
+            for( ; x <= sz.width - 8; x += 8 )
+            {
+                __m128i r0 = _mm_loadl_epi64((const __m128i*)(src1 + x));
+                r0 = op8(r0,_mm_loadl_epi64((const __m128i*)(src2 + x)));
+                _mm_storel_epi64((__m128i*)(dst + x), r0);
+            }
         }
-        for( ; x <= len - 8; x += 8 )
+    #endif
+        
+        for( ; x <= sz.width - 4; x += 4 )
         {
-            __m128i r0 = _mm_loadl_epi64((const __m128i*)(src1 + x));
-            r0 = op(r0,_mm_loadl_epi64((const __m128i*)(src2 + x)));
-            _mm_storel_epi64((__m128i*)(dst + x), r0);
+            T v0 = op(src1[x], src2[x]);
+            T v1 = op(src1[x+1], src2[x+1]);
+            dst[x] = v0; dst[x+1] = v1;
+            v0 = op(src1[x+2], src2[x+2]);
+            v1 = op(src1[x+3], src2[x+3]);
+            dst[x+2] = v0; dst[x+3] = v1;
         }
-        return x;
+        
+        for( ; x < sz.width; x++ )
+            dst[x] = op(src1[x], src2[x]);
     }
-    Op8 op;
-};
+}
 
-template<typename T, class Op16> struct VBinOp16
+template<typename T, class Op, class Op16>
+void vBinOp16(const T* src1, size_t step1, const T* src2, size_t step2,
+              T* dst, size_t step, Size sz)
 {
-    int operator()(const T* src1, const T* src2, T* dst, int len) const
+    Op16 op16;
+    Op op;
+    
+    for( ; sz.height--; src1 += step1/sizeof(src1[0]),
+        src2 += step2/sizeof(src2[0]),
+        dst += step/sizeof(dst[0]) )
     {
         int x = 0;
-        for( ; x <= len - 16; x += 16 )
+        
+    #if CV_SSE2
+        if( USE_SSE2 )
         {
-            __m128i r0 = _mm_loadu_si128((const __m128i*)(src1 + x));
-            __m128i r1 = _mm_loadu_si128((const __m128i*)(src1 + x + 8));
-            r0 = op(r0,_mm_loadu_si128((const __m128i*)(src2 + x)));
-            r1 = op(r1,_mm_loadu_si128((const __m128i*)(src2 + x + 8)));
-            _mm_storeu_si128((__m128i*)(dst + x), r0);
-            _mm_storeu_si128((__m128i*)(dst + x + 8), r1);
+            for( ; x <= sz.width - 16; x += 16 )
+            {
+                __m128i r0 = _mm_loadu_si128((const __m128i*)(src1 + x));
+                __m128i r1 = _mm_loadu_si128((const __m128i*)(src1 + x + 8));
+                r0 = op16(r0,_mm_loadu_si128((const __m128i*)(src2 + x)));
+                r1 = op16(r1,_mm_loadu_si128((const __m128i*)(src2 + x + 8)));
+                _mm_storeu_si128((__m128i*)(dst + x), r0);
+                _mm_storeu_si128((__m128i*)(dst + x + 16), r1);
+            }
+            for( ; x <= sz.width - 4; x += 4 )
+            {
+                __m128i r0 = _mm_loadl_epi64((const __m128i*)(src1 + x));
+                r0 = op16(r0,_mm_loadl_epi64((const __m128i*)(src2 + x)));
+                _mm_storel_epi64((__m128i*)(dst + x), r0);
+            }
         }
-        for( ; x <= len - 4; x += 4 )
+        else
+    #endif
+        
+        for( ; x <= sz.width - 4; x += 4 )
         {
-            __m128i r0 = _mm_loadl_epi64((const __m128i*)(src1 + x));
-            r0 = op(r0,_mm_loadl_epi64((const __m128i*)(src2 + x)));
-            _mm_storel_epi64((__m128i*)(dst + x), r0);
+            T v0 = op(src1[x], src2[x]);
+            T v1 = op(src1[x+1], src2[x+1]);
+            dst[x] = v0; dst[x+1] = v1;
+            v0 = op(src1[x+2], src2[x+2]);
+            v1 = op(src1[x+3], src2[x+3]);
+            dst[x+2] = v0; dst[x+3] = v1;
         }
-        return x;
+        
+        for( ; x < sz.width; x++ )
+            dst[x] = op(src1[x], src2[x]);
     }
-    Op16 op;
-};
+}
 
-template<class Op32f> struct VBinOp32f
+    
+template<class Op, class Op32>
+void vBinOp32s(const int* src1, size_t step1, const int* src2, size_t step2,
+               int* dst, size_t step, Size sz)
 {
-    int operator()(const float* src1, const float* src2, float* dst, int len) const
+    Op32 op32;
+    Op op;
+    
+    for( ; sz.height--; src1 += step1/sizeof(src1[0]),
+        src2 += step2/sizeof(src2[0]),
+        dst += step/sizeof(dst[0]) )
     {
         int x = 0;
-        if( (((size_t)src1|(size_t)src2|(size_t)dst)&15) == 0 )
-            for( ; x <= len - 8; x += 8 )
+        
+#if CV_SSE2
+        if( USE_SSE2 )
+        {
+            if( (((size_t)src1|(size_t)src2|(size_t)dst)&15) == 0 )
+                for( ; x <= sz.width - 8; x += 8 )
+                {
+                    __m128i r0 = _mm_load_si128((const __m128i*)(src1 + x));
+                    __m128i r1 = _mm_load_si128((const __m128i*)(src1 + x + 4));
+                    r0 = op32(r0,_mm_load_si128((const __m128i*)(src2 + x)));
+                    r1 = op32(r1,_mm_load_si128((const __m128i*)(src2 + x + 4)));
+                    _mm_store_si128((__m128i*)(dst + x), r0);
+                    _mm_store_si128((__m128i*)(dst + x + 16), r1);
+                }
+            else
+                for( ; x <= sz.width - 8; x += 8 )
+                {
+                    __m128i r0 = _mm_loadu_si128((const __m128i*)(src1 + x));
+                    __m128i r1 = _mm_loadu_si128((const __m128i*)(src1 + x + 4));
+                    r0 = op32(r0,_mm_loadu_si128((const __m128i*)(src2 + x)));
+                    r1 = op32(r1,_mm_loadu_si128((const __m128i*)(src2 + x + 4)));
+                    _mm_storeu_si128((__m128i*)(dst + x), r0);
+                    _mm_storeu_si128((__m128i*)(dst + x + 16), r1);
+                }
+        }
+#endif
+        
+        for( ; x <= sz.width - 4; x += 4 )
+        {
+            int v0 = op(src1[x], src2[x]);
+            int v1 = op(src1[x+1], src2[x+1]);
+            dst[x] = v0; dst[x+1] = v1;
+            v0 = op(src1[x+2], src2[x+2]);
+            v1 = op(src1[x+3], src2[x+3]);
+            dst[x+2] = v0; dst[x+3] = v1;
+        }
+        
+        for( ; x < sz.width; x++ )
+            dst[x] = op(src1[x], src2[x]);
+    }
+}
+
+    
+template<class Op, class Op32>
+void vBinOp32f(const float* src1, size_t step1, const float* src2, size_t step2,
+               float* dst, size_t step, Size sz)
+{
+    Op32 op32;
+    Op op;
+    
+    for( ; sz.height--; src1 += step1/sizeof(src1[0]),
+        src2 += step2/sizeof(src2[0]),
+        dst += step/sizeof(dst[0]) )
+    {
+        int x = 0;
+        
+    #if CV_SSE2
+        if( USE_SSE2 )
+        {
+            if( (((size_t)src1|(size_t)src2|(size_t)dst)&15) == 0 )
+                for( ; x <= sz.width - 8; x += 8 )
+                {
+                    __m128 r0 = _mm_load_ps(src1 + x);
+                    __m128 r1 = _mm_load_ps(src1 + x + 4);
+                    r0 = op32(r0,_mm_load_ps(src2 + x));
+                    r1 = op32(r1,_mm_load_ps(src2 + x + 4));
+                    _mm_store_ps(dst + x, r0);
+                    _mm_store_ps(dst + x + 4, r1);
+                }
+            else
+                for( ; x <= sz.width - 8; x += 8 )
+                {
+                    __m128 r0 = _mm_loadu_ps(src1 + x);
+                    __m128 r1 = _mm_loadu_ps(src1 + x + 4);
+                    r0 = op32(r0,_mm_loadu_ps(src2 + x));
+                    r1 = op32(r1,_mm_loadu_ps(src2 + x + 4));
+                    _mm_storeu_ps(dst + x, r0);
+                    _mm_storeu_ps(dst + x + 4, r1);
+                }
+        }
+    #endif
+        for( ; x <= sz.width - 4; x += 4 )
+        {
+            float v0 = op(src1[x], src2[x]);
+            float v1 = op(src1[x+1], src2[x+1]);
+            dst[x] = v0; dst[x+1] = v1;
+            v0 = op(src1[x+2], src2[x+2]);
+            v1 = op(src1[x+3], src2[x+3]);
+            dst[x+2] = v0; dst[x+3] = v1;
+        }
+        
+        for( ; x < sz.width; x++ )
+            dst[x] = op(src1[x], src2[x]);
+    }
+}
+
+template<class Op, class Op64>
+void vBinOp64f(const double* src1, size_t step1, const double* src2, size_t step2,
+               double* dst, size_t step, Size sz)
+{
+    Op64 op64;
+    Op op;
+    
+    for( ; sz.height--; src1 += step1/sizeof(src1[0]),
+        src2 += step2/sizeof(src2[0]),
+        dst += step/sizeof(dst[0]) )
+    {
+        int x = 0;
+        
+    #if CV_SSE2
+        if( USE_SSE2 && (((size_t)src1|(size_t)src2|(size_t)dst)&15) == 0 )
+            for( ; x <= sz.width - 4; x += 4 )
             {
-                __m128 r0 = _mm_load_ps(src1 + x);
-                __m128 r1 = _mm_load_ps(src1 + x + 4);
-                r0 = op(r0,_mm_load_ps(src2 + x));
-                r1 = op(r1,_mm_load_ps(src2 + x + 4));
-                _mm_store_ps(dst + x, r0);
-                _mm_store_ps(dst + x + 4, r1);
+                __m128d r0 = _mm_load_pd(src1 + x);
+                __m128d r1 = _mm_load_pd(src1 + x + 2);
+                r0 = op64(r0,_mm_load_pd(src2 + x));
+                r1 = op64(r1,_mm_load_pd(src2 + x + 2));
+                _mm_store_pd(dst + x, r0);
+                _mm_store_pd(dst + x + 2, r1);
             }
         else
-            for( ; x <= len - 8; x += 8 )
-            {
-                __m128 r0 = _mm_loadu_ps(src1 + x);
-                __m128 r1 = _mm_loadu_ps(src1 + x + 4);
-                r0 = op(r0,_mm_loadu_ps(src2 + x));
-                r1 = op(r1,_mm_loadu_ps(src2 + x + 4));
-                _mm_storeu_ps(dst + x, r0);
-                _mm_storeu_ps(dst + x + 4, r1);
-            }
-        return x;
+    #endif
+        for( ; x <= sz.width - 4; x += 4 )
+        {
+            double v0 = op(src1[x], src2[x]);
+            double v1 = op(src1[x+1], src2[x+1]);
+            dst[x] = v0; dst[x+1] = v1;
+            v0 = op(src1[x+2], src2[x+2]);
+            v1 = op(src1[x+3], src2[x+3]);
+            dst[x+2] = v0; dst[x+3] = v1;
+        }
+        
+        for( ; x < sz.width; x++ )
+            dst[x] = op(src1[x], src2[x]);
     }
-    Op32f op;
-};
-
+}
+    
+#if CV_SSE2
+    
 struct _VAdd8u { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_adds_epu8(a,b); }};
 struct _VSub8u { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_subs_epu8(a,b); }};
 struct _VMin8u { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_min_epu8(a,b); }};
 struct _VMax8u { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_max_epu8(a,b); }};
-struct _VCmpGT8u { __m128i operator()(const __m128i& a, const __m128i& b) const
-{
-    __m128i delta = _mm_set1_epi32(0x80808080);
-    return _mm_cmpgt_epi8(_mm_xor_si128(a,delta),_mm_xor_si128(b,delta));
-}};
-struct _VCmpEQ8u { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_cmpeq_epi8(a,b); }};
 struct _VAbsDiff8u
 {
     __m128i operator()(const __m128i& a, const __m128i& b) const
     { return _mm_add_epi8(_mm_subs_epu8(a,b),_mm_subs_epu8(b,a)); }
 };
+
+struct _VAdd8s { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_adds_epi8(a,b); }};
+struct _VSub8s { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_subs_epi8(a,b); }};
+struct _VMin8s
+{
+    __m128i operator()(const __m128i& a, const __m128i& b) const
+    {
+        __m128i m = _mm_cmpgt_epi8(a, b);
+        return _mm_xor_si128(a, _mm_and_si128(_mm_xor_si128(a, b), m));
+    }
+};
+struct _VMax8s
+{
+    __m128i operator()(const __m128i& a, const __m128i& b) const
+    {
+        __m128i m = _mm_cmpgt_epi8(b, a);
+        return _mm_xor_si128(a, _mm_and_si128(_mm_xor_si128(a, b), m));
+    }
+};
+struct _VAbsDiff8s
+{
+    __m128i operator()(const __m128i& a, const __m128i& b) const
+    {
+        __m128i d = _mm_subs_epi8(a, b);
+        __m128i m = _mm_cmpgt_epi8(b, a);
+        return _mm_subs_epi8(_mm_xor_si128(d, m), m);
+    }
+};
+
 struct _VAdd16u { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_adds_epu16(a,b); }};
 struct _VSub16u { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_subs_epu16(a,b); }};
 struct _VMin16u
@@ -171,6 +370,7 @@ struct _VAbsDiff16u
     __m128i operator()(const __m128i& a, const __m128i& b) const
     { return _mm_add_epi16(_mm_subs_epu16(a,b),_mm_subs_epu16(b,a)); }
 };
+
 struct _VAdd16s { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_adds_epi16(a,b); }};
 struct _VSub16s { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_subs_epi16(a,b); }};
 struct _VMin16s { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_min_epi16(a,b); }};
@@ -183,6 +383,35 @@ struct _VAbsDiff16s
         return _mm_subs_epi16(M, m);
     }
 };
+
+struct _VAdd32s { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_add_epi32(a,b); }};
+struct _VSub32s { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_sub_epi32(a,b); }};
+struct _VMin32s
+{
+    __m128i operator()(const __m128i& a, const __m128i& b) const
+    {
+        __m128i m = _mm_cmpgt_epi32(a, b);
+        return _mm_xor_si128(a, _mm_and_si128(_mm_xor_si128(a, b), m));
+    }
+};
+struct _VMax32s
+{
+    __m128i operator()(const __m128i& a, const __m128i& b) const
+    {
+        __m128i m = _mm_cmpgt_epi32(b, a);
+        return _mm_xor_si128(a, _mm_and_si128(_mm_xor_si128(a, b), m));
+    }
+};
+struct _VAbsDiff32s
+{
+    __m128i operator()(const __m128i& a, const __m128i& b) const
+    {
+        __m128i d = _mm_sub_epi32(a, b);
+        __m128i m = _mm_cmpgt_epi32(b, a);
+        return _mm_sub_epi32(_mm_xor_si128(d, m), m);
+    }
+};    
+
 struct _VAdd32f { __m128 operator()(const __m128& a, const __m128& b) const { return _mm_add_ps(a,b); }};
 struct _VSub32f { __m128 operator()(const __m128& a, const __m128& b) const { return _mm_sub_ps(a,b); }};
 struct _VMin32f { __m128 operator()(const __m128& a, const __m128& b) const { return _mm_min_ps(a,b); }};
@@ -196,862 +425,968 @@ struct _VAbsDiff32f
     }
 };
 
+struct _VAdd64f { __m128d operator()(const __m128d& a, const __m128d& b) const { return _mm_add_pd(a,b); }};
+struct _VSub64f { __m128d operator()(const __m128d& a, const __m128d& b) const { return _mm_sub_pd(a,b); }};
+struct _VMin64f { __m128d operator()(const __m128d& a, const __m128d& b) const { return _mm_min_pd(a,b); }};
+struct _VMax64f { __m128d operator()(const __m128d& a, const __m128d& b) const { return _mm_max_pd(a,b); }};
+    
+static int CV_DECL_ALIGNED(16) v64f_absmask[] = { 0xffffffff, 0x7fffffff, 0xffffffff, 0x7fffffff };
+struct _VAbsDiff64f
+{
+    __m128d operator()(const __m128d& a, const __m128d& b) const
+    {
+        return _mm_and_pd(_mm_sub_pd(a,b), *(const __m128d*)v64f_absmask);
+    }
+};    
+    
 struct _VAnd8u { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_and_si128(a,b); }};
 struct _VOr8u  { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_or_si128(a,b); }};
 struct _VXor8u { __m128i operator()(const __m128i& a, const __m128i& b) const { return _mm_xor_si128(a,b); }};
+struct _VNot8u { __m128i operator()(const __m128i& a, const __m128i&) const { return _mm_andnot_si128(_mm_setzero_si128(),a); }};
+    
+#endif
 
-typedef VBinOp8<_VAdd8u> VAdd8u;
-typedef VBinOp8<_VSub8u> VSub8u;
-typedef VBinOp8<_VMin8u> VMin8u;
-typedef VBinOp8<_VMax8u> VMax8u;
-typedef VBinOp8<_VAbsDiff8u> VAbsDiff8u;
-typedef VBinOp8<_VCmpEQ8u> VCmpEQ8u;
-typedef VBinOp8<_VCmpGT8u> VCmpGT8u;
-
-typedef VBinOp16<ushort, _VAdd16u> VAdd16u;
-typedef VBinOp16<ushort, _VSub16u> VSub16u;
-typedef VBinOp16<ushort, _VMin16u> VMin16u;
-typedef VBinOp16<ushort, _VMax16u> VMax16u;
-typedef VBinOp16<ushort, _VAbsDiff16u> VAbsDiff16u;
-
-typedef VBinOp16<short, _VAdd16s> VAdd16s;
-typedef VBinOp16<short, _VSub16s> VSub16s;
-typedef VBinOp16<short, _VMin16s> VMin16s;
-typedef VBinOp16<short, _VMax16s> VMax16s;
-typedef VBinOp16<short, _VAbsDiff16s> VAbsDiff16s;
-
-typedef VBinOp32f<_VAdd32f> VAdd32f;
-typedef VBinOp32f<_VSub32f> VSub32f;
-typedef VBinOp32f<_VMin32f> VMin32f;
-typedef VBinOp32f<_VMax32f> VMax32f;
-typedef VBinOp32f<_VAbsDiff32f> VAbsDiff32f;
-
-typedef VBinOp8<_VAnd8u> VAnd8u;
-typedef VBinOp8<_VOr8u> VOr8u;
-typedef VBinOp8<_VXor8u> VXor8u;
-
+#if CV_SSE2
+#define IF_SIMD(op) op
 #else
-
-enum { ARITHM_SIMD = CV_CPU_NONE };
-
-typedef NoVec VAdd8u;
-typedef NoVec VSub8u;
-typedef NoVec VMin8u;
-typedef NoVec VMax8u;
-typedef NoVec VAbsDiff8u;
-typedef NoVec VCmpEQ8u;
-typedef NoVec VCmpGT8u;
-
-typedef NoVec VAdd16u;
-typedef NoVec VSub16u;
-typedef NoVec VMin16u;
-typedef NoVec VMax16u;
-typedef NoVec VAbsDiff16u;
-
-typedef NoVec VAdd16s;
-typedef NoVec VSub16s;
-typedef NoVec VMin16s;
-typedef NoVec VMax16s;
-typedef NoVec VAbsDiff16s;
-
-typedef NoVec VAdd32f;
-typedef NoVec VSub32f;
-typedef NoVec VMin32f;
-typedef NoVec VMax32f;
-typedef NoVec VAbsDiff32f;
-
-typedef NoVec VAnd8u;
-typedef NoVec VOr8u;
-typedef NoVec VXor8u;
-
+#define IF_SIMD(op) NOP
 #endif
-
-
-#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
-struct IPPArithmInitializer
+    
+template<> inline uchar OpAdd<uchar>::operator ()(uchar a, uchar b) const
+{ return CV_FAST_CAST_8U(a + b); }
+template<> inline uchar OpSub<uchar>::operator ()(uchar a, uchar b) const
+{ return CV_FAST_CAST_8U(a - b); }
+    
+template<typename T> struct OpAbsDiff
 {
-    IPPArithmInitializer(void)
-    {
-      IppStatus status = ippStaticInit();
-    }
+    typedef T type1;
+    typedef T type2;
+    typedef T rtype;
+    T operator()(T a, T b) const { return (T)std::abs(a - b); }
 };
 
-IPPArithmInitializer ippArithmInitializer;
+template<> inline short OpAbsDiff<short>::operator ()(short a, short b) const
+{ return saturate_cast<short>(std::abs(a - b)); }
 
-struct ippAdd8u
+template<> inline schar OpAbsDiff<schar>::operator ()(schar a, schar b) const
+{ return saturate_cast<schar>(std::abs(a - b)); }
+    
+template<typename T, typename WT=T> struct OpAbsDiffS
 {
-    int operator()(const Ipp8u* src1, const Ipp8u* src2, Ipp8u* dst, int len) const
-    {
-        ippsAdd_8u_Sfs(src1,src2,dst,len,0);
-        return len;
-    }
+    typedef T type1;
+    typedef WT type2;
+    typedef T rtype;
+    T operator()(T a, WT b) const { return saturate_cast<T>(std::abs(a - b)); }
 };
 
-struct ippAdd16u
+template<typename T> struct OpAnd
 {
-    int operator()(const Ipp16u* src1, const Ipp16u* src2, Ipp16u* dst, int len) const
-    {
-        ippsAdd_16u_Sfs(src1,src2,dst,len,0);
-        return len;
-    }
+    typedef T type1;
+    typedef T type2;
+    typedef T rtype;
+    T operator()( T a, T b ) const { return a & b; }
 };
 
-struct ippAdd16s
+template<typename T> struct OpOr
 {
-    int operator()(const Ipp16s* src1, const Ipp16s* src2, Ipp16s* dst, int len) const
-    {
-        ippsAdd_16s_Sfs(src1,src2,dst,len,0);
-        return len;
-    }
+    typedef T type1;
+    typedef T type2;
+    typedef T rtype;
+    T operator()( T a, T b ) const { return a | b; }
 };
 
-struct ippAdd32s
+template<typename T> struct OpXor
 {
-    int operator()(const Ipp32s* src1, const Ipp32s* src2, Ipp32s* dst, int len) const
-    {
-        ippsAdd_32s_Sfs(src1,src2,dst,len,0);
-        return len;
-    }
+    typedef T type1;
+    typedef T type2;
+    typedef T rtype;
+    T operator()( T a, T b ) const { return a ^ b; }
 };
 
-struct ippAdd32f
+template<typename T> struct OpNot
 {
-    int operator()(const Ipp32f* src1, const Ipp32f* src2, Ipp32f* dst, int len) const
-    {
-        ippsAdd_32f(src1,src2,dst,len);
-        return len;
-    }
+    typedef T type1;
+    typedef T type2;
+    typedef T rtype;
+    T operator()( T a, T ) const { return ~a; }
 };
+    
+static inline void fixSteps(Size sz, size_t elemSize, size_t& step1, size_t& step2, size_t& step)
+{
+    if( sz.height == 1 )
+        step1 = step2 = step = sz.width*elemSize;
+}
+    
+static void add8u( const uchar* src1, size_t step1,
+                   const uchar* src2, size_t step2,
+                   uchar* dst, size_t step, Size sz, void* )
+{
+    IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step);
+           ippiAdd_8u_C1RSfs(src1, (int)step1, src2, (int)step2, dst, (IppiSize&)sz, 0),
+           (vBinOp8<uchar, OpAdd<uchar>, IF_SIMD(_VAdd8u)>(src1, step1, src2, step2, dst, step, sz)));
+}
 
-struct ippAdd64f
+static void add8s( const schar* src1, size_t step1,
+                   const schar* src2, size_t step2,
+                   schar* dst, size_t step, Size sz, void* )
 {
-    int operator()(const Ipp64f* src1, const Ipp64f* src2, Ipp64f* dst, int len) const
-    {
-        ippsAdd_64f(src1,src2,dst,len);
-        return len;
-    }
-};
+    vBinOp8<schar, OpAdd<schar>, IF_SIMD(_VAdd8s)>(src1, step1, src2, step2, dst, step, sz);
+}
 
-struct ippSub8u
+static void add16u( const ushort* src1, size_t step1,
+                    const ushort* src2, size_t step2,
+                    ushort* dst, size_t step, Size sz, void* )
 {
-    int operator()(const Ipp8u* src1, const Ipp8u* src2, Ipp8u* dst, int len) const
-    {
-        ippsSub_8u_Sfs(src2,src1,dst,len,0);
-        return len;
-    }
-};
+    IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step);
+           ippiAdd_16u_C1RSfs(src1, (int)step1, src2, (int)step2, dst, (IppiSize&)sz, 0),
+            (vBinOp16<ushort, OpAdd<ushort>, IF_SIMD(_VAdd16u)>(src1, step1, src2, step2, dst, step, sz)));
+}
 
-struct ippSub16u
+static void add16s( const short* src1, size_t step1,
+                    const short* src2, size_t step2,
+                    short* dst, size_t step, Size sz, void* )
 {
-    int operator()(const Ipp16u* src1, const Ipp16u* src2, Ipp16u* dst, int len) const
-    {
-        ippsSub_16u_Sfs(src2,src1,dst,len,0);
-        return len;
-    }
-};
+    IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step);
+           ippiAdd_16s_C1RSfs(src1, (int)step1, src2, (int)step2, dst, (IppiSize&)sz, 0),
+           (vBinOp16<short, OpAdd<short>, IF_SIMD(_VAdd16s)>(src1, step1, src2, step2, dst, step, sz)));
+}
 
-struct ippSub16s
+static void add32s( const int* src1, size_t step1,
+                    const int* src2, size_t step2,
+                    int* dst, size_t step, Size sz, void* )
 {
-    int operator()(const Ipp16s* src1, const Ipp16s* src2, Ipp16s* dst, int len) const
-    {
-        ippsSub_16s_Sfs(src2,src1,dst,len,0);
-        return len;
-    }
-};
+    vBinOp32s<OpAdd<int>, IF_SIMD(_VAdd32s)>(src1, step1, src2, step2, dst, step, sz);
+}
 
-struct ippSub32s
+static void add32f( const float* src1, size_t step1,
+                    const float* src2, size_t step2,
+                    float* dst, size_t step, Size sz, void* )
 {
-    int operator()(const Ipp32s* src1, const Ipp32s* src2, Ipp32s* dst, int len) const
-    {
-        ippsSub_32s_Sfs(src2,src1,dst,len,0);
-        return len;
-    }
-};
+    IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step);
+           ippiAdd_32f_C1RSfs(src1, (int)step1, src2, (int)step2, dst, (IppiSize&)sz, 0),
+           (vBinOp32f<OpAdd<float>, IF_SIMD(_VAdd32f)>(src1, step1, src2, step2, dst, step, sz)));
+}
 
-struct ippSub32f
+static void add64f( const double* src1, size_t step1,
+                    const double* src2, size_t step2,
+                    double* dst, size_t step, Size sz, void* )
 {
-    int operator()(const Ipp32f* src1, const Ipp32f* src2, Ipp32f* dst, int len) const
-    {
-        ippsSub_32f(src2,src1,dst,len);
-        return len;
-    }
-};
+    vBinOp64f<OpAdd<double>, IF_SIMD(_VAdd64f)>(src1, step1, src2, step2, dst, step, sz);
+}
 
-struct ippSub64f
+static void sub8u( const uchar* src1, size_t step1,
+                   const uchar* src2, size_t step2,
+                   uchar* dst, size_t step, Size sz, void* )
 {
-    int operator()(const Ipp64f* src1, const Ipp64f* src2, Ipp64f* dst, int len) const
-    {
-        ippsSub_64f(src2,src1,dst,len);
-        return len;
-    }
-};
+    IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step);
+           ippiSub_8u_C1RSfs(src2, (int)step2, src1, (int)step1, dst, (IppiSize&)sz, 0),
+           (vBinOp8<uchar, OpSub<uchar>, IF_SIMD(_VSub8u)>(src1, step1, src2, step2, dst, step, sz)));
+}
 
-struct ippMax8u
+static void sub8s( const schar* src1, size_t step1,
+                   const schar* src2, size_t step2,
+                   schar* dst, size_t step, Size sz, void* )
 {
-    int operator()(const Ipp8u* src1, const Ipp8u* src2, Ipp8u* dst, int len) const
-    {
-        ippsMaxEvery_8u(src1,src2,dst,len);
-        return len;
-    }
-};
+    vBinOp8<schar, OpSub<schar>, IF_SIMD(_VSub8s)>(src1, step1, src2, step2, dst, step, sz);
+}
 
-struct ippMax16u
+static void sub16u( const ushort* src1, size_t step1,
+                    const ushort* src2, size_t step2,
+                    ushort* dst, size_t step, Size sz, void* )
 {
-    int operator()(const Ipp16u* src1, const Ipp16u* src2, Ipp16u* dst, int len) const
-    {
-        ippsMaxEvery_16u(src1,src2,dst,len);
-        return len;
-    }
-};
+    IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step);
+           ippiSub_16u_C1RSfs(src2, (int)step2, src1, (int)step1, dst, (IppiSize&)sz, 0),
+           (vBinOp16<ushort, OpSub<ushort>, IF_SIMD(_VSub16u)>(src1, step1, src2, step2, dst, step, sz)));
+}
 
-struct ippMax32f
+static void sub16s( const short* src1, size_t step1,
+                    const short* src2, size_t step2,
+                    short* dst, size_t step, Size sz, void* )
 {
-    int operator()(const Ipp32f* src1, const Ipp32f* src2, Ipp32f* dst, int len) const
-    {
-        ippsMaxEvery_32f(src1,src2,dst,len);
-        return len;
-    }
-};
+    IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step);
+           ippiSub_16s_C1RSfs(src2, (int)step2, src1, (int)step1, dst, (IppiSize&)sz, 0),
+           (vBinOp16<short, OpSub<short>, IF_SIMD(_VSub16s)>(src1, step1, src2, step2, dst, step, sz)));
+}
 
-struct ippMax64f
+static void sub32s( const int* src1, size_t step1,
+                    const int* src2, size_t step2,
+                    int* dst, size_t step, Size sz, void* )
 {
-    int operator()(const Ipp64f* src1, const Ipp64f* src2, Ipp64f* dst, int len) const
-    {
-        ippsMaxEvery_64f(src1,src2,dst,len);
-        return len;
-    }
-};
+    vBinOp32s<OpSub<int>, IF_SIMD(_VSub32s)>(src1, step1, src2, step2, dst, step, sz);
+}
 
-struct ippMin8u
+static void sub32f( const float* src1, size_t step1,
+                   const float* src2, size_t step2,
+                   float* dst, size_t step, Size sz, void* )
 {
-    int operator()(const Ipp8u* src1, const Ipp8u* src2, Ipp8u* dst, int len) const
-    {
-        ippsMinEvery_8u(src1,src2,dst,len);
-        return len;
-    }
-};
+    IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step);
+           ippiSub_32f_C1RSfs(src2, (int)step2, src1, (int)step1, dst, (IppiSize&)sz, 0),
+           (vBinOp32f<OpSub<float>, IF_SIMD(_VSub32f)>(src1, step1, src2, step2, dst, step, sz)));
+}
 
-struct ippMin16u
+static void sub64f( const double* src1, size_t step1,
+                    const double* src2, size_t step2,
+                    double* dst, size_t step, Size sz, void* )
 {
-    int operator()(const Ipp16u* src1, const Ipp16u* src2, Ipp16u* dst, int len) const
-    {
-        ippsMinEvery_16u(src1,src2,dst,len);
-        return len;
-    }
-};
+    vBinOp64f<OpSub<double>, IF_SIMD(_VSub64f)>(src1, step1, src2, step2, dst, step, sz);
+}    
 
-struct ippMin32f
+template<> inline uchar OpMin<uchar>::operator ()(uchar a, uchar b) const { return CV_MIN_8U(a, b); }
+template<> inline uchar OpMax<uchar>::operator ()(uchar a, uchar b) const { return CV_MAX_8U(a, b); }
+    
+static void max8u( const uchar* src1, size_t step1,
+                   const uchar* src2, size_t step2,
+                   uchar* dst, size_t step, Size sz, void* )
 {
-    int operator()(const Ipp32f* src1, const Ipp32f* src2, Ipp32f* dst, int len) const
-    {
-        ippsMinEvery_32f(src1,src2,dst,len);
-        return len;
-    }
-};
+    IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step);
+           ippiMaxEvery_8u_C1R(src1, (int)step1, src2, (int)step2, dst, (IppiSize&)sz),
+           (vBinOp8<uchar, OpMax<uchar>, IF_SIMD(_VMax8u)>(src1, step1, src2, step2, dst, step, sz)));
+}
 
-struct ippMin64f
+static void max8s( const schar* src1, size_t step1,
+                   const schar* src2, size_t step2,
+                   schar* dst, size_t step, Size sz, void* )
 {
-    int operator()(const Ipp64f* src1, const Ipp64f* src2, Ipp64f* dst, int len) const
-    {
-        ippsMinEvery_64f(src1,src2,dst,len);
-        return len;
-    }
-};
+    vBinOp8<schar, OpMax<schar>, IF_SIMD(_VMax8s)>(src1, step1, src2, step2, dst, step, sz);
+}
 
-struct ippAbsDiff8u
+static void max16u( const ushort* src1, size_t step1,
+                    const ushort* src2, size_t step2,
+                    ushort* dst, size_t step, Size sz, void* )
 {
-    int operator()(const Ipp8u* src1, const Ipp8u* src2, Ipp8u* dst, int len) const
-    {
-        int step = len * sizeof(Ipp8u);
-        IppiSize roi = { len, 1 };
-        ippiAbsDiff_8u_C1R(src1,step,src2,step,dst,step,roi);
-        return len;
-    }
-};
+    IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step);
+           ippiMaxEvery_16u_C1R(src1, (int)step1, src2, (int)step2, dst, (IppiSize&)sz),
+           (vBinOp16<ushort, OpMax<ushort>, IF_SIMD(_VMax16u)>(src1, step1, src2, step2, dst, step, sz)));
+}
 
-struct ippAbsDiff16u
+static void max16s( const short* src1, size_t step1,
+                    const short* src2, size_t step2,
+                    short* dst, size_t step, Size sz, void* )
 {
-    int operator()(const Ipp16u* src1, const Ipp16u* src2, Ipp16u* dst, int len) const
-    {
-        int step = len * sizeof(Ipp16u);
-        IppiSize roi = { len, 1 };
-        ippiAbsDiff_16u_C1R(src1,step,src2,step,dst,step,roi);
-        return len;
-    }
-};
+    IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step);
+           ippiMaxEvery_16s_C1R(src1, (int)step1, src2, (int)step2, dst, (IppiSize&)sz),
+           (vBinOp16<short, OpMax<short>, IF_SIMD(_VMax16s)>(src1, step1, src2, step2, dst, step, sz)));
+}
 
-struct ippAbsDiff32f
+static void max32s( const int* src1, size_t step1,
+                    const int* src2, size_t step2,
+                    int* dst, size_t step, Size sz, void* )
 {
-    int operator()(const Ipp32f* src1, const Ipp32f* src2, Ipp32f* dst, int len) const
-    {
-        int step = len * sizeof(Ipp32f);
-        IppiSize roi = { len, 1 };
-        ippiAbsDiff_32f_C1R(src1,step,src2,step,dst,step,roi);
-        return len;
-    }
-};
+    vBinOp32s<OpMax<int>, IF_SIMD(_VMax32s)>(src1, step1, src2, step2, dst, step, sz);
+}
 
-struct ippAnd8u
+static void max32f( const float* src1, size_t step1,
+                    const float* src2, size_t step2,
+                    float* dst, size_t step, Size sz, void* )
 {
-    int operator()(const Ipp8u* src1, const Ipp8u* src2, Ipp8u* dst, int len) const
-    {
-        ippsAnd_8u(src1,src2,dst,len);
-        return len;
-    }
-};
+    IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step);
+           ippiMaxEvery_32f_C1R(src1, (int)step1, src2, (int)step2, dst, (IppiSize&)sz),
+           (vBinOp32f<OpMax<float>, IF_SIMD(_VMax32f)>(src1, step1, src2, step2, dst, step, sz)));
+}
 
-struct ippOr8u
+static void max64f( const double* src1, size_t step1,
+                    const double* src2, size_t step2,
+                    double* dst, size_t step, Size sz, void* )
 {
-    int operator()(const Ipp8u* src1, const Ipp8u* src2, Ipp8u* dst, int len) const
-    {
-        ippsOr_8u(src1,src2,dst,len);
-        return len;
-    }
-};
+    vBinOp64f<OpMax<double>, IF_SIMD(_VMax64f)>(src1, step1, src2, step2, dst, step, sz);
+}
 
-struct ippXor8u
+static void min8u( const uchar* src1, size_t step1,
+                   const uchar* src2, size_t step2,
+                   uchar* dst, size_t step, Size sz, void* )
 {
-    int operator()(const Ipp8u* src1, const Ipp8u* src2, Ipp8u* dst, int len) const
-    {
-        ippsXor_8u(src1,src2,dst,len);
-        return len;
-    }
-};
+    IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step);
+           ippiMinEvery_8u_C1R(src1, (int)step1, src2, (int)step2, dst, (IppiSize&)sz),
+           (vBinOp8<uchar, OpMin<uchar>, IF_SIMD(_VMin8u)>(src1, step1, src2, step2, dst, step, sz)));
+}
 
-#endif // defined(HAVE_IPP)
+static void min8s( const schar* src1, size_t step1,
+                   const schar* src2, size_t step2,
+                   schar* dst, size_t step, Size sz, void* )
+{
+    vBinOp8<schar, OpMin<schar>, IF_SIMD(_VMin8s)>(src1, step1, src2, step2, dst, step, sz);
+}
 
+static void min16u( const ushort* src1, size_t step1,
+                    const ushort* src2, size_t step2,
+                    ushort* dst, size_t step, Size sz, void* )
+{
+    IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step);
+           ippiMinEvery_16u_C1R(src1, (int)step1, src2, (int)step2, dst, (IppiSize&)sz),
+           (vBinOp16<ushort, OpMin<ushort>, IF_SIMD(_VMin16u)>(src1, step1, src2, step2, dst, step, sz)));
+}
 
-/****************************************************************************************\
-*                                   logical operations                                   *
-\****************************************************************************************/
+static void min16s( const short* src1, size_t step1,
+                    const short* src2, size_t step2,
+                    short* dst, size_t step, Size sz, void* )
+{
+    IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step);
+           ippiMinEvery_16s_C1R(src1, (int)step1, src2, (int)step2, dst, (IppiSize&)sz),
+           (vBinOp16<short, OpMin<short>, IF_SIMD(_VMin16s)>(src1, step1, src2, step2, dst, step, sz)));
+}
 
-template<typename T> struct AndOp
+static void min32s( const int* src1, size_t step1,
+                    const int* src2, size_t step2,
+                    int* dst, size_t step, Size sz, void* )
 {
-    typedef T type1;
-    typedef T type2;
-    typedef T rtype;
-    T operator()( T a, T b ) const { return a & b; }
-};
+    vBinOp32s<OpMin<int>, IF_SIMD(_VMin32s)>(src1, step1, src2, step2, dst, step, sz);
+}
 
-template<typename T> struct OrOp
+static void min32f( const float* src1, size_t step1,
+                    const float* src2, size_t step2,
+                    float* dst, size_t step, Size sz, void* )
 {
-    typedef T type1;
-    typedef T type2;
-    typedef T rtype;
-    T operator()( T a, T b ) const { return a | b; }
-};
+    IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step);
+           ippiMinEvery_32f_C1R(src1, (int)step1, src2, (int)step2, dst, (IppiSize&)sz),
+           (vBinOp32f<OpMin<float>, IF_SIMD(_VMin32f)>(src1, step1, src2, step2, dst, step, sz)));
+}
 
-template<typename T> struct XorOp
+static void min64f( const double* src1, size_t step1,
+                    const double* src2, size_t step2,
+                    double* dst, size_t step, Size sz, void* )
 {
-    typedef T type1;
-    typedef T type2;
-    typedef T rtype;
-    T operator()( T a, T b ) const { return a ^ b; }
-};
+    vBinOp64f<OpMin<double>, IF_SIMD(_VMin64f)>(src1, step1, src2, step2, dst, step, sz);
+}    
 
-template<class OPB, class OPI, class OPV> static void
-bitwiseOp_( const Mat& srcmat1, const Mat& srcmat2, Mat& dstmat )
+static void absdiff8u( const uchar* src1, size_t step1,
+                       const uchar* src2, size_t step2,
+                       uchar* dst, size_t step, Size sz, void* )
 {
-    OPB opb; OPI opi; OPV opv;
-    const uchar* src1 = srcmat1.data;
-    const uchar* src2 = srcmat2.data;
-    uchar* dst = dstmat.data;
-    size_t step1 = srcmat1.step, step2 = srcmat2.step, step = dstmat.step;
-    Size size = getContinuousSize( srcmat1, srcmat2, dstmat, (int)srcmat1.elemSize() );
-    bool useSIMD = checkHardwareSupport(ARITHM_SIMD);
+    IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step);
+           ippiAbsDiff_8u_C1R(src1, (int)step1, src2, (int)step2, dst, (IppiSize&)sz),
+           (vBinOp8<uchar, OpAbsDiff<uchar>, IF_SIMD(_VAbsDiff8u)>(src1, step1, src2, step2, dst, step, sz)));
+}
 
-    for( ; size.height--; src1 += step1, src2 += step2, dst += step )
-    {
-        int i = useSIMD ? opv(src1, src2, dst, size.width) : 0;
+static void absdiff8s( const schar* src1, size_t step1,
+                       const schar* src2, size_t step2,
+                       schar* dst, size_t step, Size sz, void* )
+{
+    vBinOp8<schar, OpAbsDiff<schar>, IF_SIMD(_VAbsDiff8s)>(src1, step1, src2, step2, dst, step, sz);
+}
 
-        if( (((size_t)src1 | (size_t)src2 | (size_t)dst) & 3) == 0 )
-        {
-            for( ; i <= size.width - 16; i += 16 )
-            {
-                int t0 = opi(((const int*)(src1+i))[0], ((const int*)(src2+i))[0]);
-                int t1 = opi(((const int*)(src1+i))[1], ((const int*)(src2+i))[1]);
+static void absdiff16u( const ushort* src1, size_t step1,
+                        const ushort* src2, size_t step2,
+                        ushort* dst, size_t step, Size sz, void* )
+{
+    IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step);
+           ippiAbsDiff_16u_C1R(src1, (int)step1, src2, (int)step2, dst, (IppiSize&)sz),
+           (vBinOp16<ushort, OpAbsDiff<ushort>, IF_SIMD(_VAbsDiff16u)>(src1, step1, src2, step2, dst, step, sz)));
+}
 
-                ((int*)(dst+i))[0] = t0;
-                ((int*)(dst+i))[1] = t1;
+static void absdiff16s( const short* src1, size_t step1,
+                        const short* src2, size_t step2,
+                        short* dst, size_t step, Size sz, void* )
+{
+    IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step);
+           ippiAbsDiff_16s_C1R(src1, (int)step1, src2, (int)step2, dst, (IppiSize&)sz),
+           (vBinOp16<short, OpAbsDiff<short>, IF_SIMD(_VAbsDiff16s)>(src1, step1, src2, step2, dst, step, sz)));
+}
 
-                t0 = opi(((const int*)(src1+i))[2], ((const int*)(src2+i))[2]);
-                t1 = opi(((const int*)(src1+i))[3], ((const int*)(src2+i))[3]);
+static void absdiff32s( const int* src1, size_t step1,
+                        const int* src2, size_t step2,
+                        int* dst, size_t step, Size sz, void* )
+{
+    vBinOp32s<OpAbsDiff<int>, IF_SIMD(_VAbsDiff32s)>(src1, step1, src2, step2, dst, step, sz);
+}
 
-                ((int*)(dst+i))[2] = t0;
-                ((int*)(dst+i))[3] = t1;
-            }
+static void absdiff32f( const float* src1, size_t step1,
+                        const float* src2, size_t step2,
+                        float* dst, size_t step, Size sz, void* )
+{
+    IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step);
+           ippiAbsDiff_32f_C1R(src1, (int)step1, src2, (int)step2, dst, (IppiSize&)sz),
+           (vBinOp32f<OpAbsDiff<float>, IF_SIMD(_VAbsDiff32f)>(src1, step1, src2, step2, dst, step, sz)));
+}
 
-            for( ; i <= size.width - 4; i += 4 )
-            {
-                int t = opi(*(const int*)(src1+i), *(const int*)(src2+i));
-                *(int*)(dst+i) = t;
-            }
-        }
+static void absdiff64f( const double* src1, size_t step1,
+                        const double* src2, size_t step2,
+                        double* dst, size_t step, Size sz, void* )
+{
+    vBinOp64f<OpAbsDiff<double>, IF_SIMD(_VAbsDiff64f)>(src1, step1, src2, step2, dst, step, sz);
+}    
+    
 
-        for( ; i < size.width; i++ )
-            dst[i] = opb(src1[i], src2[i]);
+static void and8u( const uchar* src1, size_t step1,
+                   const uchar* src2, size_t step2,
+                   uchar* dst, size_t step, Size sz, void* )
+{
+    IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step);
+           ippiAnd_8u_C1R(src1, (int)step1, src2, (int)step2, dst, (IppiSize&)sz),
+           (vBinOp8<uchar, OpAnd<uchar>, IF_SIMD(_VAnd8u)>(src1, step1, src2, step2, dst, step, sz)));
+}
+
+static void or8u( const uchar* src1, size_t step1,
+                  const uchar* src2, size_t step2,
+                  uchar* dst, size_t step, Size sz, void* )
+{
+    IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step);
+           ippiOr_8u_C1R(src1, (int)step1, src2, (int)step2, dst, (IppiSize&)sz),
+           (vBinOp8<uchar, OpOr<uchar>, IF_SIMD(_VOr8u)>(src1, step1, src2, step2, dst, step, sz)));
+}
+
+static void xor8u( const uchar* src1, size_t step1,
+                   const uchar* src2, size_t step2,
+                   uchar* dst, size_t step, Size sz, void* )
+{
+    IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step);
+           ippiXor_8u_C1R(src1, (int)step1, src2, (int)step2, dst, (IppiSize&)sz),
+           (vBinOp8<uchar, OpXor<uchar>, IF_SIMD(_VXor8u)>(src1, step1, src2, step2, dst, step, sz)));
+}    
+
+static void not8u( const uchar* src1, size_t step1,
+                   const uchar* src2, size_t step2,
+                   uchar* dst, size_t step, Size sz, void* )
+{
+    IF_IPP(fixSteps(sz, sizeof(dst[0]), step1, step2, step);
+           ippiNot_8u_C1R(src1, (int)step1, dst, (IppiSize&)sz),
+           (vBinOp8<uchar, OpNot<uchar>, IF_SIMD(_VNot8u)>(src1, step1, src2, step2, dst, step, sz)));
+}
+    
+/****************************************************************************************\
+*                                   logical operations                                   *
+\****************************************************************************************/
+    
+static inline bool checkScalar(const Mat& sc, int atype, int sckind, int akind)
+{
+    if( sc.dims > 2 || (sc.cols != 1 && sc.rows != 1) || !sc.isContinuous() )
+        return false;
+    int cn = CV_MAT_CN(atype);
+    if( akind == InputArray::MATX && sckind != InputArray::MATX )
+        return false;
+    return sc.size() == Size(1, 1) || sc.size() == Size(1, cn) || sc.size() == Size(cn, 1) ||
+        (sc.size() == Size(1, 4) && sc.type() == CV_64F && cn <= 4);
+}
+    
+static void convertAndUnrollScalar( const Mat& sc, int buftype, uchar* scbuf, size_t blocksize )
+{
+    int scn = (int)sc.total(), cn = CV_MAT_CN(buftype);
+    size_t esz = CV_ELEM_SIZE(buftype);
+    getConvertFunc(sc.depth(), buftype)(sc.data, 0, 0, 0, scbuf, 0, Size(std::min(cn, scn), 1), 0);
+    // unroll the scalar
+    if( scn < cn )
+    {
+        CV_Assert( scn == 1 );
+        size_t esz1 = CV_ELEM_SIZE1(buftype);
+        for( size_t i = esz1; i < esz; i++ )
+            scbuf[i] = scbuf[i - esz1];
+    }
+    for( size_t i = esz; i < blocksize*esz; i++ )
+        scbuf[i] = scbuf[i - esz];
+    
+}
+    
+void binary_op(const InputArray& _src1, const InputArray& _src2, OutputArray& _dst,
+               const InputArray& _mask, const BinaryFunc* tab, bool bitwise)
+{
+    int kind1 = _src1.kind(), kind2 = _src2.kind();
+    Mat src1 = _src1.getMat(), src2 = _src2.getMat();
+    bool haveMask = !_mask.empty(), haveScalar = false;
+    BinaryFunc func;
+    int c;
+    
+    if( src1.dims <= 2 && src2.dims <= 2 && kind1 == kind2 &&
+        src1.size() == src2.size() && src1.type() == src2.type() && !haveMask )
+    {
+        _dst.create(src1.size(), src1.type());
+        Mat dst = _dst.getMat();
+        if( bitwise )
+        {
+            func = *tab;
+            c = (int)src1.elemSize();
+        }
+        else
+        {
+            func = tab[src1.depth()];
+            c = src1.channels();
+        }
+            
+        Size sz = getContinuousSize(src1, src2, dst, c);
+        func(src1.data, src1.step, src2.data, src2.step, dst.data, dst.step, sz, 0);
+        return;
+    }
+    
+    if( (kind1 == InputArray::MATX) + (kind2 == InputArray::MATX) == 1 ||
+        src1.size != src2.size || src1.type() != src2.type() )
+    {
+        if( checkScalar(src1, src2.type(), kind1, kind2) )
+            // src1 is a scalar; swap it with src2
+            swap(src1, src2);
+        else if( !checkScalar(src2, src1.type(), kind2, kind1) )
+            CV_Error( CV_StsUnmatchedSizes,
+                      "The operation is neither 'array op array' (where arrays have the same size and type), "
+                      "nor 'array op scalar', nor 'scalar op array'" );
+        haveScalar = true;
+    }
+    
+    size_t esz = src1.elemSize();
+    size_t blocksize0 = (BLOCK_SIZE + esz-1)/esz;
+    int cn = src1.channels();
+    BinaryFunc copymask = 0;
+    Mat mask;
+    
+    if( haveMask )
+    {
+        mask = _mask.getMat();
+        CV_Assert( (mask.type() == CV_8UC1 || mask.type() == CV_8SC1) );
+        CV_Assert( mask.size == src1.size );
+        copymask = getCopyMaskFunc(esz);
+    }
+    
+    AutoBuffer<uchar> _buf;
+    uchar *scbuf = 0, *maskbuf = 0;
+    
+    _dst.create(src1.dims, src1.size, src1.type());
+    Mat dst = _dst.getMat();
+    
+    if( bitwise )
+    {
+        func = *tab;
+        c = (int)esz;
+    }
+    else
+    {
+        func = tab[src1.depth()];
+        c = cn;
     }
-}
-
-
-template<class OPB, class OPI, class OPV> static void
-bitwiseSOp_( const Mat& srcmat, Mat& dstmat, const Scalar& _scalar )
-{
-    OPB opb; OPI opi; OPV opv;
-    const uchar* src0 = srcmat.data;
-    uchar* dst0 = dstmat.data;
-    size_t step1 = srcmat.step, step = dstmat.step;
-    Size size = getContinuousSize( srcmat, dstmat, (int)srcmat.elemSize() );
-    const int delta = 96;
-    uchar scalar[delta];
-    scalarToRawData(_scalar, scalar, srcmat.type(), (int)(delta/srcmat.elemSize1()) );
-    bool useSIMD = checkHardwareSupport(ARITHM_SIMD);
-
-    for( ; size.height--; src0 += step1, dst0 += step )
+    
+    if( !haveScalar )
     {
-        const uchar* src = (const uchar*)src0;
-        uchar* dst = dst0;
-        int i, len = size.width;
-
-        if( (((size_t)src|(size_t)dst) & 3) == 0 )
+        const Mat* arrays[] = { &src1, &src2, &dst, &mask, 0 };
+        uchar* ptrs[4];
+        
+        NAryMatIterator it(arrays, ptrs);
+        size_t total = it.size, blocksize = total;
+        
+        if( haveMask )
+        {
+            blocksize = std::min(blocksize, blocksize0);
+            _buf.allocate(blocksize*esz);
+            maskbuf = _buf;
+        }
+        
+        for( size_t i = 0; i < it.nplanes; i++, ++it )
         {
-            while( (len -= delta) >= 0 )
+            for( size_t j = 0; j < total; j += blocksize )
             {
-                i = useSIMD ? opv(src, scalar, dst, delta) : 0;
-                for( ; i < delta; i += 16 )
+                int bsz = (int)std::min(total - j, blocksize);
+                
+                func( ptrs[0], 0, ptrs[1], 0, haveMask ? maskbuf : ptrs[2], 0, Size(bsz*c, 1), 0 );                
+                if( haveMask )
                 {
-                    int t0 = opi(((const int*)(src+i))[0], ((const int*)(scalar+i))[0]);
-                    int t1 = opi(((const int*)(src+i))[1], ((const int*)(scalar+i))[1]);
-                    ((int*)(dst+i))[0] = t0;
-                    ((int*)(dst+i))[1] = t1;
-
-                    t0 = opi(((const int*)(src+i))[2], ((const int*)(scalar+i))[2]);
-                    t1 = opi(((const int*)(src+i))[3], ((const int*)(scalar+i))[3]);
-                    ((int*)(dst+i))[2] = t0;
-                    ((int*)(dst+i))[3] = t1;
+                    copymask( maskbuf, 0, ptrs[3], 0, ptrs[2], 0, Size(bsz, 1), &esz );
+                    ptrs[3] += bsz;
                 }
-                src += delta;
-                dst += delta;
+                
+                bsz *= (int)esz;
+                ptrs[0] += bsz; ptrs[1] += bsz; ptrs[2] += bsz;
             }
         }
-        else
+    }
+    else
+    {
+        const Mat* arrays[] = { &src1, &dst, &mask, 0 };
+        uchar* ptrs[3];
+        
+        NAryMatIterator it(arrays, ptrs);
+        size_t total = it.size, blocksize = std::min(total, blocksize0);
+        
+        _buf.allocate(blocksize*(haveMask ? 2 : 1)*esz + 32);
+        scbuf = _buf;
+        maskbuf = alignPtr(scbuf + blocksize*esz, 16);
+        
+        convertAndUnrollScalar( src2, src1.type(), scbuf, blocksize);
+        
+        for( size_t i = 0; i < it.nplanes; i++, ++it )
         {
-            while( (len -= delta) >= 0 )
+            for( size_t j = 0; j < total; j += blocksize )
             {
-                for( i = 0; i < delta; i += 4 )
+                int bsz = (int)std::min(total - j, blocksize);
+                
+                func( ptrs[0], 0, scbuf, 0, haveMask ? maskbuf : ptrs[1], 0, Size(bsz*c, 1), 0 );
+                if( haveMask )
                 {
-                    uchar t0 = opb(src[i], scalar[i]);
-                    uchar t1 = opb(src[i+1], scalar[i+1]);
-                    dst[i] = t0; dst[i+1] = t1;
-
-                    t0 = opb(src[i+2], scalar[i+2]);
-                    t1 = opb(src[i+3], scalar[i+3]);
-                    dst[i+2] = t0; dst[i+3] = t1;
+                    copymask( maskbuf, 0, ptrs[2], 0, ptrs[1], 0, Size(bsz, 1), &esz );
+                    ptrs[2] += bsz;
                 }
-                src += delta;
-                dst += delta;
+                
+                bsz *= (int)esz;
+                ptrs[0] += bsz; ptrs[1] += bsz;
             }
         }
-
-        for( len += delta, i = 0; i < len; i++ )
-            dst[i] = opb(src[i],scalar[i]);
     }
 }
-
-
-static void
-binaryOp( const Mat& src1, const Mat& src2, Mat& dst, BinaryFunc func, int dsttype=-1 )
+    
+static BinaryFunc maxTab[] =
 {
-    if( dsttype == -1 )
-        dsttype = src1.type();
-    CV_Assert( src1.type() == src2.type() && func != 0 );
-
-    if( src1.dims > 2 || src2.dims > 2 )
-    {
-        dst.create(src1.dims, src1.size, dsttype);
-        const Mat* arrays[] = { &src1, &src2, &dst, 0 };
-        Mat planes[3];
-        NAryMatIterator it(arrays, planes);
+    (BinaryFunc)max8u, (BinaryFunc)max8s, (BinaryFunc)max16u, (BinaryFunc)max16s,
+    (BinaryFunc)max32s, (BinaryFunc)max32f, (BinaryFunc)max64f, 0
+};    
 
-        for( int i = 0; i < it.nplanes; i++, ++it )
-            func(it.planes[0], it.planes[1], it.planes[2]);
-        return;
-    }
+static BinaryFunc minTab[] =
+{
+    (BinaryFunc)min8u, (BinaryFunc)min8s, (BinaryFunc)min16u, (BinaryFunc)min16s,
+    (BinaryFunc)min32s, (BinaryFunc)min32f, (BinaryFunc)min64f, 0
+};
 
-    CV_Assert( src1.size() == src2.size() );
-    dst.create( src1.size(), dsttype );
-    func( src1, src2, dst );
 }
-
-
-static void
-binaryMaskOp( const Mat& src1, const Mat& src2, Mat& dst,
-              const Mat& mask, BinaryFunc func )
+    
+void cv::bitwise_and(const InputArray& a, const InputArray& b, OutputArray c, const InputArray& mask)
 {
-    CV_Assert( src1.type() == src2.type() && func != 0 );
-
-    if( src1.dims > 2 || src2.dims > 2 )
-    {
-        dst.create(src1.dims, src1.size, src1.type());
-        const Mat* arrays[] = { &src1, &src2, &dst, &mask, 0 };
-        Mat planes[4];
-        NAryMatIterator it(arrays, planes);
-
-        if( !mask.data )
-            for( int i = 0; i < it.nplanes; i++, ++it )
-                func(it.planes[0], it.planes[1], it.planes[2]);
-        else
-            for( int i = 0; i < it.nplanes; i++, ++it )
-                binaryMaskOp(it.planes[0], it.planes[1],
-                             it.planes[2], it.planes[3],
-                             func);
-        return;
-    }
-
-    CV_Assert( src1.size() == src2.size() );
-    dst.create( src1.size(), src1.type() );
-
-    if( !mask.data )
-        func(src1, src2, dst);
-    else
-    {
-        AutoBuffer<uchar> buf;
-        size_t esz = dst.elemSize(), buf_step = dst.cols*esz;
-        CopyMaskFunc copym_func = getCopyMaskFunc((int)esz);
-        int y, dy;
-
-        CV_Assert(mask.type() == CV_8UC1 && mask.size() == dst.size());
-        dy = std::min(std::max((int)(CV_MAX_LOCAL_SIZE/buf_step), 1), dst.rows);
-        buf.allocate( buf_step*dy );
-
-        for( y = 0; y < dst.rows; y += dy )
-        {
-            dy = std::min(dy, dst.rows - y);
-            Mat dstpart = dst.rowRange(y, y + dy);
-            Mat temp(dy, dst.cols, dst.type(), (uchar*)buf );
-            func( src1.rowRange(y, y + dy), src2.rowRange(y, y + dy), temp );
-            copym_func( temp, dstpart, mask.rowRange(y, y + dy) );
-        }
-    }
+    BinaryFunc f = and8u;
+    binary_op(a, b, c, mask, &f, true);
 }
 
-
-static void
-binarySMaskOp( const Mat& src1, const Scalar& s, Mat& dst,
-               const Mat& mask, BinarySFuncCn func )
+void cv::bitwise_or(const InputArray& a, const InputArray& b, OutputArray c, const InputArray& mask)
 {
-    CV_Assert( func != 0 );
-
-    if( src1.dims > 2 )
-    {
-        dst.create(src1.dims, src1.size, src1.type());
-        const Mat* arrays[] = { &src1, &dst, &mask, 0 };
-        Mat planes[3];
-        NAryMatIterator it(arrays, planes);
-
-        if( !mask.data )
-            for( int i = 0; i < it.nplanes; i++, ++it )
-                func(it.planes[0], it.planes[1], s);
-        else
-            for( int i = 0; i < it.nplanes; i++, ++it )
-                binarySMaskOp(it.planes[0], s, it.planes[1],
-                              it.planes[2], func);
-        return;
-    }
-
-    dst.create( src1.size(), src1.type() );
-
-    if( !mask.data )
-        func(src1, dst, s);
-    else
-    {
-        AutoBuffer<uchar> buf;
-        size_t esz = dst.elemSize(), buf_step = dst.cols*esz;
-        CopyMaskFunc copym_func = getCopyMaskFunc((int)esz);
-        int y, dy;
-
-        CV_Assert(mask.type() == CV_8UC1 && mask.size() == dst.size());
-        dy = std::min(std::max((int)(CV_MAX_LOCAL_SIZE/buf_step), 1), dst.rows);
-        buf.allocate( buf_step*dy );
-
-        for( y = 0; y < dst.rows; y += dy )
-        {
-            dy = std::min(dy, dst.rows - y);
-            Mat dstpart = dst.rowRange(y, y + dy);
-            Mat temp(dy, dst.cols, dst.type(), (uchar*)buf);
-            func( src1.rowRange(y, y + dy), temp, s );
-            copym_func( temp, dstpart, mask.rowRange(y, y + dy) );
-        }
-    }
+    BinaryFunc f = or8u;
+    binary_op(a, b, c, mask, &f, true);
 }
 
-
-void bitwise_and(const Mat& a, const Mat& b, Mat& c, const Mat& mask)
+void cv::bitwise_xor(const InputArray& a, const InputArray& b, OutputArray c, const InputArray& mask)
 {
-#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
-    binaryMaskOp(a, b, c, mask, bitwiseOp_<AndOp<uchar>, AndOp<int>, ippAnd8u>);
-#else
-    binaryMaskOp(a, b, c, mask, bitwiseOp_<AndOp<uchar>, AndOp<int>, VAnd8u>);
-#endif
+    BinaryFunc f = xor8u;
+    binary_op(a, b, c, mask, &f, true);
 }
 
-void bitwise_or(const Mat& a, const Mat& b, Mat& c, const Mat& mask)
+void cv::bitwise_not(const InputArray& a, OutputArray c, const InputArray& mask)
 {
-#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
-    binaryMaskOp(a, b, c, mask, bitwiseOp_<OrOp<uchar>, OrOp<int>, ippOr8u>);
-#else
-    binaryMaskOp(a, b, c, mask, bitwiseOp_<OrOp<uchar>, OrOp<int>, VOr8u>);
-#endif
+    BinaryFunc f = not8u;
+    binary_op(a, a, c, mask, &f, true);
 }
 
-void bitwise_xor(const Mat& a, const Mat& b, Mat& c, const Mat& mask)
+void cv::max( const InputArray& src1, const InputArray& src2, OutputArray dst )
 {
-#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
-    binaryMaskOp(a, b, c, mask, bitwiseOp_<XorOp<uchar>, XorOp<int>, ippXor8u>);
-#else
-    binaryMaskOp(a, b, c, mask, bitwiseOp_<XorOp<uchar>, XorOp<int>, VXor8u>);
-#endif
+    binary_op(src1, src2, dst, InputArray(), maxTab, false );
 }
 
-void bitwise_and(const Mat& a, const Scalar& s, Mat& c, const Mat& mask)
+void cv::min( const InputArray& src1, const InputArray& src2, OutputArray dst )
 {
-    binarySMaskOp(a, s, c, mask,
-        bitwiseSOp_<AndOp<uchar>, AndOp<int>, VAnd8u>);
+    binary_op(src1, src2, dst, InputArray(), minTab, false );
 }
 
-void bitwise_or(const Mat& a, const Scalar& s, Mat& c, const Mat& mask)
+void cv::max(const Mat& src1, const Mat& src2, Mat& dst)
 {
-    binarySMaskOp(a, s, c, mask,
-        bitwiseSOp_<OrOp<uchar>, OrOp<int>, VOr8u>);
+    OutputArray _dst(dst);
+    binary_op(src1, src2, _dst, InputArray(), maxTab, false );
+}    
+    
+void cv::min(const Mat& src1, const Mat& src2, Mat& dst)
+{
+    OutputArray _dst(dst);
+    binary_op(src1, src2, _dst, InputArray(), minTab, false );
 }
+    
+void cv::max(const Mat& src1, double src2, Mat& dst)
+{
+    OutputArray _dst(dst);
+    binary_op(src1, src2, _dst, InputArray(), maxTab, false );
+}    
 
-void bitwise_xor(const Mat& a, const Scalar& s, Mat& c, const Mat& mask)
+void cv::min(const Mat& src1, double src2, Mat& dst)
 {
-    binarySMaskOp(a, s, c, mask,
-        bitwiseSOp_<XorOp<uchar>, XorOp<int>, VXor8u>);
+    OutputArray _dst(dst);
+    binary_op(src1, src2, _dst, InputArray(), minTab, false );
 }
+    
+/****************************************************************************************\
+*                                      add/subtract                                      *
+\****************************************************************************************/
 
+namespace cv
+{
 
-void bitwise_not(const Mat& src, Mat& dst)
+void arithm_op(const InputArray& _src1, const InputArray& _src2, OutputArray& _dst,
+               const InputArray& _mask, int dtype, BinaryFunc* tab, bool muldiv=false, void* usrdata=0)
 {
-    if( src.dims > 2 )
+    int kind1 = _src1.kind(), kind2 = _src2.kind();
+    Mat src1 = _src1.getMat(), src2 = _src2.getMat();
+    bool haveMask = !_mask.empty();
+    
+    if( kind1 == kind2 && src1.dims <= 2 && src2.dims <= 2 &&
+        src1.size() == src2.size() && src1.type() == src2.type() &&
+        !haveMask && ((!_dst.fixedType() && (dtype < 0 || CV_MAT_DEPTH(dtype) == src1.depth())) ||
+                       (_dst.fixedType() && _dst.type() == _src1.type())) )
     {
-        dst.create(src.dims, src.size, src.type());
-        const Mat* arrays[] = { &src, &dst, 0 };
-        Mat planes[4];
-        NAryMatIterator it(arrays, planes);
-
-        for( int i = 0; i < it.nplanes; i++, ++it )
-            bitwise_not(it.planes[0], it.planes[1]);
+        _dst.create(src1.size(), src1.type());
+        Mat dst = _dst.getMat();
+        Size sz = getContinuousSize(src1, src2, dst, src1.channels());
+        tab[src1.depth()](src1.data, src1.step, src2.data, src2.step, dst.data, dst.step, sz, usrdata);
         return;
     }
-
-    const uchar* sptr = src.data;
-    dst.create( src.size(), src.type() );
-    uchar* dptr = dst.data;
-    Size size = getContinuousSize( src, dst, (int)src.elemSize() );
-
-    for( ; size.height--; sptr += src.step, dptr += dst.step )
+    
+    bool haveScalar = false, swapped12 = false;
+    
+    if( (kind1 == InputArray::MATX) + (kind2 == InputArray::MATX) == 1 ||
+        src1.size != src2.size || src1.channels() != src2.channels() )
     {
-        int i = 0;
-        if( (((size_t)sptr | (size_t)dptr) & 3) == 0 )
+        if( checkScalar(src1, src2.type(), kind1, kind2) )
+        {
+            // src1 is a scalar; swap it with src2
+            swap(src1, src2);
+            swapped12 = true;
+        }
+        else if( !checkScalar(src2, src1.type(), kind2, kind1) )
+            CV_Error( CV_StsUnmatchedSizes,
+                     "The operation is neither 'array op array' (where arrays have the same size and the same number of channels), "
+                     "nor 'array op scalar', nor 'scalar op array'" );
+        haveScalar = true;
+    }
+    
+    int cn = src1.channels(), depth1 = src1.depth(), depth2 = src2.depth(), wtype;
+    BinaryFunc cvtsrc1 = 0, cvtsrc2 = 0, cvtdst = 0;
+    
+    if( dtype < 0 )
+    {
+        if( _dst.fixedType() )
+            dtype = _dst.type();
+        else
+        {
+            if( !haveScalar && src1.type() != src2.type() )
+                CV_Error(CV_StsBadArg,
+                     "When the input arrays in add/subtract/multiply/divide functions have different types, "
+                     "the output array type must be explicitly specified");
+            dtype = src1.type();
+        }
+    }
+    dtype = CV_MAT_DEPTH(dtype);
+    
+    if( depth1 == depth2 && dtype == depth1 )
+        wtype = dtype;
+    else if( !muldiv )
+    {
+        wtype = depth1 <= CV_8S && depth2 <= CV_8S ? CV_16S :
+                depth1 <= CV_32S && depth2 <= CV_32S ? CV_32S : std::max(depth1, depth2);
+        wtype = std::max(wtype, dtype);
+    
+        // when the result of addition should be converted to an integer type,
+        // and just one of the input arrays is floating-point, it makes sense to convert that input to integer type before the operation,
+        // instead of converting the other input to floating-point and then converting the operation result back to integers.
+        if( dtype < CV_32F && (depth1 < CV_32F || depth2 < CV_32F) )
+            wtype = CV_32S;
+    }
+    else
+    {
+        wtype = std::max(depth1, std::max(depth2, CV_32F));
+        wtype = std::max(wtype, dtype);
+    }
+    
+    cvtsrc1 = depth1 == wtype ? 0 : getConvertFunc(depth1, wtype);
+    cvtsrc2 = depth2 == depth1 ? cvtsrc1 : depth2 == wtype ? 0 : getConvertFunc(depth2, wtype);
+    cvtdst = dtype == wtype ? 0 : getConvertFunc(wtype, dtype);
+    
+    dtype = CV_MAKETYPE(dtype, cn);
+    wtype = CV_MAKETYPE(wtype, cn);
+    
+    size_t esz1 = src1.elemSize(), esz2 = src2.elemSize();
+    size_t dsz = CV_ELEM_SIZE(dtype), wsz = CV_ELEM_SIZE(wtype);
+    size_t blocksize0 = (size_t)(BLOCK_SIZE + wsz-1)/wsz;
+    BinaryFunc copymask = 0;
+    Mat mask;
+    
+    if( haveMask )
+    {
+        mask = _mask.getMat();
+        CV_Assert( (mask.type() == CV_8UC1 || mask.type() == CV_8SC1) );
+        CV_Assert( mask.size == src1.size );
+        copymask = getCopyMaskFunc(dsz);
+    }
+    
+    AutoBuffer<uchar> _buf;
+    uchar *buf, *maskbuf = 0, *buf1 = 0, *buf2 = 0, *wbuf = 0;
+    size_t bufesz = (cvtsrc1 ? wsz : 0) + (cvtsrc2 || haveScalar ? wsz : 0) + (cvtdst ? wsz : 0) + (haveMask ? dsz : 0);
+    
+    _dst.create(src1.dims, src1.size, src1.type());
+    Mat dst = _dst.getMat();
+    BinaryFunc func = tab[CV_MAT_DEPTH(wtype)];
+    
+    if( !haveScalar )
+    {
+        const Mat* arrays[] = { &src1, &src2, &dst, &mask, 0 };
+        uchar* ptrs[4];
+        
+        NAryMatIterator it(arrays, ptrs);
+        size_t total = it.size, blocksize = total;
+        
+        if( haveMask || cvtsrc1 || cvtsrc2 || cvtdst )
+            blocksize = std::min(blocksize, blocksize0);
+
+        _buf.allocate(bufesz*blocksize + 64);
+        buf = _buf;
+        if( cvtsrc1 )
+            buf1 = buf, buf = alignPtr(buf + blocksize*wsz, 16);
+        if( cvtsrc2 )
+            buf2 = buf, buf = alignPtr(buf + blocksize*wsz, 16);
+        wbuf = maskbuf = buf;
+        if( cvtdst )
+            buf = alignPtr(buf + blocksize*wsz, 16);
+        if( haveMask )
+            maskbuf = buf;
+        
+        for( size_t i = 0; i < it.nplanes; i++, ++it )
         {
-            for( ; i <= size.width - 16; i += 16 )
+            for( size_t j = 0; j < total; j += blocksize )
             {
-                int t0 = ~((const int*)(sptr+i))[0];
-                int t1 = ~((const int*)(sptr+i))[1];
-
-                ((int*)(dptr+i))[0] = t0;
-                ((int*)(dptr+i))[1] = t1;
-
-                t0 = ~((const int*)(sptr+i))[2];
-                t1 = ~((const int*)(sptr+i))[3];
-
-                ((int*)(dptr+i))[2] = t0;
-                ((int*)(dptr+i))[3] = t1;
+                int bsz = (int)std::min(total - j, blocksize);
+                Size bszn(bsz*cn, 1);
+                const uchar *sptr1 = ptrs[0], *sptr2 = ptrs[1];
+                uchar* dptr = ptrs[2];
+                if( cvtsrc1 )
+                {
+                    cvtsrc1( sptr1, 0, 0, 0, buf1, 0, bszn, 0 );
+                    sptr1 = buf1;
+                }
+                if( ptrs[0] == ptrs[1] )
+                    sptr2 = sptr1;
+                else if( cvtsrc2 )
+                {
+                    cvtsrc2( sptr2, 0, 0, 0, buf2, 0, bszn, 0 );
+                    sptr2 = buf2;
+                }
+                
+                if( !haveMask && !cvtdst )
+                    func( sptr1, 0, sptr2, 0, dptr, 0, bszn, usrdata );
+                else
+                {
+                    func( sptr1, 0, sptr2, 0, wbuf, 0, bszn, usrdata );
+                    if( !haveMask )
+                        cvtdst( wbuf, 0, 0, 0, dptr, 0, bszn, 0 );
+                    else if( !cvtdst )
+                    {
+                        copymask( wbuf, 0, ptrs[3], 0, dptr, 0, Size(bsz, 1), &dsz );
+                        ptrs[3] += bsz;
+                    }
+                    else
+                    {
+                        cvtdst( wbuf, 0, 0, 0, maskbuf, 0, bszn, 0 );
+                        copymask( maskbuf, 0, ptrs[3], 0, dptr, 0, Size(bsz, 1), &dsz );
+                        ptrs[3] += bsz;
+                    }
+                }
+                ptrs[0] += bsz*esz1; ptrs[1] += bsz*esz2; ptrs[2] += bsz*dsz;
             }
-
-            for( ; i <= size.width - 4; i += 4 )
-                *(int*)(dptr+i) = ~*(const int*)(sptr+i);
         }
-
-        for( ; i < size.width; i++ )
+    }
+    else
+    {
+        const Mat* arrays[] = { &src1, &dst, &mask, 0 };
+        uchar* ptrs[3];
+        
+        NAryMatIterator it(arrays, ptrs);
+        size_t total = it.size, blocksize = std::min(total, blocksize0);
+        
+        _buf.allocate(bufesz*blocksize + 64);
+        buf = _buf;
+        if( cvtsrc1 )
+            buf1 = buf, buf = alignPtr(buf + blocksize*wsz, 16);
+        buf2 = buf; buf = alignPtr(buf + blocksize*wsz, 16);
+        wbuf = maskbuf = buf;
+        if( cvtdst )
+            buf = alignPtr(buf + blocksize*wsz, 16);
+        if( haveMask )
+            maskbuf = buf;
+        
+        convertAndUnrollScalar( src2, wtype, buf2, blocksize);
+        
+        for( size_t i = 0; i < it.nplanes; i++, ++it )
         {
-            dptr[i] = (uchar)(~sptr[i]);
+            for( size_t j = 0; j < total; j += blocksize )
+            {
+                int bsz = (int)std::min(total - j, blocksize);
+                Size bszn(bsz*cn, 1);
+                const uchar *sptr1 = ptrs[0];
+                const uchar* sptr2 = buf2;
+                uchar* dptr = ptrs[1];
+                
+                if( cvtsrc1 )
+                {
+                    cvtsrc1( sptr1, 0, 0, 0, buf1, 0, bszn, 0 );
+                    sptr1 = buf1;
+                }
+                
+                if( swapped12 )
+                    std::swap(sptr1, sptr2);
+                
+                if( !haveMask && !cvtdst )
+                    func( sptr1, 0, sptr2, 0, dptr, 0, bszn, usrdata );
+                else
+                {
+                    func( sptr1, 0, sptr2, 0, wbuf, 0, bszn, usrdata );
+                    if( !haveMask )
+                        cvtdst( wbuf, 0, 0, 0, dptr, 0, bszn, 0 );
+                    else if( !cvtdst )
+                    {
+                        copymask( wbuf, 0, ptrs[2], 0, dptr, 0, Size(bsz, 1), &dsz );
+                        ptrs[2] += bsz;
+                    }
+                    else
+                    {
+                        cvtdst( wbuf, 0, 0, 0, maskbuf, 0, bszn, 0 );
+                        copymask( maskbuf, 0, ptrs[2], 0, dptr, 0, Size(bsz, 1), &dsz );
+                        ptrs[2] += bsz;
+                    }
+                }
+                ptrs[0] += bsz*esz1; ptrs[1] += bsz*dsz;
+            }
         }
     }
 }
-
-/****************************************************************************************\
-*                                      add/subtract                                      *
-\****************************************************************************************/
-
-template<> inline uchar OpAdd<uchar>::operator ()(uchar a, uchar b) const
-{ return CV_FAST_CAST_8U(a + b); }
-template<> inline uchar OpSub<uchar>::operator ()(uchar a, uchar b) const
-{ return CV_FAST_CAST_8U(a - b); }
-
 static BinaryFunc addTab[] =
 {
-#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
-    binaryOpC1_<OpAdd<uchar>,  ippAdd8u>,
-    0,
-    binaryOpC1_<OpAdd<ushort>, ippAdd16u>,
-    binaryOpC1_<OpAdd<short>,  ippAdd16s>,
-    binaryOpC1_<OpAdd<int>,    ippAdd32s>,
-    binaryOpC1_<OpAdd<float>,  ippAdd32f>,
-    binaryOpC1_<OpAdd<double>, ippAdd64f>,
-    0
-#else
-    binaryOpC1_<OpAdd<uchar>,  VAdd8u>,
-    0,
-    binaryOpC1_<OpAdd<ushort>, VAdd16u>,
-    binaryOpC1_<OpAdd<short>,  VAdd16s>,
-    binaryOpC1_<OpAdd<int>,    NoVec>,
-    binaryOpC1_<OpAdd<float>,  VAdd32f>,
-    binaryOpC1_<OpAdd<double>, NoVec>,
-    0
-#endif
+    (BinaryFunc)add8u, (BinaryFunc)add8s, (BinaryFunc)add16u, (BinaryFunc)add16s,
+    (BinaryFunc)add32s, (BinaryFunc)add32f, (BinaryFunc)add64f, 0
 };
-
+    
 static BinaryFunc subTab[] =
 {
-#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
-    binaryOpC1_<OpSub<uchar>,  ippSub8u>,
-    0,
-    binaryOpC1_<OpSub<ushort>, ippSub16u>,
-    binaryOpC1_<OpSub<short>,  ippSub16s>,
-    binaryOpC1_<OpSub<int>,    ippSub32s>,
-    binaryOpC1_<OpSub<float>,  ippSub32f>,
-    binaryOpC1_<OpSub<double>, ippSub64f>,
-    0
-#else
-    binaryOpC1_<OpSub<uchar>,  VSub8u>,
-    0,
-    binaryOpC1_<OpSub<ushort>, VSub16u>,
-    binaryOpC1_<OpSub<short>,  VSub16s>,
-    binaryOpC1_<OpSub<int>,    NoVec>,
-    binaryOpC1_<OpSub<float>,  VSub32f>,
-    binaryOpC1_<OpSub<double>, NoVec>,
-    0
-#endif
+    (BinaryFunc)sub8u, (BinaryFunc)sub8s, (BinaryFunc)sub16u, (BinaryFunc)sub16s,
+    (BinaryFunc)sub32s, (BinaryFunc)sub32f, (BinaryFunc)sub64f, 0
 };
 
-void add( const Mat& src1, const Mat& src2, Mat& dst )
-{
-    int type = src1.type();
-    BinaryFunc func = addTab[CV_MAT_DEPTH(type)];
-    CV_Assert( type == src2.type() && func != 0 );
-
-    if( src1.dims > 2 || src2.dims > 2 )
-    {
-        dst.create(src1.dims, src1.size, src1.type());
-        const Mat* arrays[] = {&src1, &src2, &dst, 0};
-        Mat planes[3];
-        NAryMatIterator it(arrays, planes);
-
-        for( int i = 0; i < it.nplanes; i++, ++it )
-            func( it.planes[0], it.planes[1], it.planes[2] );
-        return;
-    }
-
-    Size size = src1.size();
-    CV_Assert( size == src2.size() );
-    dst.create( size, type );
-    func(src1, src2, dst);
-}
-
-void subtract( const Mat& src1, const Mat& src2, Mat& dst )
+static BinaryFunc absdiffTab[] =
 {
-    int type = src1.type();
-    BinaryFunc func = subTab[CV_MAT_DEPTH(type)];
-    CV_Assert( type == src2.type() && func != 0 );
-
-    if( src1.dims > 2 || src2.dims > 2 )
-    {
-        dst.create(src1.dims, src1.size, src1.type());
-        const Mat* arrays[] = {&src1, &src2, &dst, 0};
-        Mat planes[3];
-        NAryMatIterator it(arrays, planes);
-
-        for( int i = 0; i < it.nplanes; i++, ++it )
-            func( it.planes[0], it.planes[1], it.planes[2] );
-        return;
-    }
-
-    Size size = src1.size();
-    CV_Assert( size == src2.size() );
-    dst.create( size, type );
-    func(src1, src2, dst);
-}
+    (BinaryFunc)absdiff8u, (BinaryFunc)absdiff8s, (BinaryFunc)absdiff16u,
+    (BinaryFunc)absdiff16s, (BinaryFunc)absdiff32s, (BinaryFunc)absdiff32f,
+    (BinaryFunc)absdiff64f, 0
+};    
 
-void subtract(const Mat& a, const Scalar& s, Mat& c, const Mat& mask)
-{
-    add(a, -s, c, mask);
 }
-
-void add(const Mat& src1, const Mat& src2, Mat& dst, const Mat& mask)
+    
+void cv::add( const InputArray& src1, const InputArray& src2, OutputArray dst,
+          const InputArray& mask, int dtype )
 {
-    binaryMaskOp(src1, src2, dst, mask, addTab[src1.depth()] );
+    arithm_op(src1, src2, dst, mask, dtype, addTab );
 }
 
-void subtract(const Mat& src1, const Mat& src2, Mat& dst, const Mat& mask)
+void cv::subtract( const InputArray& src1, const InputArray& src2, OutputArray dst,
+               const InputArray& mask, int dtype )
 {
-    binaryMaskOp(src1, src2, dst, mask, subTab[src1.depth()] );
+    arithm_op(src1, src2, dst, mask, dtype, subTab );
 }
 
-void add(const Mat& src1, const Scalar& s, Mat& dst, const Mat& mask)
+void cv::absdiff( const InputArray& src1, const InputArray& src2, OutputArray dst )
 {
-    static BinarySFuncCn addSTab[] =
-    {
-        binarySOpCn_<OpAdd<uchar, int, uchar> >,
-        0,
-        binarySOpCn_<OpAdd<ushort, int, ushort> >,
-        binarySOpCn_<OpAdd<short, int, short> >,
-        binarySOpCn_<OpAdd<int> >,
-        binarySOpCn_<OpAdd<float> >,
-        binarySOpCn_<OpAdd<double> >,
-        0
-    };
-    int depth = src1.depth();
-    binarySMaskOp(src1, s, dst, mask, addSTab[depth]);
-}
-
-void subtract(const Scalar& s, const Mat& src1, Mat& dst, const Mat& mask)
-{
-    static BinarySFuncCn rsubSTab[] =
-    {
-        binarySOpCn_<OpRSub<uchar, int, uchar> >,
-        0,
-        binarySOpCn_<OpRSub<ushort, int, ushort> >,
-        binarySOpCn_<OpRSub<short, int, short> >,
-        binarySOpCn_<OpRSub<int> >,
-        binarySOpCn_<OpRSub<float> >,
-        binarySOpCn_<OpRSub<double> >,
-        0
-    };
-    int depth = src1.depth();
-    binarySMaskOp(src1, s, dst, mask, rsubSTab[depth]);
-}
+    arithm_op(src1, src2, dst, InputArray(), -1, absdiffTab);
+}    
 
 /****************************************************************************************\
 *                                    multiply/divide                                     *
 \****************************************************************************************/
 
+namespace cv
+{
+
 template<typename T, typename WT> static void
-mul_( const Mat& srcmat1, const Mat& srcmat2, Mat& dstmat, double _scale )
+mul_( const T* src1, size_t step1, const T* src2, size_t step2,
+      T* dst, size_t step, Size size, WT scale )
 {
-    const T* src1 = (const T*)srcmat1.data;
-    const T* src2 = (const T*)srcmat2.data;
-    T* dst = (T*)dstmat.data;
-    size_t step1 = srcmat1.step/sizeof(src1[0]);
-    size_t step2 = srcmat2.step/sizeof(src2[0]);
-    size_t step = dstmat.step/sizeof(dst[0]);
-    Size size = getContinuousSize( srcmat1, srcmat2, dstmat, dstmat.channels() );
+    step1 /= sizeof(src1[0]);
+    step2 /= sizeof(src2[0]);
+    step /= sizeof(dst[0]);
 
-    if( fabs(_scale - 1.) < DBL_EPSILON )
+    if( scale == (WT)1. )
     {
-        for( ; size.height--; src1+=step1, src2+=step2, dst+=step )
+        for( ; size.height--; src1 += step1, src2 += step2, dst += step )
         {
             int i;
             for( i = 0; i <= size.width - 4; i += 4 )
@@ -1075,8 +1410,7 @@ mul_( const Mat& srcmat1, const Mat& srcmat2, Mat& dstmat, double _scale )
     }
     else
     {
-        WT scale = (WT)_scale;
-        for( ; size.height--; src1+=step1, src2+=step2, dst+=step )
+        for( ; size.height--; src1 += step1, src2 += step2, dst += step )
         {
             int i;
             for( i = 0; i <= size.width - 4; i += 4 )
@@ -1096,56 +1430,15 @@ mul_( const Mat& srcmat1, const Mat& srcmat2, Mat& dstmat, double _scale )
     }
 }
 
-typedef void (*MulDivFunc)( const Mat& src1, const Mat& src2,
-                            Mat& dst, double scale );
-
-void multiply(const Mat& src1, const Mat& src2, Mat& dst, double scale)
-{
-    static MulDivFunc tab[] =
-    {
-        mul_<uchar, float>,
-        0,
-        mul_<ushort, float>,
-        mul_<short, float>,
-        mul_<int, double>,
-        mul_<float, float>,
-        mul_<double, double>,
-        0
-    };
-
-    MulDivFunc func = tab[src1.depth()];
-    CV_Assert( src1.type() == src2.type() && func != 0 );
-
-    if( src1.dims > 2 || src2.dims > 2 )
-    {
-        dst.create(src1.dims, src1.size, src1.type());
-        const Mat* arrays[] = {&src1, &src2, &dst, 0};
-        Mat planes[3];
-        NAryMatIterator it(arrays, planes);
-
-        for( int i = 0; i < it.nplanes; i++, ++it )
-            func( it.planes[0], it.planes[1], it.planes[2], scale );
-        return;
-    }
-
-    CV_Assert( src1.size() == src2.size() );
-    dst.create( src1.size(), src1.type() );
-    func( src1, src2, dst, scale );
-}
-
-
 template<typename T> static void
-div_( const Mat& srcmat1, const Mat& srcmat2, Mat& dstmat, double scale )
+div_( const T* src1, size_t step1, const T* src2, size_t step2,
+      T* dst, size_t step, Size size, double scale )
 {
-    const T* src1 = (const T*)srcmat1.data;
-    const T* src2 = (const T*)srcmat2.data;
-    T* dst = (T*)dstmat.data;
-    size_t step1 = srcmat1.step/sizeof(src1[0]);
-    size_t step2 = srcmat2.step/sizeof(src2[0]);
-    size_t step = dstmat.step/sizeof(dst[0]);
-    Size size = getContinuousSize( srcmat1, srcmat2, dstmat, dstmat.channels() );
-
-    for( ; size.height--; src1+=step1, src2+=step2, dst+=step )
+    step1 /= sizeof(src1[0]);
+    step2 /= sizeof(src2[0]);
+    step /= sizeof(dst[0]);
+    
+    for( ; size.height--; src1 += step1, src2 += step2, dst += step )
     {
         int i = 0;
         for( ; i <= size.width - 4; i += 4 )
@@ -1157,12 +1450,12 @@ div_( const Mat& srcmat1, const Mat& srcmat2, Mat& dstmat, double scale )
                 double d = scale/(a * b);
                 b *= d;
                 a *= d;
-
+                
                 T z0 = saturate_cast<T>(src2[i+1] * ((double)src1[i] * b));
                 T z1 = saturate_cast<T>(src2[i] * ((double)src1[i+1] * b));
                 T z2 = saturate_cast<T>(src2[i+3] * ((double)src1[i+2] * a));
                 T z3 = saturate_cast<T>(src2[i+2] * ((double)src1[i+3] * a));
-
+                
                 dst[i] = z0; dst[i+1] = z1;
                 dst[i+2] = z2; dst[i+3] = z3;
             }
@@ -1172,56 +1465,25 @@ div_( const Mat& srcmat1, const Mat& srcmat2, Mat& dstmat, double scale )
                 T z1 = src2[i+1] != 0 ? saturate_cast<T>(src1[i+1]*scale/src2[i+1]) : 0;
                 T z2 = src2[i+2] != 0 ? saturate_cast<T>(src1[i+2]*scale/src2[i+2]) : 0;
                 T z3 = src2[i+3] != 0 ? saturate_cast<T>(src1[i+3]*scale/src2[i+3]) : 0;
-
+                
                 dst[i] = z0; dst[i+1] = z1;
                 dst[i+2] = z2; dst[i+3] = z3;
             }
         }
-
+        
         for( ; i < size.width; i++ )
             dst[i] = src2[i] != 0 ? saturate_cast<T>(src1[i]*scale/src2[i]) : 0;
     }
 }
 
-
-void divide(const Mat& src1, const Mat& src2, Mat& dst, double scale)
-{
-    static MulDivFunc tab[] =
-    {
-        div_<uchar>, 0, div_<ushort>, div_<short>,
-        div_<int>, div_<float>, div_<double>, 0
-    };
-
-    MulDivFunc func = tab[src1.depth()];
-    CV_Assert( src1.type() == src2.type() && func != 0 );
-
-    if( src1.dims > 2 || src2.dims > 2 )
-    {
-        dst.create(src1.dims, src1.size, src1.type());
-        const Mat* arrays[] = {&src1, &src2, &dst, 0};
-        Mat planes[3];
-        NAryMatIterator it(arrays, planes);
-
-        for( int i = 0; i < it.nplanes; i++, ++it )
-            func( it.planes[0], it.planes[1], it.planes[2], scale );
-        return;
-    }
-
-    CV_Assert( src1.size() == src2.size() );
-    dst.create( src1.size(), src1.type() );
-    func( src1, src2, dst, scale );
-}
-
 template<typename T> static void
-recip_( double scale, const Mat& srcmat2, Mat& dstmat )
+recip_( const T*, size_t, const T* src2, size_t step2,
+        T* dst, size_t step, Size size, double scale )
 {
-    const T* src2 = (const T*)srcmat2.data;
-    T* dst = (T*)dstmat.data;
-    size_t step2 = srcmat2.step/sizeof(src2[0]);
-    size_t step = dstmat.step/sizeof(dst[0]);
-    Size size = getContinuousSize( srcmat2, dstmat, dstmat.channels() );
-
-    for( ; size.height--; src2+=step2, dst+=step )
+    step2 /= sizeof(src2[0]);
+    step /= sizeof(dst[0]);
+    
+    for( ; size.height--; src2 += step2, dst += step )
     {
         int i = 0;
         for( ; i <= size.width - 4; i += 4 )
@@ -1233,12 +1495,12 @@ recip_( double scale, const Mat& srcmat2, Mat& dstmat )
                 double d = scale/(a * b);
                 b *= d;
                 a *= d;
-
+                
                 T z0 = saturate_cast<T>(src2[i+1] * b);
                 T z1 = saturate_cast<T>(src2[i] * b);
                 T z2 = saturate_cast<T>(src2[i+3] * a);
                 T z3 = saturate_cast<T>(src2[i+2] * a);
-
+                
                 dst[i] = z0; dst[i+1] = z1;
                 dst[i+2] = z2; dst[i+3] = z3;
             }
@@ -1248,870 +1510,809 @@ recip_( double scale, const Mat& srcmat2, Mat& dstmat )
                 T z1 = src2[i+1] != 0 ? saturate_cast<T>(scale/src2[i+1]) : 0;
                 T z2 = src2[i+2] != 0 ? saturate_cast<T>(scale/src2[i+2]) : 0;
                 T z3 = src2[i+3] != 0 ? saturate_cast<T>(scale/src2[i+3]) : 0;
-
+                
                 dst[i] = z0; dst[i+1] = z1;
                 dst[i+2] = z2; dst[i+3] = z3;
             }
         }
-
+        
         for( ; i < size.width; i++ )
             dst[i] = src2[i] != 0 ? saturate_cast<T>(scale/src2[i]) : 0;
     }
 }
+    
+    
+static void mul8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2,
+                   uchar* dst, size_t step, Size sz, void* scale)
+{
+    mul_(src1, step1, src2, step2, dst, step, sz, (float)*(const double*)scale);
+}
+
+static void mul8s( const schar* src1, size_t step1, const schar* src2, size_t step2,
+                   schar* dst, size_t step, Size sz, void* scale)
+{
+    mul_(src1, step1, src2, step2, dst, step, sz, (float)*(const double*)scale);
+}
+
+static void mul16u( const ushort* src1, size_t step1, const ushort* src2, size_t step2,
+                    ushort* dst, size_t step, Size sz, void* scale)
+{
+    mul_(src1, step1, src2, step2, dst, step, sz, (float)*(const double*)scale);
+}
+
+static void mul16s( const short* src1, size_t step1, const short* src2, size_t step2,
+                    short* dst, size_t step, Size sz, void* scale)
+{
+    mul_(src1, step1, src2, step2, dst, step, sz, (float)*(const double*)scale);
+}
+
+static void mul32s( const int* src1, size_t step1, const int* src2, size_t step2,
+                    int* dst, size_t step, Size sz, void* scale)
+{
+    mul_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale);
+}
+    
+static void mul32f( const float* src1, size_t step1, const float* src2, size_t step2,
+                    float* dst, size_t step, Size sz, void* scale)
+{
+    mul_(src1, step1, src2, step2, dst, step, sz, (float)*(const double*)scale);
+}
+    
+static void mul64f( const double* src1, size_t step1, const double* src2, size_t step2,
+                    double* dst, size_t step, Size sz, void* scale)
+{
+    mul_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale);
+}
+    
+static void div8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2,
+                   uchar* dst, size_t step, Size sz, void* scale)
+{
+    if( src1 )
+        div_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale);
+    else
+        recip_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale);
+}
+
+static void div8s( const schar* src1, size_t step1, const schar* src2, size_t step2,
+                  schar* dst, size_t step, Size sz, void* scale)
+{
+    div_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale);
+}
+
+static void div16u( const ushort* src1, size_t step1, const ushort* src2, size_t step2,
+                    ushort* dst, size_t step, Size sz, void* scale)
+{
+    div_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale);
+}
+
+static void div16s( const short* src1, size_t step1, const short* src2, size_t step2,
+                    short* dst, size_t step, Size sz, void* scale)
+{
+    div_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale);
+}
+
+static void div32s( const int* src1, size_t step1, const int* src2, size_t step2,
+                    int* dst, size_t step, Size sz, void* scale)
+{
+    div_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale);
+}
+
+static void div32f( const float* src1, size_t step1, const float* src2, size_t step2,
+                    float* dst, size_t step, Size sz, void* scale)
+{
+    div_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale);
+}
+
+static void div64f( const double* src1, size_t step1, const double* src2, size_t step2,
+                    double* dst, size_t step, Size sz, void* scale)
+{
+    div_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale);
+}
+
+static void recip8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2,
+                  uchar* dst, size_t step, Size sz, void* scale)
+{
+    recip_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale);
+}
+
+static void recip8s( const schar* src1, size_t step1, const schar* src2, size_t step2,
+                  schar* dst, size_t step, Size sz, void* scale)
+{
+    recip_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale);
+}
+
+static void recip16u( const ushort* src1, size_t step1, const ushort* src2, size_t step2,
+                   ushort* dst, size_t step, Size sz, void* scale)
+{
+    recip_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale);
+}
+
+static void recip16s( const short* src1, size_t step1, const short* src2, size_t step2,
+                   short* dst, size_t step, Size sz, void* scale)
+{
+    recip_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale);
+}
 
-typedef void (*RecipFunc)( double scale, const Mat& src, Mat& dst );
+static void recip32s( const int* src1, size_t step1, const int* src2, size_t step2,
+                   int* dst, size_t step, Size sz, void* scale)
+{
+    recip_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale);
+}
+
+static void recip32f( const float* src1, size_t step1, const float* src2, size_t step2,
+                   float* dst, size_t step, Size sz, void* scale)
+{
+    recip_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale);
+}
+
+static void recip64f( const double* src1, size_t step1, const double* src2, size_t step2,
+                   double* dst, size_t step, Size sz, void* scale)
+{
+    recip_(src1, step1, src2, step2, dst, step, sz, *(const double*)scale);
+}
+    
+    
+static BinaryFunc mulTab[] =
+{
+    (BinaryFunc)mul8u, (BinaryFunc)mul8s, (BinaryFunc)mul16u,
+    (BinaryFunc)mul16s, (BinaryFunc)mul32s, (BinaryFunc)mul32f,
+    (BinaryFunc)mul64f, 0
+};
+
+static BinaryFunc divTab[] =
+{
+    (BinaryFunc)div8u, (BinaryFunc)div8s, (BinaryFunc)div16u,
+    (BinaryFunc)div16s, (BinaryFunc)div32s, (BinaryFunc)div32f,
+    (BinaryFunc)div64f, 0
+};
+
+static BinaryFunc recipTab[] =
+{
+    (BinaryFunc)recip8u, (BinaryFunc)recip8s, (BinaryFunc)recip16u,
+    (BinaryFunc)recip16s, (BinaryFunc)recip32s, (BinaryFunc)recip32f,
+    (BinaryFunc)recip64f, 0
+};
 
-void divide(double scale, const Mat& src, Mat& dst)
+    
+}
+    
+void cv::multiply(const InputArray& src1, const InputArray& src2,
+                  OutputArray dst, double scale, int dtype)
 {
-    static RecipFunc tab[] =
-    {
-        recip_<uchar>,
-        0,
-        recip_<ushort>,
-        recip_<short>,
-        recip_<int>,
-        recip_<float>,
-        recip_<double>,
-        0
-    };
-
-    RecipFunc func = tab[src.depth()];
-    CV_Assert( func != 0 );
-
-    if( src.dims > 2 )
-    {
-        dst.create(src.dims, src.size, src.type());
-        const Mat* arrays[] = {&src, &dst, 0};
-        Mat planes[2];
-        NAryMatIterator it(arrays, planes);
-
-        for( int i = 0; i < it.nplanes; i++, ++it )
-            func( scale, it.planes[0], it.planes[1] );
-        return;
-    }
+    arithm_op(src1, src2, dst, InputArray(), dtype, mulTab, true, &scale);
+}
 
-    dst.create( src.size(), src.type() );
-    func( scale, src, dst );
+void cv::divide(const InputArray& src1, const InputArray& src2,
+                OutputArray dst, double scale, int dtype)
+{
+    arithm_op(src1, src2, dst, InputArray(), dtype, divTab, true, &scale);
 }
 
+void cv::divide(double scale, const InputArray& src2,
+                OutputArray dst, int dtype)
+{
+    arithm_op(src2, src2, dst, InputArray(), dtype, recipTab, true, &scale);
+}    
+    
 /****************************************************************************************\
 *                                      addWeighted                                       *
 \****************************************************************************************/
 
+namespace cv
+{
+
 template<typename T, typename WT> static void
-addWeighted_( const Mat& srcmat1, double _alpha, const Mat& srcmat2,
-              double _beta, double _gamma, Mat& dstmat )
-{
-    const T* src1 = (const T*)srcmat1.data;
-    const T* src2 = (const T*)srcmat2.data;
-    T* dst = (T*)dstmat.data;
-    size_t step1 = srcmat1.step/sizeof(src1[0]);
-    size_t step2 = srcmat2.step/sizeof(src2[0]);
-    size_t step = dstmat.step/sizeof(dst[0]);
-    Size size = getContinuousSize( srcmat1, srcmat2, dstmat, dstmat.channels() );
-    WT alpha = (WT)_alpha, beta = (WT)_beta, gamma = (WT)_gamma;
-
-    for( ; size.height--; src1+=step1, src2+=step2, dst+=step )
+addWeighted_( const T* src1, size_t step1, const T* src2, size_t step2,
+              T* dst, size_t step, Size size, void* _scalars )
+{
+    const double* scalars = (const double*)_scalars;
+    WT alpha = (WT)scalars[0], beta = (WT)scalars[1], gamma = (WT)scalars[2];
+    step1 /= sizeof(src1[0]);
+    step2 /= sizeof(src2[0]);
+    step /= sizeof(dst[0]);
+
+    for( ; size.height--; src1 += step1, src2 += step2, dst += step )
     {
-        int i = 0;
-        for( ; i <= size.width - 4; i += 4 )
+        int x = 0;
+        for( ; x <= size.width - 4; x += 4 )
         {
-            T t0 = saturate_cast<T>(src1[i]*alpha + src2[i]*beta + gamma);
-            T t1 = saturate_cast<T>(src1[i+1]*alpha + src2[i+1]*beta + gamma);
-            dst[i] = t0; dst[i+1] = t1;
+            T t0 = saturate_cast<T>(src1[x]*alpha + src2[x]*beta + gamma);
+            T t1 = saturate_cast<T>(src1[x+1]*alpha + src2[x+1]*beta + gamma);
+            dst[x] = t0; dst[x+1] = t1;
 
-            t0 = saturate_cast<T>(src1[i+2]*alpha + src2[i+2]*beta + gamma);
-            t1 = saturate_cast<T>(src1[i+3]*alpha + src2[i+3]*beta + gamma);
-            dst[i+2] = t0; dst[i+3] = t1;
+            t0 = saturate_cast<T>(src1[x+2]*alpha + src2[x+2]*beta + gamma);
+            t1 = saturate_cast<T>(src1[x+3]*alpha + src2[x+3]*beta + gamma);
+            dst[x+2] = t0; dst[x+3] = t1;
         }
 
-        for( ; i < size.width; i++ )
-            dst[i] = saturate_cast<T>(src1[i]*alpha + src2[i]*beta + gamma);
+        for( ; x < size.width; x++ )
+            dst[x] = saturate_cast<T>(src1[x]*alpha + src2[x]*beta + gamma);
     }
 }
 
 
 static void
-addWeighted8u( const Mat& srcmat1, double alpha,
-               const Mat& srcmat2, double beta,
-               double gamma, Mat& dstmat )
-{
-    const int shift = 14;
-    if( srcmat1.rows*srcmat1.cols*srcmat1.channels() <= 256 ||
-        fabs(alpha) > 256 || fabs(beta) > 256 || fabs(gamma) > 256*256 )
-    {
-        addWeighted_<uchar, float>(srcmat1, alpha, srcmat2, beta, gamma, dstmat);
-        return;
-    }
-    const uchar* src1 = srcmat1.data;
-    const uchar* src2 = srcmat2.data;
-    uchar* dst = dstmat.data;
-    size_t step1 = srcmat1.step;
-    size_t step2 = srcmat2.step;
-    size_t step = dstmat.step;
-    Size size = getContinuousSize( srcmat1, srcmat2, dstmat, dstmat.channels() );
-
-    int tab1[256], tab2[256];
-    double t = 0;
-    int j, t0, t1, t2, t3;
-
-    alpha *= 1 << shift;
-    gamma = gamma*(1 << shift) + (1 << (shift - 1));
-    beta *= 1 << shift;
-
-    for( j = 0; j < 256; j++ )
-    {
-        tab1[j] = cvRound(t);
-        tab2[j] = cvRound(gamma);
-        t += alpha;
-        gamma += beta;
-    }
-
-    t0 = (tab1[0] + tab2[0]) >> shift;
-    t1 = (tab1[0] + tab2[255]) >> shift;
-    t2 = (tab1[255] + tab2[0]) >> shift;
-    t3 = (tab1[255] + tab2[255]) >> shift;
-
-    if( (unsigned)(t0+256) < 768 && (unsigned)(t1+256) < 768 &&
-        (unsigned)(t2+256) < 768 && (unsigned)(t3+256) < 768 )
+addWeighted8u( const uchar* src1, size_t step1,
+               const uchar* src2, size_t step2,
+               uchar* dst, size_t step, Size size,
+               void* _scalars )
+{
+    const double* scalars = (const double*)_scalars;
+    float alpha = (float)scalars[0], beta = (float)scalars[1], gamma = (float)scalars[2];
+    
+    for( ; size.height--; src1 += step1, src2 += step2, dst += step )
     {
-        // use faster table-based convertion back to 8u
-        for( ; size.height--; src1 += step1, src2 += step2, dst += step )
+        int x = 0;
+        
+#if CV_SSE2
+        if( USE_SSE2 )
         {
-            int i;
-
-            for( i = 0; i <= size.width - 4; i += 4 )
-            {
-                t0 = CV_FAST_CAST_8U((tab1[src1[i]] + tab2[src2[i]]) >> shift);
-                t1 = CV_FAST_CAST_8U((tab1[src1[i+1]] + tab2[src2[i+1]]) >> shift);
-
-                dst[i] = (uchar)t0;
-                dst[i+1] = (uchar)t1;
-
-                t0 = CV_FAST_CAST_8U((tab1[src1[i+2]] + tab2[src2[i+2]]) >> shift);
-                t1 = CV_FAST_CAST_8U((tab1[src1[i+3]] + tab2[src2[i+3]]) >> shift);
-
-                dst[i+2] = (uchar)t0;
-                dst[i+3] = (uchar)t1;
-            }
-
-            for( ; i < size.width; i++ )
+            __m128 a4 = _mm_set1_ps(alpha), b4 = _mm_set1_ps(beta), g4 = _mm_set1_ps(gamma);
+            __m128i z = _mm_setzero_si128();
+            
+            for( ; x <= size.width - 8; x += 8 )
             {
-                t0 = CV_FAST_CAST_8U((tab1[src1[i]] + tab2[src2[i]]) >> shift);
-                dst[i] = (uchar)t0;
+                __m128i u = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(src1 + x)), z);
+                __m128i v = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(src2 + x)), z);
+                
+                __m128 u0 = _mm_cvtepi32_ps(_mm_unpacklo_epi16(u, z));
+                __m128 u1 = _mm_cvtepi32_ps(_mm_unpackhi_epi16(u, z));
+                __m128 v0 = _mm_cvtepi32_ps(_mm_unpacklo_epi16(v, z));
+                __m128 v1 = _mm_cvtepi32_ps(_mm_unpackhi_epi16(v, z));
+                
+                u0 = _mm_add_ps(_mm_mul_ps(u0, a4), _mm_mul_ps(v0, b4));
+                u1 = _mm_add_ps(_mm_mul_ps(u1, a4), _mm_mul_ps(v1, b4));
+                u0 = _mm_add_ps(u0, g4); u1 = _mm_add_ps(u1, g4);
+                
+                u = _mm_packs_epi32(_mm_cvtps_epi32(u0), _mm_cvtps_epi32(u1));
+                u = _mm_packus_epi16(u, u);
+                
+                _mm_storel_epi64((__m128i*)(dst + x), u);
             }
         }
-    }
-    else
-    {
-        // use universal macro for convertion back to 8u
-        for( ; size.height--; src1 += step1, src2 += step2, dst += step )
+#endif
+        for( ; x <= size.width - 4; x += 4 )
         {
-            int i;
-
-            for( i = 0; i <= size.width - 4; i += 4 )
-            {
-                t0 = (tab1[src1[i]] + tab2[src2[i]]) >> shift;
-                t1 = (tab1[src1[i+1]] + tab2[src2[i+1]]) >> shift;
+            float t0, t1;
+            t0 = CV_8TO32F(src1[x])*alpha + CV_8TO32F(src2[x])*beta + gamma;
+            t1 = CV_8TO32F(src1[x+1])*alpha + CV_8TO32F(src2[x+1])*beta + gamma;
 
-                dst[i] = CV_CAST_8U( t0 );
-                dst[i+1] = CV_CAST_8U( t1 );
+            dst[x] = saturate_cast<uchar>(t0);
+            dst[x+1] = saturate_cast<uchar>(t1);
 
-                t0 = (tab1[src1[i+2]] + tab2[src2[i+2]]) >> shift;
-                t1 = (tab1[src1[i+3]] + tab2[src2[i+3]]) >> shift;
+            t0 = CV_8TO32F(src1[x+2])*alpha + CV_8TO32F(src2[x+2])*beta + gamma;
+            t1 = CV_8TO32F(src1[x+3])*alpha + CV_8TO32F(src2[x+3])*beta + gamma;
 
-                dst[i+2] = CV_CAST_8U( t0 );
-                dst[i+3] = CV_CAST_8U( t1 );
-            }
+            dst[x+2] = saturate_cast<uchar>(t0);
+            dst[x+3] = saturate_cast<uchar>(t1);
+        }
 
-            for( ; i < size.width; i++ )
-            {
-                t0 = (tab1[src1[i]] + tab2[src2[i]]) >> shift;
-                dst[i] = CV_CAST_8U( t0 );
-            }
+        for( ; x < size.width; x++ )
+        {
+            float t0 = CV_8TO32F(src1[x])*alpha + CV_8TO32F(src2[x])*beta + gamma;
+            dst[x] = saturate_cast<uchar>(t0);
         }
     }
 }
 
-typedef void (*AddWeightedFunc)( const Mat& src1, double alpha, const Mat& src2,
-                                 double beta, double gamma, Mat& dst );
-
-void addWeighted( const Mat& src1, double alpha, const Mat& src2,
-                  double beta, double gamma, Mat& dst )
+static void addWeighted8s( const schar* src1, size_t step1, const schar* src2, size_t step2,
+                           schar* dst, size_t step, Size sz, void* scalars )
 {
-    static AddWeightedFunc tab[] =
-    {
-        addWeighted8u,
-        0,
-        addWeighted_<ushort, float>,
-        addWeighted_<short, float>,
-        addWeighted_<int, double>,
-        addWeighted_<float, double>,
-        addWeighted_<double, double>,
-        0
-    };
-
-    AddWeightedFunc func = tab[src1.depth()];
-    CV_Assert( src1.type() == src2.type() && func != 0 );
-
-    if( src1.dims > 2 || src2.dims > 2 )
-    {
-        dst.create(src1.dims, src1.size, src1.type());
-        const Mat* arrays[] = {&src1, &src2, &dst, 0};
-        Mat planes[3];
-        NAryMatIterator it(arrays, planes);
-
-        for( int i = 0; i < it.nplanes; i++, ++it )
-            func( it.planes[0], alpha, it.planes[1], beta, gamma, it.planes[2] );
-        return;
-    }
-
-    CV_Assert( src1.size() == src2.size() );
-    dst.create( src1.size(), src1.type() );
-    func( src1, alpha, src2, beta, gamma, dst );
+    addWeighted_<schar, float>(src1, step1, src2, step2, dst, step, sz, scalars);
 }
 
-
-/****************************************************************************************\
-*                                      absdiff                                           *
-\****************************************************************************************/
-
-template<typename T> struct OpAbsDiff
+static void addWeighted16u( const ushort* src1, size_t step1, const ushort* src2, size_t step2,
+                            ushort* dst, size_t step, Size sz, void* scalars )
 {
-    typedef T type1;
-    typedef T type2;
-    typedef T rtype;
-    T operator()(T a, T b) { return (T)std::abs(a - b); }
-};
-
-template<> inline short OpAbsDiff<short>::operator ()(short a, short b)
-{ return saturate_cast<short>(std::abs(a - b)); }
+    addWeighted_<ushort, float>(src1, step1, src2, step2, dst, step, sz, scalars);
+}
 
-template<typename T, typename WT=T> struct OpAbsDiffS
+static void addWeighted16s( const short* src1, size_t step1, const short* src2, size_t step2,
+                            short* dst, size_t step, Size sz, void* scalars )
 {
-    typedef T type1;
-    typedef WT type2;
-    typedef T rtype;
-    T operator()(T a, WT b) { return saturate_cast<T>(std::abs(a - b)); }
-};
+    addWeighted_<short, float>(src1, step1, src2, step2, dst, step, sz, scalars);
+}
 
-void absdiff( const Mat& src1, const Mat& src2, Mat& dst )
+static void addWeighted32s( const int* src1, size_t step1, const int* src2, size_t step2,
+                            int* dst, size_t step, Size sz, void* scalars )
 {
-    static BinaryFunc tab[] =
-    {
-#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
-        binaryOpC1_<OpAbsDiff<uchar>,ippAbsDiff8u>,
-        0,
-        binaryOpC1_<OpAbsDiff<ushort>,ippAbsDiff16u>,
-        binaryOpC1_<OpAbsDiff<short>,VAbsDiff16s>,
-        binaryOpC1_<OpAbsDiff<int>,NoVec>,
-        binaryOpC1_<OpAbsDiff<float>,ippAbsDiff32f>,
-        binaryOpC1_<OpAbsDiff<double>,NoVec>,
-        0
-#else
-        binaryOpC1_<OpAbsDiff<uchar>,VAbsDiff8u>,
-        0,
-        binaryOpC1_<OpAbsDiff<ushort>,VAbsDiff16u>,
-        binaryOpC1_<OpAbsDiff<short>,VAbsDiff16s>,
-        binaryOpC1_<OpAbsDiff<int>,NoVec>,
-        binaryOpC1_<OpAbsDiff<float>,VAbsDiff32f>,
-        binaryOpC1_<OpAbsDiff<double>,NoVec>,
-        0
-#endif
-    };
-
-    binaryOp(src1, src2, dst, tab[src1.depth()]);
+    addWeighted_<int, double>(src1, step1, src2, step2, dst, step, sz, scalars);
 }
 
-
-void absdiff( const Mat& src1, const Scalar& s, Mat& dst )
+static void addWeighted32f( const float* src1, size_t step1, const float* src2, size_t step2,
+                            float* dst, size_t step, Size sz, void* scalars )
 {
-    static BinarySFuncCn tab[] =
-    {
-        binarySOpCn_<OpAbsDiffS<uchar, int> >,
-        0,
-        binarySOpCn_<OpAbsDiffS<ushort, int> >,
-        binarySOpCn_<OpAbsDiffS<short, int> >,
-        binarySOpCn_<OpAbsDiffS<int> >,
-        binarySOpCn_<OpAbsDiffS<float> >,
-        binarySOpCn_<OpAbsDiffS<double> >,
-        0
-    };
-
-    BinarySFuncCn func = tab[src1.depth()];
-    CV_Assert(src1.channels() <= 4 && func != 0);
-
-    if( src1.dims > 2 )
-    {
-        dst.create(src1.dims, src1.size, src1.type());
-        const Mat* arrays[] = {&src1, &dst, 0};
-        Mat planes[3];
-        NAryMatIterator it(arrays, planes);
+    addWeighted_<float, double>(src1, step1, src2, step2, dst, step, sz, scalars);
+}
 
-        for( int i = 0; i < it.nplanes; i++, ++it )
-            func( it.planes[0], it.planes[1], s );
-        return;
-    }
+static void addWeighted64f( const double* src1, size_t step1, const double* src2, size_t step2,
+                            double* dst, size_t step, Size sz, void* scalars )
+{
+    addWeighted_<double, double>(src1, step1, src2, step2, dst, step, sz, scalars);
+}
 
-    dst.create(src1.size(), src1.type());
-    func( src1, dst, s );
+static BinaryFunc addWeightedTab[] =
+{
+    (BinaryFunc)addWeighted8u, (BinaryFunc)addWeighted8s, (BinaryFunc)addWeighted16u,
+    (BinaryFunc)addWeighted16s, (BinaryFunc)addWeighted32s, (BinaryFunc)addWeighted32f,
+    (BinaryFunc)addWeighted64f, 0
+};
+    
+}
+    
+void cv::addWeighted( const InputArray& src1, double alpha, const InputArray& src2,
+                      double beta, double gamma, OutputArray dst, int dtype )
+{
+    double scalars[] = {alpha, beta, gamma};
+    arithm_op(src1, src2, dst, InputArray(), dtype, addWeightedTab, true, scalars);
 }
 
+    
 /****************************************************************************************\
-*                                      inRange[S]                                        *
+*                                          compare                                       *
 \****************************************************************************************/
 
-template<typename T, typename WT> struct InRangeC1
+namespace cv
 {
-    typedef T xtype;
-    typedef WT btype;
-    uchar operator()(xtype x, btype a, btype b) const
-    { return (uchar)-(a <= x && x < b); }
-};
 
-template<typename T, typename WT> struct InRangeC2
+template<typename T> static void
+cmp_(const T* src1, size_t step1, const T* src2, size_t step2,
+     uchar* dst, size_t step, Size size, int code)
 {
-    typedef Vec<T,2> xtype;
-    typedef Vec<WT,2> btype;
-    uchar operator()(const xtype& x, const btype& a, const btype& b) const
+    step1 /= sizeof(src1[0]);
+    step2 /= sizeof(src2[0]);
+    if( code == CMP_GE || code == CMP_LT )
     {
-        return (uchar)-(a[0] <= x[0] && x[0] < b[0] &&
-                        a[1] <= x[1] && x[1] < b[1]);
+        std::swap(src1, src2);
+        std::swap(step1, step2);
+        code = code == CMP_GE ? CMP_LE : CMP_GT;
     }
-};
-
-template<typename T, typename WT> struct InRangeC3
-{
-    typedef Vec<T,3> xtype;
-    typedef Vec<WT,3> btype;
-    uchar operator()(const xtype& x, const btype& a, const btype& b) const
+    
+    if( code == CMP_GT || code == CMP_LE )
     {
-        return (uchar)-(a[0] <= x[0] && x[0] < b[0] &&
-                        a[1] <= x[1] && x[1] < b[1] &&
-                        a[2] <= x[2] && x[2] < b[2]);
+        int m = code == CMP_GT ? 0 : 255;
+        for( ; size.height--; src1 += step1, src2 += step2, dst += step )
+        {
+            int x = 0;
+            for( ; x <= size.width - 4; x += 4 )
+            {
+                int t0, t1;
+                t0 = -(src1[x] > src2[x]) ^ m;
+                t1 = -(src1[x+1] > src2[x+1]) ^ m;
+                dst[x] = (uchar)t0; dst[x+1] = (uchar)t1;
+                t0 = -(src1[x+2] > src2[x+2]) ^ m;
+                t1 = -(src1[x+3] > src2[x+3]) ^ m;
+                dst[x+2] = (uchar)t0; dst[x+3] = (uchar)t1;
+            }
+            
+            for( ; x < size.width; x++ )
+                dst[x] = (uchar)(-(src1[x] > src2[x]) ^ m);
+        }
     }
-};
-
-template<typename T, typename WT> struct InRangeC4
-{
-    typedef Vec<T,4> xtype;
-    typedef Vec<WT,4> btype;
-    uchar operator()(const xtype& x, const btype& a, const btype& b) const
+    else if( code == CMP_EQ || code == CMP_NE )
     {
-        return (uchar)-(a[0] <= x[0] && x[0] < b[0] &&
-                        a[1] <= x[1] && x[1] < b[1] &&
-                        a[2] <= x[2] && x[2] < b[2] &&
-                        a[3] <= x[3] && x[3] < b[3]);
+        int m = code == CMP_EQ ? 0 : 255;
+        for( ; size.height--; src1 += step1, src2 += step2, dst += step )
+        {
+            int x = 0;
+            for( ; x <= size.width - 4; x += 4 )
+            {
+                int t0, t1;
+                t0 = -(src1[x] == src2[x]) ^ m;
+                t1 = -(src1[x+1] == src2[x+1]) ^ m;
+                dst[x] = (uchar)t0; dst[x+1] = (uchar)t1;
+                t0 = -(src1[x+2] == src2[x+2]) ^ m;
+                t1 = -(src1[x+3] == src2[x+3]) ^ m;
+                dst[x+2] = (uchar)t0; dst[x+3] = (uchar)t1;
+            }
+            
+            for( ; x < size.width; x++ )
+                dst[x] = (uchar)(-(src1[x] == src2[x]) ^ m);
+        }
     }
-};
-
-template<class Op> static void
-inRange_( const Mat& srcmat1, const Mat& srcmat2, const Mat& srcmat3, Mat& dstmat )
+}
+    
+    
+static void cmp8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2,
+                  uchar* dst, size_t step, Size size, void* _cmpop)
 {
-    Op op;
-    uchar* dst = dstmat.data;
-    size_t dstep = dstmat.step;
-    Size size = getContinuousSize( srcmat1, srcmat2, srcmat3, dstmat );
-
-    for( int y = 0; y < size.height; y++, dst += dstep )
-    {
-        const typename Op::xtype* src1 = (const typename Op::xtype*)(srcmat1.data + srcmat1.step*y);
-        const typename Op::xtype* src2 = (const typename Op::xtype*)(srcmat2.data + srcmat2.step*y);
-        const typename Op::xtype* src3 = (const typename Op::xtype*)(srcmat3.data + srcmat3.step*y);
-        for( int x = 0; x < size.width; x++ )
-            dst[x] = op( src1[x], src2[x], src3[x] );
-    }
+    cmp_(src1, step1, src2, step2, dst, step, size, *(int*)_cmpop);
 }
 
-template<class Op> static void
-inRangeS_( const Mat& srcmat1, const Scalar& _a, const Scalar& _b, Mat& dstmat )
+static void cmp8s(const schar* src1, size_t step1, const schar* src2, size_t step2,
+                  uchar* dst, size_t step, Size size, void* _cmpop)
 {
-    Op op;
-    typedef typename Op::btype WT;
-    typedef typename DataType<WT>::channel_type WT1;
-    WT a, b;
-    uchar* dst = dstmat.data;
-    size_t dstep = dstmat.step;
-    Size size = getContinuousSize( srcmat1, dstmat );
-    int cn = srcmat1.channels();
-    scalarToRawData(_a, &a, CV_MAKETYPE(DataType<WT>::depth, cn));
-    scalarToRawData(_b, &b, CV_MAKETYPE(DataType<WT>::depth, cn));
-
-    for( int y = 0; y < size.height; y++, dst += dstep )
-    {
-        const typename Op::xtype* src1 = (const typename Op::xtype*)(srcmat1.data + srcmat1.step*y);
-        for( int x = 0; x < size.width; x++ )
-            dst[x] = op( src1[x], a, b );
-    }
+    cmp_(src1, step1, src2, step2, dst, step, size, *(int*)_cmpop);
 }
 
-typedef void (*InRangeFunc)( const Mat& src1, const Mat& src2, const Mat& src3, Mat& dst );
-typedef void (*InRangeSFunc)( const Mat& src1, const Scalar& a, const Scalar& b, Mat& dst );
-
-void inRange(const Mat& src, const Mat& lowerb,
-             const Mat& upperb, Mat& dst)
+static void cmp16u(const ushort* src1, size_t step1, const ushort* src2, size_t step2,
+                  uchar* dst, size_t step, Size size, void* _cmpop)
 {
-    static InRangeFunc tab[] =
-    {
-        inRange_<InRangeC1<uchar, uchar> >,
-        0,
-        inRange_<InRangeC1<ushort, ushort> >,
-        inRange_<InRangeC1<short, short> >,
-        inRange_<InRangeC1<int, int> >,
-        inRange_<InRangeC1<float, float> >,
-        inRange_<InRangeC1<double, double> >,
-        0,
-
-        inRange_<InRangeC2<uchar, uchar> >,
-        0,
-        inRange_<InRangeC2<ushort, ushort> >,
-        inRange_<InRangeC2<short, short> >,
-        inRange_<InRangeC2<int, int> >,
-        inRange_<InRangeC2<float, float> >,
-        inRange_<InRangeC2<double, double> >,
-        0,
-
-        inRange_<InRangeC3<uchar, uchar> >,
-        0,
-        inRange_<InRangeC3<ushort, ushort> >,
-        inRange_<InRangeC3<short, short> >,
-        inRange_<InRangeC3<int, int> >,
-        inRange_<InRangeC3<float, float> >,
-        inRange_<InRangeC3<double, double> >,
-        0,
-
-        inRange_<InRangeC4<uchar, uchar> >,
-        0,
-        inRange_<InRangeC4<ushort, ushort> >,
-        inRange_<InRangeC4<short, short> >,
-        inRange_<InRangeC4<int, int> >,
-        inRange_<InRangeC4<float, float> >,
-        inRange_<InRangeC4<double, double> >,
-        0
-    };
-
-    CV_Assert( src.type() == lowerb.type() && src.type() == upperb.type() && src.channels() <= 4 );
-
-    InRangeFunc func = tab[src.type()];
-    CV_Assert( func != 0 );
-
-    if( src.dims > 2 || lowerb.dims > 2 || upperb.dims > 2 )
-    {
-        dst.create(src.dims, src.size, CV_8U);
-        const Mat* arrays[] = {&src, &lowerb, &upperb, &dst, 0};
-        Mat planes[4];
-        NAryMatIterator it(arrays, planes);
-
-        for( int i = 0; i < it.nplanes; i++, ++it )
-            func( it.planes[0], it.planes[1], it.planes[2], it.planes[3] );
-        return;
-    }
-
-    CV_Assert( src.size() == lowerb.size() && src.size() == upperb.size() );
-    dst.create(src.size(), CV_8U);
-    func( src, lowerb, upperb, dst );
+    cmp_(src1, step1, src2, step2, dst, step, size, *(int*)_cmpop);
 }
 
-void inRange(const Mat& src, const Scalar& lowerb,
-             const Scalar& upperb, Mat& dst)
+static void cmp16s(const short* src1, size_t step1, const short* src2, size_t step2,
+                  uchar* dst, size_t step, Size size, void* _cmpop)
 {
-    static InRangeSFunc tab[] =
-    {
-        inRangeS_<InRangeC1<uchar, int> >,
-        0,
-        inRangeS_<InRangeC1<ushort, int> >,
-        inRangeS_<InRangeC1<short, int> >,
-        inRangeS_<InRangeC1<int, int> >,
-        inRangeS_<InRangeC1<float, float> >,
-        inRangeS_<InRangeC1<double, double> >,
-        0,
-
-        inRangeS_<InRangeC2<uchar, int> >,
-        0,
-        inRangeS_<InRangeC2<ushort, int> >,
-        inRangeS_<InRangeC2<short, int> >,
-        inRangeS_<InRangeC2<int, int> >,
-        inRangeS_<InRangeC2<float, float> >,
-        inRangeS_<InRangeC2<double, double> >,
-        0,
-
-        inRangeS_<InRangeC3<uchar, int> >,
-        0,
-        inRangeS_<InRangeC3<ushort, int> >,
-        inRangeS_<InRangeC3<short, int> >,
-        inRangeS_<InRangeC3<int, int> >,
-        inRangeS_<InRangeC3<float, float> >,
-        inRangeS_<InRangeC3<double, double> >,
-        0,
-
-        inRangeS_<InRangeC4<uchar, int> >,
-        0,
-        inRangeS_<InRangeC4<ushort, int> >,
-        inRangeS_<InRangeC4<short, int> >,
-        inRangeS_<InRangeC4<int, int> >,
-        inRangeS_<InRangeC4<float, float> >,
-        inRangeS_<InRangeC4<double, double> >,
-        0
-    };
-
-    CV_Assert( src.channels() <= 4 );
-
-    InRangeSFunc func = tab[src.type()];
-    CV_Assert( func != 0 );
-
-    if( src.dims > 2 )
-    {
-        dst.create(src.dims, src.size, CV_8U);
-        const Mat* arrays[] = {&src, &dst, 0};
-        Mat planes[2];
-        NAryMatIterator it(arrays, planes);
-
-        for( int i = 0; i < it.nplanes; i++, ++it )
-            func( it.planes[0], lowerb, upperb, it.planes[1] );
-        return;
-    }
-
-    dst.create(src.size(), CV_8U);
-    func( src, lowerb, upperb, dst );
+    cmp_(src1, step1, src2, step2, dst, step, size, *(int*)_cmpop);
 }
 
-/****************************************************************************************\
-*                                          compare                                       *
-\****************************************************************************************/
+static void cmp32s(const int* src1, size_t step1, const int* src2, size_t step2,
+                   uchar* dst, size_t step, Size size, void* _cmpop)
+{
+    cmp_(src1, step1, src2, step2, dst, step, size, *(int*)_cmpop);
+}
 
-template<typename T, typename WT=T> struct CmpEQ
+static void cmp32f(const float* src1, size_t step1, const float* src2, size_t step2,
+                  uchar* dst, size_t step, Size size, void* _cmpop)
 {
-    typedef T type1;
-    typedef WT type2;
-    typedef uchar rtype;
-    uchar operator()(T a, WT b) const { return (uchar)-(a == b); }
-};
+    cmp_(src1, step1, src2, step2, dst, step, size, *(int*)_cmpop);
+}
 
-template<typename T, typename WT=T> struct CmpGT
+static void cmp64f(const double* src1, size_t step1, const double* src2, size_t step2,
+                  uchar* dst, size_t step, Size size, void* _cmpop)
 {
-    typedef T type1;
-    typedef WT type2;
-    typedef uchar rtype;
-    uchar operator()(T a, WT b) const { return (uchar)-(a > b); }
+    cmp_(src1, step1, src2, step2, dst, step, size, *(int*)_cmpop);
+}    
+    
+static BinaryFunc cmpTab[] =
+{
+    (BinaryFunc)cmp8u, (BinaryFunc)cmp8s, (BinaryFunc)cmp16u,
+    (BinaryFunc)cmp16s, (BinaryFunc)cmp32s, (BinaryFunc)cmp32f,
+    (BinaryFunc)cmp64f, 0
 };
 
-template<typename T, typename WT=T> struct CmpGE
+    
+static double getMinVal(int depth)
 {
-    typedef T type1;
-    typedef WT type2;
-    typedef uchar rtype;
-    uchar operator()(T a, WT b) const { return (uchar)-(a >= b); }
-};
+    static const double tab[] = {0, -128, 0, -32768, INT_MIN, -FLT_MAX, -DBL_MAX, 0};
+    return tab[depth];
+}
 
-void compare( const Mat& src1, const Mat& src2, Mat& dst, int cmpOp )
+static double getMaxVal(int depth)
 {
-    static BinaryFunc tab[][8] =
+    static const double tab[] = {255, 127, 65535, 32767, INT_MAX, FLT_MAX, DBL_MAX, 0};
+    return tab[depth];
+}    
+   
+}
+    
+void cv::compare(const InputArray& _src1, const InputArray& _src2, OutputArray _dst, int op)
+{
+    CV_Assert( op == CMP_LT || op == CMP_LE || op == CMP_EQ ||
+               op == CMP_NE || op == CMP_GE || op == CMP_GT );
+    
+    int kind1 = _src1.kind(), kind2 = _src2.kind();
+    Mat src1 = _src1.getMat(), src2 = _src2.getMat();
+    
+    if( kind1 == kind2 && src1.dims <= 2 && src2.dims <= 2 && src1.size() == src2.size() && src1.type() == src2.type() )
     {
+        _dst.create(src1.size(), CV_8UC1);
+        Mat dst = _dst.getMat();
+        Size sz = getContinuousSize(src1, src2, dst, src1.channels());
+        cmpTab[src1.depth()](src1.data, src1.step, src2.data, src2.step, dst.data, dst.step, sz, &op);
+        return;
+    }
+    
+    bool haveScalar = false;
+    
+    if( (kind1 == InputArray::MATX) + (kind2 == InputArray::MATX) == 1 ||
+        src1.size != src2.size || src1.type() != src2.type() )
+    {
+        if( checkScalar(src1, src2.type(), kind1, kind2) )
         {
-            binaryOpC1_<CmpGT<uchar>,VCmpGT8u>,
-            0,
-            binaryOpC1_<CmpGT<ushort>,NoVec>,
-            binaryOpC1_<CmpGT<short>,NoVec>,
-            binaryOpC1_<CmpGT<int>,NoVec>,
-            binaryOpC1_<CmpGT<float>,NoVec>,
-            binaryOpC1_<CmpGT<double>,NoVec>,
-            0
-        },
-
-        {
-            binaryOpC1_<CmpEQ<uchar>,VCmpEQ8u>,
-            0,
-            binaryOpC1_<CmpEQ<ushort>,NoVec>,
-            binaryOpC1_<CmpEQ<ushort>,NoVec>, // same function as for ushort's
-            binaryOpC1_<CmpEQ<int>,NoVec>,
-            binaryOpC1_<CmpEQ<float>,NoVec>,
-            binaryOpC1_<CmpEQ<double>,NoVec>,
-            0
-        },
-    };
-
-    CV_Assert(src1.channels() == 1);
-
-    int depth = src1.depth();
-    const Mat *psrc1 = &src1, *psrc2 = &src2;
-    bool invflag = false;
-
-    switch( cmpOp )
+            // src1 is a scalar; swap it with src2
+            swap(src1, src2);
+            op = op == CMP_LT ? CMP_GT : op == CMP_LE ? CMP_GE :
+                op == CMP_GE ? CMP_LE : op == CMP_GT ? CMP_LT : op;
+        }
+        else if( !checkScalar(src2, src1.type(), kind2, kind1) )
+            CV_Error( CV_StsUnmatchedSizes,
+                     "The operation is neither 'array op array' (where arrays have the same size and the same type), "
+                     "nor 'array op scalar', nor 'scalar op array'" );
+        haveScalar = true;
+    }
+    
+    int cn = src1.channels(), depth1 = src1.depth(), depth2 = src2.depth();
+    if( cn != 1 )
+        CV_Error( CV_StsUnsupportedFormat, "compare() can only process single-channel arrays" );
+        
+    size_t esz = src1.elemSize();
+    size_t blocksize0 = (size_t)(BLOCK_SIZE + esz-1)/esz;
+    
+    _dst.create(src1.dims, src1.size, CV_8U);
+    Mat dst = _dst.getMat();
+    BinaryFunc func = cmpTab[depth1];
+    
+    if( !haveScalar )
     {
-    case CMP_GT:
-    case CMP_EQ:
-        break;
-
-    case CMP_GE:
-        std::swap( psrc1, psrc2 );
-        invflag = true;
-        break;
-
-    case CMP_LT:
-        std::swap( psrc1, psrc2 );
-        break;
-
-    case CMP_LE:
-        invflag = true;
-        break;
-
-    case CMP_NE:
-        cmpOp = CMP_EQ;
-        invflag = true;
-        break;
-
-    default:
-        CV_Error(CV_StsBadArg, "Unknown comparison method");
+        const Mat* arrays[] = { &src1, &src2, &dst, 0 };
+        uchar* ptrs[3];
+        
+        NAryMatIterator it(arrays, ptrs);
+        size_t total = it.size;
+        
+        for( size_t i = 0; i < it.nplanes; i++, ++it )
+            func( ptrs[0], 0, ptrs[1], 0, ptrs[2], 0, Size((int)total, 1), &op );
     }
-
-    BinaryFunc func = tab[cmpOp == CMP_EQ][depth];
-    binaryOp(*psrc1, *psrc2, dst, func, CV_8U);
-    if( invflag )
-        bitwise_not(dst, dst);
-}
-
-
-void compare( const Mat& src1, double value, Mat& dst, int cmpOp )
-{
-    static BinarySFuncC1 tab[][8] =
+    else
     {
+        const Mat* arrays[] = { &src1, &dst, 0 };
+        uchar* ptrs[2];
+        
+        NAryMatIterator it(arrays, ptrs);
+        size_t total = it.size, blocksize = std::min(total, blocksize0);
+        
+        AutoBuffer<uchar> _buf(blocksize*esz);
+        uchar *buf = _buf;
+
+        if( depth1 > CV_32S )
+            convertAndUnrollScalar( src2, depth1, buf, blocksize );
+        else
         {
-            binarySOpC1_<CmpEQ<uchar, int> >,
-            0,
-            binarySOpC1_<CmpEQ<ushort, int> >,
-            binarySOpC1_<CmpEQ<short, int> >,
-            binarySOpC1_<CmpEQ<int> >,
-            binarySOpC1_<CmpEQ<float> >,
-            binarySOpC1_<CmpEQ<double> >,
-            0
-        },
-
-        {
-            binarySOpC1_<CmpGT<uchar, int> >,
-            0,
-            binarySOpC1_<CmpGT<ushort, int> >,
-            binarySOpC1_<CmpGT<short, int> >,
-            binarySOpC1_<CmpGT<int> >,
-            binarySOpC1_<CmpGT<float> >,
-            binarySOpC1_<CmpGT<double> >,
-            0
-        },
-
+            double fval=0;
+            getConvertFunc(depth2, CV_64F)(src2.data, 0, 0, 0, (uchar*)&fval, 0, Size(1,1), 0);
+            if( fval < getMinVal(depth1) )
+            {
+                dst = Scalar::all(op == CMP_GT || op == CMP_GE || op == CMP_NE ? 255 : 0);
+                return;
+            }
+            
+            if( fval > getMaxVal(depth1) )
+            {
+                dst = Scalar::all(op == CMP_LT || op == CMP_LE || op == CMP_NE ? 255 : 0);
+                return;
+            }
+            
+            int ival = cvRound(fval);
+            if( fval != ival )
+            {
+                if( op == CMP_LT || op == CMP_GE )
+                    ival = cvCeil(fval);
+                else if( op == CMP_LE || op == CMP_GT )
+                    ival = cvFloor(fval);
+                else
+                {
+                    dst = Scalar::all(op == CMP_NE ? 255 : 0);
+                    return;
+                }
+            }
+            convertAndUnrollScalar(Mat(1, 1, CV_32S, &ival), depth1, buf, blocksize);
+        }
+        
+        for( size_t i = 0; i < it.nplanes; i++, ++it )
         {
-            binarySOpC1_<CmpGE<uchar, int> >,
-            0,
-            binarySOpC1_<CmpGE<ushort, int> >,
-            binarySOpC1_<CmpGE<short, int> >,
-            binarySOpC1_<CmpGE<int> >,
-            binarySOpC1_<CmpGE<float> >,
-            binarySOpC1_<CmpGE<double> >,
-            0
-        },
-    };
-
-    int depth = src1.depth();
-    bool invflag = false;
-
-    switch( cmpOp )
-    {
-    case CMP_GT:
-    case CMP_EQ:
-    case CMP_GE:
-        break;
-
-    case CMP_LT:
-        invflag = true;
-        cmpOp = CMP_GE;
-        break;
-
-    case CMP_LE:
-        invflag = true;
-        cmpOp = CMP_GT;
-        break;
-
-    case CMP_NE:
-        invflag = true;
-        cmpOp = CMP_EQ;
-        break;
-
-    default:
-        CV_Error(CV_StsBadArg, "Unknown comparison method");
+            for( size_t j = 0; j < total; j += blocksize )
+            {
+                int bsz = (int)std::min(total - j, blocksize);
+                func( ptrs[0], 0, buf, 0, ptrs[1], 0, Size(bsz, 1), &op);
+                ptrs[0] += bsz*esz;
+                ptrs[1] += bsz;
+            }
+        }
     }
+}
+    
+/****************************************************************************************\
+*                                        inRange                                         *
+\****************************************************************************************/
 
-    BinarySFuncC1 func = tab[cmpOp == CMP_EQ ? 0 : cmpOp == CMP_GT ? 1 : 2][depth];
-    CV_Assert( func != 0 );
+namespace cv
+{
 
-    if( src1.dims > 2 )
+template<typename T> static void
+inRange_(const T* src1, size_t step1, const T* src2, size_t step2,
+         const T* src3, size_t step3, uchar* dst, size_t step,
+         Size size)
+{
+    step1 /= sizeof(src1[0]);
+    step2 /= sizeof(src2[0]);
+    step3 /= sizeof(src3[0]);
+    
+    for( ; size.height--; src1 += step1, src2 += step2, src3 += step3, dst += step )
     {
-        dst.create(src1.dims, src1.size, CV_8UC(src1.channels()));
-        const Mat* arrays[] = {&src1, &dst, 0};
-        Mat planes[2];
-        NAryMatIterator it(arrays, planes);
-
-        for( int i = 0; i < it.nplanes; i++, ++it )
+        int x = 0;
+        for( ; x <= size.width - 4; x += 4 )
         {
-            func( it.planes[0], it.planes[1], value );
-            if( invflag )
-                bitwise_not(it.planes[1], it.planes[1]);
+            int t0, t1;
+            t0 = src2[x] <= src1[x] && src1[x] <= src3[x];
+            t1 = src2[x+1] <= src1[x+1] && src1[x+1] <= src3[x+1];
+            dst[x] = (uchar)-t0; dst[x+1] = (uchar)-t1;
+            t0 = src2[x+2] <= src1[x+2] && src1[x+2] <= src3[x+2];
+            t1 = src2[x+3] <= src1[x+3] && src1[x+3] <= src3[x+3];
+            dst[x+2] = (uchar)-t0; dst[x+3] = (uchar)-t1;
         }
-        return;
+            
+        for( ; x < size.width; x++ )
+            dst[x] = (uchar)-(src2[x] <= src1[x] && src1[x] <= src3[x]);
     }
-
-    dst.create(src1.rows, src1.cols, CV_8UC(src1.channels()));
-    func( src1, dst, value );
-    if( invflag )
-        bitwise_not(dst, dst);
 }
 
-/****************************************************************************************\
-*                                       min/max                                          *
-\****************************************************************************************/
-
-template<typename T> struct MinOp
+    
+static void inRange8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2,
+                      const uchar* src3, size_t step3, uchar* dst, size_t step, Size size)
 {
-    typedef T type1;
-    typedef T type2;
-    typedef T rtype;
-    T operator ()(T a, T b) const { return std::min(a, b); }
-};
+    inRange_(src1, step1, src2, step2, src3, step3, dst, step, size);
+}
 
-template<typename T> struct MaxOp
+static void inRange8s(const schar* src1, size_t step1, const schar* src2, size_t step2,
+                      const schar* src3, size_t step3, uchar* dst, size_t step, Size size)
 {
-    typedef T type1;
-    typedef T type2;
-    typedef T rtype;
-    T operator ()(T a, T b) const { return std::max(a, b); }
-};
-
-template<> inline uchar MinOp<uchar>::operator ()(uchar a, uchar b) const { return CV_MIN_8U(a, b); }
-template<> inline uchar MaxOp<uchar>::operator ()(uchar a, uchar b) const { return CV_MAX_8U(a, b); }
+    inRange_(src1, step1, src2, step2, src3, step3, dst, step, size);
+}
 
-void min( const Mat& src1, const Mat& src2, Mat& dst )
+static void inRange16u(const ushort* src1, size_t step1, const ushort* src2, size_t step2,
+                       const ushort* src3, size_t step3, uchar* dst, size_t step, Size size)
 {
-    static BinaryFunc tab[] =
-    {
-#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
-        binaryOpC1_<MinOp<uchar>,ippMin8u>,
-        0,
-        binaryOpC1_<MinOp<ushort>,ippMin16u>,
-        binaryOpC1_<MinOp<short>,VMin16s>,
-        binaryOpC1_<MinOp<int>,NoVec>,
-        binaryOpC1_<MinOp<float>,ippMin32f>,
-        binaryOpC1_<MinOp<double>,ippMin64f>,
-        0
-#else
-        binaryOpC1_<MinOp<uchar>,VMin8u>,
-        0,
-        binaryOpC1_<MinOp<ushort>,VMin16u>,
-        binaryOpC1_<MinOp<short>,VMin16s>,
-        binaryOpC1_<MinOp<int>,NoVec>,
-        binaryOpC1_<MinOp<float>,VMin32f>,
-        binaryOpC1_<MinOp<double>,NoVec>,
-        0
-#endif
-    };
+    inRange_(src1, step1, src2, step2, src3, step3, dst, step, size);
+}
 
-    binaryOp(src1, src2, dst, tab[src1.depth()]);
+static void inRange16s(const short* src1, size_t step1, const short* src2, size_t step2,
+                       const short* src3, size_t step3, uchar* dst, size_t step, Size size)
+{
+    inRange_(src1, step1, src2, step2, src3, step3, dst, step, size);
 }
 
-void max( const Mat& src1, const Mat& src2, Mat& dst )
+static void inRange32s(const int* src1, size_t step1, const int* src2, size_t step2,
+                       const int* src3, size_t step3, uchar* dst, size_t step, Size size)
 {
-    static BinaryFunc tab[] =
-    {
-#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
-        binaryOpC1_<MaxOp<uchar>,ippMax8u>,
-        0,
-        binaryOpC1_<MaxOp<ushort>,ippMax16u>,
-        binaryOpC1_<MaxOp<short>,VMax16s>,
-        binaryOpC1_<MaxOp<int>,NoVec>,
-        binaryOpC1_<MaxOp<float>,ippMax32f>,
-        binaryOpC1_<MaxOp<double>,ippMax64f>,
-        0
-#else
-        binaryOpC1_<MaxOp<uchar>,VMax8u>,
-        0,
-        binaryOpC1_<MaxOp<ushort>,VMax16u>,
-        binaryOpC1_<MaxOp<short>,VMax16s>,
-        binaryOpC1_<MaxOp<int>,NoVec>,
-        binaryOpC1_<MaxOp<float>,VMax32f>,
-        binaryOpC1_<MaxOp<double>,NoVec>,
-        0
-#endif
-    };
+    inRange_(src1, step1, src2, step2, src3, step3, dst, step, size);
+}
 
-    binaryOp(src1, src2, dst, tab[src1.depth()]);
+static void inRange32f(const float* src1, size_t step1, const float* src2, size_t step2,
+                       const float* src3, size_t step3, uchar* dst, size_t step, Size size)
+{
+    inRange_(src1, step1, src2, step2, src3, step3, dst, step, size);
 }
 
-void min( const Mat& src1, double value, Mat& dst )
+static void inRange64f(const double* src1, size_t step1, const double* src2, size_t step2,
+                       const double* src3, size_t step3, uchar* dst, size_t step, Size size)
 {
-    static BinarySFuncC1 tab[] =
-    {
-        binarySOpC1_<MinOp<uchar> >,
-        0,
-        binarySOpC1_<MinOp<ushort> >,
-        binarySOpC1_<MinOp<short> >,
-        binarySOpC1_<MinOp<int> >,
-        binarySOpC1_<MinOp<float> >,
-        binarySOpC1_<MinOp<double> >,
-        0
-    };
-
-    BinarySFuncC1 func = tab[src1.depth()];
-    CV_Assert(func != 0);
-
-    if( src1.dims > 2 )
-    {
-        dst.create(src1.dims, src1.size, src1.type());
-        const Mat* arrays[] = {&src1, &dst, 0};
-        Mat planes[2];
-        NAryMatIterator it(arrays, planes);
+    inRange_(src1, step1, src2, step2, src3, step3, dst, step, size);
+}    
 
-        for( int i = 0; i < it.nplanes; i++, ++it )
-            func( it.planes[0], it.planes[1], value );
-        return;
+static void inRangeReduce(const uchar* src, uchar* dst, size_t len, int cn)
+{
+    int k = cn % 4 ? cn % 4 : 4;
+    size_t i, j;
+    if( k == 1 )
+        for( i = j = 0; i < len; i++, j += cn )
+            dst[i] = src[j];
+    else if( k == 2 )
+        for( i = j = 0; i < len; i++, j += cn )
+            dst[i] = src[j] & src[j+1];
+    else if( k == 3 )
+        for( i = j = 0; i < len; i++, j += cn )
+            dst[i] = src[j] & src[j+1] & src[j+2];
+    else
+        for( i = j = 0; i < len; i++, j += cn )
+            dst[i] = src[j] & src[j+1] & src[j+2] & src[j+3];
+    
+    for( ; k < cn; k += 4 )
+    {
+        for( i = 0, j = k; i < len; i++, j += cn )
+            dst[i] &= src[j] & src[j+1] & src[j+2] & src[j+3];
     }
-
-    dst.create(src1.size(), src1.type());
-
-    return func( src1, dst, value );
 }
+    
+typedef void (*InRangeFunc)( const uchar* src1, size_t step1, const uchar* src2, size_t step2,
+                             const uchar* src3, size_t step3, uchar* dst, size_t step, Size sz );
 
-void max( const Mat& src1, double value, Mat& dst )
+static InRangeFunc inRangeTab[] =
 {
-    static BinarySFuncC1 tab[] =
-    {
-        binarySOpC1_<MaxOp<uchar> >,
-        0,
-        binarySOpC1_<MaxOp<ushort> >,
-        binarySOpC1_<MaxOp<short> >,
-        binarySOpC1_<MaxOp<int> >,
-        binarySOpC1_<MaxOp<float> >,
-        binarySOpC1_<MaxOp<double> >,
-        0
-    };
-
-    BinarySFuncC1 func = tab[src1.depth()];
-    CV_Assert(func != 0);
-
-    if( src1.dims > 2 )
+    (InRangeFunc)inRange8u, (InRangeFunc)inRange8s, (InRangeFunc)inRange16u,
+    (InRangeFunc)inRange16s, (InRangeFunc)inRange32s, (InRangeFunc)inRange32f,
+    (InRangeFunc)inRange64f, 0
+};
+    
+}
+
+void cv::inRange(const InputArray& _src, const InputArray& _lowerb,
+                 const InputArray& _upperb, OutputArray _dst)
+{
+    int skind = _src.kind(), lkind = _lowerb.kind(), ukind = _upperb.kind();
+    Mat src = _src.getMat(), lb = _lowerb.getMat(), ub = _upperb.getMat();
+    
+    bool lbScalar = false, ubScalar = false;
+    
+    if( (lkind == InputArray::MATX && skind != InputArray::MATX) ||
+        src.size != lb.size || src.type() != lb.type() )
+    {
+        if( !checkScalar(lb, src.type(), lkind, skind) )
+            CV_Error( CV_StsUnmatchedSizes,
+                     "The lower bounary is neither an array of the same size and same type as src, nor a scalar");
+        lbScalar = true;
+    }
+    
+    if( (ukind == InputArray::MATX && skind != InputArray::MATX) ||
+        src.size != ub.size || src.type() != ub.type() )
+    {
+        if( !checkScalar(ub, src.type(), ukind, skind) )
+            CV_Error( CV_StsUnmatchedSizes,
+                     "The upper bounary is neither an array of the same size and same type as src, nor a scalar");
+        ubScalar = true;
+    }
+    
+    CV_Assert( ((int)lbScalar ^ (int)ubScalar) == 0 );
+    
+    int cn = src.channels(), depth = src.depth();
+    
+    size_t esz = src.elemSize();
+    size_t blocksize0 = (size_t)(BLOCK_SIZE + esz-1)/esz;
+    
+    _dst.create(src.dims, src.size, CV_8U);
+    Mat dst = _dst.getMat();
+    InRangeFunc func = inRangeTab[depth];
+    
+    const Mat* arrays_sc[] = { &src, &dst, 0 };
+    const Mat* arrays_nosc[] = { &src, &dst, &lb, &ub, 0 };
+    uchar* ptrs[4];
+    
+    NAryMatIterator it(lbScalar && ubScalar ? arrays_sc : arrays_nosc, ptrs);
+    size_t total = it.size, blocksize = std::min(total, blocksize0);
+    
+    AutoBuffer<uchar> _buf(blocksize*(((int)lbScalar + (int)ubScalar)*esz + cn) + 2*cn*sizeof(int) + 128);
+    uchar *buf = _buf, *mbuf = buf, *lbuf = 0, *ubuf = 0;
+    buf = alignPtr(buf + blocksize*cn, 16);
+    
+    if( lbScalar && ubScalar )
+    {
+        lbuf = buf;
+        ubuf = buf = alignPtr(buf + blocksize*esz, 16);
+        
+        CV_Assert( lb.type() == ub.type() );
+        int scdepth = lb.depth();
+        
+        if( scdepth != depth && depth < CV_32S )
+        {
+            int* ilbuf = (int*)alignPtr(buf + blocksize*esz, 16);
+            int* iubuf = ilbuf + cn;
+            
+            BinaryFunc sccvtfunc = getConvertFunc(scdepth, CV_32S);
+            sccvtfunc(lb.data, 0, 0, 0, (uchar*)ilbuf, 0, Size(cn, 1), 0);
+            sccvtfunc(ub.data, 0, 0, 0, (uchar*)iubuf, 0, Size(cn, 1), 0);
+            int minval = getMinVal(depth), maxval = getMaxVal(depth);
+            
+            for( int k = 0; k < cn; k++ )
+            {
+                if( ilbuf[k] > iubuf[k] || ilbuf[k] > maxval || iubuf[k] < minval )
+                    ilbuf[k] = minval+1, iubuf[k] = minval;
+            }
+            lb = Mat(cn, 1, CV_32S, ilbuf);
+            ub = Mat(cn, 1, CV_32S, iubuf);
+        }
+        
+        convertAndUnrollScalar( lb, src.type(), lbuf, blocksize );
+        convertAndUnrollScalar( ub, src.type(), ubuf, blocksize );
+    }
+    
+    for( size_t i = 0; i < it.nplanes; i++, ++it )
     {
-        dst.create(src1.dims, src1.size, src1.type());
-        const Mat* arrays[] = {&src1, &dst, 0};
-        Mat planes[2];
-        NAryMatIterator it(arrays, planes);
-
-        for( int i = 0; i < it.nplanes; i++, ++it )
-            func( it.planes[0], it.planes[1], value );
-        return;
+        for( size_t j = 0; j < total; j += blocksize )
+        {
+            int bsz = (int)std::min(total - j, blocksize);
+            size_t delta = bsz*esz;
+            uchar *lptr = lbuf, *uptr = ubuf;
+            if( !lbScalar )
+            {
+                lptr = ptrs[2];
+                ptrs[2] += delta;
+            }
+            if( !ubScalar )
+            {
+                int idx = !lbScalar ? 3 : 2;
+                uptr = ptrs[idx];
+                ptrs[idx] += delta;
+            }
+            func( ptrs[0], 0, lptr, 0, uptr, 0, cn == 1 ? ptrs[1] : mbuf, 0, Size(bsz*cn, 1));
+            if( cn > 1 )
+                inRangeReduce(mbuf, ptrs[1], bsz, cn);
+            ptrs[0] += delta;
+            ptrs[1] += bsz;
+        }
     }
-
-    dst.create(src1.size(), src1.type());
-
-    return func( src1, dst, value );
 }
 
-} // namespace cv
-
 /****************************************************************************************\
 *                                Earlier API: cvAdd etc.                                 *
 \****************************************************************************************/
@@ -2168,7 +2369,7 @@ cvAndS( const CvArr* srcarr, CvScalar s, CvArr* dstarr, const CvArr* maskarr )
     CV_Assert( src.size == dst.size && src.type() == dst.type() );
     if( maskarr )
         mask = cv::cvarrToMat(maskarr);
-    cv::bitwise_and( src, s, dst, mask );
+    cv::bitwise_and( src, (const cv::Scalar&)s, dst, mask );
 }
 
 
@@ -2179,7 +2380,7 @@ cvOrS( const CvArr* srcarr, CvScalar s, CvArr* dstarr, const CvArr* maskarr )
     CV_Assert( src.size == dst.size && src.type() == dst.type() );
     if( maskarr )
         mask = cv::cvarrToMat(maskarr);
-    cv::bitwise_or( src, s, dst, mask );
+    cv::bitwise_or( src, (const cv::Scalar&)s, dst, mask );
 }
 
 
@@ -2190,7 +2391,7 @@ cvXorS( const CvArr* srcarr, CvScalar s, CvArr* dstarr, const CvArr* maskarr )
     CV_Assert( src.size == dst.size && src.type() == dst.type() );
     if( maskarr )
         mask = cv::cvarrToMat(maskarr);
-    cv::bitwise_xor( src, s, dst, mask );
+    cv::bitwise_xor( src, (const cv::Scalar&)s, dst, mask );
 }
 
 
@@ -2198,10 +2399,10 @@ CV_IMPL void cvAdd( const CvArr* srcarr1, const CvArr* srcarr2, CvArr* dstarr, c
 {
     cv::Mat src1 = cv::cvarrToMat(srcarr1), src2 = cv::cvarrToMat(srcarr2),
         dst = cv::cvarrToMat(dstarr), mask;
-    CV_Assert( src1.size == dst.size && src1.type() == dst.type() );
+    CV_Assert( src1.size == dst.size && src1.channels() == dst.channels() );
     if( maskarr )
         mask = cv::cvarrToMat(maskarr);
-    cv::add( src1, src2, dst, mask );
+    cv::add( src1, src2, dst, mask, dst.type() );
 }
 
 
@@ -2209,10 +2410,10 @@ CV_IMPL void cvSub( const CvArr* srcarr1, const CvArr* srcarr2, CvArr* dstarr, c
 {
     cv::Mat src1 = cv::cvarrToMat(srcarr1), src2 = cv::cvarrToMat(srcarr2),
         dst = cv::cvarrToMat(dstarr), mask;
-    CV_Assert( src1.size == dst.size && src1.type() == dst.type() );
+    CV_Assert( src1.size == dst.size && src1.channels() == dst.channels() );
     if( maskarr )
         mask = cv::cvarrToMat(maskarr);
-    cv::subtract( src1, src2, dst, mask );
+    cv::subtract( src1, src2, dst, mask, dst.type() );
 }
 
 
@@ -2220,10 +2421,10 @@ CV_IMPL void cvAddS( const CvArr* srcarr1, CvScalar value, CvArr* dstarr, const
 {
     cv::Mat src1 = cv::cvarrToMat(srcarr1),
         dst = cv::cvarrToMat(dstarr), mask;
-    CV_Assert( src1.size == dst.size && src1.type() == dst.type() );
+    CV_Assert( src1.size == dst.size && src1.channels() == dst.channels() );
     if( maskarr )
         mask = cv::cvarrToMat(maskarr);
-    cv::add( src1, value, dst, mask );
+    cv::add( src1, (const cv::Scalar&)value, dst, mask, dst.type() );
 }
 
 
@@ -2231,10 +2432,10 @@ CV_IMPL void cvSubRS( const CvArr* srcarr1, CvScalar value, CvArr* dstarr, const
 {
     cv::Mat src1 = cv::cvarrToMat(srcarr1),
         dst = cv::cvarrToMat(dstarr), mask;
-    CV_Assert( src1.size == dst.size && src1.type() == dst.type() );
+    CV_Assert( src1.size == dst.size && src1.channels() == dst.channels() );
     if( maskarr )
         mask = cv::cvarrToMat(maskarr);
-    cv::subtract( value, src1, dst, mask );
+    cv::subtract( (const cv::Scalar&)value, src1, dst, mask, dst.type() );
 }
 
 
@@ -2243,8 +2444,8 @@ CV_IMPL void cvMul( const CvArr* srcarr1, const CvArr* srcarr2,
 {
     cv::Mat src1 = cv::cvarrToMat(srcarr1), src2 = cv::cvarrToMat(srcarr2),
         dst = cv::cvarrToMat(dstarr);
-    CV_Assert( src1.size == dst.size && src1.type() == dst.type() );
-    cv::multiply( src1, src2, dst, scale );
+    CV_Assert( src1.size == dst.size && src1.channels() == dst.channels() );
+    cv::multiply( src1, src2, dst, scale, dst.type() );
 }
 
 
@@ -2253,12 +2454,12 @@ CV_IMPL void cvDiv( const CvArr* srcarr1, const CvArr* srcarr2,
 {
     cv::Mat src2 = cv::cvarrToMat(srcarr2),
         dst = cv::cvarrToMat(dstarr), mask;
-    CV_Assert( src2.size == dst.size && src2.type() == dst.type() );
+    CV_Assert( src2.size == dst.size && src2.channels() == dst.channels() );
 
     if( srcarr1 )
-        cv::divide( cv::cvarrToMat(srcarr1), src2, dst, scale );
+        cv::divide( cv::cvarrToMat(srcarr1), src2, dst, scale, dst.type() );
     else
-        cv::divide( scale, src2, dst );
+        cv::divide( scale, src2, dst, dst.type() );
 }
 
 
@@ -2269,8 +2470,8 @@ cvAddWeighted( const CvArr* srcarr1, double alpha,
 {
     cv::Mat src1 = cv::cvarrToMat(srcarr1), src2 = cv::cvarrToMat(srcarr2),
         dst = cv::cvarrToMat(dstarr);
-    CV_Assert( src1.size == dst.size && src1.type() == dst.type() );
-    cv::addWeighted( src1, alpha, src2, beta, gamma, dst );
+    CV_Assert( src1.size == dst.size && src1.channels() == dst.channels() );
+    cv::addWeighted( src1, alpha, src2, beta, gamma, dst, dst.type() );
 }
 
 
@@ -2290,7 +2491,7 @@ cvAbsDiffS( const CvArr* srcarr1, CvArr* dstarr, CvScalar scalar )
     cv::Mat src1 = cv::cvarrToMat(srcarr1), dst = cv::cvarrToMat(dstarr);
     CV_Assert( src1.size == dst.size && src1.type() == dst.type() );
 
-    cv::absdiff( src1, scalar, dst );
+    cv::absdiff( src1, (const cv::Scalar&)scalar, dst );
 }
 
 
@@ -2311,7 +2512,7 @@ cvInRangeS( const void* srcarr1, CvScalar lowerb, CvScalar upperb, void* dstarr
     cv::Mat src1 = cv::cvarrToMat(srcarr1), dst = cv::cvarrToMat(dstarr);
     CV_Assert( src1.size == dst.size && dst.type() == CV_8U );
 
-    cv::inRange( src1, lowerb, upperb, dst );
+    cv::inRange( src1, (const cv::Scalar&)lowerb, (const cv::Scalar&)upperb, dst );
 }
 
 
@@ -2374,5 +2575,4 @@ cvMaxS( const void* srcarr1, double value, void* dstarr )
     cv::max( src1, value, dst );
 }
 
-
 /* End of file. */
index 4da903b..f065a1e 100644 (file)
@@ -722,10 +722,10 @@ icvGetNodePtr( CvSparseMat* mat, const int* idx, int* _type,
         node->hashval = hashval;
         node->next = (CvSparseNode*)mat->hashtable[tabidx];
         mat->hashtable[tabidx] = node;
-        CV_MEMCPY_INT( CV_NODE_IDX(mat,node), idx, mat->dims );
+        memcpy(CV_NODE_IDX(mat,node), idx, mat->dims*sizeof(idx[0]));
         ptr = (uchar*)CV_NODE_VAL(mat,node);
         if( create_node > 0 )
-            CV_ZERO_CHAR( ptr, CV_ELEM_SIZE(mat->type));
+            memset( ptr, 0, CV_ELEM_SIZE(mat->type));
     }
 
     if( _type )
@@ -1512,7 +1512,7 @@ cvScalarToRawData( const CvScalar* scalar, void* data, int type, int extend_to_1
         do
         {
             offset -= pix_size;
-            CV_MEMCPY_AUTO( (char*)data + offset, data, pix_size );
+            memcpy((char*)data + offset, data, pix_size);
         }
         while( offset > pix_size );
     }
@@ -2358,7 +2358,7 @@ cvClearND( CvArr* arr, const int* idx )
         uchar* ptr;
         ptr = cvPtrND( arr, idx, &type );
         if( ptr )
-            CV_ZERO_CHAR( ptr, CV_ELEM_SIZE(type) );
+            memset( ptr, 0, CV_ELEM_SIZE(type) );
     }
     else
         icvDeleteNode( (CvSparseMat*)arr, idx, 0 );
index 96e1aab..f7da74b 100644 (file)
@@ -11,7 +11,7 @@
 //                For Open Source Computer Vision Library
 //
 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
-// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
 // Third party copyrights are property of their respective owners.
 //
 // Redistribution and use in source and binary forms, with or without modification,
@@ -46,252 +46,251 @@ namespace cv
 {
 
 /****************************************************************************************\
-*                                       split                                            *
+*                                       split & merge                                    *
 \****************************************************************************************/
 
 template<typename T> static void
-splitC2_( const Mat& srcmat, Mat* dstmat )
+split_( const T* src, T** dst, int len, int cn )
 {
-    Size size = getContinuousSize( srcmat, dstmat[0], dstmat[1] );
-    for( int y = 0; y < size.height; y++ )
+    int k = cn % 4 ? cn % 4 : 4;
+    int i, j;
+    if( k == 1 )
     {
-        const T* src = (const T*)(srcmat.data + srcmat.step*y);
-        T* dst0 = (T*)(dstmat[0].data + dstmat[0].step*y);
-        T* dst1 = (T*)(dstmat[1].data + dstmat[1].step*y);
-
-        for( int x = 0; x < size.width; x++ )
+        T* dst0 = dst[0];
+        for( i = j = 0; i < len; i++, j += cn )
+            dst0[i] = src[j];
+    }
+    else if( k == 2 )
+    {
+        T *dst0 = dst[0], *dst1 = dst[1];
+        for( i = j = 0; i < len; i++, j += cn )
         {
-            T t0 = src[x*2], t1 = src[x*2+1];
-            dst0[x] = t0; dst1[x] = t1;
+            dst0[i] = src[j];
+            dst1[i] = src[j+1];
         }
     }
-}
-
-template<typename T> static void
-splitC3_( const Mat& srcmat, Mat* dstmat )
-{
-    Size size = getContinuousSize( srcmat, dstmat[0], dstmat[1], dstmat[2] );
-    for( int y = 0; y < size.height; y++ )
+    else if( k == 3 )
     {
-        const T* src = (const T*)(srcmat.data + srcmat.step*y);
-        T* dst0 = (T*)(dstmat[0].data + dstmat[0].step*y);
-        T* dst1 = (T*)(dstmat[1].data + dstmat[1].step*y);
-        T* dst2 = (T*)(dstmat[2].data + dstmat[2].step*y);
-
-        for( int x = 0; x < size.width; x++ )
+        T *dst0 = dst[0], *dst1 = dst[1], *dst2 = dst[2];
+        for( i = j = 0; i < len; i++, j += cn )
         {
-            T t0 = src[x*3], t1 = src[x*3+1], t2 = src[x*3+2];
-            dst0[x] = t0; dst1[x] = t1; dst2[x] = t2;
+            dst0[i] = src[j];
+            dst1[i] = src[j+1];
+            dst2[i] = src[j+2];
         }
     }
-}
-
-template<typename T> static void
-splitC4_( const Mat& srcmat, Mat* dstmat )
-{
-    Size size = getContinuousSize( srcmat, dstmat[0], dstmat[1], dstmat[2], dstmat[3] );
-    for( int y = 0; y < size.height; y++ )
+    else
     {
-        const T* src = (const T*)(srcmat.data + srcmat.step*y);
-        T* dst0 = (T*)(dstmat[0].data + dstmat[0].step*y);
-        T* dst1 = (T*)(dstmat[1].data + dstmat[1].step*y);
-        T* dst2 = (T*)(dstmat[2].data + dstmat[2].step*y);
-        T* dst3 = (T*)(dstmat[3].data + dstmat[3].step*y);
-
-        for( int x = 0; x < size.width; x++ )
+        T *dst0 = dst[0], *dst1 = dst[1], *dst2 = dst[2], *dst3 = dst[3];
+        for( i = j = 0; i < len; i++, j += cn )
         {
-            T t0 = src[x*4], t1 = src[x*4+1];
-            dst0[x] = t0; dst1[x] = t1;
-            t0 = src[x*4+2]; t1 = src[x*4+3];
-            dst2[x] = t0; dst3[x] = t1;
+            dst0[i] = src[j]; dst1[i] = src[j+1];
+            dst2[i] = src[j+2]; dst3[i] = src[j+3];
+        }
+    }
+    
+    for( ; k < cn; k += 4 )
+    {
+        T *dst0 = dst[k], *dst1 = dst[k+1], *dst2 = dst[k+2], *dst3 = dst[k+3];
+        for( i = 0, j = k; i < len; i++, j += cn )
+        {
+            dst0[i] = src[j]; dst1[i] = src[j+1];
+            dst2[i] = src[j+2]; dst3[i] = src[j+3];
         }
     }
 }
-
-typedef void (*SplitFunc)(const Mat& src, Mat* dst);
-
-void split(const Mat& src, Mat* mv)
+    
+template<typename T> static void
+merge_( const T** src, T* dst, int len, int cn )
 {
-    static SplitFunc tab[] =
+    int k = cn % 4 ? cn % 4 : 4;
+    int i, j;
+    if( k == 1 )
     {
-        splitC2_<uchar>, splitC2_<ushort>, splitC2_<int>, 0, splitC2_<int64>,
-        splitC3_<uchar>, splitC3_<ushort>, splitC3_<int>, 0, splitC3_<int64>,
-        splitC4_<uchar>, splitC4_<ushort>, splitC4_<int>, 0, splitC4_<int64>
-    };
-
-    int i, depth = src.depth(), cn = src.channels();
-
-    if( cn == 1 )
+        const T* src0 = src[0];
+        for( i = j = 0; i < len; i++, j += cn )
+            dst[j] = src0[i];
+    }
+    else if( k == 2 )
     {
-        src.copyTo(mv[0]);
-        return;
+        const T *src0 = src[0], *src1 = src[1];
+        for( i = j = 0; i < len; i++, j += cn )
+        {
+            dst[j] = src0[i];
+            dst[j+1] = src1[i];
+        }
     }
-
-    for( i = 0; i < cn; i++ )
-        mv[i].create(src.dims, src.size, depth);
-
-    if( cn <= 4 )
+    else if( k == 3 )
     {
-        SplitFunc func = tab[(cn-2)*5 + (src.elemSize1()>>1)];
-        CV_Assert( func != 0 );
-        
-        if( src.dims > 2 )
+        const T *src0 = src[0], *src1 = src[1], *src2 = src[2];
+        for( i = j = 0; i < len; i++, j += cn )
         {
-            const Mat* arrays[5];
-            Mat planes[5];
-            arrays[0] = &src;
-            for( i = 0; i < cn; i++ )
-                arrays[i+1] = &mv[i];
-            NAryMatIterator it(arrays, planes, cn+1);
-            
-            for( int i = 0; i < it.nplanes; i++, ++it )
-                func( it.planes[0], &it.planes[1] );
+            dst[j] = src0[i];
+            dst[j+1] = src1[i];
+            dst[j+2] = src2[i];
         }
-        else
-            func( src, mv );
     }
     else
     {
-        AutoBuffer<int> pairs(cn*2);
-
-        for( i = 0; i < cn; i++ )
+        const T *src0 = src[0], *src1 = src[1], *src2 = src[2], *src3 = src[3];
+        for( i = j = 0; i < len; i++, j += cn )
         {
-            pairs[i*2] = i;
-            pairs[i*2+1] = 0;
+            dst[j] = src0[i]; dst[j+1] = src1[i];
+            dst[j+2] = src2[i]; dst[j+3] = src3[i];
         }
-        mixChannels( &src, 1, mv, cn, &pairs[0], cn );
     }
-}
     
-void split(const Mat& m, vector<Mat>& mv)
+    for( ; k < cn; k += 4 )
+    {
+        const T *src0 = src[k], *src1 = src[k+1], *src2 = src[k+2], *src3 = src[k+3];
+        for( i = 0, j = k; i < len; i++, j += cn )
+        {
+            dst[j] = src0[i]; dst[j+1] = src1[i];
+            dst[j+2] = src2[i]; dst[j+3] = src3[i];
+        }
+    }
+}
+
+static void split8u(const uchar* src, uchar** dst, int len, int cn )
 {
-    mv.resize(!m.empty() ? m.channels() : 0);
-    if(!m.empty())
-        split(m, &mv[0]);
+    split_(src, dst, len, cn);
 }
 
-/****************************************************************************************\
-*                                       merge                                            *
-\****************************************************************************************/
+static void split16u(const ushort* src, ushort** dst, int len, int cn )
+{
+    split_(src, dst, len, cn);
+}
 
-// input vector is made non-const to make sure that we do not copy Mat on each access
-template<typename T> static void
-mergeC2_( const Mat* srcmat, Mat& dstmat )
+static void split32s(const int* src, int** dst, int len, int cn )
 {
-    Size size = getContinuousSize( srcmat[0], srcmat[1], dstmat );
-    for( int y = 0; y < size.height; y++ )
-    {
-        const T* src0 = (const T*)(srcmat[0].data + srcmat[0].step*y);
-        const T* src1 = (const T*)(srcmat[1].data + srcmat[1].step*y);
-        T* dst = (T*)(dstmat.data + dstmat.step*y);
+    split_(src, dst, len, cn);
+}
+    
+static void split64s(const int64* src, int64** dst, int len, int cn )
+{
+    split_(src, dst, len, cn);
+}
 
-        for( int x = 0; x < size.width; x++ )
-        {
-            T t0 = src0[x], t1 = src1[x];
-            dst[x*2] = t0; dst[x*2+1] = t1;
-        }
-    }
+static void merge8u(const uchar** src, uchar* dst, int len, int cn )
+{
+    merge_(src, dst, len, cn);
 }
 
-template<typename T> static void
-mergeC3_( const Mat* srcmat, Mat& dstmat )
+static void merge16u(const ushort** src, ushort* dst, int len, int cn )
 {
-    Size size = getContinuousSize( srcmat[0], srcmat[1], srcmat[2], dstmat );
-    for( int y = 0; y < size.height; y++ )
-    {
-        const T* src0 = (const T*)(srcmat[0].data + srcmat[0].step*y);
-        const T* src1 = (const T*)(srcmat[1].data + srcmat[1].step*y);
-        const T* src2 = (const T*)(srcmat[2].data + srcmat[2].step*y);
-        T* dst = (T*)(dstmat.data + dstmat.step*y);
+    merge_(src, dst, len, cn);
+}
 
-        for( int x = 0; x < size.width; x++ )
-        {
-            T t0 = src0[x], t1 = src1[x], t2 = src2[x];
-            dst[x*3] = t0; dst[x*3+1] = t1; dst[x*3+2] = t2;
-        }
-    }
+static void merge32s(const int** src, int* dst, int len, int cn )
+{
+    merge_(src, dst, len, cn);
 }
 
-template<typename T> static void
-mergeC4_( const Mat* srcmat, Mat& dstmat )
+static void merge64s(const int64** src, int64* dst, int len, int cn )
+{
+    merge_(src, dst, len, cn);
+}    
+
+typedef void (*SplitFunc)(const uchar* src, uchar** dst, int len, int cn);
+typedef void (*MergeFunc)(const uchar** src, uchar* dst, int len, int cn);
+
+static SplitFunc splitTab[] =
+{
+    (SplitFunc)split8u, (SplitFunc)split8u, (SplitFunc)split16u, (SplitFunc)split16u,
+    (SplitFunc)split32s, (SplitFunc)split32s, (SplitFunc)split64s, 0
+};
+
+static MergeFunc mergeTab[] =
+{
+    (MergeFunc)merge8u, (MergeFunc)merge8u, (MergeFunc)merge16u, (MergeFunc)merge16u,
+    (MergeFunc)merge32s, (MergeFunc)merge32s, (MergeFunc)merge64s, 0
+};
+  
+}
+    
+void cv::split(const Mat& src, Mat* mv)
 {
-    Size size = getContinuousSize( srcmat[0], srcmat[1], srcmat[2], srcmat[3], dstmat );
-    for( int y = 0; y < size.height; y++ )
+    int k, depth = src.depth(), cn = src.channels();
+    if( cn == 1 )
     {
-        const T* src0 = (const T*)(srcmat[0].data + srcmat[0].step*y);
-        const T* src1 = (const T*)(srcmat[1].data + srcmat[1].step*y);
-        const T* src2 = (const T*)(srcmat[2].data + srcmat[2].step*y);
-        const T* src3 = (const T*)(srcmat[3].data + srcmat[3].step*y);
-        T* dst = (T*)(dstmat.data + dstmat.step*y);
+        src.copyTo(mv[0]);
+        return;
+    }
 
-        for( int x = 0; x < size.width; x++ )
+    SplitFunc func = splitTab[depth];
+    CV_Assert( func != 0 );
+    
+    int esz = src.elemSize(), esz1 = src.elemSize1();
+    int blocksize0 = (BLOCK_SIZE + esz-1)/esz;
+    AutoBuffer<uchar> _buf((cn+1)*(sizeof(Mat*) + sizeof(uchar*)) + 16);
+    const Mat** arrays = (const Mat**)(uchar*)_buf;
+    uchar** ptrs = (uchar**)alignPtr(arrays + cn + 1, 16);
+    
+    arrays[0] = &src;
+    for( k = 0; k < cn; k++ )
+    {
+        mv[k].create(src.dims, src.size, depth);
+        arrays[k+1] = &mv[k];
+    }
+    
+    NAryMatIterator it(arrays, ptrs, cn+1);
+    int total = (int)it.size, blocksize = cn <= 4 ? total : std::min(total, blocksize0);
+    
+    for( size_t i = 0; i < it.nplanes; i++, ++it )
+    {
+        for( int j = 0; j < total; j += blocksize )
         {
-            T t0 = src0[x], t1 = src1[x];
-            dst[x*4] = t0; dst[x*4+1] = t1;
-            t0 = src2[x]; t1 = src3[x];
-            dst[x*4+2] = t0; dst[x*4+3] = t1;
+            int bsz = std::min(total - j, blocksize);
+            func( ptrs[0], &ptrs[1], bsz, cn );
+            
+            if( j + blocksize < total )
+            {
+                ptrs[0] += bsz*esz;
+                for( k = 0; k < cn; k++ )
+                    ptrs[k+1] += bsz*esz1;
+            }
         }
     }
 }
-
-typedef void (*MergeFunc)(const Mat* src, Mat& dst);
-
-void merge(const Mat* mv, size_t _n, Mat& dst)
+    
+void cv::split(const Mat& m, vector<Mat>& mv)
 {
-    static MergeFunc tab[] =
-    {
-        mergeC2_<uchar>, mergeC2_<ushort>, mergeC2_<int>, 0, mergeC2_<int64>,
-        mergeC3_<uchar>, mergeC3_<ushort>, mergeC3_<int>, 0, mergeC3_<int64>,
-        mergeC4_<uchar>, mergeC4_<ushort>, mergeC4_<int>, 0, mergeC4_<int64>
-    };
-
-    CV_Assert( mv && _n > 0 );
+    mv.resize(!m.empty() ? m.channels() : 0);
+    if(!m.empty())
+        split(m, &mv[0]);
+}
+    
+void cv::merge(const Mat* mv, size_t n, OutputArray _dst)
+{
+    CV_Assert( mv && n > 0 );
     
     int depth = mv[0].depth();
     bool allch1 = true;
-    int i, total = 0, n = (int)_n;
+    int k, cn = 0;
+    size_t i;
     
     for( i = 0; i < n; i++ )
     {
         CV_Assert(mv[i].size == mv[0].size && mv[i].depth() == depth);
         allch1 = allch1 && mv[i].channels() == 1;
-        total += mv[i].channels();
+        cn += mv[i].channels();
     }
-
-    CV_Assert( 0 < total && total <= CV_CN_MAX );
-
-    if( total == 1 )
+    
+    CV_Assert( 0 < cn && cn <= CV_CN_MAX );
+    _dst.create(mv[0].dims, mv[0].size, CV_MAKETYPE(depth, cn));
+    Mat dst = _dst.getMat();
+    
+    if( n == 1 )
     {
         mv[0].copyTo(dst);
         return;
     }
-
-    dst.create(mv[0].dims, mv[0].size, CV_MAKETYPE(depth, total));
-
-    if( allch1 && total <= 4 )
-    {
-        MergeFunc func = tab[(total-2)*5 + (CV_ELEM_SIZE(depth)>>1)];
-        CV_Assert( func != 0 );
-        if( mv[0].dims > 2 )
-        {
-            const Mat* arrays[5];
-            Mat planes[5];
-            arrays[total] = &dst;
-            for( i = 0; i < total; i++ )
-                arrays[i] = &mv[i];
-            NAryMatIterator it(arrays, planes, total+1);
-            
-            for( i = 0; i < it.nplanes; i++, ++it )
-                func( &it.planes[0], it.planes[total] );
-        }
-        else
-            func( mv, dst );
-    }
-    else
+    
+    if( !allch1 )
     {
-        AutoBuffer<int> pairs(total*2);
-        int j, k, ni=0;
-
+        AutoBuffer<int> pairs(cn*2);
+        int j, ni=0;
+        
         for( i = 0, j = 0; i < n; i++, j += ni )
         {
             ni = mv[i].channels();
@@ -301,104 +300,148 @@ void merge(const Mat* mv, size_t _n, Mat& dst)
                 pairs[(j+k)*2+1] = j + k;
             }
         }
-        mixChannels( mv, n, &dst, 1, &pairs[0], total );
+        mixChannels( mv, n, &dst, 1, &pairs[0], cn );
+        return;
+    }
+        
+    size_t esz = dst.elemSize(), esz1 = dst.elemSize1();
+    int blocksize0 = (BLOCK_SIZE + esz-1)/esz;
+    AutoBuffer<uchar> _buf((cn+1)*(sizeof(Mat*) + sizeof(uchar*)) + 16);
+    const Mat** arrays = (const Mat**)(uchar*)_buf;
+    uchar** ptrs = (uchar**)alignPtr(arrays + cn + 1, 16);
+    
+    arrays[0] = &dst;
+    for( k = 0; k < cn; k++ )
+        arrays[k+1] = &mv[k];
+    
+    NAryMatIterator it(arrays, ptrs, cn+1);
+    int total = (int)it.size, blocksize = cn <= 4 ? total : std::min(total, blocksize0);
+    MergeFunc func = mergeTab[depth];
+    
+    for( i = 0; i < it.nplanes; i++, ++it )
+    {
+        for( int j = 0; j < total; j += blocksize )
+        {
+            int bsz = std::min(total - j, blocksize);
+            func( (const uchar**)&ptrs[1], ptrs[0], bsz, cn );
+            
+            if( j + blocksize < total )
+            {
+                ptrs[0] += bsz*esz;
+                for( int k = 0; k < cn; k++ )
+                    ptrs[k+1] += bsz*esz1;
+            }
+        }
     }
 }
 
-void merge(const vector<Mat>& mv, Mat& dst)
+void cv::merge(const vector<Mat>& mv, OutputArray _dst)
 {
-    merge(!mv.empty() ? &mv[0] : 0, mv.size(), dst);
-}
+    merge(!mv.empty() ? &mv[0] : 0, mv.size(), _dst);
+}    
 
 /****************************************************************************************\
 *                       Generalized split/merge: mixing channels                         *
 \****************************************************************************************/
 
+namespace cv
+{
+
 template<typename T> static void
-mixChannels_( const void** _src, const int* sdelta0,
-              const int* sdelta1, void** _dst,
-              const int* ddelta0, const int* ddelta1,
-              int n, Size size )
+mixChannels_( const T** src, const int* sdelta,
+              T** dst, const int* ddelta,
+              int len, int npairs )
 {
-    const T** src = (const T**)_src;
-    T** dst = (T**)_dst;
     int i, k;
-    int block_size0 = n == 1 ? size.width : 1024;
-
-    for( ; size.height--; )
+    for( k = 0; k < npairs; k++ )
     {
-        int remaining = size.width;
-        for( ; remaining > 0; )
+        const T* s = src[k];
+        T* d = dst[k];
+        int ds = sdelta[k], dd = ddelta[k];
+        if( s )
         {
-            int block_size = MIN( remaining, block_size0 );
-            for( k = 0; k < n; k++ )
+            for( i = 0; i <= len - 2; i += 2, s += ds*2, d += dd*2 )
             {
-                const T* s = src[k];
-                T* d = dst[k];
-                int ds = sdelta1[k], dd = ddelta1[k];
-                if( s )
-                {
-                    for( i = 0; i <= block_size - 2; i += 2, s += ds*2, d += dd*2 )
-                    {
-                        T t0 = s[0], t1 = s[ds];
-                        d[0] = t0; d[dd] = t1;
-                    }
-                    if( i < block_size )
-                        d[0] = s[0], s += ds, d += dd;
-                    src[k] = s;
-                }
-                else
-                {
-                    for( i=0; i <= block_size-2; i+=2, d+=dd*2 )
-                        d[0] = d[dd] = 0;
-                    if( i < block_size )
-                        d[0] = 0, d += dd;
-                }
-                dst[k] = d;
+                T t0 = s[0], t1 = s[ds];
+                d[0] = t0; d[dd] = t1;
             }
-            remaining -= block_size;
+            if( i < len )
+                d[0] = s[0];
+        }
+        else
+        {
+            for( i = 0; i <= len - 2; i += 2, d += dd*2 )
+                d[0] = d[dd] = 0;
+            if( i < len )
+                d[0] = 0;
         }
-        for( k = 0; k < n; k++ )
-            src[k] += sdelta0[k], dst[k] += ddelta0[k];
     }
 }
 
-typedef void (*MixChannelsFunc)( const void** src, const int* sdelta0,
-        const int* sdelta1, void** dst, const int* ddelta0, const int* ddelta1, int n, Size size );
+    
+static void mixChannels8u( const uchar** src, const int* sdelta,
+                           uchar** dst, const int* ddelta,
+                           int len, int npairs )
+{
+    mixChannels_(src, sdelta, dst, ddelta, len, npairs);
+}
+
+static void mixChannels16u( const ushort** src, const int* sdelta,
+                            ushort** dst, const int* ddelta,
+                            int len, int npairs )
+{
+    mixChannels_(src, sdelta, dst, ddelta, len, npairs);
+}
 
-void mixChannels( const Mat* src, size_t nsrcs, Mat* dst, size_t ndsts, const int* fromTo, size_t npairs )
+static void mixChannels32s( const int** src, const int* sdelta,
+                            int** dst, const int* ddelta,
+                            int len, int npairs )
+{
+    mixChannels_(src, sdelta, dst, ddelta, len, npairs);
+}
+    
+static void mixChannels64s( const int64** src, const int* sdelta,
+                            int64** dst, const int* ddelta,
+                            int len, int npairs )
+{
+    mixChannels_(src, sdelta, dst, ddelta, len, npairs);
+}
+    
+typedef void (*MixChannelsFunc)( const uchar** src, const int* sdelta,
+        uchar** dst, const int* ddelta, int len, int npairs );
+
+static MixChannelsFunc mixchTab[] =
+{
+    (MixChannelsFunc)mixChannels8u, (MixChannelsFunc)mixChannels8u, (MixChannelsFunc)mixChannels16u,
+    (MixChannelsFunc)mixChannels16u, (MixChannelsFunc)mixChannels32s, (MixChannelsFunc)mixChannels32s,
+    (MixChannelsFunc)mixChannels64s, 0 
+};
+    
+}
+    
+void cv::mixChannels( const Mat* src, size_t nsrcs, Mat* dst, size_t ndsts, const int* fromTo, size_t npairs )
 {
     if( npairs == 0 )
         return;
     CV_Assert( src && nsrcs > 0 && dst && ndsts > 0 && fromTo && npairs > 0 );
     
-    if( src[0].dims > 2 )
-    {
-        size_t k, m = nsrcs, n = ndsts;
-        CV_Assert( n > 0 && m > 0 );
-        AutoBuffer<const Mat*> v(m + n);
-        AutoBuffer<Mat> planes(m + n);
-        for( k = 0; k < m; k++ )
-            v[k] = &src[k];
-        for( k = 0; k < n; k++ )
-            v[m + k] = &dst[k];
-        NAryMatIterator it(v, planes, m + n);
-        
-        for( int i = 0; i < it.nplanes; i++, ++it )
-            mixChannels( &it.planes[0], m, &it.planes[m], n, fromTo, npairs );
-        return;
-    }
+    size_t i, j, k, esz1 = dst[0].elemSize1();
+    int depth = dst[0].depth();
+
+    AutoBuffer<uchar> buf((nsrcs + ndsts + 1)*(sizeof(Mat*) + sizeof(uchar*)) + npairs*(sizeof(uchar*)*2 + sizeof(int)*6));
+    const Mat** arrays = (const Mat**)(uchar*)buf;
+    uchar** ptrs = (uchar**)(arrays + nsrcs + ndsts);
+    const uchar** srcs = (const uchar**)(ptrs + nsrcs + ndsts + 1);
+    uchar** dsts = (uchar**)(srcs + npairs);
+    int* tab = (int*)(dsts + npairs);
+    int *sdelta = (int*)(tab + npairs*4), *ddelta = sdelta + npairs;
+    
+    for( i = 0; i < nsrcs; i++ )
+        arrays[i] = &src[i];
+    for( i = 0; i < ndsts; i++ )
+        arrays[i + nsrcs] = &dst[i];
+    ptrs[nsrcs + ndsts] = 0;
     
-    size_t i, j;
-    int depth = dst[0].depth(), esz1 = (int)dst[0].elemSize1();
-    Size size = dst[0].size();
-
-    AutoBuffer<uchar> buf(npairs*(sizeof(void*)*2 + sizeof(int)*4));
-    void** srcs = (void**)(uchar*)buf;
-    void** dsts = srcs + npairs;
-    int *s0 = (int*)(dsts + npairs), *s1 = s0 + npairs, *d0 = s1 + npairs, *d1 = d0 + npairs;
-    bool isContinuous = true;
-
     for( i = 0; i < npairs; i++ )
     {
         int i0 = fromTo[i*2], i1 = fromTo[i*2+1];
@@ -407,48 +450,54 @@ void mixChannels( const Mat* src, size_t nsrcs, Mat* dst, size_t ndsts, const in
             for( j = 0; j < nsrcs; i0 -= src[j].channels(), j++ )
                 if( i0 < src[j].channels() )
                     break;
-            CV_Assert(j < nsrcs && src[j].size() == size && src[j].depth() == depth);
-            isContinuous = isContinuous && src[j].isContinuous();
-            srcs[i] = src[j].data + i0*esz1;
-            s1[i] = src[j].channels(); s0[i] = (int)src[j].step/esz1 - size.width*src[j].channels();
+            CV_Assert(j < nsrcs && src[j].depth() == depth);
+            tab[i*4] = j; tab[i*4+1] = i0*esz1;
+            sdelta[i] = src[j].channels();
         }
         else
         {
-            srcs[i] = 0; s1[i] = s0[i] = 0;
+            tab[i*4] = nsrcs + ndsts; tab[i*4+1] = 0;
+            sdelta[i] = 0;
         }
         
         for( j = 0; j < ndsts; i1 -= dst[j].channels(), j++ )
             if( i1 < dst[j].channels() )
                 break;
-        CV_Assert(i1 >= 0 && j < ndsts && dst[j].size() == size && dst[j].depth() == depth);
-        isContinuous = isContinuous && dst[j].isContinuous();
-        dsts[i] = dst[j].data + i1*esz1;
-        d1[i] = dst[j].channels(); d0[i] = (int)dst[j].step/esz1 - size.width*dst[j].channels();
+        CV_Assert(i1 >= 0 && j < ndsts && dst[j].depth() == depth);
+        tab[i*4+2] = j + nsrcs; tab[i*4+3] = i1*esz1;
+        ddelta[i] = dst[j].channels();
     }
 
-    MixChannelsFunc func = 0;
-    if( esz1 == 1 )
-        func = mixChannels_<uchar>;
-    else if( esz1 == 2 )
-        func = mixChannels_<ushort>;
-    else if( esz1 == 4 )    
-        func = mixChannels_<int>;
-    else if( esz1 == 8 )    
-        func = mixChannels_<int64>;
-    else
-        CV_Error( CV_StsUnsupportedFormat, "" );    
-
-    if( isContinuous )
+    NAryMatIterator it(arrays, ptrs, nsrcs + ndsts);
+    int total = (int)it.size, blocksize = std::min(total, (int)((BLOCK_SIZE + esz1-1)/esz1));
+    MixChannelsFunc func = mixchTab[depth];
+    
+    for( i = 0; i < it.nplanes; i++, ++it )
     {
-        size.width *= size.height;
-        size.height = 1;
+        for( k = 0; k < npairs; k++ )
+        {
+            srcs[k] = ptrs[tab[k*4]] + tab[k*4+1];
+            dsts[k] = ptrs[tab[k*4+2]] + tab[k*4+3];
+        }
+        
+        for( int j = 0; j < total; j += blocksize )
+        {
+            int bsz = std::min(total - j, blocksize);
+            func( srcs, sdelta, dsts, ddelta, bsz, (int)npairs );
+            
+            if( j + blocksize < total )
+                for( k = 0; k < npairs; k++ )
+                {
+                    srcs[k] += blocksize*sdelta[k]*esz1;
+                    dsts[k] += blocksize*ddelta[k]*esz1;
+                }
+        }
     }
-    func( (const void**)srcs, s0, s1, dsts, d0, d1, (int)npairs, size );
 }
 
 
-void mixChannels(const vector<Mat>& src, vector<Mat>& dst,
-                 const int* fromTo, int npairs)
+void cv::mixChannels(const vector<Mat>& src, vector<Mat>& dst,
+                 const int* fromTo, size_t npairs)
 {
     mixChannels(!src.empty() ? &src[0] : 0, src.size(),
                 !dst.empty() ? &dst[0] : 0, dst.size(), fromTo, npairs);
@@ -458,145 +507,74 @@ void mixChannels(const vector<Mat>& src, vector<Mat>& dst,
 *                                convertScale[Abs]                                       *
 \****************************************************************************************/
 
-template<typename sT, typename dT> struct OpCvt
-{
-    typedef sT type1;
-    typedef dT rtype;
-    rtype operator()(type1 x) const { return saturate_cast<rtype>(x); }
-};
-
-template<typename sT, typename dT, int _fbits> struct OpCvtFixPt
-{
-    typedef sT type1;
-    typedef dT rtype;
-    enum { fbits = _fbits };
-    rtype operator()(type1 x) const
-    {
-        return saturate_cast<rtype>((x + (1<<(fbits-1)))>>fbits);
-    }
-};
-
-template<typename sT, typename dT> struct OpCvtAbs
-{
-    typedef sT type1;
-    typedef dT rtype;
-    rtype operator()(type1 x) const { return saturate_cast<rtype>(std::abs(x)); }
-};
-
-template<typename sT, typename dT, int _fbits> struct OpCvtAbsFixPt
-{
-    typedef sT type1;
-    typedef dT rtype;
-    enum { fbits = _fbits };
-
-    rtype operator()(type1 x) const
-    {
-        return saturate_cast<rtype>((std::abs(x) + (1<<(fbits-1)))>>fbits);
-    }
-};
-
-template<class Op> static void
-cvtScaleLUT_( const Mat& srcmat, Mat& dstmat, double scale, double shift )
+namespace cv
 {
-    Op op;
-    typedef typename Op::rtype DT;
-    DT lut[256];
-    int i, sdepth = srcmat.depth(), ddepth = dstmat.depth();
-    double val = shift;
-
-    for( i = 0; i < 128; i++, val += scale )
-        lut[i] = op(val);
-
-    if( sdepth == CV_8S )
-        val = shift*2 - val;
-
-    for( ; i < 256; i++, val += scale )
-        lut[i] = op(val);
 
-    Mat _srcmat = srcmat;
-    if( sdepth == CV_8S )
-        _srcmat = Mat(srcmat.size(), CV_8UC(srcmat.channels()), srcmat.data, srcmat.step);
-    LUT(_srcmat, Mat(1, 256, ddepth, lut), dstmat);
-}
-
-template<typename T, class Op> static void
-cvtScale_( const Mat& srcmat, Mat& dstmat, double _scale, double _shift )
+template<typename T, typename DT, typename WT> static void
+cvtScaleAbs_( const T* src, size_t sstep,
+              DT* dst, size_t dstep, Size size,
+              WT scale, WT shift )
 {
-    Op op;
-    typedef typename Op::type1 WT;
-    typedef typename Op::rtype DT;
-    Size size = getContinuousSize( srcmat, dstmat, srcmat.channels() );
-    WT scale = saturate_cast<WT>(_scale), shift = saturate_cast<WT>(_shift);
-
-    for( int y = 0; y < size.height; y++ )
+    sstep /= sizeof(src[0]);
+    dstep /= sizeof(dst[0]);
+    
+    for( ; size.height--; src += sstep, dst += dstep )
     {
-        const T* src = (const T*)(srcmat.data + srcmat.step*y);
-        DT* dst = (DT*)(dstmat.data + dstmat.step*y);
         int x = 0;
-
         for( ; x <= size.width - 4; x += 4 )
         {
             DT t0, t1;
-            t0 = op(src[x]*scale + shift);
-            t1 = op(src[x+1]*scale + shift);
+            t0 = saturate_cast<DT>(std::abs(src[x]*scale + shift));
+            t1 = saturate_cast<DT>(std::abs(src[x+1]*scale + shift));
             dst[x] = t0; dst[x+1] = t1;
-            t0 = op(src[x+2]*scale + shift);
-            t1 = op(src[x+3]*scale + shift);
+            t0 = saturate_cast<DT>(std::abs(src[x+2]*scale + shift));
+            t1 = saturate_cast<DT>(std::abs(src[x+3]*scale + shift));
             dst[x+2] = t0; dst[x+3] = t1;
         }
-
+        
         for( ; x < size.width; x++ )
-            dst[x] = op(src[x]*scale + shift);
+            dst[x] = saturate_cast<DT>(std::abs(src[x]*scale + shift));
     }
-}
-
-template<typename T, class OpFixPt, class Op, int MAX_SHIFT> static void
-cvtScaleInt_( const Mat& srcmat, Mat& dstmat, double _scale, double _shift )
+}    
+    
+template<typename T, typename DT, typename WT> static void
+cvtScale_( const T* src, size_t sstep,
+           DT* dst, size_t dstep, Size size,
+           WT scale, WT shift )
 {
-    if( std::abs(_scale) > 1 || std::abs(_shift) > MAX_SHIFT )
-    {
-        cvtScale_<T, Op>(srcmat, dstmat, _scale, _shift);
-        return;
-    }
-    OpFixPt op;
-    typedef typename OpFixPt::rtype DT;
-    Size size = getContinuousSize( srcmat, dstmat, srcmat.channels() );
-    int scale = saturate_cast<int>(_scale*(1<<OpFixPt::fbits)),
-        shift = saturate_cast<int>(_shift*(1<<OpFixPt::fbits));
-
-    for( int y = 0; y < size.height; y++ )
+    sstep /= sizeof(src[0]);
+    dstep /= sizeof(dst[0]);
+    
+    for( ; size.height--; src += sstep, dst += dstep )
     {
-        const T* src = (const T*)(srcmat.data + srcmat.step*y);
-        DT* dst = (DT*)(dstmat.data + dstmat.step*y);
         int x = 0;
-
         for( ; x <= size.width - 4; x += 4 )
         {
             DT t0, t1;
-            t0 = op(src[x]*scale + shift);
-            t1 = op(src[x+1]*scale + shift);
+            t0 = saturate_cast<DT>(src[x]*scale + shift);
+            t1 = saturate_cast<DT>(src[x+1]*scale + shift);
             dst[x] = t0; dst[x+1] = t1;
-            t0 = op(src[x+2]*scale + shift);
-            t1 = op(src[x+3]*scale + shift);
+            t0 = saturate_cast<DT>(src[x+2]*scale + shift);
+            t1 = saturate_cast<DT>(src[x+3]*scale + shift);
             dst[x+2] = t0; dst[x+3] = t1;
         }
 
         for( ; x < size.width; x++ )
-            dst[x] = op(src[x]*scale + shift);
+            dst[x] = saturate_cast<DT>(src[x]*scale + shift);
     }
 }
 
+
 template<typename T, typename DT> static void
-cvt_( const Mat& srcmat, Mat& dstmat )
+cvt_( const T* src, size_t sstep,
+      DT* dst, size_t dstep, Size size )
 {
-    Size size = getContinuousSize( srcmat, dstmat, srcmat.channels() );
-
-    for( int y = 0; y < size.height; y++ )
+    sstep /= sizeof(src[0]);
+    dstep /= sizeof(dst[0]);
+    
+    for( ; size.height--; src += sstep, dst += dstep )
     {
-        const T* src = (const T*)(srcmat.data + srcmat.step*y);
-        DT* dst = (DT*)(dstmat.data + dstmat.step*y);
         int x = 0;
-
         for( ; x <= size.width - 4; x += 4 )
         {
             DT t0, t1;
@@ -607,322 +585,447 @@ cvt_( const Mat& srcmat, Mat& dstmat )
             t1 = saturate_cast<DT>(src[x+3]);
             dst[x+2] = t0; dst[x+3] = t1;
         }
-
+        
         for( ; x < size.width; x++ )
             dst[x] = saturate_cast<DT>(src[x]);
     }
 }
 
-static const int FBITS = 15;
-#define ICV_SCALE(x) CV_DESCALE((x), FBITS)
+template<typename T> static void
+cpy_( const T* src, size_t sstep, T* dst, size_t dstep, Size size )
+{
+    sstep /= sizeof(src[0]);
+    dstep /= sizeof(dst[0]);
+    
+    for( ; size.height--; src += sstep, dst += dstep )
+        memcpy(dst, src, size.width*sizeof(src[0]));
+}
+    
+#define DEF_CVT_SCALE_ABS_FUNC(suffix, tfunc, stype, dtype, wtype) \
+static void cvtScaleAbs##suffix( const stype* src, size_t sstep, const uchar*, size_t, \
+                         dtype* dst, size_t dstep, Size size, double* scale) \
+{ \
+    tfunc(src, sstep, dst, dstep, size, (wtype)scale[0], (wtype)scale[1]); \
+}
+
+#define DEF_CVT_SCALE_FUNC(suffix, stype, dtype, wtype) \
+static void cvtScale##suffix( const stype* src, size_t sstep, const uchar*, size_t, \
+dtype* dst, size_t dstep, Size size, double* scale) \
+{ \
+    cvtScale_(src, sstep, dst, dstep, size, (wtype)scale[0], (wtype)scale[1]); \
+}
+    
+    
+#define DEF_CVT_FUNC(suffix, stype, dtype) \
+static void cvt##suffix( const stype* src, size_t sstep, const uchar*, size_t, \
+                         dtype* dst, size_t dstep, Size size, double*) \
+{ \
+    cvt_(src, sstep, dst, dstep, size); \
+}
 
-typedef void (*CvtFunc)( const Mat& src, Mat& dst );
-typedef void (*CvtScaleFunc)( const Mat& src, Mat& dst, double scale, double shift );
+#define DEF_CPY_FUNC(suffix, stype) \
+static void cvt##suffix( const stype* src, size_t sstep, const uchar*, size_t, \
+stype* dst, size_t dstep, Size size, double*) \
+{ \
+    cpy_(src, sstep, dst, dstep, size); \
+}
+    
+    
+DEF_CVT_SCALE_ABS_FUNC(8u, cvtScaleAbs_, uchar, uchar, float);
+DEF_CVT_SCALE_ABS_FUNC(8s8u, cvtScaleAbs_, schar, uchar, float);
+DEF_CVT_SCALE_ABS_FUNC(16u8u, cvtScaleAbs_, ushort, uchar, float);
+DEF_CVT_SCALE_ABS_FUNC(16s8u, cvtScaleAbs_, short, uchar, float);
+DEF_CVT_SCALE_ABS_FUNC(32s8u, cvtScaleAbs_, int, uchar, float);
+DEF_CVT_SCALE_ABS_FUNC(32f8u, cvtScaleAbs_, float, uchar, float);
+DEF_CVT_SCALE_ABS_FUNC(64f8u, cvtScaleAbs_, double, uchar, float);    
+
+DEF_CVT_SCALE_FUNC(8u,     uchar, uchar, float);
+DEF_CVT_SCALE_FUNC(8s8u,   schar, uchar, float);
+DEF_CVT_SCALE_FUNC(16u8u,  ushort, uchar, float);
+DEF_CVT_SCALE_FUNC(16s8u,  short, uchar, float);
+DEF_CVT_SCALE_FUNC(32s8u,  int, uchar, float);
+DEF_CVT_SCALE_FUNC(32f8u,  float, uchar, float);
+DEF_CVT_SCALE_FUNC(64f8u,  double, uchar, float);    
+
+DEF_CVT_SCALE_FUNC(8u8s,   uchar, schar, float);
+DEF_CVT_SCALE_FUNC(8s,     schar, schar, float);
+DEF_CVT_SCALE_FUNC(16u8s,  ushort, schar, float);
+DEF_CVT_SCALE_FUNC(16s8s,  short, schar, float);
+DEF_CVT_SCALE_FUNC(32s8s,  int, schar, float);
+DEF_CVT_SCALE_FUNC(32f8s,  float, schar, float);
+DEF_CVT_SCALE_FUNC(64f8s,  double, schar, float);    
+
+DEF_CVT_SCALE_FUNC(8u16u,  uchar, ushort, float);
+DEF_CVT_SCALE_FUNC(8s16u,  schar, ushort, float);
+DEF_CVT_SCALE_FUNC(16u,    ushort, ushort, float);
+DEF_CVT_SCALE_FUNC(16s16u, short, ushort, float);
+DEF_CVT_SCALE_FUNC(32s16u, int, ushort, float);
+DEF_CVT_SCALE_FUNC(32f16u, float, ushort, float);
+DEF_CVT_SCALE_FUNC(64f16u, double, ushort, float);    
+
+DEF_CVT_SCALE_FUNC(8u16s,  uchar, short, float);
+DEF_CVT_SCALE_FUNC(8s16s,  schar, short, float);
+DEF_CVT_SCALE_FUNC(16u16s, ushort, short, float);
+DEF_CVT_SCALE_FUNC(16s,    short, short, float);
+DEF_CVT_SCALE_FUNC(32s16s, int, short, float);
+DEF_CVT_SCALE_FUNC(32f16s, float, short, float);
+DEF_CVT_SCALE_FUNC(64f16s, double, short, float);
+    
+DEF_CVT_SCALE_FUNC(8u32s,  uchar, int, float);
+DEF_CVT_SCALE_FUNC(8s32s,  schar, int, float);
+DEF_CVT_SCALE_FUNC(16u32s, ushort, int, float);
+DEF_CVT_SCALE_FUNC(16s32s, short, int, float);
+DEF_CVT_SCALE_FUNC(32s,    int, int, double);
+DEF_CVT_SCALE_FUNC(32f32s, float, int, float);
+DEF_CVT_SCALE_FUNC(64f32s, double, int, double);
+
+DEF_CVT_SCALE_FUNC(8u32f,  uchar, float, float);
+DEF_CVT_SCALE_FUNC(8s32f,  schar, float, float);
+DEF_CVT_SCALE_FUNC(16u32f, ushort, float, float);
+DEF_CVT_SCALE_FUNC(16s32f, short, float, float);
+DEF_CVT_SCALE_FUNC(32s32f, int, float, double);
+DEF_CVT_SCALE_FUNC(32f,    float, float, float);
+DEF_CVT_SCALE_FUNC(64f32f, double, float, double);
+
+DEF_CVT_SCALE_FUNC(8u64f,  uchar, double, double);
+DEF_CVT_SCALE_FUNC(8s64f,  schar, double, double);
+DEF_CVT_SCALE_FUNC(16u64f, ushort, double, double);
+DEF_CVT_SCALE_FUNC(16s64f, short, double, double);
+DEF_CVT_SCALE_FUNC(32s64f, int, double, double);
+DEF_CVT_SCALE_FUNC(32f64f, float, double, double);
+DEF_CVT_SCALE_FUNC(64f,    double, double, double);
+
+DEF_CPY_FUNC(8u,     uchar);
+DEF_CVT_FUNC(8s8u,   schar, uchar);
+DEF_CVT_FUNC(16u8u,  ushort, uchar);
+DEF_CVT_FUNC(16s8u,  short, uchar);
+DEF_CVT_FUNC(32s8u,  int, uchar);
+DEF_CVT_FUNC(32f8u,  float, uchar);
+DEF_CVT_FUNC(64f8u,  double, uchar);
+
+DEF_CVT_FUNC(8u8s,   uchar, schar);
+DEF_CVT_FUNC(16u8s,  ushort, schar);
+DEF_CVT_FUNC(16s8s,  short, schar);
+DEF_CVT_FUNC(32s8s,  int, schar);
+DEF_CVT_FUNC(32f8s,  float, schar);
+DEF_CVT_FUNC(64f8s,  double, schar);
+
+DEF_CVT_FUNC(8u16u,  uchar, ushort);
+DEF_CVT_FUNC(8s16u,  schar, ushort);
+DEF_CPY_FUNC(16u,    ushort);
+DEF_CVT_FUNC(16s16u, short, ushort);
+DEF_CVT_FUNC(32s16u, int, ushort);
+DEF_CVT_FUNC(32f16u, float, ushort);
+DEF_CVT_FUNC(64f16u, double, ushort);
+
+DEF_CVT_FUNC(8u16s,  uchar, short);
+DEF_CVT_FUNC(8s16s,  schar, short);
+DEF_CVT_FUNC(16u16s, ushort, short);
+DEF_CVT_FUNC(32s16s, int, short);
+DEF_CVT_FUNC(32f16s, float, short);
+DEF_CVT_FUNC(64f16s, double, short);
+
+DEF_CVT_FUNC(8u32s,  uchar, int);
+DEF_CVT_FUNC(8s32s,  schar, int);
+DEF_CVT_FUNC(16u32s, ushort, int);
+DEF_CVT_FUNC(16s32s, short, int);
+DEF_CPY_FUNC(32s,    int);
+DEF_CVT_FUNC(32f32s, float, int);
+DEF_CVT_FUNC(64f32s, double, int);
+
+DEF_CVT_FUNC(8u32f,  uchar, float);
+DEF_CVT_FUNC(8s32f,  schar, float);
+DEF_CVT_FUNC(16u32f, ushort, float);
+DEF_CVT_FUNC(16s32f, short, float);
+DEF_CVT_FUNC(32s32f, int, float);
+DEF_CVT_FUNC(64f32f, double, float);
+
+DEF_CVT_FUNC(8u64f,  uchar, double);
+DEF_CVT_FUNC(8s64f,  schar, double);
+DEF_CVT_FUNC(16u64f, ushort, double);
+DEF_CVT_FUNC(16s64f, short, double);
+DEF_CVT_FUNC(32s64f, int, double);
+DEF_CVT_FUNC(32f64f, float, double);
+DEF_CPY_FUNC(64s,    int64);
+    
+static BinaryFunc cvtScaleAbsTab[] =
+{
+    (BinaryFunc)cvtScaleAbs8u, (BinaryFunc)cvtScaleAbs8s8u, (BinaryFunc)cvtScaleAbs16u8u,
+    (BinaryFunc)cvtScaleAbs16s8u, (BinaryFunc)cvtScaleAbs32s8u, (BinaryFunc)cvtScaleAbs32f8u,
+    (BinaryFunc)cvtScaleAbs64f8u, 0
+};
+
+static BinaryFunc cvtScaleTab[][8] =
+{
+    {
+        (BinaryFunc)cvtScale8u, (BinaryFunc)cvtScale8s8u, (BinaryFunc)cvtScale16u8u,
+        (BinaryFunc)cvtScale16s8u, (BinaryFunc)cvtScale32s8u, (BinaryFunc)cvtScale32f8u,
+        (BinaryFunc)cvtScale64f8u, 0
+    },
+    {
+        (BinaryFunc)cvtScale8u8s, (BinaryFunc)cvtScale8s, (BinaryFunc)cvtScale16u8s,
+        (BinaryFunc)cvtScale16s8s, (BinaryFunc)cvtScale32s8s, (BinaryFunc)cvtScale32f8s,
+        (BinaryFunc)cvtScale64f8s, 0
+    },
+    {
+        (BinaryFunc)cvtScale8u16u, (BinaryFunc)cvtScale8s16u, (BinaryFunc)cvtScale16u,
+        (BinaryFunc)cvtScale16s16u, (BinaryFunc)cvtScale32s16u, (BinaryFunc)cvtScale32f16u,
+        (BinaryFunc)cvtScale64f16u, 0
+    },
+    {
+        (BinaryFunc)cvtScale8u16s, (BinaryFunc)cvtScale8s16s, (BinaryFunc)cvtScale16u16s,
+        (BinaryFunc)cvtScale16s, (BinaryFunc)cvtScale32s16s, (BinaryFunc)cvtScale32f16s,
+        (BinaryFunc)cvtScale64f16s, 0
+    },
+    {
+        (BinaryFunc)cvtScale8u32s, (BinaryFunc)cvtScale8s32s, (BinaryFunc)cvtScale16u32s,
+        (BinaryFunc)cvtScale16s32s, (BinaryFunc)cvtScale32s, (BinaryFunc)cvtScale32f32s,
+        (BinaryFunc)cvtScale64f32s, 0
+    },
+    {
+        (BinaryFunc)cvtScale8u32f, (BinaryFunc)cvtScale8s32f, (BinaryFunc)cvtScale16u32f,
+        (BinaryFunc)cvtScale16s32f, (BinaryFunc)cvtScale32s32f, (BinaryFunc)cvtScale32f,
+        (BinaryFunc)cvtScale64f32f, 0
+    },
+    {
+        (BinaryFunc)cvtScale8u64f, (BinaryFunc)cvtScale8s64f, (BinaryFunc)cvtScale16u64f,
+        (BinaryFunc)cvtScale16s64f, (BinaryFunc)cvtScale32s64f, (BinaryFunc)cvtScale32f64f,
+        (BinaryFunc)cvtScale64f, 0
+    },
+    {
+        0, 0, 0, 0, 0, 0, 0, 0
+    }
+};
 
-void convertScaleAbs( const Mat& src0, Mat& dst, double scale, double shift )
+static BinaryFunc cvtTab[][8] =
 {
-    static CvtScaleFunc tab[] =
     {
-        cvtScaleLUT_<OpCvtAbs<double, uchar> >,
-        cvtScaleLUT_<OpCvtAbs<double, uchar> >,
-        cvtScaleInt_<ushort, OpCvtAbsFixPt<int, uchar, FBITS>, OpCvtAbs<float, uchar>, 0>,
-        cvtScaleInt_<short, OpCvtAbsFixPt<int, uchar, FBITS>, OpCvtAbs<float, uchar>, 1<<15>,
-        cvtScale_<int, OpCvtAbs<double, uchar> >,
-        cvtScale_<float, OpCvtAbs<float, uchar> >,
-        cvtScale_<double, OpCvtAbs<double, uchar> >, 0
-    };
-
-    Mat src = src0;
-    dst.create( src.dims, src.size, CV_8UC(src.channels()) );
-    CvtScaleFunc func = tab[src.depth()];
+        (BinaryFunc)cvt8u, (BinaryFunc)cvt8s8u, (BinaryFunc)cvt16u8u,
+        (BinaryFunc)cvt16s8u, (BinaryFunc)cvt32s8u, (BinaryFunc)cvt32f8u,
+        (BinaryFunc)cvt64f8u, 0
+    },
+    {
+        (BinaryFunc)cvt8u8s, (BinaryFunc)cvt8u, (BinaryFunc)cvt16u8s,
+        (BinaryFunc)cvt16s8s, (BinaryFunc)cvt32s8s, (BinaryFunc)cvt32f8s,
+        (BinaryFunc)cvt64f8s, 0
+    },
+    {
+        (BinaryFunc)cvt8u16u, (BinaryFunc)cvt8s16u, (BinaryFunc)cvt16u,
+        (BinaryFunc)cvt16s16u, (BinaryFunc)cvt32s16u, (BinaryFunc)cvt32f16u,
+        (BinaryFunc)cvt64f16u, 0
+    },
+    {
+        (BinaryFunc)cvt8u16s, (BinaryFunc)cvt8s16s, (BinaryFunc)cvt16u16s,
+        (BinaryFunc)cvt16u, (BinaryFunc)cvt32s16s, (BinaryFunc)cvt32f16s,
+        (BinaryFunc)cvt64f16s, 0
+    },
+    {
+        (BinaryFunc)cvt8u32s, (BinaryFunc)cvt8s32s, (BinaryFunc)cvt16u32s,
+        (BinaryFunc)cvt16s32s, (BinaryFunc)cvt32s, (BinaryFunc)cvt32f32s,
+        (BinaryFunc)cvt64f32s, 0
+    },
+    {
+        (BinaryFunc)cvt8u32f, (BinaryFunc)cvt8s32f, (BinaryFunc)cvt16u32f,
+        (BinaryFunc)cvt16s32f, (BinaryFunc)cvt32s32f, (BinaryFunc)cvt32s,
+        (BinaryFunc)cvt64f32f, 0
+    },
+    {
+        (BinaryFunc)cvt8u64f, (BinaryFunc)cvt8s64f, (BinaryFunc)cvt16u64f,
+        (BinaryFunc)cvt16s64f, (BinaryFunc)cvt32s64f, (BinaryFunc)cvt32f64f,
+        (BinaryFunc)cvt64s, 0
+    },
+    {
+        0, 0, 0, 0, 0, 0, 0, 0
+    }
+};
+  
+BinaryFunc getConvertFunc(int sdepth, int ddepth)
+{
+    return cvtTab[CV_MAT_DEPTH(ddepth)][CV_MAT_DEPTH(sdepth)];
+}
+
+BinaryFunc getConvertScaleFunc(int sdepth, int ddepth)
+{
+    return cvtScaleTab[CV_MAT_DEPTH(ddepth)][CV_MAT_DEPTH(sdepth)];
+}    
+    
+}
+    
+void cv::convertScaleAbs( const InputArray& _src, OutputArray _dst, double alpha, double beta )
+{
+    Mat src = _src.getMat();
+    int cn = src.channels();
+    double scale[] = {alpha, beta};
+    _dst.create( src.dims, src.size, CV_8UC(cn) );
+    Mat dst = _dst.getMat();
+    BinaryFunc func = cvtScaleAbsTab[src.depth()];
     CV_Assert( func != 0 );
     
     if( src.dims <= 2 )
     {
-        func( src, dst, scale, shift );
+        Size sz = getContinuousSize(src, dst, cn);
+        func( src.data, src.step, 0, 0, dst.data, dst.step, sz, scale );
     }
     else
     {
         const Mat* arrays[] = {&src, &dst, 0};
-        Mat planes[2];
-        NAryMatIterator it(arrays, planes);
+        uchar* ptrs[2];
+        NAryMatIterator it(arrays, ptrs);
+        Size sz((int)it.size*cn, 1);
         
-        for( int i = 0; i < it.nplanes; i++, ++it )
-            func(it.planes[0], it.planes[1], scale, shift);
+        for( size_t i = 0; i < it.nplanes; i++, ++it )
+            func( ptrs[0], 0, 0, 0, ptrs[1], 0, sz, scale );
     }
 }
 
-
-void Mat::convertTo(Mat& dst, int _type, double alpha, double beta) const
+void cv::Mat::convertTo(OutputArray _dst, int _type, double alpha, double beta) const
 {
-    static CvtFunc tab[8][8] =
-    {
-        {0, cvt_<uchar, schar>, cvt_<uchar, ushort>, cvt_<uchar, short>,
-        cvt_<uchar, int>, cvt_<uchar, float>, cvt_<uchar, double>, 0},
-
-        {cvt_<schar, uchar>, 0, cvt_<schar, ushort>, cvt_<schar, short>,
-        cvt_<schar, int>, cvt_<schar, float>, cvt_<schar, double>, 0},
-
-        {cvt_<ushort, uchar>, cvt_<ushort, schar>, 0, cvt_<ushort, short>,
-        cvt_<ushort, int>, cvt_<ushort, float>, cvt_<ushort, double>, 0},
-
-        {cvt_<short, uchar>, cvt_<short, schar>, cvt_<short, ushort>, 0,
-        cvt_<short, int>, cvt_<short, float>, cvt_<short, double>, 0},
-
-        {cvt_<int, uchar>, cvt_<int, schar>, cvt_<int, ushort>,
-        cvt_<int, short>, 0, cvt_<int, float>, cvt_<int, double>, 0},
-
-        {cvt_<float, uchar>, cvt_<float, schar>, cvt_<float, ushort>,
-        cvt_<float, short>, cvt_<float, int>, 0, cvt_<float, double>, 0},
-
-        {cvt_<double, uchar>, cvt_<double, schar>, cvt_<double, ushort>,
-        cvt_<double, short>, cvt_<double, int>, cvt_<double, float>, 0, 0},
-
-        {0,0,0,0,0,0,0,0}
-    };
-
-    static CvtScaleFunc stab[8][8] =
-    {
-        {
-            cvtScaleLUT_<OpCvt<double, uchar> >,
-            cvtScaleLUT_<OpCvt<double, schar> >,
-            cvtScaleLUT_<OpCvt<double, ushort> >,
-            cvtScaleLUT_<OpCvt<double, short> >,
-            cvtScaleLUT_<OpCvt<double, int> >,
-            cvtScaleLUT_<OpCvt<double, float> >,
-            cvtScaleLUT_<OpCvt<double, double> >, 0
-        },
-
-        {
-            // this is copy of the above section,
-            // since cvScaleLUT handles both 8u->? and 8s->? cases
-            cvtScaleLUT_<OpCvt<double, uchar> >,
-            cvtScaleLUT_<OpCvt<double, schar> >,
-            cvtScaleLUT_<OpCvt<double, ushort> >,
-            cvtScaleLUT_<OpCvt<double, short> >,
-            cvtScaleLUT_<OpCvt<double, int> >,
-            cvtScaleLUT_<OpCvt<double, float> >,
-            cvtScaleLUT_<OpCvt<double, double> >, 0,
-        },
-
-        {
-            cvtScaleInt_<ushort, OpCvtFixPt<int, uchar, FBITS>, OpCvt<float, uchar>, 0>,
-            cvtScaleInt_<ushort, OpCvtFixPt<int, schar, FBITS>, OpCvt<float, schar>, 0>,
-            cvtScaleInt_<ushort, OpCvtFixPt<int, ushort, FBITS>, OpCvt<float, ushort>, 0>,
-            cvtScaleInt_<ushort, OpCvtFixPt<int, short, FBITS>, OpCvt<float, short>, 0>,
-            cvtScale_<ushort, OpCvt<double, int> >,
-            cvtScale_<ushort, OpCvt<double, float> >,
-            cvtScale_<ushort, OpCvt<double, double> >, 0,
-        },
-
-        {
-            cvtScaleInt_<short, OpCvtFixPt<int, uchar, FBITS>, OpCvt<float, uchar>, 1<<15>,
-            cvtScaleInt_<short, OpCvtFixPt<int, schar, FBITS>, OpCvt<float, schar>, 1<<15>,
-            cvtScaleInt_<short, OpCvtFixPt<int, ushort, FBITS>, OpCvt<float, ushort>, 1<<15>,
-            cvtScaleInt_<short, OpCvtFixPt<int, short, FBITS>, OpCvt<float, short>, 1<<15>,
-            cvtScale_<short, OpCvt<double, int> >,
-            cvtScale_<short, OpCvt<double, float> >,
-            cvtScale_<short, OpCvt<double, double> >, 0,
-        },
-
-        {
-            cvtScale_<int, OpCvt<float, uchar> >,
-            cvtScale_<int, OpCvt<float, schar> >,
-            cvtScale_<int, OpCvt<double, ushort> >,
-            cvtScale_<int, OpCvt<double, short> >,
-            cvtScale_<int, OpCvt<double, int> >,
-            cvtScale_<int, OpCvt<double, float> >,
-            cvtScale_<int, OpCvt<double, double> >, 0,
-        },
-
-        {
-            cvtScale_<float, OpCvt<float, uchar> >,
-            cvtScale_<float, OpCvt<float, schar> >,
-            cvtScale_<float, OpCvt<float, ushort> >,
-            cvtScale_<float, OpCvt<float, short> >,
-            cvtScale_<float, OpCvt<float, int> >,
-            cvtScale_<float, OpCvt<float, float> >,
-            cvtScale_<float, OpCvt<double, double> >, 0,
-        },
-
-        {
-            cvtScale_<double, OpCvt<double, uchar> >,
-            cvtScale_<double, OpCvt<double, schar> >,
-            cvtScale_<double, OpCvt<double, ushort> >,
-            cvtScale_<double, OpCvt<double, short> >,
-            cvtScale_<double, OpCvt<double, int> >,
-            cvtScale_<double, OpCvt<double, float> >,
-            cvtScale_<double, OpCvt<double, double> >, 0,
-        }
-    };
-
     bool noScale = fabs(alpha-1) < DBL_EPSILON && fabs(beta) < DBL_EPSILON;
 
     if( _type < 0 )
-        _type = type();
+        _type = _dst.fixedType() ? _dst.type() : type();
     else
         _type = CV_MAKETYPE(CV_MAT_DEPTH(_type), channels());
 
     int sdepth = depth(), ddepth = CV_MAT_DEPTH(_type);
     if( sdepth == ddepth && noScale )
     {
-        copyTo(dst);
+        copyTo(_dst);
         return;
     }
 
-    Mat temp;
-    const Mat* psrc = this;
-    if( sdepth != ddepth && data == dst.data )
-        psrc = &(temp = *this);
+    Mat src = *this;
         
-    CvtFunc func = 0;
-    CvtScaleFunc scaleFunc = 0;
-    
-    if( noScale )
-    {
-        func = tab[sdepth][ddepth];
-        CV_Assert( func != 0 );
-    }
-    else
-    {
-        scaleFunc = stab[sdepth][ddepth];
-        CV_Assert( scaleFunc != 0 );
-    }
+    BinaryFunc func = noScale ? getConvertFunc(sdepth, ddepth) : getConvertScaleFunc(sdepth, ddepth);
+    double scale[] = {alpha, beta};
+    int cn = channels();
+    CV_Assert( func != 0 );
     
     if( dims <= 2 )
     {
-        dst.create( size(), _type );
-        if( func )
-            func( *psrc, dst );
-        else
-            scaleFunc( *psrc, dst, alpha, beta );
+        _dst.create( size(), _type );
+        Mat dst = _dst.getMat();
+        Size sz = getContinuousSize(src, dst, cn);
+        func( src.data, src.step, 0, 0, dst.data, dst.step, sz, scale );
     }
     else
     {
-        dst.create( dims, size, _type );
-        const Mat* arrays[] = {psrc, &dst, 0};
-        Mat planes[2];
-        NAryMatIterator it(arrays, planes);
+        _dst.create( dims, size, _type );
+        Mat dst = _dst.getMat();
+        const Mat* arrays[] = {&src, &dst, 0};
+        uchar* ptrs[2];
+        NAryMatIterator it(arrays, ptrs);
+        Size sz((int)(it.size*cn), 1);
         
-        for( int i = 0; i < it.nplanes; i++, ++it )
-        {
-            if( func )
-                func(it.planes[0], it.planes[1]);
-            else
-                scaleFunc(it.planes[0], it.planes[1], alpha, beta);
-        }
-    }    
+        for( size_t i = 0; i < it.nplanes; i++, ++it )
+            func(ptrs[0], 0, 0, 0, ptrs[1], 0, sz, scale);
+    }
 }
 
 /****************************************************************************************\
 *                                    LUT Transform                                       *
 \****************************************************************************************/
 
-template<typename T> static void
-LUT8u( const Mat& srcmat, Mat& dstmat, const Mat& lut )
+namespace cv
 {
-    int cn = lut.channels();
-    int max_block_size = (1 << 10)*cn;
-    const T* _lut = (const T*)lut.data;
-    T lutp[4][256];
-    int y, i, k;
-    Size size = getContinuousSize( srcmat, dstmat, srcmat.channels() );
 
+template<typename T> static void
+LUT8u_( const uchar* src, const T* lut, T* dst, int len, int cn )
+{
     if( cn == 1 )
     {
-        for( y = 0; y < size.height; y++ )
-        {
-            const uchar* src = srcmat.data + srcmat.step*y;
-            T* dst = (T*)(dstmat.data + dstmat.step*y);
-
-            for( i = 0; i < size.width; i++ )
-                dst[i] = _lut[src[i]];
-        }
-        return;
+        for( int i = 0; i < len; i++ )
+            dst[i] = lut[src[i]];
     }
-
-    if( size.width*size.height < 256 )
+    else
     {
-        for( y = 0; y < size.height; y++ )
-        {
-            const uchar* src = srcmat.data + srcmat.step*y;
-            T* dst = (T*)(dstmat.data + dstmat.step*y);
-
-            for( k = 0; k < cn; k++ )
-                for( i = 0; i < size.width; i += cn )
-                    dst[i+k] = _lut[src[i+k]*cn+k];
-        }
-        return;
+        for( int i = 0; i < len*cn; i += cn )
+            for( int k = 0; k < cn; k++ )
+                dst[i+k] = lut[src[i+k]*cn+k];
     }
+}
 
-    /* repack the lut to planar layout */
-    for( k = 0; k < cn; k++ )
-        for( i = 0; i < 256; i++ )
-            lutp[k][i] = _lut[i*cn+k];
+static void LUT8u_8u( const uchar* src, const uchar* lut, uchar* dst, int len, int cn )
+{
+    LUT8u_( src, lut, dst, len, cn );
+}
 
-    for( y = 0; y < size.height; y++ )
-    {
-        const uchar* src = srcmat.data + srcmat.step*y;
-        T* dst = (T*)(dstmat.data + dstmat.step*y);
+static void LUT8u_8s( const uchar* src, const schar* lut, schar* dst, int len, int cn )
+{
+    LUT8u_( src, lut, dst, len, cn );
+}
 
-        for( i = 0; i < size.width; )
-        {
-            int j, limit = std::min(size.width, i + max_block_size);
-            for( k = 0; k < cn; k++, src++, dst++ )
-            {
-                const T* lut = lutp[k];
-                for( j = i; j <= limit - cn*2; j += cn*2 )
-                {
-                    T t0 = lut[src[j]];
-                    T t1 = lut[src[j+cn]];
-                    dst[j] = t0; dst[j+cn] = t1;
-                }
+static void LUT8u_16u( const uchar* src, const ushort* lut, ushort* dst, int len, int cn )
+{
+    LUT8u_( src, lut, dst, len, cn );
+}
 
-                for( ; j < limit; j += cn )
-                    dst[j] = lut[src[j]];
-            }
-            src -= cn;
-            dst -= cn;
-            i = limit;
-        }
-    }
+static void LUT8u_16s( const uchar* src, const short* lut, short* dst, int len, int cn )
+{
+    LUT8u_( src, lut, dst, len, cn );
 }
 
-typedef void (*LUTFunc)( const Mat& src, Mat& dst, const Mat& lut );
+static void LUT8u_32s( const uchar* src, const int* lut, int* dst, int len, int cn )
+{
+    LUT8u_( src, lut, dst, len, cn );
+}
+
+static void LUT8u_32f( const uchar* src, const float* lut, float* dst, int len, int cn )
+{
+    LUT8u_( src, lut, dst, len, cn );
+}
+
+static void LUT8u_64f( const uchar* src, const double* lut, double* dst, int len, int cn )
+{
+    LUT8u_( src, lut, dst, len, cn );
+}    
+    
+typedef void (*LUTFunc)( const uchar* src, const uchar* lut, uchar* dst, int len, int cn );
+    
+static LUTFunc lutTab[] =
+{
+    (LUTFunc)LUT8u_8u, (LUTFunc)LUT8u_8s, (LUTFunc)LUT8u_16u, (LUTFunc)LUT8u_16s,
+    (LUTFunc)LUT8u_32s, (LUTFunc)LUT8u_32f, (LUTFunc)LUT8u_64f, 0
+};
 
-void LUT( const Mat& src, const Mat& lut, Mat& dst )
+}
+    
+void cv::LUT( const InputArray& _src, const InputArray& _lut, OutputArray _dst, int interpolation )
 {
-    int cn = src.channels(), esz1 = (int)lut.elemSize1();
+    Mat src = _src.getMat(), lut = _lut.getMat();
+    CV_Assert( interpolation == 0 );
+    int cn = src.channels();
 
     CV_Assert( (lut.channels() == cn || lut.channels() == 1) &&
-        lut.rows*lut.cols == 256 && lut.isContinuous() &&
+        lut.total() == 256 && lut.isContinuous() &&
         (src.depth() == CV_8U || src.depth() == CV_8S) );
-    dst.create( src.size(), CV_MAKETYPE(lut.depth(), cn));
-
-    LUTFunc func = 0;
-    if( esz1 == 1 )
-        func = LUT8u<uchar>;
-    else if( esz1 == 2 )
-        func = LUT8u<ushort>;
-    else if( esz1 == 4 )
-        func = LUT8u<int>;
-    else if( esz1 == 8 )
-        func = LUT8u<int64>;
-    else    
-        CV_Error(CV_StsUnsupportedFormat, "");
-    func( src, dst, lut );
+    _dst.create( src.dims, src.size, CV_MAKETYPE(lut.depth(), cn));
+    Mat dst = _dst.getMat();
+
+    LUTFunc func = lutTab[src.depth()];
+    CV_Assert( func != 0 );
+    
+    const Mat* arrays[] = {&src, &dst, 0};
+    uchar* ptrs[2];
+    NAryMatIterator it(arrays, ptrs);
+    int len = (int)it.size;
+    
+    for( size_t i = 0; i < it.nplanes; i++, ++it )
+        func(ptrs[0], lut.data, ptrs[1], len, cn);
 }
 
 
-void normalize( const Mat& src, Mat& dst, double a, double b,
-                int norm_type, int rtype, const Mat& mask )
+void cv::normalize( const InputArray& _src, OutputArray _dst, double a, double b,
+                    int norm_type, int rtype, const InputArray& _mask )
 {
+    Mat src = _src.getMat(), mask = _mask.getMat();
+    
     double scale = 1, shift = 0;
     if( norm_type == CV_MINMAX )
     {
         double smin = 0, smax = 0;
         double dmin = MIN( a, b ), dmax = MAX( a, b );
-        minMaxLoc( src, &smin, &smax, 0, 0, mask );
+        minMaxLoc( _src, &smin, &smax, 0, 0, mask );
         scale = (dmax - dmin)*(smax - smin > DBL_EPSILON ? 1./(smax - smin) : 0);
         shift = dmin - smin*scale;
     }
@@ -935,6 +1038,12 @@ void normalize( const Mat& src, Mat& dst, double a, double b,
     else
         CV_Error( CV_StsBadArg, "Unknown/unsupported norm type" );
     
+    if( rtype < 0 )
+        rtype = _dst.fixedType() ? _dst.depth() : src.depth();
+    
+    _dst.create(src.dims, src.size, CV_MAKETYPE(rtype, src.channels()));
+    Mat dst = _dst.getMat();
+    
     if( !mask.data )
         src.convertTo( dst, rtype, scale, shift );
     else
@@ -945,8 +1054,6 @@ void normalize( const Mat& src, Mat& dst, double a, double b,
     }
 }
 
-}
-
 CV_IMPL void
 cvSplit( const void* srcarr, void* dstarr0, void* dstarr1, void* dstarr2, void* dstarr3 )
 {
index e3e5672..e2ab4f1 100644 (file)
@@ -11,7 +11,7 @@
 //                For Open Source Computer Vision Library
 //
 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
-// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
 // Third party copyrights are property of their respective owners.
 //
 // Redistribution and use in source and binary forms, with or without modification,
@@ -52,18 +52,12 @@ namespace cv
 {
 
 template<typename T> static void
-copyMask_(const Mat& srcmat, Mat& dstmat, const Mat& maskmat)
+copyMask_(const uchar* _src, size_t sstep, const uchar* mask, size_t mstep, uchar* _dst, size_t dstep, Size size)
 {
-    const uchar* mask = maskmat.data;
-    size_t sstep = srcmat.step;
-    size_t dstep = dstmat.step;
-    size_t mstep = maskmat.step;
-    Size size = getContinuousSize(srcmat, dstmat, maskmat);
-
-    for( int y = 0; y < size.height; y++, mask += mstep )
+    for( ; size.height--; mask += mstep, _src += sstep, _dst += dstep )
     {
-        const T* src = (const T*)(srcmat.data + sstep*y);
-        T* dst = (T*)(dstmat.data + dstep*y);
+        const T* src = (const T*)_src;
+        T* dst = (T*)_dst;
         int x = 0;
         for( ; x <= size.width - 4; x += 4 )
         {
@@ -82,389 +76,397 @@ copyMask_(const Mat& srcmat, Mat& dstmat, const Mat& maskmat)
     }
 }
 
-template<typename T> static void
-setMask_(const void* _scalar, Mat& dstmat, const Mat& maskmat)
+static void
+copyMaskGeneric(const uchar* _src, size_t sstep, const uchar* mask, size_t mstep, uchar* _dst, size_t dstep, Size size, void* _esz)
 {
-    T scalar = *(T*)_scalar;
-    const uchar* mask = maskmat.data;
-    size_t dstep = dstmat.step;
-    size_t mstep = maskmat.step;
-    Size size = dstmat.size();
-
-    if( dstmat.isContinuous() && maskmat.isContinuous() )
+    size_t k, esz = *(size_t*)_esz;
+    for( ; size.height--; mask += mstep, _src += sstep, _dst += dstep )
     {
-        size.width *= size.height;
-        size.height = 1;
+        const uchar* src = _src;
+        uchar* dst = _dst;
+        int x = 0;
+        for( ; x < size.width; x++, src += esz, dst += esz )
+        {
+            if( !mask[x] )
+                continue;
+            for( k = 0; k < esz; k++ )
+                dst[k] = src[k];
+        }
     }
-
-    for( int y = 0; y < size.height; y++, mask += mstep )
+}
+    
+template<typename T> static void
+setMask_(T value, const uchar* mask, size_t mstep, uchar* _dst, size_t dstep, Size size)
+{
+    for( ; size.height--; mask += mstep, _dst += dstep )
     {
-        T* dst = (T*)(dstmat.data + dstep*y);
+        T* dst = (T*)_dst;
         int x = 0;
         for( ; x <= size.width - 4; x += 4 )
         {
             if( mask[x] )
-                dst[x] = scalar;
+                dst[x] = value;
             if( mask[x+1] )
-                dst[x+1] = scalar;
+                dst[x+1] = value;
             if( mask[x+2] )
-                dst[x+2] = scalar;
+                dst[x+2] = value;
             if( mask[x+3] )
-                dst[x+3] = scalar;
+                dst[x+3] = value;
         }
         for( ; x < size.width; x++ )
             if( mask[x] )
-                dst[x] = scalar;
+                dst[x] = value;
     }
 }
 
-typedef void (*SetMaskFunc)(const void* scalar, Mat& dst, const Mat& mask);
-
-CopyMaskFunc g_copyMaskFuncTab[] =
+static void
+setMaskGeneric(const uchar* value, size_t, const uchar* mask, size_t mstep, uchar* _dst, size_t dstep, Size size, void* _esz)
+{
+    size_t k, esz = *(size_t*)_esz;
+    for( ; size.height--; mask += mstep, _dst += dstep )
+    {
+        uchar* dst = _dst;
+        int x = 0;
+        for( ; x < size.width; x++, dst += esz )
+        {
+            if( !mask[x] )
+                continue;
+            for( k = 0; k < esz; k++ )
+                dst[k] = value[k];
+        }
+    }
+}
+    
+#define DEF_COPY_SET_MASK(suffix, type) \
+static void copyMask##suffix(const uchar* src, size_t sstep, const uchar* mask, size_t mstep, \
+                             uchar* dst, size_t dstep, Size size, void*) \
+{ \
+    copyMask_<type>(src, sstep, mask, mstep, dst, dstep, size); \
+} \
+static void setMask##suffix( const uchar* src, size_t, const uchar* mask, size_t mstep, \
+                             uchar* dst, size_t dstep, Size size, void*) \
+{ \
+    setMask_<type>(*(const type*)src, mask, mstep, dst, dstep, size); \
+}
+    
+    
+DEF_COPY_SET_MASK(8u, uchar);
+DEF_COPY_SET_MASK(16u, ushort);
+DEF_COPY_SET_MASK(8uC3, Vec3b);
+DEF_COPY_SET_MASK(32s, int);
+DEF_COPY_SET_MASK(16uC3, Vec3s);
+DEF_COPY_SET_MASK(32sC2, Vec2i);
+DEF_COPY_SET_MASK(32sC3, Vec3i);
+DEF_COPY_SET_MASK(32sC4, Vec4i);
+DEF_COPY_SET_MASK(32sC6, Vec6i);
+DEF_COPY_SET_MASK(32sC8, Vec8i);
+    
+BinaryFunc copyMaskTab[] =
 {
     0,
-    copyMask_<uchar>, // 1
-    copyMask_<ushort>, // 2
-    copyMask_<Vec<uchar,3> >, // 3
-    copyMask_<int>, // 4
+    copyMask8u,
+    copyMask16u,
+    copyMask8uC3,
+    copyMask32s,
     0,
-    copyMask_<Vec<ushort,3> >, // 6
+    copyMask16uC3,
     0,
-    copyMask_<Vec<int,2> >, // 8
+    copyMask32sC2,
     0, 0, 0,
-    copyMask_<Vec<int,3> >, // 12
+    copyMask32sC3,
     0, 0, 0,
-    copyMask_<Vec<int,4> >, // 16
+    copyMask32sC4,
     0, 0, 0, 0, 0, 0, 0,
-    copyMask_<Vec<int,6> >, // 24
+    copyMask32sC6,
     0, 0, 0, 0, 0, 0, 0,
-    copyMask_<Vec<int,8> > // 32
+    copyMask32sC8
 };
 
-static SetMaskFunc setMaskFuncTab[] =
+BinaryFunc setMaskTab[] =
 {
     0,
-    setMask_<uchar>, // 1
-    setMask_<ushort>, // 2
-    setMask_<Vec<uchar,3> >, // 3
-    setMask_<int>, // 4
+    setMask8u,
+    setMask16u,
+    setMask8uC3,
+    setMask32s,
     0,
-    setMask_<Vec<ushort,3> >, // 6
+    setMask16uC3,
     0,
-    setMask_<Vec<int,2> >, // 8
+    setMask32sC2,
     0, 0, 0,
-    setMask_<Vec<int,3> >, // 12
+    setMask32sC3,
     0, 0, 0,
-    setMask_<Vec<int,4> >, // 16
+    setMask32sC4,
     0, 0, 0, 0, 0, 0, 0,
-    setMask_<Vec<int,6> >, // 24
+    setMask32sC6,
     0, 0, 0, 0, 0, 0, 0,
-    setMask_<Vec<int,8> > // 32
-};
-
+    setMask32sC8
+};    
+    
+BinaryFunc getCopyMaskFunc(size_t esz)
+{
+    return esz <= 32 && copyMaskTab[esz] ? copyMaskTab[esz] : copyMaskGeneric;
+}
 
 /* dst = src */
-void Mat::copyTo( Mat& dst ) const
+void Mat::copyTo( OutputArray _dst ) const
 {
-    if( data == dst.data && data != 0 )
+    int dtype = _dst.type();
+    if( _dst.fixedType() && dtype != type() )
+    {
+        convertTo( _dst, dtype );
+        return;
+    }
+    
+    if( empty() )
+    {
+        _dst.release();
         return;
+    }
     
-    if( dims > 2 )
+    if( dims <= 2 )
     {
-        dst.create( dims, size, type() );
-        if( total() != 0 )
-        {
-            const Mat* arrays[] = { this, &dst, 0 };
-            Mat planes[2];
-            NAryMatIterator it(arrays, planes);
-            CV_DbgAssert(it.planes[0].isContinuous() &&
-                         it.planes[1].isContinuous());
-            size_t planeSize = it.planes[0].elemSize()*it.planes[0].rows*it.planes[0].cols;
+        _dst.create( rows, cols, type() );
+        Mat dst = _dst.getMat();
+        if( data == dst.data )
+            return;
         
-            for( int i = 0; i < it.nplanes; i++, ++it )
-                memcpy(it.planes[1].data, it.planes[0].data, planeSize);
+        if( rows > 0 && cols > 0 )
+        {
+            const uchar* sptr = data;
+            uchar* dptr = dst.data;
+            
+            Size sz = getContinuousSize(*this, dst, (int)elemSize());            
+            for( ; sz.height--; sptr += step, dptr += dst.step )
+                memcpy( dptr, sptr, sz.width );
         }
         return;
     }
     
-    dst.create( rows, cols, type() );
-    Size sz = size();
+    _dst.create( dims, size, type() );
+    Mat dst = _dst.getMat();
+    if( data == dst.data )
+        return;
     
-    if( rows > 0 && cols > 0 )
+    if( total() != 0 )
     {
-        const uchar* sptr = data;
-        uchar* dptr = dst.data;
-
-        size_t width = sz.width*elemSize();
-        if( isContinuous() && dst.isContinuous() )
-        {
-            width *= sz.height;
-            sz.height = 1;
-        }
-
-        for( ; sz.height--; sptr += step, dptr += dst.step )
-            memcpy( dptr, sptr, width );
+        const Mat* arrays[] = { this, &dst };
+        uchar* ptrs[2];
+        NAryMatIterator it(arrays, ptrs, 2);
+        size_t size = it.size*elemSize();
+    
+        for( size_t i = 0; i < it.nplanes; i++, ++it )
+            memcpy(ptrs[1], ptrs[0], size);
     }
 }
 
-void Mat::copyTo( Mat& dst, const Mat& mask ) const
+void Mat::copyTo( OutputArray _dst, const InputArray& _mask ) const
 {
+    Mat mask = _mask.getMat();
     if( !mask.data )
     {
-        copyTo(dst);
+        copyTo(_dst);
         return;
     }
     
-    if( dims > 2 )
+    CV_Assert( mask.type() == CV_8U );
+    
+    size_t esz = elemSize();
+    BinaryFunc copymask = getCopyMaskFunc(esz);
+    
+    uchar* data0 = _dst.getMat().data;
+    _dst.create( dims, size, type() );
+    Mat dst = _dst.getMat();
+    
+    if( dst.data != data0 ) // do not leave dst uninitialized
+        dst = Scalar(0);
+    
+    if( dims <= 2 )
     {
-        dst.create( dims, size, type() );
-        const Mat* arrays[] = { this, &dst, &mask, 0 };
-        Mat planes[3];
-        NAryMatIterator it(arrays, planes);
-        
-        for( int i = 0; i < it.nplanes; i++, ++it )
-            it.planes[0].copyTo(it.planes[1], it.planes[2]);
+        Size sz = getContinuousSize(*this, dst, mask);
+        copymask(data, step, mask.data, mask.step, dst.data, dst.step, sz, &esz);
         return;
     }
-
-    uchar* data0 = dst.data;
-    dst.create( size(), type() );
-    if( dst.data != data0 ) // do not leave dst uninitialized
-        dst = Scalar(0);
-    getCopyMaskFunc((int)elemSize())(*this, dst, mask);
+    
+    const Mat* arrays[] = { this, &dst, &mask, 0 };
+    uchar* ptrs[3];
+    NAryMatIterator it(arrays, ptrs);
+    Size sz((int)it.size, 1);
+    
+    for( size_t i = 0; i < it.nplanes; i++, ++it )
+        copymask(ptrs[0], 0, ptrs[2], 0, ptrs[1], 0, sz, &esz);
 }
 
 Mat& Mat::operator = (const Scalar& s)
 {
-    if( dims > 2 )
-    {
-        const Mat* arrays[] = { this, 0 };
-        Mat planes[1];
-        NAryMatIterator it(arrays, planes);
-        
-        for( int i = 0; i < it.nplanes; i++, ++it )
-            it.planes[0] = s;
-        return *this;
-    }
-    
-    Size sz = size();
-    uchar* dst = data;
-
-    sz.width *= (int)elemSize();
-    if( isContinuous() )
-    {
-        sz.width *= sz.height;
-        sz.height = 1;
-    }
+    const Mat* arrays[] = { this };
+    uchar* ptr;
+    NAryMatIterator it(arrays, &ptr, 1);
+    size_t size = it.size*elemSize();
     
     if( s[0] == 0 && s[1] == 0 && s[2] == 0 && s[3] == 0 )
     {
-        for( ; sz.height--; dst += step )
-            memset( dst, 0, sz.width );
+        for( size_t i = 0; i < it.nplanes; i++, ++it )
+            memset( ptr, 0, size );
     }
     else
     {
-        int t = type(), esz1 = (int)elemSize1();
-        double scalar[12];
-        scalarToRawData(s, scalar, t, 12);
-        int copy_len = 12*esz1;
-        uchar* dst_limit = dst + sz.width;
-        
-        if( sz.height-- )
+        if( it.nplanes > 0 )
         {
-            while( dst + copy_len <= dst_limit )
+            double scalar[12];
+            scalarToRawData(s, scalar, type(), 12);
+            size_t blockSize = 12*elemSize1();
+            
+            for( size_t j = 0; j < size; j += blockSize )
             {
-                memcpy( dst, scalar, copy_len );
-                dst += copy_len;
+                size_t sz = std::min(blockSize, size - j);
+                memcpy( ptr + j, scalar, sz );
             }
-            memcpy( dst, scalar, dst_limit - dst );
         }
-
-        if( sz.height > 0 )
+        
+        for( size_t i = 1; i < it.nplanes; i++ )
         {
-            dst = dst_limit - sz.width + step;
-            for( ; sz.height--; dst += step )
-                memcpy( dst, data, sz.width );
+            ++it;
+            memcpy( ptr, data, size );
         }
     }
     return *this;
 }
 
-Mat& Mat::setTo(const Scalar& s, const Mat& mask)
+Mat& Mat::setTo(const Scalar& s, const InputArray& _mask)
 {
+    Mat mask = _mask.getMat();
     if( !mask.data )
         *this = s;
     else
     {
-        CV_Assert( channels() <= 4 );
-        SetMaskFunc func = setMaskFuncTab[elemSize()];
-        CV_Assert( func != 0 );
+        CV_Assert( channels() <= 4 && mask.type() == CV_8U );
+        size_t esz = elemSize();
+        BinaryFunc func = esz <= 32 ? setMaskTab[esz] : setMaskGeneric;
         double buf[4];
         scalarToRawData(s, buf, type(), 0);
         
-        if( dims > 2 )
-        {
-            const Mat* arrays[] = { this, &mask, 0 };
-            Mat planes[2];
-            NAryMatIterator it(arrays, planes);
-            
-            for( int i = 0; i < it.nplanes; i++, ++it )
-                func(buf, it.planes[0], it.planes[1]);
-        }
-        else
-            func(buf, *this, mask);
+        const Mat* arrays[] = { this, &mask, 0 };
+        uchar* ptrs[2];
+        NAryMatIterator it(arrays, ptrs);
+        Size sz((int)it.size, 1);
+        
+        for( size_t i = 0; i < it.nplanes; i++, ++it )
+            func((const uchar*)buf, 0, ptrs[1], 0, ptrs[0], 0, sz, &esz);
     }
     return *this;
 }
 
 
-template<typename T> static void
-flipHoriz_( const Mat& srcmat, Mat& dstmat, bool flipv )
+static void
+flipHoriz( const uchar* src, size_t sstep, uchar* dst, size_t dstep, Size size, size_t esz )
 {
-    uchar* dst0 = dstmat.data;
-    size_t srcstep = srcmat.step;
-    int dststep = (int)dstmat.step;
-    Size size = srcmat.size();
-
-    if( flipv )
-    {
-        dst0 += (size.height - 1)*dststep;
-        dststep = -dststep;
-    }
+    int i, j, limit = ((size.width + 1)/2)*esz;
+    AutoBuffer<int> _tab(size.width*esz);
+    int* tab = _tab;
+    
+    for( i = 0; i < size.width; i++ )
+        for( size_t k = 0; k < esz; k++ )
+            tab[i*esz + k] = (size.width - i - 1)*esz + k;
 
-    for( int y = 0; y < size.height; y++ )
+    for( ; size.height--; src += sstep, dst += dstep )
     {
-        const T* src = (const T*)(srcmat.data + srcstep*y);
-        T* dst = (T*)(dst0 + dststep*y);
-
-        for( int i = 0; i < (size.width + 1)/2; i++ )
+        for( i = 0; i < limit; i++ )
         {
-            T t0 = src[i], t1 = src[size.width - i - 1];
-            dst[i] = t1; dst[size.width - i - 1] = t0;
+            j = tab[i];
+            uchar t0 = src[i], t1 = src[j];
+            dst[i] = t1; dst[j] = t0;
         }
     }
 }
 
-typedef void (*FlipHorizFunc)( const Mat& src, Mat& dst, bool flipv );
-
 static void
-flipVert( const Mat& srcmat, Mat& dstmat )
+flipVert( const uchar* src0, size_t sstep, uchar* dst0, size_t dstep, Size size, size_t esz )
 {
-    const uchar* src = srcmat.data;
-    uchar* dst = dstmat.data;
-    size_t srcstep = srcmat.step, dststep = dstmat.step;
-    Size size = srcmat.size();
-    const uchar* src1 = src + (size.height - 1)*srcstep;
-    uchar* dst1 = dst + (size.height - 1)*dststep;
-    size.width *= (int)srcmat.elemSize();
-
-    for( int y = 0; y < (size.height + 1)/2; y++, src += srcstep, src1 -= srcstep,
-                                              dst += dststep, dst1 -= dststep )
+    const uchar* src1 = src0 + (size.height - 1)*sstep;
+    uchar* dst1 = dst0 + (size.height - 1)*dstep;
+    size.width *= (int)esz;
+
+    for( int y = 0; y < (size.height + 1)/2; y++, src0 += sstep, src1 -= sstep,
+                                                  dst0 += dstep, dst1 -= dstep )
     {
         int i = 0;
-        if( ((size_t)(src)|(size_t)(dst)|(size_t)src1|(size_t)dst1) % sizeof(int) == 0 )
+        if( ((size_t)src0|(size_t)dst0|(size_t)src1|(size_t)dst1) % sizeof(int) == 0 )
         {
             for( ; i <= size.width - 16; i += 16 )
             {
-                int t0 = ((int*)(src + i))[0];
+                int t0 = ((int*)(src0 + i))[0];
                 int t1 = ((int*)(src1 + i))[0];
 
-                ((int*)(dst + i))[0] = t1;
+                ((int*)(dst0 + i))[0] = t1;
                 ((int*)(dst1 + i))[0] = t0;
 
-                t0 = ((int*)(src + i))[1];
+                t0 = ((int*)(src0 + i))[1];
                 t1 = ((int*)(src1 + i))[1];
 
-                ((int*)(dst + i))[1] = t1;
+                ((int*)(dst0 + i))[1] = t1;
                 ((int*)(dst1 + i))[1] = t0;
 
-                t0 = ((int*)(src + i))[2];
+                t0 = ((int*)(src0 + i))[2];
                 t1 = ((int*)(src1 + i))[2];
 
-                ((int*)(dst + i))[2] = t1;
+                ((int*)(dst0 + i))[2] = t1;
                 ((int*)(dst1 + i))[2] = t0;
 
-                t0 = ((int*)(src + i))[3];
+                t0 = ((int*)(src0 + i))[3];
                 t1 = ((int*)(src1 + i))[3];
 
-                ((int*)(dst + i))[3] = t1;
+                ((int*)(dst0 + i))[3] = t1;
                 ((int*)(dst1 + i))[3] = t0;
             }
 
             for( ; i <= size.width - 4; i += 4 )
             {
-                int t0 = ((int*)(src + i))[0];
+                int t0 = ((int*)(src0 + i))[0];
                 int t1 = ((int*)(src1 + i))[0];
 
-                ((int*)(dst + i))[0] = t1;
+                ((int*)(dst0 + i))[0] = t1;
                 ((int*)(dst1 + i))[0] = t0;
             }
         }
 
         for( ; i < size.width; i++ )
         {
-            uchar t0 = src[i];
+            uchar t0 = src0[i];
             uchar t1 = src1[i];
 
-            dst[i] = t1;
+            dst0[i] = t1;
             dst1[i] = t0;
         }
     }
 }
 
-void flip( const Mat& src, Mat& dst, int flip_mode )
+void flip( const InputArray& _src, OutputArray _dst, int flip_mode )
 {
-    static FlipHorizFunc tab[] =
-    {
-        0,
-        flipHoriz_<uchar>, // 1
-        flipHoriz_<ushort>, // 2
-        flipHoriz_<Vec<uchar,3> >, // 3
-        flipHoriz_<int>, // 4
-        0,
-        flipHoriz_<Vec<ushort,3> >, // 6
-        0,
-        flipHoriz_<Vec<int,2> >, // 8
-        0, 0, 0,
-        flipHoriz_<Vec<int,3> >, // 12
-        0, 0, 0,
-        flipHoriz_<Vec<int,4> >, // 16
-        0, 0, 0, 0, 0, 0, 0,
-        flipHoriz_<Vec<int,6> >, // 24
-        0, 0, 0, 0, 0, 0, 0,
-        flipHoriz_<Vec<int,8> > // 32
-    };
+    Mat src = _src.getMat();
     
     CV_Assert( src.dims <= 2 );
-    dst.create( src.size(), src.type() );
+    _dst.create( src.size(), src.type() );
+    Mat dst = _dst.getMat();
+    size_t esz = src.elemSize();
 
-    if( flip_mode == 0 )
-        flipVert( src, dst );
+    if( flip_mode <= 0 )
+        flipVert( src.data, src.step, dst.data, dst.step, src.size(), esz );
     else
-    {
-        int esz = (int)src.elemSize();
-        CV_Assert( esz <= 32 );
-        FlipHorizFunc func = tab[esz];
-        CV_Assert( func != 0 );
-
-        if( flip_mode > 0 )
-            func( src, dst, false );
-        else if( src.data != dst.data )
-            func( src, dst, true );
-        else
-        {
-            func( dst, dst, false );
-            flipVert( dst, dst );
-        }
-    }
+        flipHoriz( src.data, src.step, dst.data, dst.step, src.size(), esz );
+    
+    if( flip_mode < 0 )
+        flipHoriz( dst.data, dst.step, dst.data, dst.step, dst.size(), esz );
 }
 
 
-void repeat(const Mat& src, int ny, int nx, Mat& dst)
+void repeat(const InputArray& _src, int ny, int nx, OutputArray _dst)
 {
+    Mat src = _src.getMat();
     CV_Assert( src.dims <= 2 );
     
-    dst.create(src.rows*ny, src.cols*nx, src.type());
+    _dst.create(src.rows*ny, src.cols*nx, src.type());
+    Mat dst = _dst.getMat();
     Size ssize = src.size(), dsize = dst.size();
     int esz = (int)src.elemSize();
     int x, y;
@@ -524,7 +526,7 @@ cvCopy( const void* srcarr, void* dstarr, const void* maskarr )
         {
             CvSparseNode* node_copy = (CvSparseNode*)cvSetNew( dst1->heap );
             int tabidx = node->hashval & (dst1->hashsize - 1);
-            CV_MEMCPY_AUTO( node_copy, node, dst1->heap->elem_size );
+            memcpy( node_copy, node, dst1->heap->elem_size );
             node_copy->next = (CvSparseNode*)dst1->hashtable[tabidx];
             dst1->hashtable[tabidx] = node_copy;
         }
index 535c9a3..330e400 100644 (file)
@@ -1146,7 +1146,7 @@ cvSeqPush( CvSeq *seq, const void *element )
     }
 
     if( element )
-        CV_MEMCPY_AUTO( ptr, element, elem_size );
+        memcpy( ptr, element, elem_size );
     seq->first->prev->count++;
     seq->total++;
     seq->ptr = ptr + elem_size;
@@ -1171,7 +1171,7 @@ cvSeqPop( CvSeq *seq, void *element )
     seq->ptr = ptr = seq->ptr - elem_size;
 
     if( element )
-        CV_MEMCPY_AUTO( element, ptr, elem_size );
+        memcpy( element, ptr, elem_size );
     seq->ptr = ptr;
     seq->total--;
 
@@ -1208,7 +1208,7 @@ cvSeqPushFront( CvSeq *seq, const void *element )
     ptr = block->data -= elem_size;
 
     if( element )
-        CV_MEMCPY_AUTO( ptr, element, elem_size );
+        memcpy( ptr, element, elem_size );
     block->count++;
     block->start_index--;
     seq->total++;
@@ -1233,7 +1233,7 @@ cvSeqPopFront( CvSeq *seq, void *element )
     block = seq->first;
 
     if( element )
-        CV_MEMCPY_AUTO( element, block->data, elem_size );
+        memcpy( element, block->data, elem_size );
     block->data += elem_size;
     block->start_index++;
     seq->total--;
@@ -1708,7 +1708,7 @@ cvSeqRemoveSlice( CvSeq* seq, CvSlice slice )
 
             for( i = 0; i < count; i++ )
             {
-                CV_MEMCPY_AUTO( reader_to.ptr, reader_from.ptr, elem_size );
+                memcpy( reader_to.ptr, reader_from.ptr, elem_size );
                 CV_NEXT_SEQ_ELEM( elem_size, reader_to );
                 CV_NEXT_SEQ_ELEM( elem_size, reader_from );
             }
@@ -1726,7 +1726,7 @@ cvSeqRemoveSlice( CvSeq* seq, CvSlice slice )
                 CV_PREV_SEQ_ELEM( elem_size, reader_to );
                 CV_PREV_SEQ_ELEM( elem_size, reader_from );
 
-                CV_MEMCPY_AUTO( reader_to.ptr, reader_from.ptr, elem_size );
+                memcpy( reader_to.ptr, reader_from.ptr, elem_size );
             }
 
             cvSeqPopMulti( seq, 0, slice.end_index - slice.start_index, 1 );
@@ -1796,7 +1796,7 @@ cvSeqInsertSlice( CvSeq* seq, int index, const CvArr* from_arr )
 
         for( i = 0; i < index; i++ )
         {
-            CV_MEMCPY_AUTO( reader_to.ptr, reader_from.ptr, elem_size );
+            memcpy( reader_to.ptr, reader_from.ptr, elem_size );
             CV_NEXT_SEQ_ELEM( elem_size, reader_to );
             CV_NEXT_SEQ_ELEM( elem_size, reader_from );
         }
@@ -1814,7 +1814,7 @@ cvSeqInsertSlice( CvSeq* seq, int index, const CvArr* from_arr )
         {
             CV_PREV_SEQ_ELEM( elem_size, reader_to );
             CV_PREV_SEQ_ELEM( elem_size, reader_from );
-            CV_MEMCPY_AUTO( reader_to.ptr, reader_from.ptr, elem_size );
+            memcpy( reader_to.ptr, reader_from.ptr, elem_size );
         }
     }
 
@@ -1823,7 +1823,7 @@ cvSeqInsertSlice( CvSeq* seq, int index, const CvArr* from_arr )
 
     for( i = 0; i < from_total; i++ )
     {
-        CV_MEMCPY_AUTO( reader_to.ptr, reader_from.ptr, elem_size );
+        memcpy( reader_to.ptr, reader_from.ptr, elem_size );
         CV_NEXT_SEQ_ELEM( elem_size, reader_to );
         CV_NEXT_SEQ_ELEM( elem_size, reader_from );
     }
@@ -2525,7 +2525,7 @@ cvSetAdd( CvSet* set, CvSetElem* element, CvSetElem** inserted_element )
 
     id = free_elem->flags & CV_SET_ELEM_IDX_MASK;
     if( element )
-        CV_MEMCPY_INT( free_elem, element, (size_t)set->elem_size/sizeof(int) );
+        memcpy( free_elem, element, set->elem_size );
 
     free_elem->flags = id;
     set->active_count++;
@@ -2616,8 +2616,7 @@ cvGraphAddVtx( CvGraph* graph, const CvGraphVtx* _vertex, CvGraphVtx** _inserted
     if( vertex )
     {
         if( _vertex )
-            CV_MEMCPY_INT( vertex + 1, _vertex + 1,
-                (size_t)(graph->elem_size - sizeof(CvGraphVtx))/sizeof(int) );
+            memcpy( vertex + 1, _vertex + 1, graph->elem_size - sizeof(CvGraphVtx) );
         vertex->first = 0;
         index = vertex->flags;
     }
@@ -2784,17 +2783,17 @@ cvGraphAddEdgeByPtr( CvGraph* graph,
     edge->next[1] = end_vtx->first;
     start_vtx->first = end_vtx->first = edge;
 
-    delta = (graph->edges->elem_size - sizeof(*edge))/sizeof(int);
+    delta = graph->edges->elem_size - sizeof(*edge);
     if( _edge )
     {
         if( delta > 0 )
-            CV_MEMCPY_INT( edge + 1, _edge + 1, delta );
+            memcpy( edge + 1, _edge + 1, delta );
         edge->weight = _edge->weight;
     }
     else
     {
         if( delta > 0 )
-            CV_ZERO_INT( edge + 1, delta );
+            memset( edge + 1, 0, delta );
         edge->weight = 1.f;
     }
 
@@ -3548,14 +3547,14 @@ KDTree::KDTree()
     normType = NORM_L2;
 }
 
-KDTree::KDTree(const Mat& _points, bool _copyData)
+KDTree::KDTree(const InputArray& _points, bool _copyData)
 {
     maxDepth = -1;
     normType = NORM_L2;
     build(_points, _copyData);
 }
 
-KDTree::KDTree(const Mat& _points, const Mat& _labels, bool _copyData)
+KDTree::KDTree(const InputArray& _points, const InputArray& _labels, bool _copyData)
 {
     maxDepth = -1;
     normType = NORM_L2;
@@ -3638,14 +3637,15 @@ computeSums( const Mat& points, const size_t* ofs, int a, int b, double* sums )
 }
 
     
-void KDTree::build(const Mat& _points, bool _copyData)
+void KDTree::build(const InputArray& _points, bool _copyData)
 {
-    build(_points, Mat(), _copyData);
+    build(_points, InputArray(), _copyData);
 }
 
 
-void KDTree::build(const Mat& _points, const Mat& _labels, bool _copyData)
+void KDTree::build(const InputArray& __points, const InputArray& __labels, bool _copyData)
 {
+    Mat _points = __points.getMat(), _labels = __labels.getMat();
     CV_Assert(_points.type() == CV_32F && !_points.empty());
     vector<KDTree::Node>().swap(nodes);
 
@@ -3744,57 +3744,6 @@ void KDTree::build(const Mat& _points, const Mat& _labels, bool _copyData)
 }
 
 
-int KDTree::findNearest(const float* vec, int K, int emax,
-                         vector<int>* neighborsIdx,
-                         Mat* neighbors,
-                         vector<float>* dist,
-                         vector<int>* labels) const
-{
-    K = std::min(K, points.rows);
-    CV_Assert(K > 0);
-    if(neighborsIdx)
-        neighborsIdx->resize(K);
-    if(dist)
-        dist->resize(K);
-    if(labels)
-        labels->resize(K);
-    K = findNearest(vec, K, emax, neighborsIdx ? &(*neighborsIdx)[0] : 0,
-                    neighbors, dist ? &(*dist)[0] : 0, labels ? &(*labels)[0] : 0);
-    if(neighborsIdx)
-        neighborsIdx->resize(K);
-    if(dist)
-        dist->resize(K);
-    if(labels)
-        labels->resize(K);
-    return K;
-}
-    
-int KDTree::findNearest(const vector<float>& vec, int K, int emax,
-                        vector<int>* neighborsIdx,
-                        Mat* neighbors,
-                        vector<float>* dist,
-                        vector<int>* labels) const
-{
-    CV_Assert((int)vec.size() == points.cols);
-    K = std::min(K, points.rows);
-    CV_Assert(K > 0);
-    if(neighborsIdx)
-        neighborsIdx->resize(K);
-    if(dist)
-        dist->resize(K);
-    if(labels)
-        labels->resize(K);
-    K = findNearest(&vec[0], K, emax, neighborsIdx ? &(*neighborsIdx)[0] : 0,
-                    neighbors, dist ? &(*dist)[0] : 0, labels ? &(*labels)[0] : 0);
-    if(neighborsIdx)
-        neighborsIdx->resize(K);
-    if(dist)
-        dist->resize(K);
-    if(labels)
-        labels->resize(K);
-    return K;
-}    
-
 struct PQueueElem
 {
     PQueueElem() : dist(0), idx(0) {}
@@ -3804,11 +3753,14 @@ struct PQueueElem
 };
 
 
-int KDTree::findNearest(const float* vec, int K, int emax,
-                        int* _neighborsIdx, Mat* _neighbors,
-                        float* _dist, int* _labels) const
+int KDTree::findNearest(const InputArray& _vec, int K, int emax,
+                        OutputArray _neighborsIdx, OutputArray _neighbors,
+                        OutputArray _dist, OutputArray _labels) const
     
 {
+    Mat vecmat = _vec.getMat();
+    CV_Assert( vecmat.isContinuous() && vecmat.type() == CV_32F && vecmat.total() == (size_t)points.cols );
+    const float* vec = vecmat.ptr<float>();
     K = std::min(K, points.rows);
     int dims = points.cols;
 
@@ -3929,42 +3881,43 @@ int KDTree::findNearest(const float* vec, int K, int emax,
     }
 
     K = std::min(K, ncount);
-    if( _neighborsIdx )
-    {
-        for( i = 0; i < K; i++ )
-            _neighborsIdx[i] = idx[i];
-    }
-    if( _dist )
-    {
-        for( i = 0; i < K; i++ )
-            _dist[i] = std::sqrt(dist[i]);
-    }
-    if( _labels )
+    if( _neighborsIdx.needed() )
     {
-        for( i = 0; i < K; i++ )
-            _labels[i] = labels[idx[i]];
+        _neighborsIdx.create(K, 1, CV_32S, -1, true);
+        Mat nidx = _neighborsIdx.getMat();
+        Mat(nidx.size(), CV_32S, &idx[0]).copyTo(nidx);
     }
+    if( _dist.needed() )
+        sqrt(Mat(K, 1, CV_32F, dist), _dist);
 
-    if( _neighbors )
-        getPoints(idx, K, *_neighbors);
+    if( _neighbors.needed() || _labels.needed() )
+        getPoints(Mat(K, 1, CV_32S, idx), _neighbors, _labels);
     return K;
 }
 
 
-void KDTree::findOrthoRange(const float* L, const float* R,
-                            vector<int>* neighborsIdx,
-                            Mat* neighbors, vector<int>* _labels) const
+void KDTree::findOrthoRange(const InputArray& _lowerBound,
+                            const InputArray& _upperBound,
+                            OutputArray _neighborsIdx,
+                            OutputArray _neighbors,
+                            OutputArray _labels ) const
 {
     int dims = points.cols;
+    Mat lowerBound = _lowerBound.getMat(), upperBound = _upperBound.getMat();
+    CV_Assert( lowerBound.size == upperBound.size &&
+               lowerBound.isContinuous() &&
+               upperBound.isContinuous() &&
+               lowerBound.type() == upperBound.type() &&
+               lowerBound.type() == CV_32F &&
+               lowerBound.total() == (size_t)dims );
+    const float* L = lowerBound.ptr<float>();
+    const float* R = upperBound.ptr<float>();
     
-    CV_Assert( L && R );
-    
-    vector<int> _idx, *idx = neighborsIdx ? neighborsIdx : &_idx;
+    vector<int> idx;
     AutoBuffer<int> _stack(MAX_TREE_DEPTH*2 + 1);
     int* stack = _stack;
     int top = 0;
     
-    idx->clear();
     stack[top++] = 0;
 
     while( --top >= 0 )
@@ -3981,7 +3934,7 @@ void KDTree::findOrthoRange(const float* L, const float* R,
                 if( row[j] < L[j] || row[j] >= R[j] )
                     break;
             if( j == dims )
-                idx->push_back(i);
+                idx.push_back(i);
             continue;
         }
         if( L[n.idx] <= n.boundary )
@@ -3990,55 +3943,57 @@ void KDTree::findOrthoRange(const float* L, const float* R,
             stack[top++] = n.right;
     }
 
-    if( neighbors )
-        getPoints( &(*idx)[0], idx->size(), *neighbors, _labels );
+    if( _neighborsIdx.needed() )
+    {
+        _neighborsIdx.create(idx.size(), 1, CV_32S, -1, true);
+        Mat nidx = _neighborsIdx.getMat();
+        Mat(nidx.size(), CV_32S, &idx[0]).copyTo(nidx);
+    }
+    getPoints( idx, _neighbors, _labels );
 }
 
     
-void KDTree::findOrthoRange(const vector<float>& L, const vector<float>& R,
-                            vector<int>* neighborsIdx, Mat* neighbors, vector<int>* _labels) const
+void KDTree::getPoints(const InputArray& _idx, OutputArray _pts, OutputArray _labels) const
 {
-    size_t dims = points.cols;
-    CV_Assert(L.size() == dims && R.size() == dims);
-    findOrthoRange(&L[0], &R[0], neighborsIdx, neighbors, _labels);
-}
-        
+    Mat idxmat = _idx.getMat(), pts, labelsmat;
+    CV_Assert( idxmat.isContinuous() && idxmat.type() == CV_32S &&
+               (idxmat.cols == 1 || idxmat.rows == 1) );
+    const int* idx = idxmat.ptr<int>();
+    int* dstlabels = 0;
     
-void KDTree::getPoints(const int* idx, size_t nidx, Mat& pts, vector<int>* _labels) const
-{
-    int dims = points.cols, n = (int)nidx;
-    pts.create( n, dims, points.type());
-    if(_labels)
-        _labels->resize(nidx);
-
-    for( int i = 0; i < n; i++ )
+    int dims = points.cols;
+    int i, nidx = (int)idxmat.total();
+    if( nidx == 0 )
     {
-        int k = idx[i];
-        CV_Assert( (unsigned)k < (unsigned)points.rows );
-        const float* src = points.ptr<float>(k);
-        std::copy(src, src + dims, pts.ptr<float>(i));
-        if(_labels)
-            (*_labels)[i] = labels[k];
+        _pts.release();
+        _labels.release();
+        return;
     }
-}
-
-
-void KDTree::getPoints(const vector<int>& idx, Mat& pts, vector<int>* _labels) const
-{
-    int dims = points.cols;
-    int i, nidx = (int)idx.size();
-    pts.create( nidx, dims, points.type());
     
-    if(_labels)
-        _labels->resize(nidx);
+    if( _pts.needed() )
+    {
+        _pts.create( nidx, dims, points.type());
+        pts = _pts.getMat();
+    }
+    
+    if(_labels.needed())
+    {
+        _labels.create(nidx, 1, CV_32S, -1, true);
+        labelsmat = _labels.getMat();
+        CV_Assert( labelsmat.isContinuous() );
+        dstlabels = labelsmat.ptr<int>();
+    }
+    const int* srclabels = !labels.empty() ? &labels[0] : 0;
     
     for( i = 0; i < nidx; i++ )
     {
         int k = idx[i];
         CV_Assert( (unsigned)k < (unsigned)points.rows );
         const float* src = points.ptr<float>(k);
-        std::copy(src, src + dims, pts.ptr<float>(i));
-        if(_labels) (*_labels)[i] = labels[k];
+        if( pts.data )
+            std::copy(src, src + dims, pts.ptr<float>(i));
+        if( dstlabels )
+            dstlabels[i] = srclabels ? srclabels[k] : k;
     }
 }
 
@@ -4047,7 +4002,7 @@ const float* KDTree::getPoint(int ptidx, int* label) const
 {
     CV_Assert( (unsigned)ptidx < (unsigned)points.rows);
     if(label)
-        *label = label[ptidx];
+        *label = labels[ptidx];
     return points.ptr<float>(ptidx);
 }
 
index ada9e7a..d8101fd 100644 (file)
@@ -235,7 +235,7 @@ LineIterator::LineIterator(const Mat& img, Point pt1, Point pt2,
 
 static void
 Line( Mat& img, Point pt1, Point pt2,
-      const void* color, int connectivity = 8 )
+      const void* _color, int connectivity = 8 )
 {
     if( connectivity == 0 )
         connectivity = 8;
@@ -245,10 +245,21 @@ Line( Mat& img, Point pt1, Point pt2,
     LineIterator iterator(img, pt1, pt2, connectivity, true);
     int i, count = iterator.count;
     int pix_size = (int)img.elemSize();
+    const uchar* color = (const uchar*)_color;
 
     for( i = 0; i < count; i++, ++iterator )
     {
-        CV_MEMCPY_AUTO( *iterator, color, pix_size );
+        uchar* ptr = *iterator;
+        if( pix_size == 1 )
+            ptr[0] = color[0];
+        else if( pix_size == 3 )
+        {
+            ptr[0] = color[0];
+            ptr[1] = color[1];
+            ptr[2] = color[2];
+        }
+        else
+            memcpy( *iterator, color, pix_size );
     }
 }
 
@@ -1317,7 +1328,7 @@ Circle( Mat& img, Point center, int radius, const void* color, int fill )
         center.y >= radius && center.y < size.height - radius;
 
     #define ICV_PUT_POINT( ptr, x )     \
-        CV_MEMCPY_CHAR( ptr + (x)*pix_size, color, pix_size );
+        memcpy( ptr + (x)*pix_size, color, pix_size );
 
     while( dx >= dy )
     {
index 470b2bc..cb7e4b8 100644 (file)
@@ -1449,27 +1449,25 @@ static void CCSIDFT_64f( const double* src, double* dst, int n, int nf, int* fac
     CCSIDFT( src, dst, n, nf, factors, itab, wave, tab_size, spec, buf, flags, scale);
 }
     
+}
+    
 
-void dft( const Mat& src0, Mat& dst, int flags, int nonzero_rows )
+void cv::dft( const InputArray& _src0, OutputArray _dst, int flags, int nonzero_rows )
 {
-    static DFTFunc dft_tbl[6];
-    static int inittab = 0;
-
-    if( !inittab )
+    static DFTFunc dft_tbl[6] =
     {
-        dft_tbl[0] = (DFTFunc)DFT_32f;
-        dft_tbl[1] = (DFTFunc)RealDFT_32f;
-        dft_tbl[2] = (DFTFunc)CCSIDFT_32f;
-        dft_tbl[3] = (DFTFunc)DFT_64f;
-        dft_tbl[4] = (DFTFunc)RealDFT_64f;
-        dft_tbl[5] = (DFTFunc)CCSIDFT_64f;
-        inittab = 1;
-    }
+        (DFTFunc)DFT_32f,
+        (DFTFunc)RealDFT_32f,
+        (DFTFunc)CCSIDFT_32f,
+        (DFTFunc)DFT_64f,
+        (DFTFunc)RealDFT_64f,
+        (DFTFunc)CCSIDFT_64f
+    };
 
     AutoBuffer<uchar> buf;
     void *spec = 0;
     
-    Mat src = src0;
+    Mat src0 = _src0.getMat(), src = src0;
     int prev_len = 0, stage = 0;
     bool inv = (flags & DFT_INVERSE) != 0;
     int nf = 0, real_transform = src.channels() == 1 || (inv && (flags & DFT_REAL_OUTPUT)!=0);
@@ -1485,11 +1483,13 @@ void dft( const Mat& src0, Mat& dst, int flags, int nonzero_rows )
     CV_Assert( type == CV_32FC1 || type == CV_32FC2 || type == CV_64FC1 || type == CV_64FC2 );
 
     if( !inv && src.channels() == 1 && (flags & DFT_COMPLEX_OUTPUT) )
-        dst.create( src.size(), CV_MAKETYPE(depth, 2) );
+        _dst.create( src.size(), CV_MAKETYPE(depth, 2) );
     else if( inv && src.channels() == 2 && (flags & DFT_REAL_OUTPUT) )
-        dst.create( src.size(), depth );
+        _dst.create( src.size(), depth );
     else
-        dst.create( src.size(), type );
+        _dst.create( src.size(), type );
+    
+    Mat dst = _dst.getMat();
 
     if( !real_transform )
         elem_size = complex_elem_size;
@@ -1840,14 +1840,15 @@ void dft( const Mat& src0, Mat& dst, int flags, int nonzero_rows )
 }
 
 
-void idft( const Mat& src, Mat& dst, int flags, int nonzero_rows )
+void cv::idft( const InputArray& src, OutputArray dst, int flags, int nonzero_rows )
 {
     dft( src, dst, flags | DFT_INVERSE, nonzero_rows );
 }
 
-void mulSpectrums( const Mat& srcA, const Mat& srcB,
-                   Mat& dst, int flags, bool conjB )
+void cv::mulSpectrums( const InputArray& _srcA, const InputArray& _srcB,
+                       OutputArray _dst, int flags, bool conjB )
 {
+    Mat srcA = _srcA.getMat(), srcB = _srcB.getMat();
     int depth = srcA.depth(), cn = srcA.channels(), type = srcA.type();
     int rows = srcA.rows, cols = srcA.cols;
     int j, k;
@@ -1855,7 +1856,8 @@ void mulSpectrums( const Mat& srcA, const Mat& srcB,
     CV_Assert( type == srcB.type() && srcA.size() == srcB.size() );
     CV_Assert( type == CV_32FC1 || type == CV_32FC2 || type == CV_64FC1 || type == CV_64FC2 );
 
-    dst.create( srcA.rows, srcA.cols, type );
+    _dst.create( srcA.rows, srcA.cols, type );
+    Mat dst = _dst.getMat();
     
     bool is_1d = (flags & DFT_ROWS) || (rows == 1 || (cols == 1 &&
              srcA.isContinuous() && srcB.isContinuous() && dst.isContinuous()));
@@ -2008,6 +2010,9 @@ void mulSpectrums( const Mat& srcA, const Mat& srcB,
                                Discrete Cosine Transform
 \****************************************************************************************/
 
+namespace cv
+{
+
 /* DCT is calculated using DFT, as described here:
    http://www.ece.utexas.edu/~bevans/courses/ee381k/lectures/09_DCT/lecture9/:
 */
@@ -2210,23 +2215,21 @@ static void IDCT_64f(const double* src, int src_step, double* dft_src, double* d
     IDCT(src, src_step, dft_src, dft_dst, dst, dst_step,
          n, nf, factors, itab, dft_wave, dct_wave, spec, buf);
 }    
+
+}
     
-void dct( const Mat& src0, Mat& dst, int flags )
+void cv::dct( const InputArray& _src0, OutputArray _dst, int flags )
 {
-    static DCTFunc dct_tbl[4];
-    static int inittab = 0;
-    
-    if( !inittab )
+    static DCTFunc dct_tbl[4] =
     {
-        dct_tbl[0] = (DCTFunc)DCT_32f;
-        dct_tbl[1] = (DCTFunc)IDCT_32f;
-        dct_tbl[2] = (DCTFunc)DCT_64f;
-        dct_tbl[3] = (DCTFunc)IDCT_64f;
-        inittab = 1;
-    }
+        (DCTFunc)DCT_32f,
+        (DCTFunc)IDCT_32f,
+        (DCTFunc)DCT_64f,
+        (DCTFunc)IDCT_64f
+    };
 
     bool inv = (flags & DCT_INVERSE) != 0;
-    Mat src = src0;
+    Mat src0 = _src0.getMat(), src = src0;
     int type = src.type(), depth = src.depth();
     void /* *spec_dft = 0, */ *spec = 0;
 
@@ -2242,7 +2245,8 @@ void dct( const Mat& src0, Mat& dst, int flags )
     AutoBuffer<uchar> buf;
 
     CV_Assert( type == CV_32FC1 || type == CV_64FC1 );
-    dst.create( src.rows, src.cols, type );
+    _dst.create( src.rows, src.cols, type );
+    Mat dst = _dst.getMat();
 
     DCTFunc dct_func = dct_tbl[inv + (depth == CV_64F)*2];
 
@@ -2369,11 +2373,14 @@ void dct( const Mat& src0, Mat& dst, int flags )
 }
 
 
-void idct( const Mat& src, Mat& dst, int flags )
+void cv::idct( const InputArray& src, OutputArray dst, int flags )
 {
     dct( src, dst, flags | DCT_INVERSE );
 }
 
+namespace cv
+{
+
 static const int optimalDFTSizeTab[] = {
 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, 36, 40, 45, 48, 
 50, 54, 60, 64, 72, 75, 80, 81, 90, 96, 100, 108, 120, 125, 128, 135, 144, 150, 160, 
@@ -2555,8 +2562,9 @@ static const int optimalDFTSizeTab[] = {
 2097152000, 2099520000, 2109375000, 2123366400, 2125764000
 };
 
-int
-getOptimalDFTSize( int size0 )
+}
+    
+int cv::getOptimalDFTSize( int size0 )
 {
     int a = 0, b = sizeof(optimalDFTSizeTab)/sizeof(optimalDFTSizeTab[0]) - 1;
     if( (unsigned)size0 >= (unsigned)optimalDFTSizeTab[b] )
@@ -2574,8 +2582,6 @@ getOptimalDFTSize( int size0 )
     return optimalDFTSizeTab[b];
 }
 
-}
-
 CV_IMPL void
 cvDFT( const CvArr* srcarr, CvArr* dstarr, int flags, int nonzero_rows )
 {
index 6df9454..97f78b9 100644 (file)
@@ -212,6 +212,8 @@ bool Cholesky(double* A, int m, double* b, int n)
 {
     return CholImpl(A, m, b, n);
 }
+
+}
     
 /****************************************************************************************\
 *                                 Determinant of the matrix                              *
@@ -222,8 +224,9 @@ bool Cholesky(double* A, int m, double* b, int n)
                    m(0,1)*((double)m(1,0)*m(2,2) - (double)m(1,2)*m(2,0)) +  \
                    m(0,2)*((double)m(1,0)*m(2,1) - (double)m(1,1)*m(2,0)))
 
-double determinant( const Mat& mat )
+double cv::determinant( const InputArray& _mat )
 {
+    Mat mat = _mat.getMat();
     double result = 0;
     int type = mat.type(), rows = mat.rows;
     size_t step = mat.step;
@@ -325,13 +328,16 @@ double determinant( const Mat& mat )
 #define Df( y, x ) ((float*)(dstdata + y*dststep))[x]
 #define Dd( y, x ) ((double*)(dstdata + y*dststep))[x]
 
-double invert( const Mat& src, Mat& dst, int method )
+double cv::invert( const InputArray& _src, OutputArray _dst, int method )
 {
     double result = 0;
+    Mat src = _src.getMat();
     int type = src.type();
 
     CV_Assert( method == DECOMP_LU || method == DECOMP_CHOLESKY || method == DECOMP_SVD );
-
+    _dst.create( src.cols, src.rows, type );
+    Mat dst = _dst.getMat();
+    
     if( method == DECOMP_SVD )
     {
         int n = std::min(src.rows, src.cols);
@@ -346,8 +352,7 @@ double invert( const Mat& src, Mat& dst, int method )
     }
 
     CV_Assert( src.rows == src.cols && (type == CV_32F || type == CV_64F));
-    dst.create( src.rows, src.cols, type );
-
+    
     if( src.rows <= 3 )
     {
         uchar* srcdata = src.data;
@@ -572,9 +577,10 @@ double invert( const Mat& src, Mat& dst, int method )
 *                              Solving a linear system                                   *
 \****************************************************************************************/
 
-bool solve( const Mat& src, const Mat& _src2, Mat& dst, int method )
+bool cv::solve( const InputArray& _src, const InputArray& _src2arg, OutputArray _dst, int method )
 {
     bool result = true;
+    Mat src = _src.getMat(), _src2 = _src2arg.getMat();
     int type = src.type();
     bool is_normal = (method & DECOMP_NORMAL) != 0;
 
@@ -588,7 +594,8 @@ bool solve( const Mat& src, const Mat& _src2, Mat& dst, int method )
     if( (method == DECOMP_LU || method == DECOMP_CHOLESKY) &&
         src.rows <= 3 && src.rows == src.cols && _src2.cols == 1 )
     {
-        dst.create( src.cols, _src2.cols, src.type() );
+        _dst.create( src.cols, _src2.cols, src.type() );
+        Mat dst = _dst.getMat();
         
         #define bf(y) ((float*)(bdata + y*src2step))[0]
         #define bd(y) ((double*)(bdata + y*src2step))[0]
@@ -729,7 +736,8 @@ bool solve( const Mat& src, const Mat& _src2, Mat& dst, int method )
     char N[] = {'N', '\0'}, L[] = {'L', '\0'};
 
     Mat src2 = _src2;
-    dst.create( src.cols, src2.cols, src.type() );
+    _dst.create( src.cols, src2.cols, src.type() );
+    Mat dst = _dst.getMat();
         
     if( m <= n )
         is_normal = false;
@@ -905,6 +913,9 @@ bool solve( const Mat& src, const Mat& _src2, Mat& dst, int method )
 
 /////////////////// finding eigenvalues and eigenvectors of a symmetric matrix ///////////////
 
+namespace cv
+{
+
 template<typename Real> static inline Real hypot(Real a, Real b)
 {
     a = std::abs(a);
@@ -1077,9 +1088,10 @@ template<typename Real> bool jacobi(const Mat& _S0, Mat& _e, Mat& matE, bool com
 }
     
     
-static bool eigen( const Mat& src, Mat& evals, Mat& evects, bool computeEvects,
+static bool eigen( const InputArray& _src, OutputArray _evals, OutputArray _evects, bool computeEvects,
                    int lowindex, int highindex )
 {
+    Mat src = _src.getMat();
     int type = src.type();
     integer n = src.rows;
 
@@ -1094,9 +1106,14 @@ static bool eigen( const Mat& src, Mat& evals, Mat& evects, bool computeEvects,
     CV_Assert( src.rows == src.cols );
     CV_Assert (type == CV_32F || type == CV_64F);
 
-    // allow for 1xn eigenvalue matrix too
-    if( !(evals.rows == 1 && evals.cols == n && evals.type() == type) )
-        evals.create(n, 1, type);
+    _evals.create(n, 1, type, -1, true);
+    Mat evals = _evals.getMat(), evects;
+    
+    if( computeEvects )
+    {
+        _evects.create(n, n, type);
+        evects = _evects.getMat();
+    }
     
     if( n <= 20 )
     {
@@ -1122,10 +1139,7 @@ static bool eigen( const Mat& src, Mat& evals, Mat& evects, bool computeEvects,
     lda = (int)(src.step/elem_size);
     
     if( computeEvects )
-    {
-        evects.create(n, n, type);
         ldv = (int)(evects.step/elem_size);
-    }
 
     bool copy_evals = !evals.isContinuous();
 
@@ -1211,19 +1225,21 @@ static bool eigen( const Mat& src, Mat& evals, Mat& evects, bool computeEvects,
     return result;
 }
 
-bool eigen( const Mat& src, Mat& evals, int lowindex, int highindex )
+}
+    
+bool cv::eigen( const InputArray& src, OutputArray evals, int lowindex, int highindex )
 {
-    Mat evects;
-    return eigen(src, evals, evects, false, lowindex, highindex);
+    return eigen(src, evals, OutputArray(), false, lowindex, highindex);
 }
 
-bool eigen( const Mat& src, Mat& evals, Mat& evects, int lowindex,
-            int highindex )
+bool cv::eigen( const InputArray& src, OutputArray evals, OutputArray evects,
+                int lowindex, int highindex )
 {
     return eigen(src, evals, evects, true, lowindex, highindex);
 }
 
-
+namespace cv
+{
 
 /* y[0:m,0:n] += diag(a[0:1,0:m]) * x[0:m,0:n] */
 template<typename T1, typename T2, typename T3> static void
@@ -1316,29 +1332,33 @@ SVBkSb( int m, int n, const T* w, int incw,
 }
 
 
-static void _SVDcompute( const Mat& a, Mat& w, Mat* u, Mat* vt, int flags )
+static void _SVDcompute( const InputArray& _aarr, OutputArray _w,
+                         OutputArray _u, OutputArray _vt, int flags )
 {
+    Mat a = _aarr.getMat(), u, vt;
     integer m = a.rows, n = a.cols, mn = std::max(m, n), nm = std::min(m, n);
     int type = a.type(), elem_size = (int)a.elemSize();
-    bool compute_uv = u && vt;
+    bool compute_uv = _u.needed() || _vt.needed();
     
     if( flags & SVD::NO_UV )
     {
-        if(u) u->release();
-        if(vt) vt->release();
-        u = vt = 0;
+        _u.release();
+        _vt.release();
         compute_uv = false;
     }
     
     if( compute_uv )
     {
-        u->create( (int)m, (int)((flags & SVD::FULL_UV) ? m : nm), type );
-        vt->create( (int)((flags & SVD::FULL_UV) ? n : nm), n, type );
+        _u.create( (int)m, (int)((flags & SVD::FULL_UV) ? m : nm), type );
+        _vt.create( (int)((flags & SVD::FULL_UV) ? n : nm), n, type );
+        u = _u.getMat();
+        vt = _vt.getMat();
     }
     
-    w.create(nm, 1, type);
+    _w.create(nm, 1, type, -1, true);
     
-    Mat _a = a;
+    Mat _a = a, w = _w.getMat();
+    CV_Assert( w.isContinuous() );
     int a_ofs = 0, work_ofs=0, iwork_ofs=0, buf_size = 0;
     bool temp_a = false;
     double u1=0, v1=0, work1=0;
@@ -1353,7 +1373,7 @@ static void _SVDcompute( const Mat& a, Mat& w, Mat* u, Mat* vt, int flags )
     {
         if( mode[0] == 'N' || mode[0] == 'A' )
             temp_a = true;
-        else if( compute_uv && (a.size() == vt->size() || a.size() == u->size()) && mode[0] == 'S' )
+        else if( compute_uv && (a.size() == vt.size() || a.size() == u.size()) && mode[0] == 'S' )
             mode[0] = 'O';
     }
     
@@ -1396,59 +1416,67 @@ static void _SVDcompute( const Mat& a, Mat& w, Mat* u, Mat* vt, int flags )
     
     if( !(flags & SVD::MODIFY_A) && !temp_a )
     {
-        if( compute_uv && a.size() == vt->size() )
+        if( compute_uv && a.size() == vt.size() )
         {
-            a.copyTo(*vt);
-            _a = *vt;
+            a.copyTo(vt);
+            _a = vt;
         }
-        else if( compute_uv && a.size() == u->size() )
+        else if( compute_uv && a.size() == u.size() )
         {
-            a.copyTo(*u);
-            _a = *u;
+            a.copyTo(u);
+            _a = u;
         }
     }
     
     if( compute_uv )
     {
-        ldv = (int)(vt->step ? vt->step/elem_size : vt->cols);
-        ldu = (int)(u->step ? u->step/elem_size : u->cols);
+        ldv = (int)(vt.step ? vt.step/elem_size : vt.cols);
+        ldu = (int)(u.step ? u.step/elem_size : u.cols);
     }
     
     lda = (int)(_a.step ? _a.step/elem_size : _a.cols);
     if( type == CV_32F )
     {
-        sgesdd_(mode, &n, &m, (float*)_a.data, &lda, (float*)w.data,
-                vt ? (float*)vt->data : (float*)&v1, &ldv, u ? (float*)u->data : (float*)&u1, &ldu,
-                (float*)(buffer + work_ofs), &lwork, (integer*)(buffer + iwork_ofs), &info );
+        sgesdd_(mode, &n, &m, _a.ptr<float>(), &lda, w.ptr<float>(),
+                vt.data ? vt.ptr<float>() : (float*)&v1, &ldv,
+                u.data ? u.ptr<float>() : (float*)&u1, &ldu,
+                (float*)(buffer + work_ofs), &lwork,
+                (integer*)(buffer + iwork_ofs), &info );
     }
     else
     {
-        dgesdd_(mode, &n, &m, (double*)_a.data, &lda, (double*)w.data,
-                vt ? (double*)vt->data : &v1, &ldv, u ? (double*)u->data : &u1, &ldu,
-                (double*)(buffer + work_ofs), &lwork, (integer*)(buffer + iwork_ofs), &info );
+        dgesdd_(mode, &n, &m, _a.ptr<double>(), &lda, w.ptr<double>(),
+                vt.data ? vt.ptr<double>() : &v1, &ldv,
+                u.data ? u.ptr<double>() : &u1, &ldu,
+                (double*)(buffer + work_ofs), &lwork,
+                (integer*)(buffer + iwork_ofs), &info );
     }
     CV_Assert(info >= 0);
     if(info != 0)
     {
-        *u = Scalar(0.);
-        *vt = Scalar(0.);
+        if( u.data )
+            u = Scalar(0.);
+        if( vt.data )
+            vt = Scalar(0.);
         w = Scalar(0.);
     }
 }       
     
     
-void SVD::compute( const Mat& a, Mat& w, Mat& u, Mat& vt, int flags )
+void SVD::compute( const InputArray& a, OutputArray w, OutputArray u, OutputArray vt, int flags )
 {
-    _SVDcompute(a, w, &u, &vt, flags);
+    _SVDcompute(a, w, u, vt, flags);
 }
 
-void SVD::compute( const Mat& a, Mat& w, int flags )
+void SVD::compute( const InputArray& a, OutputArray w, int flags )
 {
-    _SVDcompute(a, w, 0, 0, flags);
+    _SVDcompute(a, w, OutputArray(), OutputArray(), flags);
 }
     
-void SVD::backSubst( const Mat& w, const Mat& u, const Mat& vt, const Mat& rhs, Mat& dst )
+void SVD::backSubst( const InputArray& _w, const InputArray& _u, const InputArray& _vt,
+                     const InputArray& _rhs, OutputArray _dst )
 {
+    Mat w = _w.getMat(), u = _u.getMat(), vt = _vt.getMat(), rhs = _rhs.getMat();
     int type = w.type(), esz = (int)w.elemSize();
     int m = u.rows, n = vt.cols, nb = rhs.data ? rhs.cols : m;
     AutoBuffer<double> buffer(nb);
@@ -1456,7 +1484,8 @@ void SVD::backSubst( const Mat& w, const Mat& u, const Mat& vt, const Mat& rhs,
     
     CV_Assert( rhs.data == 0 || (rhs.type() == type && rhs.rows == m) );
     
-    dst.create( n, nb, type );
+    _dst.create( n, nb, type );
+    Mat dst = _dst.getMat();
     if( type == CV_32F )
         SVBkSb(m, n, (float*)w.data, 1, (float*)u.data, (int)(u.step/esz), false,
                (float*)vt.data, (int)(vt.step/esz), true, (float*)rhs.data, (int)(rhs.step/esz),
@@ -1470,14 +1499,14 @@ void SVD::backSubst( const Mat& w, const Mat& u, const Mat& vt, const Mat& rhs,
 }
 
     
-SVD& SVD::operator ()(const Mat& a, int flags)
+SVD& SVD::operator ()(const InputArray& a, int flags)
 {
-    _SVDcompute(a, w, &u, &vt, flags);
+    _SVDcompute(a, w, u, vt, flags);
     return *this;
 }
 
 
-void SVD::backSubst( const Mat& rhs, Mat& dst ) const
+void SVD::backSubst( const InputArray& rhs, OutputArray dst ) const
 {
     backSubst( w, u, vt, rhs, dst );
 }
index 7bd55f4..f28bb0c 100644 (file)
@@ -11,7 +11,7 @@
 //                For Open Source Computer Vision Library
 //
 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
-// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
 // Third party copyrights are property of their respective owners.
 //
 // Redistribution and use in source and binary forms, with or without modification,
@@ -47,7 +47,7 @@ namespace cv
 {
 
 static const int MAX_BLOCK_SIZE = 1024;
-typedef CvStatus (CV_STDCALL * MathFunc)(const void* src, void* dst, int len);
+typedef void (*MathFunc)(const void* src, void* dst, int len);
 
 float fastAtan2( float y, float x )
 {
@@ -61,16 +61,13 @@ float fastAtan2( float y, float x )
        return (float)(y >= 0 ? 90 - a : 270 - a);
 }
 
-static CvStatus CV_STDCALL FastAtan2_32f(const float *Y, const float *X, float *angle, int len, bool angleInDegrees=true )
+static void FastAtan2_32f(const float *Y, const float *X, float *angle, int len, bool angleInDegrees=true )
 {
-    if( !Y || !X || !angle || len < 0 )
-        return CV_BADFACTOR_ERR;
-       
        int i = 0;
        float scale = angleInDegrees ? (float)(180/CV_PI) : 1.f;
 
 #if CV_SSE2
-    if( checkHardwareSupport(CV_CPU_SSE) )
+    if( USE_SSE2 )
     {
         Cv32suf iabsmask; iabsmask.i = 0x7fffffff;
         __m128 eps = _mm_set1_ps((float)DBL_EPSILON), absmask = _mm_set1_ps(iabsmask.f);
@@ -120,8 +117,6 @@ static CvStatus CV_STDCALL FastAtan2_32f(const float *Y, const float *X, float *
         }
         angle[i] = a*scale;
        }
-
-    return CV_OK;
 }
 
 
@@ -166,13 +161,12 @@ float  cubeRoot( float value )
     return v.f;
 }
 
-static CvStatus CV_STDCALL
-Magnitude_32f(const float* x, const float* y, float* mag, int len)
+static void Magnitude_32f(const float* x, const float* y, float* mag, int len)
 {
     int i = 0;
     
 #if CV_SSE
-    if( checkHardwareSupport(CV_CPU_SSE) )
+    if( USE_SSE2 )
     {
         for( ; i <= len - 8; i += 8 )
         {
@@ -191,17 +185,14 @@ Magnitude_32f(const float* x, const float* y, float* mag, int len)
         float x0 = x[i], y0 = y[i];
         mag[i] = std::sqrt(x0*x0 + y0*y0);
     }
-
-    return CV_OK;
 }
 
-static CvStatus CV_STDCALL
-Magnitude_64f(const double* x, const double* y, double* mag, int len)
+static void Magnitude_64f(const double* x, const double* y, double* mag, int len)
 {
     int i = 0;
     
 #if CV_SSE2   
-    if( checkHardwareSupport(CV_CPU_SSE2) )
+    if( USE_SSE2 )
     {
         for( ; i <= len - 4; i += 4 )
         {
@@ -220,17 +211,15 @@ Magnitude_64f(const double* x, const double* y, double* mag, int len)
         double x0 = x[i], y0 = y[i];
         mag[i] = std::sqrt(x0*x0 + y0*y0);
     }
-    
-    return CV_OK;
 }
 
     
-static CvStatus CV_STDCALL InvSqrt_32f(const float* src, float* dst, int len)
+static void InvSqrt_32f(const float* src, float* dst, int len)
 {
     int i = 0;
     
 #if CV_SSE   
-    if( checkHardwareSupport(CV_CPU_SSE) )
+    if( USE_SSE2 )
     {    
         __m128 _0_5 = _mm_set1_ps(0.5f), _1_5 = _mm_set1_ps(1.5f);
         if( (((size_t)src|(size_t)dst) & 15) == 0 )
@@ -258,24 +247,22 @@ static CvStatus CV_STDCALL InvSqrt_32f(const float* src, float* dst, int len)
     
     for( ; i < len; i++ )
         dst[i] = 1/std::sqrt(src[i]);
-    return CV_OK;
 }
 
     
-static CvStatus CV_STDCALL InvSqrt_64f(const double* src, double* dst, int len)
+static void InvSqrt_64f(const double* src, double* dst, int len)
 {
     for( int i = 0; i < len; i++ )
         dst[i] = 1/std::sqrt(src[i]);
-    return CV_OK;
 }    
     
     
-static CvStatus CV_STDCALL Sqrt_32f(const float* src, float* dst, int len)
+static void Sqrt_32f(const float* src, float* dst, int len)
 {
     int i = 0;
     
 #if CV_SSE    
-    if( checkHardwareSupport(CV_CPU_SSE) )
+    if( USE_SSE2 )
     {
         if( (((size_t)src|(size_t)dst) & 15) == 0 )
             for( ; i <= len - 8; i += 8 )
@@ -296,17 +283,15 @@ static CvStatus CV_STDCALL Sqrt_32f(const float* src, float* dst, int len)
     
     for( ; i < len; i++ )
         dst[i] = std::sqrt(src[i]);
-    
-    return CV_OK;
 }
 
     
-static CvStatus CV_STDCALL Sqrt_64f(const double* src, double* dst, int len)
+static void Sqrt_64f(const double* src, double* dst, int len)
 {
     int i = 0;
     
 #if CV_SSE2    
-    if( checkHardwareSupport(CV_CPU_SSE2) )
+    if( USE_SSE2 )
     {
         if( (((size_t)src|(size_t)dst) & 15) == 0 )
             for( ; i <= len - 4; i += 4 )
@@ -327,7 +312,6 @@ static CvStatus CV_STDCALL Sqrt_64f(const double* src, double* dst, int len)
     
     for( ; i < len; i++ )
         dst[i] = std::sqrt(src[i]);
-    return CV_OK;
 }
 
 
@@ -335,172 +319,151 @@ static CvStatus CV_STDCALL Sqrt_64f(const double* src, double* dst, int len)
 *                                  Cartezian -> Polar                                    *
 \****************************************************************************************/
 
-void magnitude( const Mat& X, const Mat& Y, Mat& Mag )
+void magnitude( const InputArray& src1, const InputArray& src2, OutputArray dst )
 {
-       if( X.dims > 2 )
-    {
-        Mag.create(X.dims, X.size, X.type());
-        const Mat* arrays[] = {&X, &Y, &Mag, 0};
-        Mat planes[3];
-        NAryMatIterator it(arrays, planes);
-        
-        for( int i = 0; i < it.nplanes; i++, ++it )
-            magnitude( it.planes[0], it.planes[1], it.planes[2] );
-        return;
-    }
-    
+    Mat X = src1.getMat(), Y = src2.getMat();
     int type = X.type(), depth = X.depth(), cn = X.channels();
-       CV_Assert( X.size() == Y.size() && type == Y.type() && (depth == CV_32F || depth == CV_64F));
-    Mag.create( X.size(), type );
-
-    Size size = getContinuousSize( X, Y, Mag, cn );
-
-    if( depth == CV_32F )
-    {
-        const float *x = (const float*)X.data, *y = (const float*)Y.data;
-        float *mag = (float*)Mag.data;
-        size_t xstep = X.step/sizeof(x[0]), ystep = Y.step/sizeof(y[0]);
-        size_t mstep = Mag.step/sizeof(mag[0]);
-
-        for( ; size.height--; x += xstep, y += ystep, mag += mstep )
-            Magnitude_32f( x, y, mag, size.width );
-    }
-    else
+       CV_Assert( X.size == Y.size && type == Y.type() && (depth == CV_32F || depth == CV_64F));
+    dst.create(X.dims, X.size, X.type());
+    Mat Mag = dst.getMat();
+    
+    const Mat* arrays[] = {&X, &Y, &Mag, 0};
+    uchar* ptrs[3];
+    NAryMatIterator it(arrays, ptrs);
+    int len = (int)it.size*cn;
+        
+    for( size_t i = 0; i < it.nplanes; i++, ++it )
     {
-        const double *x = (const double*)X.data, *y = (const double*)Y.data;
-        double *mag = (double*)Mag.data;
-        size_t xstep = X.step/sizeof(x[0]), ystep = Y.step/sizeof(y[0]);
-        size_t mstep = Mag.step/sizeof(mag[0]);
-
-        for( ; size.height--; x += xstep, y += ystep, mag += mstep )
-            Magnitude_64f( x, y, mag, size.width );
+        if( depth == CV_32F )
+        {
+            const float *x = (const float*)ptrs[0], *y = (const float*)ptrs[1];
+            float *mag = (float*)ptrs[2];
+            Magnitude_32f( x, y, mag, len );
+        }
+        else
+        {
+            const double *x = (const double*)ptrs[0], *y = (const double*)ptrs[1];
+            double *mag = (double*)ptrs[2];
+            Magnitude_64f( x, y, mag, len );
+        }
     }
 }
 
-void phase( const Mat& X, const Mat& Y, Mat& Angle, bool angleInDegrees )
+    
+void phase( const InputArray& src1, const InputArray& src2, OutputArray dst, bool angleInDegrees )
 {
-    if( X.dims > 2 )
-    {
-        Angle.create(X.dims, X.size, X.type());
-        const Mat* arrays[] = {&X, &Y, &Angle, 0};
-        Mat planes[3];
-        NAryMatIterator it(arrays, planes);
-        
-        for( int i = 0; i < it.nplanes; i++, ++it )
-            phase( it.planes[0], it.planes[1], it.planes[2], angleInDegrees );
-        return;
-    }
+    Mat X = src1.getMat(), Y = src2.getMat();
+    int type = X.type(), depth = X.depth(), cn = X.channels();
+    CV_Assert( X.size == Y.size && type == Y.type() && (depth == CV_32F || depth == CV_64F));
+    dst.create( X.dims, X.size, type );
+    Mat Angle = dst.getMat();
     
-    float buf[2][MAX_BLOCK_SIZE];
-    int i, j, type = X.type(), depth = X.depth(), cn = X.channels();
-
-    CV_Assert( X.size() == Y.size() && type == Y.type() && (depth == CV_32F || depth == CV_64F));
-    Angle.create( X.size(), type );
-
-    Size size = getContinuousSize( X, Y, Angle, cn );
-
-    if( depth == CV_32F )
+    const Mat* arrays[] = {&X, &Y, &Angle, 0};
+    uchar* ptrs[3];
+    NAryMatIterator it(arrays, ptrs);
+    cv::AutoBuffer<float> _buf;
+    float* buf[2] = {0, 0};
+    int j, k, total = (int)(it.size*cn), blockSize = total;
+    size_t esz1 = X.elemSize1();
+    
+    if( depth == CV_64F )
     {
-        const float *x = (const float*)X.data, *y = (const float*)Y.data;
-        float *angle = (float*)Angle.data;
-        size_t xstep = X.step/sizeof(x[0]), ystep = Y.step/sizeof(y[0]);
-        size_t astep = Angle.step/sizeof(angle[0]);
-
-        for( ; size.height--; x += xstep, y += ystep, angle += astep )
-            FastAtan2_32f( y, x, angle, size.width, angleInDegrees );
+        blockSize = std::min(blockSize, ((BLOCK_SIZE+cn-1)/cn)*cn);
+        _buf.allocate(blockSize*2);
+        buf[0] = _buf;
+        buf[1] = buf[0] + blockSize;
     }
-    else
+    
+    for( size_t i = 0; i < it.nplanes; i++, ++it )
     {
-        const double *x = (const double*)X.data, *y = (const double*)Y.data;
-        double *angle = (double*)Angle.data;
-        size_t xstep = X.step/sizeof(x[0]), ystep = Y.step/sizeof(y[0]);
-        size_t astep = Angle.step/sizeof(angle[0]);
-
-        for( ; size.height--; x += xstep, y += ystep, angle += astep )
+        for( j = 0; j < total; j += blockSize )
         {
-            for( i = 0; i < size.width; i += MAX_BLOCK_SIZE )
+            int len = std::min(total - j, blockSize);
+            if( depth == CV_32F )
             {
-                int block_size = std::min(MAX_BLOCK_SIZE, size.width - i);
-                for( j = 0; j < block_size; j++ )
+                const float *x = (const float*)ptrs[0], *y = (const float*)ptrs[1];
+                float *angle = (float*)ptrs[2];
+                FastAtan2_32f( y, x, angle, len, angleInDegrees );
+            }
+            else
+            {
+                const double *x = (const double*)ptrs[0], *y = (const double*)ptrs[1];
+                double *angle = (double*)ptrs[2];
+                for( k = 0; k < len; k++ )
                 {
-                    buf[0][j] = (float)x[i + j];
-                    buf[1][j] = (float)y[i + j];
+                    buf[0][k] = (float)x[k];
+                    buf[1][k] = (float)y[k];
                 }
-                FastAtan2_32f( buf[1], buf[0], buf[0], block_size, angleInDegrees );
-                for( j = 0; j < block_size; j++ )
-                                       angle[i + j] = buf[0][j];
+                    
+                FastAtan2_32f( buf[1], buf[0], buf[0], len, angleInDegrees );
+                for( k = 0; k < len; k++ )
+                                       angle[k] = buf[0][k];
             }
+            ptrs[0] += len*esz1;
+            ptrs[1] += len*esz1;
+            ptrs[2] += len*esz1;
         }
     }
 }
-
-void cartToPolar( const Mat& X, const Mat& Y, Mat& Mag, Mat& Angle, bool angleInDegrees )
+    
+void cartToPolar( const InputArray& src1, const InputArray& src2,
+                  OutputArray dst1, OutputArray dst2, bool angleInDegrees )
 {
-    if( X.dims > 2 )
+    Mat X = src1.getMat(), Y = src2.getMat();
+    int type = X.type(), depth = X.depth(), cn = X.channels();
+    CV_Assert( X.size == Y.size && type == Y.type() && (depth == CV_32F || depth == CV_64F));
+    dst1.create( X.dims, X.size, type );
+    dst2.create( X.dims, X.size, type );
+    Mat Mag = dst1.getMat(), Angle = dst2.getMat();
+    
+    const Mat* arrays[] = {&X, &Y, &Mag, &Angle, 0};
+    uchar* ptrs[4];
+    NAryMatIterator it(arrays, ptrs);
+    cv::AutoBuffer<float> _buf;
+    float* buf[2] = {0, 0};
+    int j, k, total = (int)(it.size*cn), blockSize = std::min(total, ((BLOCK_SIZE+cn-1)/cn)*cn);
+    size_t esz1 = X.elemSize1();
+    
+    if( depth == CV_64F )
     {
-        Mag.create(X.dims, X.size, X.type());
-        Angle.create(X.dims, X.size, X.type());
-        const Mat* arrays[] = {&X, &Y, &Mag, &Angle, 0};
-        Mat planes[4];
-        NAryMatIterator it(arrays, planes);
-        
-        for( int i = 0; i < it.nplanes; i++, ++it )
-            cartToPolar( it.planes[0], it.planes[1], it.planes[2], it.planes[3], angleInDegrees );
-        return;
+        _buf.allocate(blockSize*2);
+        buf[0] = _buf;
+        buf[1] = buf[0] + blockSize;
     }
     
-    float buf[2][MAX_BLOCK_SIZE];
-    int i, j, type = X.type(), depth = X.depth(), cn = X.channels();
-
-    CV_Assert( X.size() == Y.size() && type == Y.type() && (depth == CV_32F || depth == CV_64F));
-    Mag.create( X.size(), type );
-    Angle.create( X.size(), type );
-
-    Size size = getContinuousSize( X, Y, Mag, Angle, cn );
-    bool inplace = Mag.data == X.data || Mag.data == Y.data;
-
-    if( depth == CV_32F )
+    for( size_t i = 0; i < it.nplanes; i++, ++it )
     {
-        const float *x = (const float*)X.data, *y = (const float*)Y.data;
-        float *mag = (float*)Mag.data, *angle = (float*)Angle.data;
-        size_t xstep = X.step/sizeof(x[0]), ystep = Y.step/sizeof(y[0]);
-        size_t mstep = Mag.step/sizeof(mag[0]), astep = Angle.step/sizeof(angle[0]);
-
-        for( ; size.height--; x += xstep, y += ystep, mag += mstep, angle += astep )
+        for( j = 0; j < total; j += blockSize )
         {
-            for( i = 0; i < size.width; i += MAX_BLOCK_SIZE )
+            int len = std::min(total - j, blockSize);
+            if( depth == CV_32F )
             {
-                int block_size = std::min(MAX_BLOCK_SIZE, size.width - i);
-                Magnitude_32f( x + i, y + i, inplace ? buf[0] : mag + i, block_size );
-                FastAtan2_32f( y + i, x + i, angle + i, block_size, angleInDegrees );
-                if( inplace )
-                    for( j = 0; j < block_size; j++ )
-                        mag[i + j] = buf[0][j];
+                const float *x = (const float*)ptrs[0], *y = (const float*)ptrs[1];
+                float *mag = (float*)ptrs[2], *angle = (float*)ptrs[3];
+                Magnitude_32f( x, y, mag, len );
+                FastAtan2_32f( y, x, angle, len, angleInDegrees );
             }
-        }
-    }
-    else
-    {
-        const double *x = (const double*)X.data, *y = (const double*)Y.data;
-        double *mag = (double*)Mag.data, *angle = (double*)Angle.data;
-        size_t xstep = X.step/sizeof(x[0]), ystep = Y.step/sizeof(y[0]);
-        size_t mstep = Mag.step/sizeof(mag[0]), astep = Angle.step/sizeof(angle[0]);
-
-        for( ; size.height--; x += xstep, y += ystep, mag += mstep, angle += astep )
-        {
-            for( i = 0; i < size.width; i += MAX_BLOCK_SIZE )
+            else
             {
-                int block_size = std::min(MAX_BLOCK_SIZE, size.width - i);
-                for( j = 0; j < block_size; j++ )
+                const double *x = (const double*)ptrs[0], *y = (const double*)ptrs[1];
+                double *angle = (double*)ptrs[3];
+                
+                Magnitude_64f(x, y, (double*)ptrs[2], len);
+                for( k = 0; k < len; k++ )
                 {
-                    buf[0][j] = (float)x[i + j];
-                    buf[1][j] = (float)y[i + j];
+                    buf[0][k] = (float)x[k];
+                    buf[1][k] = (float)y[k];
                 }
-                FastAtan2_32f( buf[1], buf[0], buf[0], block_size, angleInDegrees );
-                Magnitude_64f( x + i, y + i, mag + i, block_size );
-                               for( j = 0; j < block_size; j++ )
-                                       angle[i + j] = buf[0][j];
+                
+                FastAtan2_32f( buf[1], buf[0], buf[0], len, angleInDegrees );
+                for( k = 0; k < len; k++ )
+                                       angle[k] = buf[0][k];
             }
+            ptrs[0] += len*esz1;
+            ptrs[1] += len*esz1;
+            ptrs[2] += len*esz1;
+            ptrs[3] += len*esz1;
         }
     }
 }
@@ -510,9 +473,8 @@ void cartToPolar( const Mat& X, const Mat& Y, Mat& Mag, Mat& Angle, bool angleIn
 *                                  Polar -> Cartezian                                    *
 \****************************************************************************************/
 
-static CvStatus CV_STDCALL
-SinCos_32f( const float *angle,float *sinval, float* cosval,
-            int len, int angle_in_degrees )
+static void SinCos_32f( const float *angle, float *sinval, float* cosval,
+                        int len, int angle_in_degrees )
 {
     const int N = 64;
 
@@ -588,81 +550,80 @@ SinCos_32f( const float *angle,float *sinval, float* cosval,
         sinval[i] = (float)sin_val;
         cosval[i] = (float)cos_val;
     }
-
-    return CV_OK;
 }
 
 
-void polarToCart( const Mat& Mag, const Mat& Angle, Mat& X, Mat& Y, bool angleInDegrees )
+void polarToCart( const InputArray& src1, const InputArray& src2,
+                  OutputArray dst1, OutputArray dst2, bool angleInDegrees )
 {
-    if( Mag.dims > 2 )
-    {
-        X.create(Mag.dims, Mag.size, Mag.type());
-        Y.create(Mag.dims, Mag.size, Mag.type());
-        const Mat* arrays[] = {&Mag, &Angle, &X, &Y, 0};
-        Mat planes[4];
-        NAryMatIterator it(arrays, planes);
-        
-        for( int i = 0; i < it.nplanes; i++, ++it )
-            polarToCart( it.planes[0], it.planes[1], it.planes[2], it.planes[3], angleInDegrees );
-        return;
-    }
+    Mat Mag = src1.getMat(), Angle = src2.getMat();
+    int type = Angle.type(), depth = Angle.depth(), cn = Angle.channels();
+    if( !Mag.empty() )
+        CV_Assert( Angle.size == Mag.size && type == Mag.type() && (depth == CV_32F || depth == CV_64F));
+    dst1.create( Angle.dims, Angle.size, type );
+    dst2.create( Angle.dims, Angle.size, type );
+    Mat X = dst1.getMat(), Y = dst2.getMat();
     
-    int i, j, type = Angle.type(), depth = Angle.depth();
-    Size size;
-
-    CV_Assert( depth == CV_32F || depth == CV_64F );
-    X.create( Angle.size(), type );
-    Y.create( Angle.size(), type );
-
-    if( Mag.data )
+    const Mat* arrays[] = {&Mag, &Angle, &X, &Y, 0};
+    uchar* ptrs[4];
+    NAryMatIterator it(arrays, ptrs);
+    cv::AutoBuffer<float> _buf;
+    float* buf[2] = {0, 0};
+    int j, k, total = (int)(it.size*cn), blockSize = std::min(total, ((BLOCK_SIZE+cn-1)/cn)*cn);
+    size_t esz1 = Angle.elemSize1();
+    
+    if( depth == CV_64F )
     {
-        CV_Assert( Mag.size() == Angle.size() && Mag.type() == Angle.type() );
-        size = getContinuousSize( Mag, Angle, X, Y, Angle.channels() );
+        _buf.allocate(blockSize*2);
+        buf[0] = _buf;
+        buf[1] = buf[0] + blockSize;
     }
-    else
-        size = getContinuousSize( Angle, X, Y, Angle.channels() );
-
-    if( depth == CV_32F )
+    
+    for( size_t i = 0; i < it.nplanes; i++, ++it )
     {
-        float *x = (float*)X.data, *y = (float*)Y.data;
-        const float *mag = (const float*)Mag.data, *angle = (const float*)Angle.data;
-        size_t xstep = X.step/sizeof(x[0]), ystep = Y.step/sizeof(y[0]);
-        size_t mstep = Mag.step/sizeof(mag[0]), astep = Angle.step/sizeof(angle[0]);
-        float x_tmp[MAX_BLOCK_SIZE];
-        float y_tmp[MAX_BLOCK_SIZE];
-
-        for( ; size.height--; x += xstep, y += ystep, mag += mstep, angle += astep )
+        for( j = 0; j < total; j += blockSize )
         {
-            for( i = 0; i < size.width; i += MAX_BLOCK_SIZE )
+            int len = std::min(total - j, blockSize);
+            if( depth == CV_32F )
             {
-                int block_size = std::min(MAX_BLOCK_SIZE, size.width - i);
-                SinCos_32f( angle + i, y_tmp, x_tmp, block_size, angleInDegrees );
-                for( j = 0; j < block_size; j++ )
-                {
-                    float m = mag ? mag[i + j] : 1.f;
-                    float t0 = x_tmp[j]*m, t1 = y_tmp[j]*m;
-                    x[i + j] = t0; y[i + j] = t1;
-                }
+                const float *mag = (const float*)ptrs[0], *angle = (const float*)ptrs[1];
+                float *x = (float*)ptrs[2], *y = (float*)ptrs[3];
+                
+                SinCos_32f( angle, y, x, len, angleInDegrees );
+                if( mag )
+                    for( k = 0; k < len; k++ )
+                    {
+                        float m = mag[k];
+                        x[k] *= m; y[k] *= m;
+                    }
             }
-        }
-    }
-    else
-    {
-        double *x = (double*)X.data, *y = (double*)Y.data;
-        const double *mag = (const double*)Mag.data, *angle = (const double*)Angle.data;
-        size_t xstep = X.step/sizeof(x[0]), ystep = Y.step/sizeof(y[0]);
-        size_t mstep = Mag.step/sizeof(mag[0]), astep = Angle.step/sizeof(angle[0]);
-        double ascale = angleInDegrees ? CV_PI/180. : 1;
-
-        for( ; size.height--; x += xstep, y += ystep, mag += mstep, angle += astep )
-        {
-            for( j = 0; j < size.width; j++ )
+            else
             {
-                double alpha = angle[j]*ascale, m = mag ? mag[j] : 1.;
-                double a = cos(alpha), b = sin(alpha);
-                x[j] = m*a; y[j] = m*b;
+                const double *mag = (const double*)ptrs[0], *angle = (const double*)ptrs[1];
+                double *x = (double*)ptrs[2], *y = (double*)ptrs[3];
+                
+                for( k = 0; k < len; k++ )
+                    buf[0][k] = (float)angle[k];
+                
+                SinCos_32f( buf[0], buf[1], buf[0], len, angleInDegrees );
+                if( mag )
+                    for( k = 0; k < len; k++ )
+                    {
+                        double m = mag[k];
+                        x[k] = buf[0][k]*m; y[k] = buf[1][k]*m;
+                    }
+                else
+                    for( k = 0; k < len; k++ )
+                    {
+                        x[k] = buf[0][k]; y[k] = buf[1][k];
+                    }
             }
+            
+            if( ptrs[0] )
+                ptrs[0] += len*esz1;
+            ptrs[1] += len*esz1;
+            ptrs[2] += len*esz1;
+            ptrs[3] += len*esz1;
         }
     }
 }
@@ -772,7 +733,7 @@ static const double exp_prescale = 1.4426950408889634073599246810019 * (1 << EXP
 static const double exp_postscale = 1./(1 << EXPTAB_SCALE);
 static const double exp_max_val = 3000.*(1 << EXPTAB_SCALE); // log10(DBL_MAX) < 3000
 
-static CvStatus CV_STDCALL Exp_32f( const float *_x, float *y, int n )
+static void Exp_32f( const float *_x, float *y, int n )
 {
     static const float
         A4 = (float)(1.000000000000002438532970795181890933776 / EXPPOLY_32F_A0),
@@ -789,7 +750,7 @@ static CvStatus CV_STDCALL Exp_32f( const float *_x, float *y, int n )
     Cv32suf buf[4];
 
 #if CV_SSE2
-    if( n >= 8 && checkHardwareSupport(CV_CPU_SSE) )
+    if( n >= 8 && USE_SSE2 )
     {
         static const __m128d prescale2 = _mm_set1_pd(exp_prescale);
         static const __m128 postscale4 = _mm_set1_ps((float)exp_postscale);
@@ -969,12 +930,10 @@ static CvStatus CV_STDCALL Exp_32f( const float *_x, float *y, int n )
         
         y[i] = (float)(buf[0].f * expTab[val0 & EXPTAB_MASK] * EXPPOLY(x0));
     }
-    
-    return CV_OK;
 }
     
 
-static CvStatus CV_STDCALL Exp_64f( const double *_x, double *y, int n )
+static void Exp_64f( const double *_x, double *y, int n )
 {
     static const double
     A5 = .99999999999999999998285227504999 / EXPPOLY_32F_A0,
@@ -992,7 +951,7 @@ static CvStatus CV_STDCALL Exp_64f( const double *_x, double *y, int n )
     const Cv64suf* x = (const Cv64suf*)_x;
     
 #if CV_SSE2
-    if( checkHardwareSupport(CV_CPU_SSE) )
+    if( USE_SSE2 )
     {
         static const __m128d prescale2 = _mm_set1_pd(exp_prescale);
         static const __m128d postscale2 = _mm_set1_pd(exp_postscale);
@@ -1145,8 +1104,6 @@ static CvStatus CV_STDCALL Exp_64f( const double *_x, double *y, int n )
         
         y[i] = buf[0].f * expTab[val0 & EXPTAB_MASK] * EXPPOLY( x0 );
     }
-    
-    return CV_OK;
 }
 
 #undef EXPTAB_SCALE
@@ -1160,32 +1117,28 @@ static CvStatus CV_STDCALL Exp_64f( const double *_x, double *y, int n )
 
 #endif
 
-void exp( const Mat& src, Mat& dst )
+void exp( const InputArray& _src, OutputArray _dst )
 {
-    if( src.dims > 2 )
+    Mat src = _src.getMat();
+    int type = src.type(), depth = src.depth(), cn = src.channels();
+    
+    _dst.create( src.dims, src.size, type );
+    Mat dst = _dst.getMat();
+    
+    CV_Assert( depth == CV_32F || depth == CV_64F );
+    
+    const Mat* arrays[] = {&src, &dst, 0};
+    uchar* ptrs[2];
+    NAryMatIterator it(arrays, ptrs);
+    int len = (int)(it.size*cn);
+    
+    for( size_t i = 0; i < it.nplanes; i++, ++it )
     {
-        dst.create(src.dims, src.size, src.type());
-        const Mat* arrays[] = {&src, &dst, 0};
-        Mat planes[2];
-        NAryMatIterator it(arrays, planes);
-        
-        for( int i = 0; i < it.nplanes; i++, ++it )
-            exp( it.planes[0], it.planes[1] );
-        return;
+        if( depth == CV_32F )
+            Exp_32f( (const float*)ptrs[0], (float*)ptrs[1], len );
+        else
+            Exp_64f( (const double*)ptrs[0], (double*)ptrs[1], len );
     }
-    
-    int depth = src.depth();
-    dst.create( src.size(), src.type() );
-    Size size = getContinuousSize( src, dst, src.channels() );
-
-    if( depth == CV_32F )
-        for( int y = 0; y < size.height; y++ )
-            Exp_32f( src.ptr<float>(y), dst.ptr<float>(y), size.width );
-    else if( depth == CV_64F )
-        for( int y = 0; y < size.height; y++ )
-            Exp_64f( src.ptr<double>(y), dst.ptr<double>(y), size.width );
-    else
-        CV_Error( CV_StsUnsupportedFormat, "" );
 }
 
 
@@ -1464,7 +1417,7 @@ static const double CV_DECL_ALIGNED(16) icvLogTab[] = {
 #define LOGTAB_TRANSLATE(x,h) (((x) - 1.)*icvLogTab[(h)+1])
 static const double ln_2 = 0.69314718055994530941723212145818;
 
-static CvStatus CV_STDCALL Log_32f( const float *_x, float *y, int n )
+static void Log_32f( const float *_x, float *y, int n )
 {
     static const float shift[] = { 0, -1.f/512 };
     static const float
@@ -1480,7 +1433,7 @@ static CvStatus CV_STDCALL Log_32f( const float *_x, float *y, int n )
     const int* x = (const int*)_x;
 
 #if CV_SSE2
-    if( checkHardwareSupport(CV_CPU_SSE) )
+    if( USE_SSE2 )
     {
         static const __m128d ln2_2 = _mm_set1_pd(ln_2);
         static const __m128 _1_4 = _mm_set1_ps(1.f);
@@ -1610,12 +1563,10 @@ static CvStatus CV_STDCALL Log_32f( const float *_x, float *y, int n )
 
         y[i] = (float)y0;
     }
-
-    return CV_OK;
 }
 
 
-static CvStatus CV_STDCALL Log_64f( const double *x, double *y, int n )
+static void Log_64f( const double *x, double *y, int n )
 {
     static const double shift[] = { 0, -1./512 };
     static const double
@@ -1638,7 +1589,7 @@ static CvStatus CV_STDCALL Log_64f( const double *x, double *y, int n )
     DBLINT *X = (DBLINT *) x;
 
 #if CV_SSE2
-    if( checkHardwareSupport(CV_CPU_SSE) )
+    if( USE_SSE2 )
     {
         static const __m128d ln2_2 = _mm_set1_pd(ln_2);
         static const __m128d _1_2 = _mm_set1_pd(1.);
@@ -1802,8 +1753,6 @@ static CvStatus CV_STDCALL Log_64f( const double *x, double *y, int n )
         y0 += LOGPOLY( x0, h0 == 510 );
         y[i] = y0;
     }
-
-    return CV_OK;
 }
 
 #else
@@ -1813,46 +1762,39 @@ static CvStatus CV_STDCALL Log_64f( const double *x, double *y, int n )
 
 #endif
 
-void log( const Mat& src, Mat& dst )
+void log( const InputArray& _src, OutputArray _dst )
 {
-    if( src.dims > 2 )
+    Mat src = _src.getMat();
+    int type = src.type(), depth = src.depth(), cn = src.channels();
+    
+    _dst.create( src.dims, src.size, type );
+    Mat dst = _dst.getMat();
+    
+    CV_Assert( depth == CV_32F || depth == CV_64F );
+    
+    const Mat* arrays[] = {&src, &dst, 0};
+    uchar* ptrs[2];
+    NAryMatIterator it(arrays, ptrs);
+    int len = (int)(it.size*cn);
+    
+    for( size_t i = 0; i < it.nplanes; i++, ++it )
     {
-        dst.create(src.dims, src.size, src.type());
-        const Mat* arrays[] = {&src, &dst, 0};
-        Mat planes[2];
-        NAryMatIterator it(arrays, planes);
-        
-        for( int i = 0; i < it.nplanes; i++, ++it )
-            log( it.planes[0], it.planes[1] );
-        return;
+        if( depth == CV_32F )
+            Log_32f( (const float*)ptrs[0], (float*)ptrs[1], len );
+        else
+            Log_64f( (const double*)ptrs[0], (double*)ptrs[1], len );
     }
-    
-    int depth = src.depth();
-    dst.create( src.size(), src.type() );
-    Size size = getContinuousSize( src, dst, src.channels() );
-
-    if( depth == CV_32F )
-        for( int y = 0; y < size.height; y++ )
-            Log_32f( src.ptr<float>(y), dst.ptr<float>(y), size.width );
-    else if( depth == CV_64F )
-        for( int y = 0; y < size.height; y++ )
-            Log_64f( src.ptr<double>(y), dst.ptr<double>(y), size.width );
-    else
-        CV_Error( CV_StsUnsupportedFormat, "" );
-}
-
+}    
 
 /****************************************************************************************\
 *                                    P O W E R                                           *
 \****************************************************************************************/
 
 template<typename T, typename WT>
-static CvStatus CV_STDCALL
-IPow( const void* _src, void* _dst, int len, int power )
+static void
+iPow_( const T* src, T* dst, int len, int power )
 {
     int i;
-    const T* src = (const T*)_src;
-    T* dst = (T*)_dst;
     for( i = 0; i < len; i++ )
     {
         WT a = 1, b = src[i];
@@ -1868,53 +1810,86 @@ IPow( const void* _src, void* _dst, int len, int power )
         a *= b;
         dst[i] = saturate_cast<T>(a);
     }
-    return CV_OK;
 }
 
-typedef CvStatus (CV_STDCALL * IPowFunc)( const void* src, void* dst, int len, int power );
+    
+void iPow8u(const uchar* src, uchar* dst, int len, int power)
+{
+    iPow_<uchar, int>(src, dst, len, power);
+}
 
-void pow( const Mat& _src, double power, Mat& dst )
+void iPow8s(const schar* src, schar* dst, int len, int power)
 {
-    if( _src.dims > 2 )
-    {
-        dst.create(_src.dims, _src.size, _src.type());
-        const Mat* arrays[] = {&_src, &dst, 0};
-        Mat planes[2];
-        NAryMatIterator it(arrays, planes);
-        
-        for( int i = 0; i < it.nplanes; i++, ++it )
-            pow( it.planes[0], power, it.planes[1] );
-        return;
-    }
+    iPow_<schar, int>(src, dst, len, power);
+}
+    
+void iPow16u(const ushort* src, ushort* dst, int len, int power)
+{
+    iPow_<ushort, int>(src, dst, len, power);
+}
+
+void iPow16s(const short* src, short* dst, int len, int power)
+{
+    iPow_<short, int>(src, dst, len, power);
+}
     
-    int ipower = cvRound( power ), i, j;
-    bool is_ipower = 0;
-    int depth = _src.depth();
-    const Mat* src = &_src;
+void iPow32s(const int* src, int* dst, int len, int power)
+{
+    iPow_<int, int>(src, dst, len, power);
+}
+
+void iPow32f(const float* src, float* dst, int len, int power)
+{
+    iPow_<float, float>(src, dst, len, power);
+}
+
+void iPow64f(const double* src, double* dst, int len, int power)
+{
+    iPow_<double, double>(src, dst, len, power);
+}
 
-    dst.create( _src.size(), _src.type() );
+    
+typedef void (*IPowFunc)( const uchar* src, uchar* dst, int len, int power );
+    
+static IPowFunc ipowTab[] =
+{
+    (IPowFunc)iPow8u, (IPowFunc)iPow8s, (IPowFunc)iPow16u, (IPowFunc)iPow16s,
+    (IPowFunc)iPow32s, (IPowFunc)iPow32f, (IPowFunc)iPow64f, 0
+};
 
+    
+void pow( const InputArray& _src, double power, OutputArray _dst )
+{
+    Mat src = _src.getMat();
+    int type = src.type(), depth = src.depth(), cn = src.channels();
+    
+    _dst.create( src.dims, src.size, type );
+    Mat dst = _dst.getMat();
+    
+    int ipower = cvRound(power);
+    bool is_ipower = false;
+    
     if( fabs(ipower - power) < DBL_EPSILON )
     {
         if( ipower < 0 )
         {
-            divide( 1., _src, dst );
+            divide( 1., src, dst );
             if( ipower == -1 )
                 return;
             ipower = -ipower;
-            src = &dst;
+            src = dst;
         }
-
+        
         switch( ipower )
         {
         case 0:
             dst = Scalar::all(1);
             return;
         case 1:
-            src->copyTo(dst);
+            src.copyTo(dst);
             return;
         case 2:
-            multiply(*src, *src, dst);
+            multiply(src, src, dst);
             return;
         default:
             is_ipower = true;
@@ -1922,87 +1897,84 @@ void pow( const Mat& _src, double power, Mat& dst )
     }
     else
         CV_Assert( depth == CV_32F || depth == CV_64F );
-
-    Size size = getContinuousSize( *src, dst, src->channels() );
-
+    
+    const Mat* arrays[] = {&src, &dst, 0};
+    uchar* ptrs[2];
+    NAryMatIterator it(arrays, ptrs);
+    int len = (int)(it.size*cn);
+    
     if( is_ipower )
     {
-        static IPowFunc tab[] =
-        {
-            IPow<uchar, int>, 0, IPow<ushort, int>, IPow<short, int>, IPow<int, int>,
-            IPow<float, float>, IPow<double, double>, 0
-        };
-
-        IPowFunc func = tab[depth];
+        IPowFunc func = ipowTab[depth];
         CV_Assert( func != 0 );
-        for( i = 0; i < size.height; i++ )
-            func( src->data + src->step*i, dst.data + dst.step*i, size.width, ipower );
+        
+        for( size_t i = 0; i < it.nplanes; i++, ++it )
+            func( ptrs[0], ptrs[1], len, ipower );
     }
     else if( fabs(fabs(power) - 0.5) < DBL_EPSILON )
     {
         MathFunc func = power < 0 ?
             (depth == CV_32F ? (MathFunc)InvSqrt_32f : (MathFunc)InvSqrt_64f) :
             (depth == CV_32F ? (MathFunc)Sqrt_32f : (MathFunc)Sqrt_64f);
-
-        for( i = 0; i < size.height; i++ )
-            func( src->data + src->step*i, dst.data + dst.step*i, size.width );
-    }
-    else if( depth == CV_32F )
-    {
-        const float *x = (const float*)src->data;
-        float *y = (float*)dst.data;
-        size_t xstep = src->step/sizeof(x[0]), ystep = dst.step/sizeof(y[0]);
-        float p = (float)power;
-
-        for( ; size.height--; x += xstep, y += ystep )
-        {
-            for( i = 0; i < size.width; i += MAX_BLOCK_SIZE )
-            {
-                int block_size = std::min(MAX_BLOCK_SIZE, size.width - i);
-                Log_32f(x + i, y + i, block_size);
-                for( j = 0; j < block_size; j++ )
-                    y[i + j] *= p;
-                Exp_32f(y + i, y + i, block_size);
-            }
-        }
+        
+        for( size_t i = 0; i < it.nplanes; i++, ++it )
+            func( ptrs[0], ptrs[1], len );
     }
     else
     {
-        const double *x = (const double*)src->data;
-        double *y = (double*)dst.data;
-        size_t xstep = src->step/sizeof(x[0]), ystep = dst.step/sizeof(y[0]);
-
-        for( ; size.height--; x += xstep, y += ystep )
+        int j, k, blockSize = std::min(len, ((BLOCK_SIZE + cn-1)/cn)*cn);
+        size_t esz1 = src.elemSize1();
+        
+        for( size_t i = 0; i < it.nplanes; i++, ++it )
         {
-            for( i = 0; i < size.width; i += MAX_BLOCK_SIZE )
+            for( j = 0; j < len; j += blockSize )
             {
-                int block_size = std::min(MAX_BLOCK_SIZE, size.width - i);
-                Log_64f(x + i, y + i, block_size);
-                for( j = 0; j < block_size; j++ )
-                    y[i + j] *= power;
-                Exp_64f(y + i, y + i, block_size);
+                int bsz = std::min(len - j, blockSize);
+                if( depth == CV_32F )
+                {
+                    const float* x = (const float*)ptrs[0];
+                    float* y = (float*)ptrs[1];
+                    
+                    Log_32f(x, y, bsz);
+                    for( k = 0; k < bsz; k++ )
+                        y[k] = (float)(y[k]*power);
+                    Exp_32f(y, y, bsz);
+                }
+                else
+                {
+                    const double* x = (const double*)ptrs[0];
+                    double* y = (double*)ptrs[1];
+                    
+                    Log_64f(x, y, bsz);
+                    for( k = 0; k < bsz; k++ )
+                        y[k] *= power;
+                    Exp_64f(y, y, bsz);
+                }
+                ptrs[0] += bsz*esz1;
+                ptrs[1] += bsz*esz1;
             }
         }
     }
 }
 
-void sqrt(const Mat& a, Mat& b)
+void sqrt(const InputArray& a, OutputArray b)
 {
     pow(a, 0.5, b);
 }
 
 /************************** CheckArray for NaN's, Inf's *********************************/
 
-bool checkRange(const Mat& src, bool quiet, Point* pt,
+bool checkRange(const InputArray& _src, bool quiet, Point* pt,
                 double minVal, double maxVal)
 {
+    Mat src = _src.getMat();
     if( src.dims > 2 )
     {
         const Mat* arrays[] = {&src, 0};
         Mat planes[1];
         NAryMatIterator it(arrays, planes);
         
-        for( int i = 0; i < it.nplanes; i++, ++it )
+        for( size_t i = 0; i < it.nplanes; i++, ++it )
         {
             if( !checkRange( it.planes[0], quiet, pt, minVal, maxVal ))
             {
@@ -2218,61 +2190,46 @@ CV_IMPL int cvCheckArr( const CvArr* arr, int flags,
     this copyright notice and the above warranty information.
   -----------------------------------------------------------------------
 */
-CV_IMPL int
-cvSolveCubic( const CvMat* coeffs, CvMat* roots )
-{
-    int n = 0;
 
+int cv::solveCubic( const InputArray& _coeffs, OutputArray _roots )
+{
+    const int n0 = 3;
+    Mat coeffs = _coeffs.getMat();
+    int ctype = coeffs.type();
+    
+    CV_Assert( ctype == CV_32F || ctype == CV_64F );
+    CV_Assert( (coeffs.size() == Size(n0, 1) ||
+                coeffs.size() == Size(n0+1, 1) ||
+                coeffs.size() == Size(1, n0) ||
+                coeffs.size() == Size(1, n0+1)) );
+    
+    _roots.create(n0, 1, ctype, -1, true, DEPTH_MASK_FLT);
+    Mat roots = _roots.getMat();
+    
+    int i = -1, n = 0;
     double a0 = 1., a1, a2, a3;
     double x0 = 0., x1 = 0., x2 = 0.;
-    size_t step = 1;
-    int coeff_count;
-
-    if( !CV_IS_MAT(coeffs) )
-        CV_Error( !coeffs ? CV_StsNullPtr : CV_StsBadArg, "Input parameter is not a valid matrix" );
-
-    if( !CV_IS_MAT(roots) )
-        CV_Error( !roots ? CV_StsNullPtr : CV_StsBadArg, "Output parameter is not a valid matrix" );
-
-    if( (CV_MAT_TYPE(coeffs->type) != CV_32FC1 && CV_MAT_TYPE(coeffs->type) != CV_64FC1) ||
-        (CV_MAT_TYPE(roots->type) != CV_32FC1 && CV_MAT_TYPE(roots->type) != CV_64FC1) )
-        CV_Error( CV_StsUnsupportedFormat,
-        "Both matrices should be floating-point (single or double precision)" );
-
-    coeff_count = coeffs->rows + coeffs->cols - 1;
-
-    if( (coeffs->rows != 1 && coeffs->cols != 1) || (coeff_count != 3 && coeff_count != 4) )
-        CV_Error( CV_StsBadSize,
-        "The matrix of coefficients must be 1-dimensional vector of 3 or 4 elements" );
-
-    if( (roots->rows != 1 && roots->cols != 1) ||
-        roots->rows + roots->cols - 1 != 3 )
-        CV_Error( CV_StsBadSize,
-        "The matrix of roots must be 1-dimensional vector of 3 elements" );
-
-    if( CV_MAT_TYPE(coeffs->type) == CV_32FC1 )
+    int ncoeffs = coeffs.rows + coeffs.cols - 1;
+    
+    if( ctype == CV_32FC1 )
     {
-        const float* c = coeffs->data.fl;
-        if( coeffs->rows > 1 )
-            step = coeffs->step/sizeof(c[0]);
-        if( coeff_count == 4 )
-            a0 = c[0], c += step;
-        a1 = c[0];
-        a2 = c[step];
-        a3 = c[step*2];
+        if( ncoeffs == 4 )
+            a0 = coeffs.at<float>(++i);
+        
+        a1 = coeffs.at<float>(i+1);
+        a2 = coeffs.at<float>(i+2);
+        a3 = coeffs.at<float>(i+3);
     }
     else
     {
-        const double* c = coeffs->data.db;
-        if( coeffs->rows > 1 )
-            step = coeffs->step/sizeof(c[0]);
-        if( coeff_count == 4 )
-            a0 = c[0], c += step;
-        a1 = c[0];
-        a2 = c[step];
-        a3 = c[step*2];
+        if( ncoeffs == 4 )
+            a0 = coeffs.at<double>(++i);
+        
+        a1 = coeffs.at<double>(i+1);
+        a2 = coeffs.at<double>(i+2);
+        a3 = coeffs.at<double>(i+3);
     }
-
+    
     if( a0 == 0 )
     {
         if( a1 == 0 )
@@ -2315,12 +2272,12 @@ cvSolveCubic( const CvMat* coeffs, CvMat* roots )
         a1 *= a0;
         a2 *= a0;
         a3 *= a0;
-
+        
         double Q = (a1 * a1 - 3 * a2) * (1./9);
         double R = (2 * a1 * a1 * a1 - 9 * a1 * a2 + 27 * a3) * (1./54);
         double Qcubed = Q * Q * Q;
         double d = Qcubed - R * R;
-
+        
         if( d >= 0 )
         {
             double theta = acos(R / sqrt(Qcubed));
@@ -2344,72 +2301,43 @@ cvSolveCubic( const CvMat* coeffs, CvMat* roots )
             n = 1;
         }
     }
-
-    step = 1;
-
-    if( CV_MAT_TYPE(roots->type) == CV_32FC1 )
+    
+    if( roots.type() == CV_32FC1 )
     {
-        float* r = roots->data.fl;
-        if( roots->rows > 1 )
-            step = roots->step/sizeof(r[0]);
-        r[0] = (float)x0;
-        r[step] = (float)x1;
-        r[step*2] = (float)x2;
+        roots.at<float>(0) = (float)x0;
+        roots.at<float>(1) = (float)x1;
+        roots.at<float>(2) = (float)x2;
     }
     else
     {
-        double* r = roots->data.db;
-        if( roots->rows > 1 )
-            step = roots->step/sizeof(r[0]);
-        r[0] = x0;
-        r[step] = x1;
-        r[step*2] = x2;
+        roots.at<double>(0) = x0;
+        roots.at<double>(1) = x1;
+        roots.at<double>(2) = x2;
     }
-
+    
     return n;
 }
 
-
-int cv::solveCubic( const Mat& coeffs, Mat& roots )
-{
-    CV_Assert( coeffs.dims <= 2 );
-    const int n = 3;
-    if( ((roots.rows != 1 || roots.cols != n) &&
-        (roots.rows != n || roots.cols != 1)) ||
-        (roots.type() != CV_32F && roots.type() != CV_64F) )
-        roots.create(n, 1, CV_64F);
-
-    CvMat _coeffs = coeffs, _roots = roots;
-    int nroots = cvSolveCubic( &_coeffs, &_roots);
-    if( nroots == 0 )
-        roots = Mat();
-    else if( roots.rows > 1 )
-        roots = roots.rowRange(0, nroots);
-    else
-        roots = roots.colRange(0, nroots);
-    return nroots;
-}
-
 /* finds complex roots of a polynomial using Durand-Kerner method:
    http://en.wikipedia.org/wiki/Durand%E2%80%93Kerner_method */
-double cv::solvePoly( const Mat& coeffs0, Mat& roots0, int maxIters )
+double cv::solvePoly( const InputArray& _coeffs0, OutputArray _roots0, int maxIters )
 {
     typedef Complex<double> C;
 
     double maxDiff = 0;
-    int iter, i, j, n;
-
-    CV_Assert( coeffs0.dims <= 2 &&
-               (coeffs0.cols == 1 || coeffs0.rows == 1) &&
-               (coeffs0.depth() == CV_32F || coeffs0.depth() == CV_64F) &&
-               coeffs0.channels() <= 2 );
-    n = coeffs0.cols + coeffs0.rows - 2;
-
-    if( ((roots0.rows != 1 || roots0.cols != n) &&
-        (roots0.rows != n || roots0.cols != 1)) ||
-        (roots0.type() != CV_32FC2 && roots0.type() != CV_64FC2) )
-        roots0.create( n, 1, CV_64FC2 );
+    int iter, i, j;
+    Mat coeffs0 = _coeffs0.getMat();
+    int ctype = _coeffs0.type();
+    int cdepth = CV_MAT_DEPTH(ctype);
+    
+    CV_Assert( CV_MAT_DEPTH(ctype) >= CV_32F && CV_MAT_CN(ctype) <= 2 );
+    CV_Assert( coeffs0.rows == 1 || coeffs0.cols == 1 );
+    
+    int n = coeffs0.cols + coeffs0.rows - 2;
 
+    _roots0.create(n, 1, CV_MAKETYPE(cdepth, 2), -1, true, DEPTH_MASK_FLT);    
+    Mat roots0 = _roots0.getMat();
+    
     AutoBuffer<C> buf(n*2+2);
     C *coeffs = buf, *roots = coeffs + n + 1;
     Mat coeffs1(coeffs0.size(), CV_MAKETYPE(CV_64F, coeffs0.channels()), coeffs0.channels() == 2 ? coeffs : roots);
@@ -2463,6 +2391,16 @@ double cv::solvePoly( const Mat& coeffs0, Mat& roots0, int maxIters )
 }
 
 
+CV_IMPL int
+cvSolveCubic( const CvMat* coeffs, CvMat* roots )
+{
+    cv::Mat _coeffs = cv::cvarrToMat(coeffs), _roots = cv::cvarrToMat(roots), _roots0 = _roots;
+    int nroots = cv::solveCubic(_coeffs, _roots);
+    CV_Assert( _roots.data == _roots0.data ); // check that the array of roots was not reallocated
+    return nroots;
+}
+
+
 void cvSolvePoly(const CvMat* a, CvMat *r, int maxiter, int)
 {
     cv::Mat _a = cv::cvarrToMat(a), _r = cv::cvarrToMat(r), _r0 = r;
index 2c2aa26..20bb513 100644 (file)
@@ -11,7 +11,7 @@
 //                For Open Source Computer Vision Library
 //
 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
-// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
 // Third party copyrights are property of their respective owners.
 //
 // Redistribution and use in source and binary forms, with or without modification,
@@ -683,9 +683,10 @@ static void GEMMStore_64fc( const Complexd* c_data, size_t c_step,
     GEMMStore(c_data, c_step, d_buf, d_buf_step, d_data, d_step, d_size, alpha, beta, flags);
 }
 
+}
 
-void gemm( const Mat& matA, const Mat& matB, double alpha,
-           const Mat& matC, double beta, Mat& D, int flags )
+void cv::gemm( const InputArray& matA, const InputArray& matB, double alpha,
+           const InputArray& matC, double beta, OutputArray matD, int flags )
 {
     const int block_lin_size = 128;
     const int block_size = block_lin_size * block_lin_size;
@@ -693,8 +694,7 @@ void gemm( const Mat& matA, const Mat& matB, double alpha,
     static double zero[] = {0,0,0,0};
     static float zerof[] = {0,0,0,0};
 
-    Mat A = matA, B = matB;
-    const Mat* C = matC.data && beta != 0 ? &matC : 0;
+    Mat A = matA.getMat(), B = matB.getMat(), C = beta != 0 ? matC.getMat() : Mat();
     Size a_size = A.size(), d_size;
     int i, len = 0, type = A.type();
 
@@ -724,19 +724,20 @@ void gemm( const Mat& matA, const Mat& matB, double alpha,
         break;
     }
 
-    if( C )
+    if( C.data )
     {
-        CV_Assert( C->type() == type &&
-            (((flags&GEMM_3_T) == 0 && C->rows == d_size.height && C->cols == d_size.width) ||
-             ((flags&GEMM_3_T) != 0 && C->rows == d_size.width && C->cols == d_size.height)));
-        if( (flags & GEMM_3_T) != 0 && C->data == D.data )
-        {
-            transpose( D, D );
-            flags &= ~GEMM_3_T;
-        }
+        CV_Assert( C.type() == type &&
+            (((flags&GEMM_3_T) == 0 && C.rows == d_size.height && C.cols == d_size.width) ||
+             ((flags&GEMM_3_T) != 0 && C.rows == d_size.width && C.cols == d_size.height)));
     }
 
-    D.create( d_size.height, d_size.width, type );
+    matD.create( d_size.height, d_size.width, type );
+    Mat D = matD.getMat();
+    if( (flags & GEMM_3_T) != 0 && C.data == D.data )
+    {
+        transpose( C, C );
+        flags &= ~GEMM_3_T;
+    }
 
     if( flags == 0 && 2 <= len && len <= 4 && (len == d_size.width || len == d_size.height) )
     {
@@ -745,11 +746,11 @@ void gemm( const Mat& matA, const Mat& matB, double alpha,
             float* d = (float*)D.data;
             const float *a = (const float*)A.data,
                         *b = (const float*)B.data,
-                        *c = (const float*)(C ? C->data : 0);
+                        *c = (const float*)C.data;
             size_t d_step = D.step/sizeof(d[0]),
                 a_step = A.step/sizeof(a[0]),
                 b_step = B.step/sizeof(b[0]),
-                c_step = C ? C->step/sizeof(c[0]) : 0;
+                c_step = C.data ? C.step/sizeof(c[0]) : 0;
 
             if( !c )
                 c = zerof;
@@ -873,11 +874,11 @@ void gemm( const Mat& matA, const Mat& matB, double alpha,
             double* d = (double*)D.data;
             const double *a = (const double*)A.data,
                          *b = (const double*)B.data,
-                         *c = (const double*)(C ? C->data : 0);
+                         *c = (const double*)C.data;
             size_t d_step = D.step/sizeof(d[0]),
                 a_step = A.step/sizeof(a[0]),
                 b_step = B.step/sizeof(b[0]),
-                c_step = C ? C->step/sizeof(c[0]) : 0;
+                c_step = C.data ? C.step/sizeof(c[0]) : 0;
             if( !c )
                 c = zero;
 
@@ -1002,8 +1003,8 @@ void gemm( const Mat& matA, const Mat& matB, double alpha,
     GEMMBlockMulFunc blockMulFunc;
     GEMMStoreFunc storeFunc;
     Mat *matD = &D, tmat;
-    const uchar* Cdata = C ? C->data : 0;
-    size_t Cstep = C ? (size_t)C->step : 0;
+    const uchar* Cdata = C.data;
+    size_t Cstep = C.data ? (size_t)C.step : 0;
     AutoBuffer<uchar> buf;
 
     if( type == CV_32FC1 )
@@ -1140,15 +1141,15 @@ void gemm( const Mat& matA, const Mat& matB, double alpha,
         else
             b_step0 = elem_size, b_step1 = b_step;
 
-        if( !C )
+        if( !C.data )
         {
             c_step0 = c_step1 = 0;
             flags &= ~GEMM_3_T;
         }
         else if( !(flags & GEMM_3_T) )
-            c_step0 = C->step, c_step1 = elem_size;
+            c_step0 = C.step, c_step1 = elem_size;
         else
-            c_step0 = elem_size, c_step1 = C->step;
+            c_step0 = elem_size, c_step1 = C.step;
 
         dm0 = std::min( block_lin_size, d_size.height );
         dn0 = std::min( block_lin_size, d_size.width );
@@ -1265,131 +1266,70 @@ void gemm( const Mat& matA, const Mat& matB, double alpha,
 *                                        Transform                                       *
 \****************************************************************************************/
 
-template<typename T, typename WT> static void
-transformC1_( const Mat& srcmat, Mat& dstmat, Mat& tmat )
+namespace cv
 {
-    Size size = getContinuousSize( srcmat, dstmat );
-    const WT* m = (const WT*)tmat.data;
-    int dst_cn = dstmat.channels();
-    int x, y, k;
-
-    for( y = 0; y < size.height; y++ )
-    {
-        const T* src = (const T*)(srcmat.data + srcmat.step*y);
-        T* dst = (T*)(dstmat.data + dstmat.step*y);
-        const WT* _m = m;
-
-        for( k = 0; k < dst_cn; k++, dst++, _m += 2 )
-            for( x = 0; x < size.width; x++ )
-                dst[x*dst_cn] = saturate_cast<T>(_m[0]*src[x] + _m[1]);
-    }
-}
 
 template<typename T, typename WT> static void
-transformC2_( const Mat& srcmat, Mat& dstmat, Mat& tmat )
+transform_( const T* src, T* dst, const WT* m, int len, int scn, int dcn )
 {
-    Size size = getContinuousSize( srcmat, dstmat );
-    const WT* m = (const WT*)tmat.data;
-    int dst_cn = dstmat.channels();
-    int x, y, k;
-
-    for( y = 0; y < size.height; y++ )
+    int x;
+    
+    if( scn == 2 && dcn == 2 )
     {
-        const T* src = (const T*)(srcmat.data + srcmat.step*y);
-        T* dst = (T*)(dstmat.data + dstmat.step*y);
-
-        if( dst_cn == 2 )
-            for( x = 0; x < size.width*2; x += 2 )
-            {
-                WT v0 = src[x], v1 = src[x+1];
-                T t0 = saturate_cast<T>(m[0]*v0 + m[1]*v1 + m[2]);
-                T t1 = saturate_cast<T>(m[3]*v0 + m[4]*v1 + m[5]);
-                dst[x] = t0; dst[x+1] = t1;
-            }
-        else
+        for( x = 0; x < len*2; x += 2 )
         {
-            const WT* _m = m;
-            for( k = 0; k < dst_cn; k++, dst++, _m += 3 )
-                for( x = 0; x < size.width; x++ )
-                    dst[x*dst_cn] = saturate_cast<T>(_m[0]*src[x*2] +
-                        _m[1]*src[x*2+1] + _m[2]);
+            WT v0 = src[x], v1 = src[x+1];
+            T t0 = saturate_cast<T>(m[0]*v0 + m[1]*v1 + m[2]);
+            T t1 = saturate_cast<T>(m[3]*v0 + m[4]*v1 + m[5]);
+            dst[x] = t0; dst[x+1] = t1;
         }
     }
-}
-
-template<typename T, typename WT> static void
-transformC3_( const Mat& srcmat, Mat& dstmat, Mat& tmat )
-{
-    Size size = getContinuousSize( srcmat, dstmat );
-    const WT* m = (const WT*)tmat.data;
-    int dst_cn = dstmat.channels();
-    int x, y, k;
-
-    for( y = 0; y < size.height; y++ )
+    else if( scn == 3 && dcn == 3 )
     {
-        const T* src = (const T*)(srcmat.data + srcmat.step*y);
-        T* dst = (T*)(dstmat.data + dstmat.step*y);
-
-        if( dst_cn == 3 )
-            for( x = 0; x < size.width*3; x += 3 )
-            {
-                WT v0 = src[x], v1 = src[x+1], v2 = src[x+2];
-                T t0 = saturate_cast<T>(m[0]*v0 + m[1]*v1 + m[2]*v2 + m[3]);
-                T t1 = saturate_cast<T>(m[4]*v0 + m[5]*v1 + m[6]*v2 + m[7]);
-                T t2 = saturate_cast<T>(m[8]*v0 + m[9]*v1 + m[10]*v2 + m[11]);
-                dst[x] = t0; dst[x+1] = t1; dst[x+2] = t2;
-            }
-        else if( dst_cn == 1 )
-            for( x = 0; x < size.width; x++, src += 3 )
-                dst[x] = saturate_cast<T>(m[0]*src[0] + m[1]*src[1] + m[2]*src[2] + m[3]);
-        else
+        for( x = 0; x < len*3; x += 3 )
         {
-            const WT* _m = m;
-            for( k = 0; k < dst_cn; k++, dst++, _m += 4 )
-                for( x = 0; x < size.width; x++ )
-                    dst[x*dst_cn] = saturate_cast<T>(_m[0]*src[x*3] +
-                        _m[1]*src[x*3+1] + _m[2]*src[x*3+2] + _m[3]);
+            WT v0 = src[x], v1 = src[x+1], v2 = src[x+2];
+            T t0 = saturate_cast<T>(m[0]*v0 + m[1]*v1 + m[2]*v2 + m[3]);
+            T t1 = saturate_cast<T>(m[4]*v0 + m[5]*v1 + m[6]*v2 + m[7]);
+            T t2 = saturate_cast<T>(m[8]*v0 + m[9]*v1 + m[10]*v2 + m[11]);
+            dst[x] = t0; dst[x+1] = t1; dst[x+2] = t2;
         }
     }
-}
-
-
-template<typename T, typename WT> static void
-transformC4_( const Mat& srcmat, Mat& dstmat, Mat& tmat )
-{
-    Size size = getContinuousSize( srcmat, dstmat );
-    const WT* m = (const WT*)tmat.data;
-    int dst_cn = dstmat.channels();
-    int x, y, k;
-
-    for( y = 0; y < size.height; y++ )
+    else if( scn == 3 && dcn == 1 )
     {
-        const T* src = (const T*)(srcmat.data + srcmat.step*y);
-        T* dst = (T*)(dstmat.data + dstmat.step*y);
-
-        if( dst_cn == 4 )
-            for( x = 0; x < size.width*4; x += 4 )
-            {
-                WT v0 = src[x], v1 = src[x+1], v2 = src[x+2], v3 = src[x+3];
-                T t0 = saturate_cast<T>(m[0]*v0 + m[1]*v1 + m[2]*v2 + m[3]*v3 + m[4]);
-                T t1 = saturate_cast<T>(m[5]*v0 + m[6]*v1 + m[7]*v2 + m[8]*v3 + m[9]);
-                dst[x] = t0; dst[x+1] = t1;
-                t0 = saturate_cast<T>(m[10]*v0 + m[11]*v1 + m[12]*v2 + m[13]*v3 + m[14]);
-                t1 = saturate_cast<T>(m[15]*v0 + m[16]*v1 + m[17]*v2 + m[18]*v3 + m[19]);
-                dst[x+2] = t0; dst[x+3] = t1;
-            }
-        else
+        for( x = 0; x < len; x++, src += 3 )
+            dst[x] = saturate_cast<T>(m[0]*src[0] + m[1]*src[1] + m[2]*src[2] + m[3]);
+    }
+    else if( scn == 4 && dcn == 4 )
+    {
+        for( x = 0; x < len*4; x += 4 )
+        {
+            WT v0 = src[x], v1 = src[x+1], v2 = src[x+2], v3 = src[x+3];
+            T t0 = saturate_cast<T>(m[0]*v0 + m[1]*v1 + m[2]*v2 + m[3]*v3 + m[4]);
+            T t1 = saturate_cast<T>(m[5]*v0 + m[6]*v1 + m[7]*v2 + m[8]*v3 + m[9]);
+            dst[x] = t0; dst[x+1] = t1;
+            t0 = saturate_cast<T>(m[10]*v0 + m[11]*v1 + m[12]*v2 + m[13]*v3 + m[14]);
+            t1 = saturate_cast<T>(m[15]*v0 + m[16]*v1 + m[17]*v2 + m[18]*v3 + m[19]);
+            dst[x+2] = t0; dst[x+3] = t1;
+        }
+    }
+    else
+    {
+        for( x = 0; x < len; x++, src += scn, dst += dcn )
         {
             const WT* _m = m;
-            for( k = 0; k < dst_cn; k++, dst++, _m += 5 )
-                for( x = 0; x < size.width; x++ )
-                    dst[x*dst_cn] = saturate_cast<T>(_m[0]*src[x*4] + _m[1]*src[x*4+1] +
-                                            _m[2]*src[x*4+2] + _m[3]*src[x*4+3] + _m[4]);
+            int j, k;
+            for( j = 0; j < dcn; j++, _m += scn + 1 )
+            {
+                WT s = _m[scn];
+                for( k = 0; k < scn; k++ )
+                    s += _m[k]*src[k];
+                dst[j] = saturate_cast<T>(s);
+            }
         }
     }
 }
 
-
 #if CV_SSE2
 
 static inline void
@@ -1411,19 +1351,16 @@ load4x4Matrix( const float* m, __m128& m0, __m128& m1, __m128& m2, __m128& m3, _
     m4 = _mm_setr_ps(m[4], m[9], m[14], m[19]);
 }
 
-template<> void
-transformC3_<uchar, float>( const Mat& srcmat, Mat& dstmat, Mat& tmat )
+#endif
+    
+static void
+transform_8u( const uchar* src, uchar* dst, const float* m, int len, int scn, int dcn )
 {
-    typedef uchar T;
-    typedef float WT;
+#if CV_SSE2
     const int BITS = 10, SCALE = 1 << BITS;
     const float MAX_M = (float)(1 << (15 - BITS));
-    Size size = getContinuousSize( srcmat, dstmat );
-    const float* m = (const float*)tmat.data;
-    int dst_cn = dstmat.channels();
-    int x, y, k;
 
-    if( checkHardwareSupport(CV_CPU_SSE2) && dst_cn == 3 &&
+    if( USE_SSE2 && scn == 3 && dcn == 3 &&
         std::abs(m[0]) < MAX_M && std::abs(m[1]) < MAX_M && std::abs(m[2]) < MAX_M && std::abs(m[3]) < MAX_M*256 &&
         std::abs(m[4]) < MAX_M && std::abs(m[5]) < MAX_M && std::abs(m[6]) < MAX_M && std::abs(m[7]) < MAX_M*256 &&
         std::abs(m[8]) < MAX_M && std::abs(m[9]) < MAX_M && std::abs(m[10]) < MAX_M && std::abs(m[11]) < MAX_M*256 )
@@ -1441,238 +1378,182 @@ transformC3_<uchar, float>( const Mat& srcmat, Mat& dstmat, Mat& tmat )
         __m128i m1 = _mm_setr_epi16(0, m10, m11, m12, m10, m11, m12, 0);
         __m128i m2 = _mm_setr_epi16(0, m20, m21, m22, m20, m21, m22, 0);
         __m128i m3 = _mm_setr_epi32(m03, m13, m23, 0);
-
-        for( y = 0; y < size.height; y++ )
-        {
-            const T* src = (const T*)(srcmat.data + srcmat.step*y);
-            T* dst = (T*)(dstmat.data + dstmat.step*y);
-            int x = 0;
-
-            for( ; x <= (size.width - 8)*3; x += 8*3 )
-            {
-                __m128i z = _mm_setzero_si128(), t0, t1, t2, r0, r1;
-                __m128i v0 = _mm_loadl_epi64((const __m128i*)(src + x));
-                __m128i v1 = _mm_loadl_epi64((const __m128i*)(src + x + 8));
-                __m128i v2 = _mm_loadl_epi64((const __m128i*)(src + x + 16)), v3;
-                v0 = _mm_unpacklo_epi8(v0, z); // b0 g0 r0 b1 g1 r1 b2 g2
-                v1 = _mm_unpacklo_epi8(v1, z); // r2 b3 g3 r3 b4 g4 r4 b5
-                v2 = _mm_unpacklo_epi8(v2, z); // g5 r5 b6 g6 r6 b7 g7 r7
-
-                v3 = _mm_srli_si128(v2, 2); // ? b6 g6 r6 b7 g7 r7 0
-                v2 = _mm_or_si128(_mm_slli_si128(v2, 10), _mm_srli_si128(v1, 6)); // ? b4 g4 r4 b5 g5 r5 ?
-                v1 = _mm_or_si128(_mm_slli_si128(v1, 6), _mm_srli_si128(v0, 10)); // ? b2 g2 r2 b3 g3 r3 ?
-                v0 = _mm_slli_si128(v0, 2); // 0 b0 g0 r0 b1 g1 r1 ?
-
-                // process pixels 0 & 1
-                t0 = _mm_madd_epi16(v0, m0); // a0 b0 a1 b1
-                t1 = _mm_madd_epi16(v0, m1); // c0 d0 c1 d1
-                t2 = _mm_madd_epi16(v0, m2); // e0 f0 e1 f1
-                v0 = _mm_unpacklo_epi32(t0, t1); // a0 c0 b0 d0
-                t0 = _mm_unpackhi_epi32(t0, t1); // a1 b1 c1 d1
-                t1 = _mm_unpacklo_epi32(t2, z);  // e0 0 f0 0
-                t2 = _mm_unpackhi_epi32(t2, z);  // e1 0 f1 0
-                r0 = _mm_add_epi32(_mm_add_epi32(_mm_unpacklo_epi64(v0, t1), _mm_unpackhi_epi64(v0,t1)), m3); // B0 G0 R0 0
-                r1 = _mm_add_epi32(_mm_add_epi32(_mm_unpacklo_epi64(t0, t2), _mm_unpackhi_epi64(t0,t2)), m3); // B1 G1 R1 0
-                r0 = _mm_srai_epi32(r0, BITS);
-                r1 = _mm_srai_epi32(r1, BITS);
-                v0 = _mm_packus_epi16(_mm_packs_epi32(_mm_slli_si128(r0, 4), r1), z); // 0 B0 G0 R0 B1 G1 R1 0
-
-                // process pixels 2 & 3
-                t0 = _mm_madd_epi16(v1, m0); // a0 b0 a1 b1
-                t1 = _mm_madd_epi16(v1, m1); // c0 d0 c1 d1
-                t2 = _mm_madd_epi16(v1, m2); // e0 f0 e1 f1
-                v1 = _mm_unpacklo_epi32(t0, t1); // a0 c0 b0 d0
-                t0 = _mm_unpackhi_epi32(t0, t1); // a1 b1 c1 d1
-                t1 = _mm_unpacklo_epi32(t2, z);  // e0 0 f0 0
-                t2 = _mm_unpackhi_epi32(t2, z);  // e1 0 f1 0
-                r0 = _mm_add_epi32(_mm_add_epi32(_mm_unpacklo_epi64(v1, t1), _mm_unpackhi_epi64(v1,t1)), m3); // B2 G2 R2 0
-                r1 = _mm_add_epi32(_mm_add_epi32(_mm_unpacklo_epi64(t0, t2), _mm_unpackhi_epi64(t0,t2)), m3); // B3 G3 R3 0
-                r0 = _mm_srai_epi32(r0, BITS);
-                r1 = _mm_srai_epi32(r1, BITS);
-                v1 = _mm_packus_epi16(_mm_packs_epi32(_mm_slli_si128(r0, 4), r1), z); // 0 B2 G2 R2 B3 G3 R3 0
-
-                // process pixels 4 & 5
-                t0 = _mm_madd_epi16(v2, m0); // a0 b0 a1 b1
-                t1 = _mm_madd_epi16(v2, m1); // c0 d0 c1 d1
-                t2 = _mm_madd_epi16(v2, m2); // e0 f0 e1 f1
-                v2 = _mm_unpacklo_epi32(t0, t1); // a0 c0 b0 d0
-                t0 = _mm_unpackhi_epi32(t0, t1); // a1 b1 c1 d1
-                t1 = _mm_unpacklo_epi32(t2, z);  // e0 0 f0 0
-                t2 = _mm_unpackhi_epi32(t2, z);  // e1 0 f1 0
-                r0 = _mm_add_epi32(_mm_add_epi32(_mm_unpacklo_epi64(v2, t1), _mm_unpackhi_epi64(v2,t1)), m3); // B4 G4 R4 0
-                r1 = _mm_add_epi32(_mm_add_epi32(_mm_unpacklo_epi64(t0, t2), _mm_unpackhi_epi64(t0,t2)), m3); // B5 G5 R5 0
-                r0 = _mm_srai_epi32(r0, BITS);
-                r1 = _mm_srai_epi32(r1, BITS);
-                v2 = _mm_packus_epi16(_mm_packs_epi32(_mm_slli_si128(r0, 4), r1), z); // 0 B4 G4 R4 B5 G5 R5 0
-
-                // process pixels 6 & 7
-                t0 = _mm_madd_epi16(v3, m0); // a0 b0 a1 b1
-                t1 = _mm_madd_epi16(v3, m1); // c0 d0 c1 d1
-                t2 = _mm_madd_epi16(v3, m2); // e0 f0 e1 f1
-                v3 = _mm_unpacklo_epi32(t0, t1); // a0 c0 b0 d0
-                t0 = _mm_unpackhi_epi32(t0, t1); // a1 b1 c1 d1
-                t1 = _mm_unpacklo_epi32(t2, z);  // e0 0 f0 0
-                t2 = _mm_unpackhi_epi32(t2, z);  // e1 0 f1 0
-                r0 = _mm_add_epi32(_mm_add_epi32(_mm_unpacklo_epi64(v3, t1), _mm_unpackhi_epi64(v3,t1)), m3); // B6 G6 R6 0
-                r1 = _mm_add_epi32(_mm_add_epi32(_mm_unpacklo_epi64(t0, t2), _mm_unpackhi_epi64(t0,t2)), m3); // B7 G7 R7 0
-                r0 = _mm_srai_epi32(r0, BITS);
-                r1 = _mm_srai_epi32(r1, BITS);
-                v3 = _mm_packus_epi16(_mm_packs_epi32(_mm_slli_si128(r0, 4), r1), z); // 0 B6 G6 R6 B7 G7 R7 0
-
-                v0 = _mm_or_si128(_mm_srli_si128(v0, 1), _mm_slli_si128(v1, 5));
-                v1 = _mm_or_si128(_mm_srli_si128(v1, 3), _mm_slli_si128(v2, 3));
-                v2 = _mm_or_si128(_mm_srli_si128(v2, 5), _mm_slli_si128(v3, 1));
-                _mm_storel_epi64((__m128i*)(dst + x), v0);
-                _mm_storel_epi64((__m128i*)(dst + x + 8), v1);
-                _mm_storel_epi64((__m128i*)(dst + x + 16), v2);
-            }
-
-            for( ; x < size.width*3; x += 3 )
-            {
-                int v0 = src[x], v1 = src[x+1], v2 = src[x+2];
-                uchar t0 = saturate_cast<uchar>((m00*v0 + m01*v1 + m02*v2 + m03)>>BITS);
-                uchar t1 = saturate_cast<uchar>((m10*v0 + m11*v1 + m12*v2 + m13)>>BITS);
-                uchar t2 = saturate_cast<uchar>((m20*v0 + m21*v1 + m22*v2 + m23)>>BITS);
-                dst[x] = t0; dst[x+1] = t1; dst[x+2] = t2;
-            }
+        int x = 0;
+        
+        for( ; x <= (len - 8)*3; x += 8*3 )
+        {
+            __m128i z = _mm_setzero_si128(), t0, t1, t2, r0, r1;
+            __m128i v0 = _mm_loadl_epi64((const __m128i*)(src + x));
+            __m128i v1 = _mm_loadl_epi64((const __m128i*)(src + x + 8));
+            __m128i v2 = _mm_loadl_epi64((const __m128i*)(src + x + 16)), v3;
+            v0 = _mm_unpacklo_epi8(v0, z); // b0 g0 r0 b1 g1 r1 b2 g2
+            v1 = _mm_unpacklo_epi8(v1, z); // r2 b3 g3 r3 b4 g4 r4 b5
+            v2 = _mm_unpacklo_epi8(v2, z); // g5 r5 b6 g6 r6 b7 g7 r7
+
+            v3 = _mm_srli_si128(v2, 2); // ? b6 g6 r6 b7 g7 r7 0
+            v2 = _mm_or_si128(_mm_slli_si128(v2, 10), _mm_srli_si128(v1, 6)); // ? b4 g4 r4 b5 g5 r5 ?
+            v1 = _mm_or_si128(_mm_slli_si128(v1, 6), _mm_srli_si128(v0, 10)); // ? b2 g2 r2 b3 g3 r3 ?
+            v0 = _mm_slli_si128(v0, 2); // 0 b0 g0 r0 b1 g1 r1 ?
+
+            // process pixels 0 & 1
+            t0 = _mm_madd_epi16(v0, m0); // a0 b0 a1 b1
+            t1 = _mm_madd_epi16(v0, m1); // c0 d0 c1 d1
+            t2 = _mm_madd_epi16(v0, m2); // e0 f0 e1 f1
+            v0 = _mm_unpacklo_epi32(t0, t1); // a0 c0 b0 d0
+            t0 = _mm_unpackhi_epi32(t0, t1); // a1 b1 c1 d1
+            t1 = _mm_unpacklo_epi32(t2, z);  // e0 0 f0 0
+            t2 = _mm_unpackhi_epi32(t2, z);  // e1 0 f1 0
+            r0 = _mm_add_epi32(_mm_add_epi32(_mm_unpacklo_epi64(v0, t1), _mm_unpackhi_epi64(v0,t1)), m3); // B0 G0 R0 0
+            r1 = _mm_add_epi32(_mm_add_epi32(_mm_unpacklo_epi64(t0, t2), _mm_unpackhi_epi64(t0,t2)), m3); // B1 G1 R1 0
+            r0 = _mm_srai_epi32(r0, BITS);
+            r1 = _mm_srai_epi32(r1, BITS);
+            v0 = _mm_packus_epi16(_mm_packs_epi32(_mm_slli_si128(r0, 4), r1), z); // 0 B0 G0 R0 B1 G1 R1 0
+
+            // process pixels 2 & 3
+            t0 = _mm_madd_epi16(v1, m0); // a0 b0 a1 b1
+            t1 = _mm_madd_epi16(v1, m1); // c0 d0 c1 d1
+            t2 = _mm_madd_epi16(v1, m2); // e0 f0 e1 f1
+            v1 = _mm_unpacklo_epi32(t0, t1); // a0 c0 b0 d0
+            t0 = _mm_unpackhi_epi32(t0, t1); // a1 b1 c1 d1
+            t1 = _mm_unpacklo_epi32(t2, z);  // e0 0 f0 0
+            t2 = _mm_unpackhi_epi32(t2, z);  // e1 0 f1 0
+            r0 = _mm_add_epi32(_mm_add_epi32(_mm_unpacklo_epi64(v1, t1), _mm_unpackhi_epi64(v1,t1)), m3); // B2 G2 R2 0
+            r1 = _mm_add_epi32(_mm_add_epi32(_mm_unpacklo_epi64(t0, t2), _mm_unpackhi_epi64(t0,t2)), m3); // B3 G3 R3 0
+            r0 = _mm_srai_epi32(r0, BITS);
+            r1 = _mm_srai_epi32(r1, BITS);
+            v1 = _mm_packus_epi16(_mm_packs_epi32(_mm_slli_si128(r0, 4), r1), z); // 0 B2 G2 R2 B3 G3 R3 0
+
+            // process pixels 4 & 5
+            t0 = _mm_madd_epi16(v2, m0); // a0 b0 a1 b1
+            t1 = _mm_madd_epi16(v2, m1); // c0 d0 c1 d1
+            t2 = _mm_madd_epi16(v2, m2); // e0 f0 e1 f1
+            v2 = _mm_unpacklo_epi32(t0, t1); // a0 c0 b0 d0
+            t0 = _mm_unpackhi_epi32(t0, t1); // a1 b1 c1 d1
+            t1 = _mm_unpacklo_epi32(t2, z);  // e0 0 f0 0
+            t2 = _mm_unpackhi_epi32(t2, z);  // e1 0 f1 0
+            r0 = _mm_add_epi32(_mm_add_epi32(_mm_unpacklo_epi64(v2, t1), _mm_unpackhi_epi64(v2,t1)), m3); // B4 G4 R4 0
+            r1 = _mm_add_epi32(_mm_add_epi32(_mm_unpacklo_epi64(t0, t2), _mm_unpackhi_epi64(t0,t2)), m3); // B5 G5 R5 0
+            r0 = _mm_srai_epi32(r0, BITS);
+            r1 = _mm_srai_epi32(r1, BITS);
+            v2 = _mm_packus_epi16(_mm_packs_epi32(_mm_slli_si128(r0, 4), r1), z); // 0 B4 G4 R4 B5 G5 R5 0
+
+            // process pixels 6 & 7
+            t0 = _mm_madd_epi16(v3, m0); // a0 b0 a1 b1
+            t1 = _mm_madd_epi16(v3, m1); // c0 d0 c1 d1
+            t2 = _mm_madd_epi16(v3, m2); // e0 f0 e1 f1
+            v3 = _mm_unpacklo_epi32(t0, t1); // a0 c0 b0 d0
+            t0 = _mm_unpackhi_epi32(t0, t1); // a1 b1 c1 d1
+            t1 = _mm_unpacklo_epi32(t2, z);  // e0 0 f0 0
+            t2 = _mm_unpackhi_epi32(t2, z);  // e1 0 f1 0
+            r0 = _mm_add_epi32(_mm_add_epi32(_mm_unpacklo_epi64(v3, t1), _mm_unpackhi_epi64(v3,t1)), m3); // B6 G6 R6 0
+            r1 = _mm_add_epi32(_mm_add_epi32(_mm_unpacklo_epi64(t0, t2), _mm_unpackhi_epi64(t0,t2)), m3); // B7 G7 R7 0
+            r0 = _mm_srai_epi32(r0, BITS);
+            r1 = _mm_srai_epi32(r1, BITS);
+            v3 = _mm_packus_epi16(_mm_packs_epi32(_mm_slli_si128(r0, 4), r1), z); // 0 B6 G6 R6 B7 G7 R7 0
+
+            v0 = _mm_or_si128(_mm_srli_si128(v0, 1), _mm_slli_si128(v1, 5));
+            v1 = _mm_or_si128(_mm_srli_si128(v1, 3), _mm_slli_si128(v2, 3));
+            v2 = _mm_or_si128(_mm_srli_si128(v2, 5), _mm_slli_si128(v3, 1));
+            _mm_storel_epi64((__m128i*)(dst + x), v0);
+            _mm_storel_epi64((__m128i*)(dst + x + 8), v1);
+            _mm_storel_epi64((__m128i*)(dst + x + 16), v2);
+        }
+
+        for( ; x < len*3; x += 3 )
+        {
+            int v0 = src[x], v1 = src[x+1], v2 = src[x+2];
+            uchar t0 = saturate_cast<uchar>((m00*v0 + m01*v1 + m02*v2 + m03)>>BITS);
+            uchar t1 = saturate_cast<uchar>((m10*v0 + m11*v1 + m12*v2 + m13)>>BITS);
+            uchar t2 = saturate_cast<uchar>((m20*v0 + m21*v1 + m22*v2 + m23)>>BITS);
+            dst[x] = t0; dst[x+1] = t1; dst[x+2] = t2;
         }
         return;
     }
-
-    for( y = 0; y < size.height; y++ )
-    {
-        const T* src = (const T*)(srcmat.data + srcmat.step*y);
-        T* dst = (T*)(dstmat.data + dstmat.step*y);
-
-        if( dst_cn == 1 )
-            for( x = 0; x < size.width; x++, src += 3 )
-                dst[x] = saturate_cast<T>(m[0]*CV_8TO32F(src[0]) +
-                        m[1]*CV_8TO32F(src[1]) + m[2]*CV_8TO32F(src[2]) + m[3]);
-        else
-        {
-            const WT* _m = m;
-            for( k = 0; k < dst_cn; k++, dst++, _m += 4 )
-                for( x = 0; x < size.width; x++ )
-                    dst[x*dst_cn] = saturate_cast<T>(_m[0]*CV_8TO32F(src[x*3]) +
-                        _m[1]*CV_8TO32F(src[x*3+1]) + _m[2]*CV_8TO32F(src[x*3+2]) + _m[3]);
-        }
-    }
+#endif
+    
+    transform_(src, dst, m, len, scn, dcn);
 }
 
-template<> void
-transformC3_<ushort, float>( const Mat& srcmat, Mat& dstmat, Mat& tmat )
+static void
+transform_16u( const ushort* src, ushort* dst, const float* m, int len, int scn, int dcn )
 {
-    typedef ushort T;
-    typedef float WT;
-    Size size = getContinuousSize( srcmat, dstmat );
-    const float* m = (const float*)tmat.data;
-    int dst_cn = dstmat.channels();
-    int x, y, k;
-
-    if( checkHardwareSupport(CV_CPU_SSE2) && dst_cn == 3 )
+#if CV_SSE2    
+    if( USE_SSE2 && scn == 3 && dcn == 3 )
     {
         __m128 m0, m1, m2, m3;
         __m128i delta = _mm_setr_epi16(0,-32768,-32768,-32768,-32768,-32768,-32768,0);
         load3x3Matrix(m, m0, m1, m2, m3);
         m3 = _mm_sub_ps(m3, _mm_setr_ps(32768.f, 32768.f, 32768.f, 0.f));
 
-        for( y = 0; y < size.height; y++ )
-        {
-            const T* src = (const T*)(srcmat.data + srcmat.step*y);
-            T* dst = (T*)(dstmat.data + dstmat.step*y);
-            int x = 0;
-
-            for( ; x <= (size.width - 4)*3; x += 4*3 )
-            {
-                __m128i z = _mm_setzero_si128();
-                __m128i v0 = _mm_loadu_si128((const __m128i*)(src + x)), v1;
-                __m128i v2 = _mm_loadl_epi64((const __m128i*)(src + x + 8)), v3;
-                v1 = _mm_unpacklo_epi16(_mm_srli_si128(v0, 6), z); // b1 g1 r1
-                v3 = _mm_unpacklo_epi16(_mm_srli_si128(v2, 2), z); // b3 g3 r3
-                v2 = _mm_or_si128(_mm_srli_si128(v0, 12), _mm_slli_si128(v2, 4));
-                v0 = _mm_unpacklo_epi16(v0, z); // b0 g0 r0
-                v2 = _mm_unpacklo_epi16(v2, z); // b2 g2 r2
-                __m128 x0 = _mm_cvtepi32_ps(v0), x1 = _mm_cvtepi32_ps(v1);
-                __m128 x2 = _mm_cvtepi32_ps(v2), x3 = _mm_cvtepi32_ps(v3);
-                __m128 y0 = _mm_add_ps(_mm_add_ps(_mm_add_ps(
-                            _mm_mul_ps(m0, _mm_shuffle_ps(x0,x0,_MM_SHUFFLE(0,0,0,0))),
-                            _mm_mul_ps(m1, _mm_shuffle_ps(x0,x0,_MM_SHUFFLE(1,1,1,1)))),
-                            _mm_mul_ps(m2, _mm_shuffle_ps(x0,x0,_MM_SHUFFLE(2,2,2,2)))), m3);
-                __m128 y1 = _mm_add_ps(_mm_add_ps(_mm_add_ps(
-                            _mm_mul_ps(m0, _mm_shuffle_ps(x1,x1,_MM_SHUFFLE(0,0,0,0))),
-                            _mm_mul_ps(m1, _mm_shuffle_ps(x1,x1,_MM_SHUFFLE(1,1,1,1)))),
-                            _mm_mul_ps(m2, _mm_shuffle_ps(x1,x1,_MM_SHUFFLE(2,2,2,2)))), m3);
-                __m128 y2 = _mm_add_ps(_mm_add_ps(_mm_add_ps(
-                            _mm_mul_ps(m0, _mm_shuffle_ps(x2,x2,_MM_SHUFFLE(0,0,0,0))),
-                            _mm_mul_ps(m1, _mm_shuffle_ps(x2,x2,_MM_SHUFFLE(1,1,1,1)))),
-                            _mm_mul_ps(m2, _mm_shuffle_ps(x2,x2,_MM_SHUFFLE(2,2,2,2)))), m3);
-                __m128 y3 = _mm_add_ps(_mm_add_ps(_mm_add_ps(
-                            _mm_mul_ps(m0, _mm_shuffle_ps(x3,x3,_MM_SHUFFLE(0,0,0,0))),
-                            _mm_mul_ps(m1, _mm_shuffle_ps(x3,x3,_MM_SHUFFLE(1,1,1,1)))),
-                            _mm_mul_ps(m2, _mm_shuffle_ps(x3,x3,_MM_SHUFFLE(2,2,2,2)))), m3);
-                v0 = _mm_cvtps_epi32(y0); v1 = _mm_cvtps_epi32(y1);
-                v2 = _mm_cvtps_epi32(y2); v3 = _mm_cvtps_epi32(y3);
-
-                v0 = _mm_add_epi16(_mm_packs_epi32(_mm_slli_si128(v0,4), v1), delta); // 0 b0 g0 r0 b1 g1 r1 0
-                v2 = _mm_add_epi16(_mm_packs_epi32(_mm_slli_si128(v2,4), v3), delta); // 0 b2 g2 r2 b3 g3 r3 0
-                v1 = _mm_or_si128(_mm_srli_si128(v0,2), _mm_slli_si128(v2,10)); // b0 g0 r0 b1 g1 r1 b2 g2
-                v2 = _mm_srli_si128(v2, 6); // r2 b3 g3 r3 0 0 0 0
-                _mm_storeu_si128((__m128i*)(dst + x), v1);
-                _mm_storel_epi64((__m128i*)(dst + x + 8), v2);
-            }
-
-            for( ; x < size.width*3; x += 3 )
-            {
-                WT v0 = src[x], v1 = src[x+1], v2 = src[x+2];
-                T t0 = saturate_cast<T>(m[0]*v0 + m[1]*v1 + m[2]*v2 + m[3]);
-                T t1 = saturate_cast<T>(m[4]*v0 + m[5]*v1 + m[6]*v2 + m[7]);
-                T t2 = saturate_cast<T>(m[8]*v0 + m[9]*v1 + m[10]*v2 + m[11]);
-                dst[x] = t0; dst[x+1] = t1; dst[x+2] = t2;
-            }
+        int x = 0;
+        for( ; x <= (len - 4)*3; x += 4*3 )
+        {
+            __m128i z = _mm_setzero_si128();
+            __m128i v0 = _mm_loadu_si128((const __m128i*)(src + x)), v1;
+            __m128i v2 = _mm_loadl_epi64((const __m128i*)(src + x + 8)), v3;
+            v1 = _mm_unpacklo_epi16(_mm_srli_si128(v0, 6), z); // b1 g1 r1
+            v3 = _mm_unpacklo_epi16(_mm_srli_si128(v2, 2), z); // b3 g3 r3
+            v2 = _mm_or_si128(_mm_srli_si128(v0, 12), _mm_slli_si128(v2, 4));
+            v0 = _mm_unpacklo_epi16(v0, z); // b0 g0 r0
+            v2 = _mm_unpacklo_epi16(v2, z); // b2 g2 r2
+            __m128 x0 = _mm_cvtepi32_ps(v0), x1 = _mm_cvtepi32_ps(v1);
+            __m128 x2 = _mm_cvtepi32_ps(v2), x3 = _mm_cvtepi32_ps(v3);
+            __m128 y0 = _mm_add_ps(_mm_add_ps(_mm_add_ps(
+                        _mm_mul_ps(m0, _mm_shuffle_ps(x0,x0,_MM_SHUFFLE(0,0,0,0))),
+                        _mm_mul_ps(m1, _mm_shuffle_ps(x0,x0,_MM_SHUFFLE(1,1,1,1)))),
+                        _mm_mul_ps(m2, _mm_shuffle_ps(x0,x0,_MM_SHUFFLE(2,2,2,2)))), m3);
+            __m128 y1 = _mm_add_ps(_mm_add_ps(_mm_add_ps(
+                        _mm_mul_ps(m0, _mm_shuffle_ps(x1,x1,_MM_SHUFFLE(0,0,0,0))),
+                        _mm_mul_ps(m1, _mm_shuffle_ps(x1,x1,_MM_SHUFFLE(1,1,1,1)))),
+                        _mm_mul_ps(m2, _mm_shuffle_ps(x1,x1,_MM_SHUFFLE(2,2,2,2)))), m3);
+            __m128 y2 = _mm_add_ps(_mm_add_ps(_mm_add_ps(
+                        _mm_mul_ps(m0, _mm_shuffle_ps(x2,x2,_MM_SHUFFLE(0,0,0,0))),
+                        _mm_mul_ps(m1, _mm_shuffle_ps(x2,x2,_MM_SHUFFLE(1,1,1,1)))),
+                        _mm_mul_ps(m2, _mm_shuffle_ps(x2,x2,_MM_SHUFFLE(2,2,2,2)))), m3);
+            __m128 y3 = _mm_add_ps(_mm_add_ps(_mm_add_ps(
+                        _mm_mul_ps(m0, _mm_shuffle_ps(x3,x3,_MM_SHUFFLE(0,0,0,0))),
+                        _mm_mul_ps(m1, _mm_shuffle_ps(x3,x3,_MM_SHUFFLE(1,1,1,1)))),
+                        _mm_mul_ps(m2, _mm_shuffle_ps(x3,x3,_MM_SHUFFLE(2,2,2,2)))), m3);
+            v0 = _mm_cvtps_epi32(y0); v1 = _mm_cvtps_epi32(y1);
+            v2 = _mm_cvtps_epi32(y2); v3 = _mm_cvtps_epi32(y3);
+
+            v0 = _mm_add_epi16(_mm_packs_epi32(_mm_slli_si128(v0,4), v1), delta); // 0 b0 g0 r0 b1 g1 r1 0
+            v2 = _mm_add_epi16(_mm_packs_epi32(_mm_slli_si128(v2,4), v3), delta); // 0 b2 g2 r2 b3 g3 r3 0
+            v1 = _mm_or_si128(_mm_srli_si128(v0,2), _mm_slli_si128(v2,10)); // b0 g0 r0 b1 g1 r1 b2 g2
+            v2 = _mm_srli_si128(v2, 6); // r2 b3 g3 r3 0 0 0 0
+            _mm_storeu_si128((__m128i*)(dst + x), v1);
+            _mm_storel_epi64((__m128i*)(dst + x + 8), v2);
+        }
+
+        for( ; x < len*3; x += 3 )
+        {
+            float v0 = src[x], v1 = src[x+1], v2 = src[x+2];
+            ushort t0 = saturate_cast<ushort>(m[0]*v0 + m[1]*v1 + m[2]*v2 + m[3]);
+            ushort t1 = saturate_cast<ushort>(m[4]*v0 + m[5]*v1 + m[6]*v2 + m[7]);
+            ushort t2 = saturate_cast<ushort>(m[8]*v0 + m[9]*v1 + m[10]*v2 + m[11]);
+            dst[x] = t0; dst[x+1] = t1; dst[x+2] = t2;
         }
         return;
     }
-
-    for( y = 0; y < size.height; y++ )
-    {
-        const T* src = (const T*)(srcmat.data + srcmat.step*y);
-        T* dst = (T*)(dstmat.data + dstmat.step*y);
-
-        if( dst_cn == 1 )
-            for( x = 0; x < size.width; x++, src += 3 )
-                dst[x] = saturate_cast<T>(m[0]*src[0] + m[1]*src[1] + m[2]*src[2] + m[3]);
-        else
-        {
-            const WT* _m = m;
-            for( k = 0; k < dst_cn; k++, dst++, _m += 4 )
-                for( x = 0; x < size.width; x++ )
-                    dst[x*dst_cn] = saturate_cast<T>(_m[0]*src[x*3] + _m[1]*src[x*3+1] + _m[2]*src[x*3+2] + _m[3]);
-        }
-    }
+#endif
+    
+    transform_(src, dst, m, len, scn, dcn);
 }
-
-template<> void
-transformC3_<float, float>( const Mat& srcmat, Mat& dstmat, Mat& tmat )
+    
+    
+static void
+transform_32f( const float* src, float* dst, const float* m, int len, int scn, int dcn )
 {
-    typedef float T;
-    typedef float WT;
-    Size size = getContinuousSize( srcmat, dstmat );
-    const float* m = (const float*)tmat.data;
-    int dst_cn = dstmat.channels();
-    int x, y, k;
-
-    if( checkHardwareSupport(CV_CPU_SSE2) && dst_cn == 3 )
+#if CV_SSE2
+    if( USE_SSE2 )
     {
-        __m128 m0, m1, m2, m3;
-        load3x3Matrix(m, m0, m1, m2, m3);
-
-        for( y = 0; y < size.height; y++ )
+        int x = 0;
+        if( scn == 3 && dcn == 3 )
         {
-            const T* src = (const T*)(srcmat.data + srcmat.step*y);
-            T* dst = (T*)(dstmat.data + dstmat.step*y);
-            int x = 0;
+            __m128 m0, m1, m2, m3;
+            load3x3Matrix(m, m0, m1, m2, m3);
 
-            for( ; x < (size.width - 1)*3; x += 3 )
+            for( ; x < (len - 1)*3; x += 3 )
             {
                 __m128 x0 = _mm_loadu_ps(src + x);
                 __m128 y0 = _mm_add_ps(_mm_add_ps(_mm_add_ps(
@@ -1683,119 +1564,82 @@ transformC3_<float, float>( const Mat& srcmat, Mat& dstmat, Mat& tmat )
                 _mm_store_ss(dst + x + 2, _mm_movehl_ps(y0,y0));
             }
 
-            for( ; x < size.width*3; x += 3 )
+            for( ; x < len*3; x += 3 )
             {
-                WT v0 = src[x], v1 = src[x+1], v2 = src[x+2];
-                T t0 = saturate_cast<T>(m[0]*v0 + m[1]*v1 + m[2]*v2 + m[3]);
-                T t1 = saturate_cast<T>(m[4]*v0 + m[5]*v1 + m[6]*v2 + m[7]);
-                T t2 = saturate_cast<T>(m[8]*v0 + m[9]*v1 + m[10]*v2 + m[11]);
+                float v0 = src[x], v1 = src[x+1], v2 = src[x+2];
+                float t0 = saturate_cast<float>(m[0]*v0 + m[1]*v1 + m[2]*v2 + m[3]);
+                float t1 = saturate_cast<float>(m[4]*v0 + m[5]*v1 + m[6]*v2 + m[7]);
+                float t2 = saturate_cast<float>(m[8]*v0 + m[9]*v1 + m[10]*v2 + m[11]);
                 dst[x] = t0; dst[x+1] = t1; dst[x+2] = t2;
             }
+            return;
         }
-        return;
-    }
-
-    for( y = 0; y < size.height; y++ )
-    {
-        const T* src = (const T*)(srcmat.data + srcmat.step*y);
-        T* dst = (T*)(dstmat.data + dstmat.step*y);
-
-        if( dst_cn == 1 )
-            for( x = 0; x < size.width; x++, src += 3 )
-                dst[x] = saturate_cast<T>(m[0]*src[0] + m[1]*src[1] + m[2]*src[2] + m[3]);
-        else
-        {
-            const WT* _m = m;
-            for( k = 0; k < dst_cn; k++, dst++, _m += 4 )
-                for( x = 0; x < size.width; x++ )
-                    dst[x*dst_cn] = saturate_cast<T>(_m[0]*src[x*3] + _m[1]*src[x*3+1] + _m[2]*src[x*3+2] + _m[3]);
-        }
-    }
-}
-
-
-template<> void
-transformC4_<float, float>( const Mat& srcmat, Mat& dstmat, Mat& tmat )
-{
-    typedef float T;
-    typedef float WT;
-    Size size = getContinuousSize( srcmat, dstmat );
-    const WT* m = (const WT*)tmat.data;
-    int dst_cn = dstmat.channels();
-    int x, y, k;
-
-    if( checkHardwareSupport(CV_CPU_SSE2) && dst_cn == 4 )
-    {
-        __m128 m0, m1, m2, m3, m4;
-        load4x4Matrix(m, m0, m1, m2, m3, m4);
-
-        for( y = 0; y < size.height; y++ )
+        
+        if( scn == 4 && dcn == 4 )
         {
-            const T* src = (const T*)(srcmat.data + srcmat.step*y);
-            T* dst = (T*)(dstmat.data + dstmat.step*y);
-            for( x = 0; x < size.width*4; x += 4 )
+            __m128 m0, m1, m2, m3, m4;
+            load4x4Matrix(m, m0, m1, m2, m3, m4);
+        
+            for( ; x < len*4; x += 4 )
             {
                 __m128 x0 = _mm_loadu_ps(src + x);
                 __m128 y0 = _mm_add_ps(_mm_add_ps(_mm_add_ps(_mm_add_ps(
-                            _mm_mul_ps(m0, _mm_shuffle_ps(x0,x0,_MM_SHUFFLE(0,0,0,0))),
-                            _mm_mul_ps(m1, _mm_shuffle_ps(x0,x0,_MM_SHUFFLE(1,1,1,1)))),
-                            _mm_mul_ps(m2, _mm_shuffle_ps(x0,x0,_MM_SHUFFLE(2,2,2,2)))),
-                            _mm_mul_ps(m3, _mm_shuffle_ps(x0,x0,_MM_SHUFFLE(3,3,3,3)))), m4);
+                                    _mm_mul_ps(m0, _mm_shuffle_ps(x0,x0,_MM_SHUFFLE(0,0,0,0))),
+                                    _mm_mul_ps(m1, _mm_shuffle_ps(x0,x0,_MM_SHUFFLE(1,1,1,1)))),
+                                    _mm_mul_ps(m2, _mm_shuffle_ps(x0,x0,_MM_SHUFFLE(2,2,2,2)))),
+                                    _mm_mul_ps(m3, _mm_shuffle_ps(x0,x0,_MM_SHUFFLE(3,3,3,3)))), m4);
                 _mm_storeu_ps(dst + x, y0);
             }
+            return;
         }
-        return;
     }
+#endif
 
-    for( y = 0; y < size.height; y++ )
-    {
-        const T* src = (const T*)(srcmat.data + srcmat.step*y);
-        T* dst = (T*)(dstmat.data + dstmat.step*y);
-        const WT* _m = m;
-        for( k = 0; k < dst_cn; k++, dst++, _m += 5 )
-            for( x = 0; x < size.width; x++ )
-                dst[x*dst_cn] = saturate_cast<T>(_m[0]*src[x*4] + _m[1]*src[x*4+1] +
-                                                 _m[2]*src[x*4+2] + _m[3]*src[x*4+3] + _m[4]);
-    }
+    transform_(src, dst, m, len, scn, dcn);
 }
 
-#endif
 
+static void
+transform_8s(const schar* src, schar* dst, const float* m, int len, int scn, int dcn)
+{
+    transform_(src, dst, m, len, scn, dcn);
+}
 
-template<typename T, typename WT> static void
-diagtransC2_( const Mat& srcmat, Mat& dstmat, Mat& tmat )
+static void
+transform_16s(const short* src, short* dst, const float* m, int len, int scn, int dcn)
 {
-    Size size = getContinuousSize( srcmat, dstmat );
-    const WT* m = (const WT*)tmat.data;
-    int x, y;
+    transform_(src, dst, m, len, scn, dcn);
+}
 
-    for( y = 0; y < size.height; y++ )
+static void
+transform_32s(const int* src, int* dst, const double* m, int len, int scn, int dcn)
+{
+    transform_(src, dst, m, len, scn, dcn);
+}
+    
+static void
+transform_64f(const double* src, double* dst, const double* m, int len, int scn, int dcn)
+{
+    transform_(src, dst, m, len, scn, dcn);
+}    
+    
+template<typename T, typename WT> static void
+diagtransform_( const T* src, T* dst, const WT* m, int len, int cn, int )
+{
+    int x;
+    
+    if( cn == 2 )
     {
-        const T* src = (const T*)(srcmat.data + srcmat.step*y);
-        T* dst = (T*)(dstmat.data + dstmat.step*y);
-
-        for( x = 0; x < size.width*2; x += 2 )
+        for( x = 0; x < len*2; x += 2 )
         {
             T t0 = saturate_cast<T>(m[0]*src[x] + m[2]);
             T t1 = saturate_cast<T>(m[4]*src[x+1] + m[5]);
             dst[x] = t0; dst[x+1] = t1;
         }
     }
-}
-
-template<typename T, typename WT> static void
-diagtransC3_( const Mat& srcmat, Mat& dstmat, Mat& tmat )
-{
-    Size size = getContinuousSize( srcmat, dstmat );
-    const WT* m = (const WT*)tmat.data;
-    int x, y;
-
-    for( y = 0; y < size.height; y++ )
+    else if( cn == 3 )
     {
-        const T* src = (const T*)(srcmat.data + srcmat.step*y);
-        T* dst = (T*)(dstmat.data + dstmat.step*y);
-
-        for( x = 0; x < size.width*3; x += 3 )
+        for( x = 0; x < len*3; x += 3 )
         {
             T t0 = saturate_cast<T>(m[0]*src[x] + m[3]);
             T t1 = saturate_cast<T>(m[5]*src[x+1] + m[7]);
@@ -1803,21 +1647,9 @@ diagtransC3_( const Mat& srcmat, Mat& dstmat, Mat& tmat )
             dst[x] = t0; dst[x+1] = t1; dst[x+2] = t2;
         }
     }
-}
-
-template<typename T, typename WT> static void
-diagtransC4_( const Mat& srcmat, Mat& dstmat, Mat& tmat )
-{
-    Size size = getContinuousSize( srcmat, dstmat );
-    const WT* m = (const WT*)tmat.data;
-    int x, y;
-
-    for( y = 0; y < size.height; y++ )
+    else if( cn == 4 )
     {
-        const T* src = (const T*)(srcmat.data + srcmat.step*y);
-        T* dst = (T*)(dstmat.data + dstmat.step*y);
-
-        for( x = 0; x < size.width*4; x += 4 )
+        for( x = 0; x < len*4; x += 4 )
         {
             T t0 = saturate_cast<T>(m[0]*src[x] + m[4]);
             T t1 = saturate_cast<T>(m[6]*src[x+1] + m[9]);
@@ -1827,49 +1659,108 @@ diagtransC4_( const Mat& srcmat, Mat& dstmat, Mat& tmat )
             dst[x+2] = t0; dst[x+3] = t1;
         }
     }
+    else
+    {
+        for( x = 0; x < len; x++, src += cn, dst += cn )
+        {
+            const WT* _m = m;
+            for( int j = 0; j < cn; j++, _m += cn + 1 )
+                dst[j] = src[j]*_m[j] + _m[cn];
+        }
+    }
 }
 
-typedef void (*TransformFunc)( const Mat &src, Mat& dst, Mat& M );
-
-void transform( const Mat& src, Mat& dst, const Mat& _m )
+static void
+diagtransform_8u(const uchar* src, uchar* dst, const float* m, int len, int scn, int dcn)
 {
-    static TransformFunc tab[2][32] =
-    {
-        {transformC1_<uchar, float>, 0, transformC1_<ushort, float>, transformC1_<short,float>,
-        transformC1_<int, double>, transformC1_<float, float>, transformC1_<double, double>, 0,
-        transformC2_<uchar, float>, 0, transformC2_<ushort, float>, transformC2_<short,float>,
-        transformC2_<int, double>, transformC2_<float, float>, transformC2_<double, double>, 0,
-        transformC3_<uchar, float>, 0, transformC3_<ushort, float>, transformC3_<short,float>,
-        transformC3_<int, double>, transformC3_<float, float>, transformC3_<double, double>, 0,
-        transformC4_<uchar, float>, 0, transformC4_<ushort, float>, transformC4_<short,float>,
-        transformC4_<int, double>, transformC4_<float, float>, transformC4_<double, double>, 0},
+    diagtransform_(src, dst, m, len, scn, dcn);
+}    
+    
+static void
+diagtransform_8s(const schar* src, schar* dst, const float* m, int len, int scn, int dcn)
+{
+    diagtransform_(src, dst, m, len, scn, dcn);
+}
 
-        {0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, diagtransC2_<ushort, float>, diagtransC2_<short,float>,
-        diagtransC2_<int, double>, diagtransC2_<float, float>, diagtransC2_<double, double>, 0,
-        0, 0, diagtransC3_<ushort, float>, diagtransC3_<short,float>,
-        diagtransC3_<int, double>, diagtransC3_<float, float>, diagtransC3_<double, double>, 0,
-        0, 0, diagtransC4_<ushort, float>, diagtransC4_<short,float>,
-        diagtransC4_<int, double>, diagtransC4_<float, float>, diagtransC4_<double, double>, 0}
-    };
+static void
+diagtransform_16u(const ushort* src, ushort* dst, const float* m, int len, int scn, int dcn)
+{
+    diagtransform_(src, dst, m, len, scn, dcn);
+}    
+    
+static void
+diagtransform_16s(const short* src, short* dst, const float* m, int len, int scn, int dcn)
+{
+    diagtransform_(src, dst, m, len, scn, dcn);
+}
 
-    int type = src.type(), depth = src.depth(), scn = src.channels(), dcn = _m.rows;
-    bool isDiag = false;
-    CV_Assert( (scn == _m.cols || scn + 1 == _m.cols) && scn <= 4 && dcn <= 4 );
+static void
+diagtransform_32s(const int* src, int* dst, const double* m, int len, int scn, int dcn)
+{
+    diagtransform_(src, dst, m, len, scn, dcn);
+}
 
-    double mbuf[20] = {0};
-    Mat m = _m;
+static void
+diagtransform_32f(const float* src, float* dst, const float* m, int len, int scn, int dcn)
+{
+    diagtransform_(src, dst, m, len, scn, dcn);
+}    
+    
+static void
+diagtransform_64f(const double* src, double* dst, const double* m, int len, int scn, int dcn)
+{
+    diagtransform_(src, dst, m, len, scn, dcn);
+}    
+    
+    
+typedef void (*TransformFunc)( const uchar* src, uchar* dst, const uchar* m, int, int, int );
+    
+static TransformFunc transformTab[] =
+{
+    (TransformFunc)transform_8u, (TransformFunc)transform_8s, (TransformFunc)transform_16u,
+    (TransformFunc)transform_16s, (TransformFunc)transform_32s, (TransformFunc)transform_32f,
+    (TransformFunc)transform_64f, 0
+};
 
-    dst.create( src.size(), CV_MAKETYPE(depth, dcn) );
-    Size size = getContinuousSize( src, dst );
+static TransformFunc diagTransformTab[] =
+{
+    (TransformFunc)diagtransform_8u, (TransformFunc)diagtransform_8s, (TransformFunc)diagtransform_16u,
+    (TransformFunc)diagtransform_16s, (TransformFunc)diagtransform_32s, (TransformFunc)diagtransform_32f,
+    (TransformFunc)diagtransform_64f, 0
+};
+    
+}
+    
+void cv::transform( const InputArray& _src, OutputArray _dst, const InputArray& _mtx )
+{
+    Mat src = _src.getMat(), m = _mtx.getMat();
+    int depth = src.depth(), scn = src.channels(), dcn = m.rows;
+    CV_Assert( scn == m.cols || scn + 1 == m.cols );
+    bool isDiag = false;
+    
+    _dst.create( src.size(), CV_MAKETYPE(depth, dcn) );
+    Mat dst = _dst.getMat();
 
     int mtype = depth == CV_32S || depth == CV_64F ? CV_64F : CV_32F;
-    if( !_m.isContinuous() || _m.type() != mtype || _m.cols != scn + 1 )
+    AutoBuffer<double> _mbuf;
+    double* mbuf = _mbuf;
+    
+    if( !m.isContinuous() || m.type() != mtype || m.cols != scn + 1 )
     {
-        m = Mat(dcn, scn + 1, mtype, mbuf);
-        Mat tmat_part = m.colRange(0, _m.cols);
-        _m.convertTo(tmat_part, mtype);
+        _mbuf.allocate(dcn*(scn+1));
+        Mat tmp(dcn, scn+1, mtype, (double*)_mbuf);
+        memset(tmp.data, 0, tmp.total()*tmp.elemSize());
+        if( m.cols == scn+1 )
+            m.convertTo(tmp, mtype);
+        else
+        {
+            Mat tmppart = tmp.colRange(0, m.cols);
+            m.convertTo(tmppart, mtype);
+        }
+        m = tmp;
     }
+    else
+        mbuf = (double*)m.data;
 
     if( scn == dcn )
     {
@@ -1880,10 +1771,10 @@ void transform( const Mat& src, Mat& dst, const Mat& _m )
         {
             double alpha, beta;
             if( mtype == CV_32F )
-                alpha = ((float*)m.data)[0], beta = ((float*)m.data)[1];
+                alpha = m.at<float>(0), beta = m.at<float>(1);
             else
-                alpha = ((double*)m.data)[0], beta = ((double*)m.data)[1];
-            src.convertTo( dst, dst.type(), alpha, beta );
+                alpha = m.at<double>(0), beta = m.at<double>(1);
+            src.convertTo(dst, dst.type(), alpha, beta);
             return;
         }
 
@@ -1891,279 +1782,306 @@ void transform( const Mat& src, Mat& dst, const Mat& _m )
         {
             for( j = 0; isDiag && j < scn; j++ )
             {
-                double v = mtype == CV_32F ? ((float*)m.data)[i*(scn+1)+j] :
-                    ((double*)m.data)[i*(scn+1)+j];
+                double v = mtype == CV_32F ? m.at<float>(i, j) : m.at<double>(i, j);
                 if( i != j && fabs(v) > eps )
                     isDiag = false;
             }
         }
-
-        if( isDiag && depth == CV_8U )
-        {
-            Mat lut(1, 256, CV_8UC(scn));
-            for( i = 0; i < scn; i++ )
-            {
-                uchar* data = lut.data + i;
-                double val, delta;
-                if( mtype == CV_32F )
-                {
-                    val = ((float*)m.data)[i*(scn+1) + scn];
-                    delta = ((float*)m.data)[i*(scn+1) + i];
-                }
-                else
-                {
-                    val = ((double*)m.data)[i*(scn+1) + scn];
-                    delta = ((double*)m.data)[i*(scn+1) + i];
-                }
-                for( j = 0; j < 256; j++, val += delta )
-                {
-                    int ival = cvRound(val);
-                    data[j*scn] = CV_CAST_8U(ival);
-                }
-            }
-            LUT( src, lut, dst );
-            return;
-        }
     }
 
-    TransformFunc func = tab[isDiag][type];
+    TransformFunc func = isDiag ? diagTransformTab[depth] : transformTab[depth];
     CV_Assert( func != 0 );
-    func( src, dst, m );
+    
+    const Mat* arrays[] = {&src, &dst, 0};
+    uchar* ptrs[2];
+    NAryMatIterator it(arrays, ptrs);
+    size_t i, total = it.size;
+    
+    for( i = 0; i < it.nplanes; i++, ++it )
+        func( ptrs[0], ptrs[1], (uchar*)mbuf, (int)total, scn, dcn );
 }
 
-
 /****************************************************************************************\
 *                                  Perspective Transform                                 *
 \****************************************************************************************/
 
-template<typename T> static void
-perspectiveTransform2_( const Mat& srcmat, Mat& dstmat, const double* mat )
+namespace cv
 {
-    Size size = getContinuousSize( srcmat, dstmat, srcmat.channels() );
 
-    for( int i = 0; i < size.height; i++ )
+template<typename T> static void
+perspectiveTransform_( const T* src, T* dst, const double* m, int len, int scn, int dcn )
+{
+    const double eps = FLT_EPSILON;
+    int i;
+    
+    if( scn == 2 && dcn == 2 )
     {
-        const T* src = (const T*)(srcmat.data + srcmat.step*i);
-        T* dst = (T*)(dstmat.data + dstmat.step*i);
-
-        for( int j = 0; j < size.width; j += 2 )
+        for( i = 0; i < len*2; i += 2 )
         {
-            T x = src[j], y = src[j + 1];
-            double w = x*mat[6] + y*mat[7] + mat[8];
+            T x = src[i], y = src[i + 1];
+            double w = x*m[6] + y*m[7] + m[8];
 
-            if( fabs(w) > FLT_EPSILON )
+            if( fabs(w) > eps )
             {
                 w = 1./w;
-                dst[j] = (T)((x*mat[0] + y*mat[1] + mat[2])*w);
-                dst[j+1] = (T)((x*mat[3] + y*mat[4] + mat[5])*w);
+                dst[i] = (T)((x*m[0] + y*m[1] + m[2])*w);
+                dst[i+1] = (T)((x*m[3] + y*m[4] + m[5])*w);
             }
             else
-                dst[j] = dst[j+1] = (T)0;
+                dst[i] = dst[i+1] = (T)0;
         }
     }
-}
-
-template<typename T> static void
-perspectiveTransform3_( const Mat& srcmat, Mat& dstmat, const double* mat )
-{
-    Size size = getContinuousSize( srcmat, dstmat, srcmat.channels() );
-
-    for( int i = 0; i < size.height; i++ )
+    else if( scn == 3 && dcn == 3 )
     {
-        const T* src = (const T*)(srcmat.data + srcmat.step*i);
-        T* dst = (T*)(dstmat.data + dstmat.step*i);
-
-        for( int j = 0; j < size.width; j += 3 )
+        for( i = 0; i < len*3; i += 3 )
         {
-            T x = src[j], y = src[j + 1], z = src[j + 2];
-            double w = x*mat[12] + y*mat[13] + z*mat[14] + mat[15];
-
-            if( fabs(w) > FLT_EPSILON )
+            T x = src[i], y = src[i + 1], z = src[i + 2];
+            double w = x*m[12] + y*m[13] + z*m[14] + m[15];
+            
+            if( fabs(w) > eps )
             {
                 w = 1./w;
-                dst[j] = (T)((x*mat[0] + y*mat[1] + z*mat[2] + mat[3]) * w);
-                dst[j+1] = (T)((x*mat[4] + y*mat[5] + z*mat[6] + mat[7]) * w);
-                dst[j+2] = (T)((x*mat[8] + y*mat[9] + z*mat[10] + mat[11]) * w);
+                dst[i] = (T)((x*m[0] + y*m[1] + z*m[2] + m[3]) * w);
+                dst[i+1] = (T)((x*m[4] + y*m[5] + z*m[6] + m[7]) * w);
+                dst[i+2] = (T)((x*m[8] + y*m[9] + z*m[10] + m[11]) * w);
             }
             else
-                dst[j] = dst[j+1] = dst[j+2] = (T)0;
+                dst[i] = dst[i+1] = dst[i+2] = (T)0;
         }
     }
-}
-
-template<typename T> static void
-perspectiveTransform23_( const Mat& srcmat, Mat& dstmat, const double* mat )
-{
-    Size size = getContinuousSize( srcmat, dstmat, srcmat.channels() );
-
-    for( int i = 0; i < size.height; i++ )
+    else if( scn == 3 && dcn == 2 )
     {
-        const T* src = (const T*)(srcmat.data + srcmat.step*i);
-        T* dst = (T*)(dstmat.data + dstmat.step*i);
-
-        for( int j = 0; j < size.width; j++, src += 3, dst += 2 )
+        for( i = 0; i < len; i++, src += 3, dst += 2 )
         {
             T x = src[0], y = src[1], z = src[2];
-            double w = x*mat[8] + y*mat[9] + z*mat[10] + mat[11];
-
-            if( fabs(w) > FLT_EPSILON )
+            double w = x*m[8] + y*m[9] + z*m[10] + m[11];
+            
+            if( fabs(w) > eps )
             {
                 w = 1./w;
-                dst[0] = (T)((x*mat[0] + y*mat[1] + z*mat[2] + mat[3])*w);
-                dst[1] = (T)((x*mat[4] + y*mat[5] + z*mat[6] + mat[7])*w);
+                dst[0] = (T)((x*m[0] + y*m[1] + z*m[2] + m[3])*w);
+                dst[1] = (T)((x*m[4] + y*m[5] + z*m[6] + m[7])*w);
             }
             else
                 dst[0] = dst[1] = (T)0;
         }
     }
+    else
+    {
+        for( i = 0; i < len; i++, src += scn, dst += dcn )
+        {
+            const double* _m = m + dcn*(scn + 1);
+            double w = _m[scn];
+            int j, k;
+            for( k = 0; k < scn; k++ )
+                w += _m[k]*src[k];
+            if( fabs(w) > eps )
+            {
+                _m = m;
+                for( j = 0; j < dcn; j++, _m += scn + 1 )
+                {
+                    double s = _m[scn];
+                    for( k = 0; k < scn; k++ )
+                        s += _m[k]*src[k];
+                    dst[j] = (T)(s*w);
+                }
+            }
+            else
+                for( j = 0; j < dcn; j++ )
+                    dst[j] = 0;
+        }
+    }
 }
 
-typedef void (*PerspectiveTransformFunc)(const Mat& src, Mat& dst, const double* mat );
-
-void perspectiveTransform( const Mat& src, Mat& dst, const Mat& _m )
+    
+static void
+perspectiveTransform_32f(const float* src, float* dst, const double* m, int len, int scn, int dcn)
 {
-    int depth = src.depth(), scn = src.channels(), dcn = _m.rows-1;
-    CV_Assert( (depth == CV_32F || depth == CV_64F) && scn+1 == _m.cols && scn <= 4 &&
-        ((scn == 2 && dcn == 2) || (scn == 3 && dcn == 3) || (scn == 2 && dcn == 3)));
-
-    double mbuf[16] = {0};
-    Mat tmat;
-    const double* m = (const double*)_m.data;
-
-    dst.create( src.size(), CV_MAKETYPE(depth, dcn) );
-
-    if( !_m.isContinuous() || _m.type() != CV_64F )
-    {
-        tmat = Mat(dcn + 1, scn + 1, CV_64F, mbuf);
-        _m.convertTo(tmat, CV_64F);
-        m = (const double*)tmat.data;
-    }
+    perspectiveTransform_(src, dst, m, len, scn, dcn);
+}
 
-    PerspectiveTransformFunc func = 0;
-    if( scn == 2 && dcn == 2 )
-    {
-        if(depth == CV_32F)
-            func = perspectiveTransform2_<float>;
-        else
-            func = perspectiveTransform2_<double>;
-    }
-    else if( scn == 2 && dcn == 3 )
-    {
-        if(depth == CV_32F)
-            func = perspectiveTransform23_<float>;
-        else
-            func = perspectiveTransform23_<double>;
-    }
-    else if( scn == 3 && dcn == 3 )
+static void
+perspectiveTransform_64f(const double* src, double* dst, const double* m, int len, int scn, int dcn)
+{
+    perspectiveTransform_(src, dst, m, len, scn, dcn);
+}
+    
+}
+    
+void cv::perspectiveTransform( const InputArray& _src, OutputArray _dst, const InputArray& _mtx )
+{
+    Mat src = _src.getMat(), m = _mtx.getMat();
+    int depth = src.depth(), scn = src.channels(), dcn = m.rows-1;
+    CV_Assert( scn + 1 == m.cols && (depth == CV_32F || depth == CV_64F));
+    
+    _dst.create( src.size(), CV_MAKETYPE(depth, dcn) );
+    Mat dst = _dst.getMat();
+    
+    const int mtype = CV_64F;
+    AutoBuffer<double> _mbuf;
+    double* mbuf = _mbuf;
+    
+    if( !m.isContinuous() || m.type() != mtype )
     {
-        if(depth == CV_32F)
-            func = perspectiveTransform3_<float>;
-        else
-            func = perspectiveTransform3_<double>;
+        _mbuf.allocate((dcn+1)*(scn+1));
+        Mat tmp(dcn+1, scn+1, mtype, (double*)_mbuf);
+        m.convertTo(tmp, mtype);
+        m = tmp;
     }
     else
-        CV_Error( CV_StsNotImplemented, "Only 2->2, 2->3 and 3->3 perspective transformation is implemented" );
-    func( src, dst, m );
-}
+        mbuf = (double*)m.data;
+    
+    TransformFunc func = depth == CV_32F ?
+        (TransformFunc)perspectiveTransform_32f :
+        (TransformFunc)perspectiveTransform_64f;
+    CV_Assert( func != 0 );
+    
+    const Mat* arrays[] = {&src, &dst, 0};
+    uchar* ptrs[2];
+    NAryMatIterator it(arrays, ptrs);
+    size_t i, total = it.size;
+    
+    for( i = 0; i < it.nplanes; i++, ++it )
+        func( ptrs[0], ptrs[1], (uchar*)mbuf, (int)total, scn, dcn );
+}    
 
 /****************************************************************************************\
 *                                       ScaleAdd                                         *
 \****************************************************************************************/
 
-void scaleAdd( const Mat& src1, double alpha, const Mat& src2, Mat& dst )
+namespace cv
 {
-    if( src1.dims > 2 || src2.dims > 2 )
-    {
-        dst.create(src1.dims, src1.size, src1.type());
-        const Mat* arrays[] = {&src1, &src2, &dst, 0};
-        Mat planes[3];
-        NAryMatIterator it(arrays, planes);
-        
-        for( int i = 0; i < it.nplanes; i++, ++it )
-            scaleAdd( it.planes[0], alpha, it.planes[1], it.planes[2] );
-        return;
-    }
-    
-    int type = src1.type(), depth = CV_MAT_DEPTH(type);
-    CV_Assert( src1.size() == src2.size() && type == src2.type() );
-    dst.create( src1.size(), type );
-    Size size = getContinuousSize( src1, src2, dst, src1.channels() );
 
-    if( depth == CV_32F )
+static void scaleAdd_32f(const float* src1, const float* src2, float* dst,
+                         int len, float* _alpha)
+{
+    float alpha = *_alpha;
+    int i = 0;
+#if CV_SSE2
+    if( USE_SSE2 )
     {
-        const float *s1 = (const float*)src1.data, *s2 = (const float*)src2.data;
-        float* d = (float*)dst.data;
-        size_t step1 = src1.step/sizeof(s1[0]), step2 = src2.step/sizeof(s2[0]);
-        size_t step = dst.step/sizeof(d[0]);
-
-        if( size.width == 1 )
-        {
-            for( ; size.height--; s1 += step1, s2 += step2, d += step )
-                d[0] = (float)(s1[0]*alpha + s2[0]);
-            return;
-        }
-
-        for( ; size.height--; s1 += step1, s2 += step2, d += step )
-        {
-            int i;
-            for( i = 0; i <= size.width - 4; i += 4 )
+        __m128 a4 = _mm_set1_ps(alpha);
+        if( (((size_t)src1|(size_t)src2|(size_t)dst) & 15) == 0 )
+            for( ; i <= len - 8; i += 8 )
             {
-                float t0 = (float)(s1[i]*alpha + s2[i]);
-                float t1 = (float)(s1[i+1]*alpha + s2[i+1]);
-                d[i] = t0;
-                d[i+1] = t1;
-                t0 = (float)(s1[i+2]*alpha + s2[i+2]);
-                t1 = (float)(s1[i+3]*alpha + s2[i+3]);
-                d[i+2] = t0;
-                d[i+3] = t1;
+                __m128 x0, x1, y0, y1, t0, t1;
+                x0 = _mm_load_ps(src1 + i); x1 = _mm_load_ps(src1 + i + 4);
+                y0 = _mm_load_ps(src2 + i); y1 = _mm_load_ps(src2 + i + 4);
+                t0 = _mm_add_ps(_mm_mul_ps(x0, a4), y0);
+                t1 = _mm_add_ps(_mm_mul_ps(x1, a4), y1);
+                _mm_store_ps(dst + i, t0);
+                _mm_store_ps(dst + i + 4, t1);
+            }
+        else
+            for( ; i <= len - 8; i += 8 )
+            {
+                __m128 x0, x1, y0, y1, t0, t1;
+                x0 = _mm_loadu_ps(src1 + i); x1 = _mm_loadu_ps(src1 + i + 4);
+                y0 = _mm_loadu_ps(src2 + i); y1 = _mm_loadu_ps(src2 + i + 4);
+                t0 = _mm_add_ps(_mm_mul_ps(x0, a4), y0);
+                t1 = _mm_add_ps(_mm_mul_ps(x1, a4), y1);
+                _mm_storeu_ps(dst + i, t0);
+                _mm_storeu_ps(dst + i + 4, t1);
             }
-
-            for( ; i < size.width; i++ )
-                d[i] = (float)(s1[i]*alpha + s2[i]);
-        }
     }
-    else if( depth == CV_64F )
-    {
-        const double *s1 = (const double*)src1.data, *s2 = (const double*)src2.data;
-        double* d = (double*)dst.data;
-        size_t step1 = src1.step/sizeof(s1[0]), step2 = src2.step/sizeof(s2[0]);
-        size_t step = dst.step/sizeof(d[0]);
+    else
+#endif
+    for( ; i <= len - 4; i += 4 )
+    {
+        float t0, t1;
+        t0 = src1[i]*alpha + src2[i];
+        t1 = src1[i+1]*alpha + src2[i+1];
+        dst[i] = t0; dst[i+1] = t1;
+        t0 = src1[i+2]*alpha + src2[i+2];
+        t1 = src1[i+3]*alpha + src2[i+3];
+        dst[i+2] = t0; dst[i+3] = t1;
+    }
+    for( ; i < len; i++ )
+        dst[i] = src1[i]*alpha + src2[i];
+}
 
-        if( size.width == 1 )
+    
+static void scaleAdd_64f(const double* src1, const double* src2, double* dst,
+                         int len, double* _alpha)
+{
+    double alpha = *_alpha;
+    int i = 0;
+#if CV_SSE2
+    if( USE_SSE2 && (((size_t)src1|(size_t)src2|(size_t)dst) & 15) == 0 )
+    {
+        __m128d a2 = _mm_set1_pd(alpha);
+        for( ; i <= len - 4; i += 4 )
         {
-            for( ; size.height--; s1 += step1, s2 += step2, d += step )
-                d[0] = s1[0]*alpha + s2[0];
-            return;
+            __m128d x0, x1, y0, y1, t0, t1;
+            x0 = _mm_load_pd(src1 + i); x1 = _mm_load_pd(src1 + i + 2);
+            y0 = _mm_load_pd(src2 + i); y1 = _mm_load_pd(src2 + i + 2);
+            t0 = _mm_add_pd(_mm_mul_pd(x0, a2), y0);
+            t1 = _mm_add_pd(_mm_mul_pd(x1, a2), y1);
+            _mm_store_pd(dst + i, t0);
+            _mm_store_pd(dst + i + 2, t1);
         }
+    }
+    else
+#endif
+    for( ; i <= len - 4; i += 4 )
+    {
+        double t0, t1;
+        t0 = src1[i]*alpha + src2[i];
+        t1 = src1[i+1]*alpha + src2[i+1];
+        dst[i] = t0; dst[i+1] = t1;
+        t0 = src1[i+2]*alpha + src2[i+2];
+        t1 = src1[i+3]*alpha + src2[i+3];
+        dst[i+2] = t0; dst[i+3] = t1;
+    }
+    for( ; i < len; i++ )
+        dst[i] = src1[i]*alpha + src2[i];
+}
 
-        for( ; size.height--; s1 += step1, s2 += step2, d += step )
-        {
-            int i;
-            for( i = 0; i <= size.width - 4; i += 4 )
-            {
-                double t0 = s1[i]*alpha + s2[i];
-                double t1 = s1[i+1]*alpha + s2[i+1];
-                d[i] = t0;
-                d[i+1] = t1;
-                t0 = s1[i+2]*alpha + s2[i+2];
-                t1 = s1[i+3]*alpha + s2[i+3];
-                d[i+2] = t0;
-                d[i+3] = t1;
-            }
+typedef void (*ScaleAddFunc)(const uchar* src1, const uchar* src2, uchar* dst, int len, const void* alpha);
 
-            for( ; i < size.width; i++ )
-                d[i] = s1[i]*alpha + s2[i];
-        }
+}
+    
+void cv::scaleAdd( const InputArray& _src1, double alpha, const InputArray& _src2, OutputArray _dst )
+{
+    Mat src1 = _src1.getMat(), src2 = _src2.getMat();
+    int depth = src1.depth(), cn = src1.channels();
+    
+    CV_Assert( src1.type() == src2.type() );
+    if( depth < CV_32F )
+    {
+        addWeighted(_src1, alpha, _src2, 1, 0, _dst, depth);
+        return;
     }
-    else
-        addWeighted(src1, alpha, src2, 1, 0, dst);
+    
+    _dst.create(src1.dims, src1.size, src1.type());
+    Mat dst = _dst.getMat();
+    
+    float falpha = (float)alpha;
+    void* palpha = depth == CV_32F ? (void*)&falpha : (void*)&alpha;
+    
+    ScaleAddFunc func = depth == CV_32F ? (ScaleAddFunc)scaleAdd_32f : (ScaleAddFunc)scaleAdd_64f; 
+    
+    if( src1.isContinuous() && src2.isContinuous() && dst.isContinuous() )
+    {
+        size_t len = src1.total()*cn;
+        func(src1.data, src2.data, dst.data, (int)len, palpha);
+        return;
+    }
+    
+    const Mat* arrays[] = {&src1, &src2, &dst, 0};
+    uchar* ptrs[3];
+    NAryMatIterator it(arrays, ptrs);
+    size_t i, len = it.size*cn;
+    
+    for( i = 0; i < it.nplanes; i++, ++it )
+        func( ptrs[0], ptrs[1], ptrs[2], (int)len, palpha );
 }
 
 /****************************************************************************************\
 *                                 Covariation Matrix                                     *
 \****************************************************************************************/
 
-void calcCovarMatrix( const Mat* data, int nsamples, Mat& covar, Mat& _mean, int flags, int ctype )
+void cv::calcCovarMatrix( const Mat* data, int nsamples, Mat& covar, Mat& _mean, int flags, int ctype )
 {
     CV_Assert( data && nsamples > 0 );
     Size size = data[0].size();
@@ -2202,30 +2120,37 @@ void calcCovarMatrix( const Mat* data, int nsamples, Mat& covar, Mat& _mean, int
         _mean = mean.reshape(1, size.height);
 }
 
-void calcCovarMatrix( const Mat& data, Mat& covar, Mat& _mean, int flags, int ctype )
+void cv::calcCovarMatrix( const InputArray& _data, OutputArray _covar, InputOutputArray _mean, int flags, int ctype )
 {
+    Mat data = _data.getMat(), mean;
     CV_Assert( ((flags & CV_COVAR_ROWS) != 0) ^ ((flags & CV_COVAR_COLS) != 0) );
     bool takeRows = (flags & CV_COVAR_ROWS) != 0;
     int type = data.type();
     int nsamples = takeRows ? data.rows : data.cols;
     CV_Assert( nsamples > 0 );
     Size size = takeRows ? Size(data.cols, 1) : Size(1, data.rows);
-    Mat mean = _mean;
-    ctype = std::max(std::max(CV_MAT_DEPTH(ctype >= 0 ? ctype : type), _mean.depth()), CV_32F);
 
     if( (flags & CV_COVAR_USE_AVG) != 0 )
     {
+        mean = _mean.getMat();
+        ctype = std::max(std::max(CV_MAT_DEPTH(ctype >= 0 ? ctype : type), mean.depth()), CV_32F);
         CV_Assert( mean.size() == size );
         if( mean.type() != ctype )
-            _mean.convertTo(mean, ctype);
+        {
+            _mean.create(mean.size(), ctype);
+            Mat tmp = _mean.getMat();
+            mean.convertTo(tmp, ctype);
+            mean = tmp;
+        }
     }
     else
     {
-        reduce( data, _mean, takeRows ? 0 : 1, CV_REDUCE_AVG, ctype );
-        mean = _mean;
+        ctype = std::max(CV_MAT_DEPTH(ctype >= 0 ? ctype : type), CV_32F);
+        reduce( _data, _mean, takeRows ? 0 : 1, CV_REDUCE_AVG, ctype );
+        mean = _mean.getMat();
     }
 
-    mulTransposed( data, covar, ((flags & CV_COVAR_NORMAL) == 0) ^ takeRows,
+    mulTransposed( data, _covar, ((flags & CV_COVAR_NORMAL) == 0) ^ takeRows,
         mean, (flags & CV_COVAR_SCALE) != 0 ? 1./nsamples : 1, ctype );
 }
 
@@ -2233,8 +2158,9 @@ void calcCovarMatrix( const Mat& data, Mat& covar, Mat& _mean, int flags, int ct
 *                                        Mahalanobis                                     *
 \****************************************************************************************/
 
-double Mahalanobis( const Mat& v1, const Mat& v2, const Mat& icovar )
+double cv::Mahalanobis( const InputArray& _v1, const InputArray& _v2, const InputArray& _icovar )
 {
+    Mat v1 = _v1.getMat(), v2 = _v2.getMat(), icovar = _icovar.getMat(); 
     int type = v1.type(), depth = v1.depth();
     Size sz = v1.size();
     int i, j, len = sz.width*sz.height*v1.channels();
@@ -2313,15 +2239,18 @@ double Mahalanobis( const Mat& v1, const Mat& v2, const Mat& icovar )
     return std::sqrt(result);
 }
 
-double Mahalonobis(const Mat& v1, const Mat& v2, const Mat& icovar)
+double cv::Mahalonobis( const InputArray& _v1, const InputArray& _v2, const InputArray& _icovar )
 {
-    return Mahalanobis(v1, v2, icovar);
+    return Mahalanobis(_v1, _v2, _icovar);
 }
     
 /****************************************************************************************\
-*                                        cvMulTransposed                                 *
+*                                        MulTransposed                                   *
 \****************************************************************************************/
 
+namespace cv
+{
+
 template<typename sT, typename dT> static void
 MulTransposedR( const Mat& srcmat, Mat& dstmat, const Mat& deltamat, double scale )
 {
@@ -2515,12 +2444,14 @@ MulTransposedL( const Mat& srcmat, Mat& dstmat, const Mat& deltamat, double scal
 
 typedef void (*MulTransposedFunc)(const Mat& src, Mat& dst, const Mat& delta, double scale);
 
-void mulTransposed( const Mat& src, Mat& dst, bool ata,
-                    const Mat& _delta, double scale, int dtype )
+}
+    
+void cv::mulTransposed( const InputArray& _src, OutputArray _dst, bool ata,
+                        const InputArray& _delta, double scale, int dtype )
 {
+    Mat src = _src.getMat(), delta = _delta.getMat();
     const int gemm_level = 100; // boundary above which GEMM is faster.
     int stype = src.type();
-    Mat delta = _delta;
     dtype = std::max(std::max(CV_MAT_DEPTH(dtype >= 0 ? dtype : stype), delta.depth()), CV_32F);
     CV_Assert( src.channels() == 1 );
 
@@ -2530,11 +2461,12 @@ void mulTransposed( const Mat& src, Mat& dst, bool ata,
             (delta.rows == src.rows || delta.rows == 1) &&
             (delta.cols == src.cols || delta.cols == 1));
         if( delta.type() != dtype )
-            _delta.convertTo(delta, dtype);
+            delta.convertTo(delta, dtype);
     }
 
     int dsize = ata ? src.cols : src.rows;
-    dst.create( dsize, dsize, dtype );
+    _dst.create( dsize, dsize, dtype );
+    Mat dst = _dst.getMat();
 
     if( src.data == dst.data || (stype == dtype &&
         (dst.cols >= gemm_level && dst.rows >= gemm_level &&
@@ -2633,260 +2565,165 @@ void mulTransposed( const Mat& src, Mat& dst, bool ata,
 *                                      Dot Product                                       *
 \****************************************************************************************/
 
-#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
-
-static double ippDotProd8u(const Mat& srcmat1, const Mat& srcmat2)
+namespace cv
 {
-    int      nchan  = srcmat1.channels();
-    Ipp64f   sum[4] = { 0.0 };
-    IppiSize roi    = { srcmat1.cols, srcmat1.rows };
-
-    switch(nchan)
-    {
-        case 1:
-            ippiDotProd_8u64f_C1R((const Ipp8u*)srcmat1.data, (int)srcmat1.step,
-                                  (const Ipp8u*)srcmat2.data, (int)srcmat2.step, roi, sum);
-            break;
-
-        case 3:
-            ippiDotProd_8u64f_C3R((const Ipp8u*)srcmat1.data, (int)srcmat1.step,
-                                  (const Ipp8u*)srcmat2.data, (int)srcmat2.step, roi, sum);
-            break;
-
-        case 4:
-            ippiDotProd_8u64f_C4R((const Ipp8u*)srcmat1.data, (int)srcmat1.step,
-                                  (const Ipp8u*)srcmat2.data, (int)srcmat2.step, roi, sum);
-            break;
-    }
-
-    for(int c = 1; c < nchan; c++)
-    {
-        sum[0] += sum[c];
-    }
-
-    return sum[0];
-} // ippDotProd8u()
 
-
-static double ippDotProd16u(const Mat& srcmat1, const Mat& srcmat2)
+template<typename T> double
+dotProd_(const T* src1, const T* src2, int len)
 {
-    int      nchan  = srcmat1.channels();
-    Ipp64f   sum[4] = { 0.0 };
-    IppiSize roi    = { srcmat1.cols, srcmat1.rows };
-
-    switch(nchan)
-    {
-        case 1:
-            ippiDotProd_16u64f_C1R((const Ipp16u*)srcmat1.data, (int)srcmat1.step,
-                                   (const Ipp16u*)srcmat2.data, (int)srcmat2.step, roi, sum);
-            break;
-
-        case 3:
-            ippiDotProd_16u64f_C3R((const Ipp16u*)srcmat1.data, (int)srcmat1.step,
-                                   (const Ipp16u*)srcmat2.data, (int)srcmat2.step, roi, sum);
-            break;
-
-        case 4:
-            ippiDotProd_16u64f_C4R((const Ipp16u*)srcmat1.data, (int)srcmat1.step,
-                                   (const Ipp16u*)srcmat2.data, (int)srcmat2.step, roi, sum);
-            break;
-    }
-
-    for(int c = 1; c < nchan; c++)
-    {
-        sum[0] += sum[c];
-    }
-
-    return sum[0];
-} // ippDotProd16u()
+    int i = 0;
+    double result = 0;
+    for( ; i <= len - 4; i += 4 )
+        result += (double)src1[i]*src2[i] + (double)src1[i+1]*src2[i+1] +
+            (double)src1[i+2]*src2[i+2] + (double)src1[i+3]*src2[i+3];
+    for( ; i < len; i++ )
+        result += (double)src1[i]*src2[i];
+    
+    return result;
+}
 
 
-static double ippDotProd16s(const Mat& srcmat1, const Mat& srcmat2)
+static double dotProd_8u(const uchar* src1, const uchar* src2, int len)
 {
-    int      nchan  = srcmat1.channels();
-    Ipp64f   sum[4] = { 0.0 };
-    IppiSize roi    = { srcmat1.cols, srcmat1.rows };
-
-    switch(nchan)
-    {
-        case 1:
-            ippiDotProd_16s64f_C1R((const Ipp16s*)srcmat1.data, (int)srcmat1.step,
-                                   (const Ipp16s*)srcmat2.data, (int)srcmat2.step, roi, sum);
-            break;
-
-        case 3:
-            ippiDotProd_16s64f_C3R((const Ipp16s*)srcmat1.data, (int)srcmat1.step,
-                                   (const Ipp16s*)srcmat2.data, (int)srcmat2.step, roi, sum);
-            break;
-
-        case 4:
-            ippiDotProd_16s64f_C4R((const Ipp16s*)srcmat1.data, (int)srcmat1.step,
-                                   (const Ipp16s*)srcmat2.data, (int)srcmat2.step, roi, sum);
-            break;
-    }
-
-    for(int c = 1; c < nchan; c++)
+    double r = 0;
+#if ARITHM_USE_IPP
+    ippiDotProd_8u64f_C1R(src1, (int)(len*sizeof(src1[0])),
+                          src2, (int)(len*sizeof(src2[0])),
+                          ippiSize(len, 1), &r);
+#else
+    int i = 0;
+    
+#if CV_SSE2
+    if( USE_SSE2 )
     {
-        sum[0] += sum[c];
+        int j, len0 = len & -4, blockSize0 = (1 << 15), blockSize;
+        __m128i z = _mm_setzero_si128();
+        while( i < len0 )
+        {
+            blockSize = std::min(len0 - j, blockSize0);
+            __m128i s = _mm_setzero_si128();
+            for( j = 0; j <= blockSize - 16; j += 16 )
+            {
+                __m128i b0 = _mm_loadu_si128((const __m128i*)(src1 + j));
+                __m128i b1 = _mm_loadu_si128((const __m128i*)(src2 + j));
+                __m128i s0, s1, s2, s3;
+                s0 = _mm_unpacklo_epi8(b0, z);
+                s2 = _mm_unpackhi_epi8(b0, z);
+                s1 = _mm_unpacklo_epi8(b1, z);
+                s3 = _mm_unpackhi_epi8(b1, z);
+                s0 = _mm_madd_epi16(s0, s1);
+                s1 = _mm_madd_epi16(s2, s3);
+                s = _mm_add_epi32(s, s0);
+                s = _mm_add_epi32(s, s2);
+            }
+            
+            for( ; j < blockSize; j += 4 )
+            {
+                __m128i s0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(const int*)(src1 + j)), z);
+                __m128i s1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(const int*)(src2 + j)), z);
+                s0 = _mm_madd_epi16(s0, s1);
+                s = _mm_add_epi32(s, s0);
+            }
+            CV_DECL_ALIGNED(16) int buf[4];
+            _mm_store_si128((__m128i*)buf, s);
+            r += buf[0] + buf[1] + buf[2] + buf[3];
+            
+            src1 += blockSize;
+            src2 += blockSize;
+            i += blockSize;
+        }
     }
-
-    return sum[0];
-} // ippDotProd16s()
+#endif
+    return r + dotProd_(src1, src2, len - i);
+#endif
+}
 
 
-static double ippDotProd32s(const Mat& srcmat1, const Mat& srcmat2)
+static double dotProd_8s(const schar* src1, const schar* src2, int len)
 {
-    int      nchan  = srcmat1.channels();
-    Ipp64f   sum[4] = { 0.0 };
-    IppiSize roi    = { srcmat1.cols, srcmat1.rows };
-
-    switch(nchan)
-    {
-        case 1:
-            ippiDotProd_32s64f_C1R((const Ipp32s*)srcmat1.data, (int)srcmat1.step,
-                                   (const Ipp32s*)srcmat2.data, (int)srcmat2.step, roi, sum);
-            break;
-
-        case 3:
-            ippiDotProd_32s64f_C3R((const Ipp32s*)srcmat1.data, (int)srcmat1.step,
-                                   (const Ipp32s*)srcmat2.data, (int)srcmat2.step, roi, sum);
-            break;
-
-        case 4:
-            ippiDotProd_32s64f_C4R((const Ipp32s*)srcmat1.data, (int)srcmat1.step,
-                                   (const Ipp32s*)srcmat2.data, (int)srcmat2.step, roi, sum);
-            break;
-    }
-
-    for(int c = 1; c < nchan; c++)
-    {
-        sum[0] += sum[c];
-    }
-
-    return sum[0];
-} // ippDotProd32s()
-
+    return dotProd_(src1, src2, len);
+}
 
-static double ippDotProd32f(const Mat& srcmat1, const Mat& srcmat2)
+static double dotProd_16u(const ushort* src1, const ushort* src2, int len)
 {
-    int      nchan  = srcmat1.channels();
-    Ipp64f   sum[4] = { 0.0 };
-    IppiSize roi    = { srcmat1.cols, srcmat1.rows };
-
-    switch(nchan)
-    {
-        case 1:
-            ippiDotProd_32f64f_C1R((const Ipp32f*)srcmat1.data, (int)srcmat1.step,
-                                   (const Ipp32f*)srcmat2.data, (int)srcmat2.step, roi, sum, ippAlgHintAccurate);
-            break;
-
-        case 3:
-            ippiDotProd_32f64f_C3R((const Ipp32f*)srcmat1.data, (int)srcmat1.step,
-                                   (const Ipp32f*)srcmat2.data, (int)srcmat2.step, roi, sum, ippAlgHintAccurate);
-            break;
-
-        case 4:
-            ippiDotProd_32f64f_C4R((const Ipp32f*)srcmat1.data, (int)srcmat1.step,
-                                   (const Ipp32f*)srcmat2.data, (int)srcmat2.step, roi, sum, ippAlgHintAccurate);
-            break;
-    }
-
-    for(int c = 1; c < nchan; c++)
-    {
-        sum[0] += sum[c];
-    }
-
-    return sum[0];
-} // ippDotProd32f()
-
-#endif
+    double r = 0;
+    IF_IPP(ippiDotProd_16u64f_C1R(src1, (int)(len*sizeof(src1[0])),
+                                  src2, (int)(len*sizeof(src2[0])),
+                                  ippiSize(len, 1), &r),
+           r = dotProd_(src1, src2, len));
+    return r;
+}
 
-template<typename T, typename WT, typename ST> static double
-dotprod_( const Mat& srcmat1, const Mat& srcmat2 )
+static double dotProd_16s(const short* src1, const short* src2, int len)
 {
-    const T* src1 = (const T*)srcmat1.data;
-    const T* src2 = (const T*)srcmat2.data;
-
-    size_t step1 = srcmat1.step/sizeof(src1[0]);
-    size_t step2 = srcmat2.step/sizeof(src2[0]);
-
-    ST sum = 0;
-    Size size = getContinuousSize( srcmat1, srcmat2, srcmat1.channels() );
-
-    if( size.width == 1 )
-    {
-        WT t = 0;
-        for( ; size.height--; src1 += step1, src2 += step2 )
-            t += (WT)src1[0]*src2[0];
-
-        sum += t;
-    }
-    else
-    {
-        for( ; size.height--; src1 += step1, src2 += step2 )
-        {
-            int i;
-            WT t = 0;
-            for( i = 0; i <= size.width - 4; i += 4 )
-            {
-                sum += (WT)src1[i  ]*src2[i  ] +
-                       (WT)src1[i+1]*src2[i+1] +
-                       (WT)src1[i+2]*src2[i+2] +
-                       (WT)src1[i+3]*src2[i+3];
-            }
+    double r = 0;
+    IF_IPP(ippiDotProd_16s64f_C1R(src1, (int)(len*sizeof(src1[0])),
+                                  src2, (int)(len*sizeof(src2[0])),
+                                  ippiSize(len, 1), &r),
+           r = dotProd_(src1, src2, len));
+    return r;
+}
 
-            for( ; i < size.width; i++ )
-                t += (WT)src1[i]*src2[i];
+static double dotProd_32s(const int* src1, const int* src2, int len)
+{
+    double r = 0;
+    IF_IPP(ippiDotProd_32s64f_C1R(src1, (int)(len*sizeof(src1[0])),
+                                  src2, (int)(len*sizeof(src2[0])),
+                                  ippiSize(len, 1), &r),
+           r = dotProd_(src1, src2, len));
+    return r;
+}
 
-            sum += t;
-        }
-    }
+static double dotProd_32f(const float* src1, const float* src2, int len)
+{
+    double r = 0;
+    IF_IPP(ippsDotProd_32f64f(src1, src2, len, &r),
+           r = dotProd_(src1, src2, len));
+    return r;
+}
 
-    return (double)sum;
+static double dotProd_64f(const double* src1, const double* src2, int len)
+{
+    double r = 0;
+    IF_IPP(ippsDotProd_64f(src1, src2, len, &r),
+           r = dotProd_(src1, src2, len));
+    return r;
 }
 
-typedef double (*DotProductFunc)(const Mat& src1, const Mat& src2);
 
-double Mat::dot(const Mat& mat) const
+typedef double (*DotProdFunc)(const uchar* src1, const uchar* src2, int len);
+    
+static DotProdFunc dotProdTab[] =
 {
-#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
-    static DotProductFunc ipptab[] =
-    {
-        dotprod_<uchar, int, int64>,
-        0,
-        dotprod_<ushort, double, double>,
-        dotprod_<short, double, double>,
-        dotprod_<int, double, double>,
-        ippDotProd32f,
-        dotprod_<double, double, double>,
-        0
-    };
-#endif
-
-    static DotProductFunc tab[] =
-    {
-        dotprod_<uchar, int, int64>,
-        0,
-        dotprod_<ushort, double, double>,
-        dotprod_<short, double, double>,
-        dotprod_<int, double, double>,
-        dotprod_<float, double, double>,
-        dotprod_<double, double, double>,
-        0
-    };
+    (DotProdFunc)dotProd_8u, (DotProdFunc)dotProd_8s, (DotProdFunc)dotProd_16u,
+    (DotProdFunc)dotProd_16s, (DotProdFunc)dotProd_32s, (DotProdFunc)dotProd_32f,
+    (DotProdFunc)dotProd_64f, 0
+};
 
-    DotProductFunc func = tab[depth()];
+double Mat::dot(const InputArray& _mat) const
+{
+    Mat mat = _mat.getMat();
+    int cn = channels();
+    DotProdFunc func = dotProdTab[depth()];
+    CV_Assert( mat.type() == type() && mat.size == size && func != 0 );
 
-#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
-    if((*this).channels() != 2)
+    if( isContinuous() && mat.isContinuous() )
     {
-        func = ipptab[depth()];
+        size_t len = total()*cn;
+        if( len == (size_t)(int)len )
+            return func(data, mat.data, len);
     }
-#endif
-
-    CV_Assert( mat.type() == type() && mat.size() == size() && func != 0 );
-
-    return func( *this, mat );
+    
+    const Mat* arrays[] = {this, &mat, 0};
+    uchar* ptrs[2];
+    NAryMatIterator it(arrays, ptrs);
+    int len = (int)(it.size*cn);
+    double r = 0;
+    
+    for( size_t i = 0; i < it.nplanes; i++, ++it )
+        r += func( ptrs[0], ptrs[1], len );
+    
+    return r;
 }
 
 /****************************************************************************************\
@@ -2895,13 +2732,14 @@ double Mat::dot(const Mat& mat) const
 
 PCA::PCA() {}
 
-PCA::PCA(const Mat& data, const Mat& mean, int flags, int maxComponents)
+PCA::PCA(const InputArray& data, const InputArray& mean, int flags, int maxComponents)
 {
     operator()(data, mean, flags, maxComponents);
 }
 
-PCA& PCA::operator()(const Mat& data, const Mat& _mean, int flags, int maxComponents)
+PCA& PCA::operator()(const InputArray& _data, const InputArray& __mean, int flags, int maxComponents)
 {
+    Mat data = _data.getMat(), _mean = __mean.getMat();
     int covar_flags = CV_COVAR_SCALE;
     int i, len, in_count;
     Size mean_sz;
@@ -2984,8 +2822,9 @@ PCA& PCA::operator()(const Mat& data, const Mat& _mean, int flags, int maxCompon
 }
 
 
-void PCA::project(const Mat& data, Mat& result) const
+void PCA::project(const InputArray& _data, OutputArray result) const
 {
+    Mat data = _data.getMat();
     CV_Assert( mean.data && eigenvectors.data &&
         ((mean.rows == 1 && mean.cols == data.cols) || (mean.cols == 1 && mean.rows == data.rows)));
     Mat tmp_data, tmp_mean = repeat(mean, data.rows/mean.rows, data.cols/mean.cols);
@@ -3006,15 +2845,16 @@ void PCA::project(const Mat& data, Mat& result) const
         gemm( eigenvectors, tmp_data, 1, Mat(), 0, result, 0 );
 }
 
-Mat PCA::project(const Mat& data) const
+Mat PCA::project(const InputArray& data) const
 {
     Mat result;
     project(data, result);
     return result;
 }
 
-void PCA::backProject(const Mat& data, Mat& result) const
+void PCA::backProject(const InputArray& _data, OutputArray result) const
 {
+    Mat data = _data.getMat();
     CV_Assert( mean.data && eigenvectors.data &&
         ((mean.rows == 1 && eigenvectors.rows == data.cols) ||
          (mean.cols == 1 && eigenvectors.rows == data.rows)));
@@ -3033,7 +2873,7 @@ void PCA::backProject(const Mat& data, Mat& result) const
     }
 }
 
-Mat PCA::backProject(const Mat& data) const
+Mat PCA::backProject(const InputArray& data) const
 {
     Mat result;
     backProject(data, result);
index 6406eba..959c887 100644 (file)
@@ -208,9 +208,11 @@ static inline bool isIdentity(const MatExpr& e) { return e.op == &g_MatOp_Identi
 static inline bool isAddEx(const MatExpr& e) { return e.op == &g_MatOp_AddEx; }
 static inline bool isScaled(const MatExpr& e) { return isAddEx(e) && (!e.b.data || e.beta == 0) && e.s == Scalar(); }
 static inline bool isBin(const MatExpr& e, char c) { return e.op == &g_MatOp_Bin && e.flags == c; }
+static inline bool isCmp(const MatExpr& e) { return e.op == &g_MatOp_Cmp; }
 static inline bool isReciprocal(const MatExpr& e) { return isBin(e,'/') && (!e.b.data || e.beta == 0); }
 static inline bool isT(const MatExpr& e) { return e.op == &g_MatOp_T; }
 static inline bool isInv(const MatExpr& e) { return e.op == &g_MatOp_Invert; }
+static inline bool isSolve(const MatExpr& e) { return e.op == &g_MatOp_Solve; }
 static inline bool isGEMM(const MatExpr& e) { return e.op == &g_MatOp_GEMM; }
 static inline bool isMatProd(const MatExpr& e) { return e.op == &g_MatOp_GEMM && (!e.c.data || e.beta == 0); }
 static inline bool isInitializer(const MatExpr& e) { return e.op == &g_MatOp_Initializer; }
@@ -571,7 +573,18 @@ void MatOp::invert(const MatExpr& expr, int method, MatExpr& res) const
     expr.op->assign(expr, m);
     MatOp_Invert::makeExpr(res, method, m);
 }
+    
+    
+Size MatOp::size(const MatExpr& expr) const
+{
+    return !expr.a.empty() ? expr.a.size() : expr.b.empty() ? expr.b.size() : expr.c.size();
+}
 
+int MatOp::type(const MatExpr& expr) const
+{
+    return !expr.a.empty() ? expr.a.type() : expr.b.empty() ? expr.b.type() : expr.c.type();
+}    
+    
 //////////////////////////////////////////////////////////////////////////////////////////////////
 
 MatExpr::MatExpr(const Mat& m) : op(&g_MatOp_Identity), flags(0), a(m), b(Mat()), c(Mat()), alpha(1), beta(0), s(Scalar())
@@ -1142,6 +1155,30 @@ MatExpr abs(const MatExpr& e)
 }
 
     
+Size MatExpr::size() const
+{
+    if( isT(*this) || isInv(*this) )
+        return Size(a.rows, a.cols);
+    if( isGEMM(*this) )
+        return Size(b.cols, a.rows);
+    if( isSolve(*this) )
+        return Size(b.cols, a.cols);
+    if( isInitializer(*this) )
+        return a.size();
+    return op ? op->size(*this) : Size();
+}
+    
+    
+int MatExpr::type() const
+{
+    if( isInitializer(*this) )
+        return a.type();
+    if( isCmp(*this) )
+        return CV_8U;
+    return op ? op->type(*this) : -1;
+}
+    
+    
 /////////////////////////////////////////////////////////////////////////////////////////////////////
     
 void MatOp_Identity::assign(const MatExpr& e, Mat& m, int type) const
@@ -1552,10 +1589,10 @@ MatExpr Mat::inv(int method) const
 }
     
 
-MatExpr Mat::mul(const Mat& m, double scale) const
+MatExpr Mat::mul(const InputArray& m, double scale) const
 {
     MatExpr e;
-    MatOp_Bin::makeExpr(e, '*', *this, m, scale);
+    MatOp_Bin::makeExpr(e, '*', *this, m.getMat(), scale);
     return e;
 }
     
index e574d80..c6c8003 100644 (file)
@@ -50,11 +50,6 @@ namespace cv {
 
 void swap( Mat& a, Mat& b )
 {
-    /*int *ap = (int*)&a, *bp = (int*)&b;
-    size_t i, n = sizeof(Mat)/sizeof(ap[0]);
-    
-    for( i = 0; i < n; i++ )
-        std::swap(ap[i], bp[i]);*/
     std::swap(a.flags, b.flags);
     std::swap(a.dims, b.dims);
     std::swap(a.rows, b.rows);
@@ -681,11 +676,14 @@ Mat& Mat::adjustROI( int dtop, int dbottom, int dleft, int dright )
         flags &= ~CONTINUOUS_FLAG;
     return *this;
 }    
+
+}
     
-void extractImageCOI(const CvArr* arr, Mat& ch, int coi)
+void cv::extractImageCOI(const CvArr* arr, OutputArray _ch, int coi)
 {
     Mat mat = cvarrToMat(arr, false, true, 1);
-    ch.create(mat.dims, mat.size, mat.depth());
+    _ch.create(mat.dims, mat.size, mat.depth());
+    Mat ch = _ch.getMat();
     if(coi < 0)
     { 
         CV_Assert( CV_IS_IMAGE(arr) );
@@ -696,9 +694,9 @@ void extractImageCOI(const CvArr* arr, Mat& ch, int coi)
     mixChannels( &mat, 1, &ch, 1, _pairs, 1 );
 }
     
-void insertImageCOI(const Mat& ch, CvArr* arr, int coi)
+void cv::insertImageCOI(const InputArray& _ch, CvArr* arr, int coi)
 {
-    Mat mat = cvarrToMat(arr, false, true, 1);
+    Mat ch = _ch.getMat(), mat = cvarrToMat(arr, false, true, 1);
     if(coi < 0)
     { 
         CV_Assert( CV_IS_IMAGE(arr) );
@@ -709,6 +707,8 @@ void insertImageCOI(const Mat& ch, CvArr* arr, int coi)
     mixChannels( &ch, 1, &mat, 1, _pairs, 1 );
 }
     
+namespace cv
+{
 
 Mat Mat::reshape(int new_cn, int new_rows) const
 {
@@ -850,16 +850,553 @@ void scalarToRawData(const Scalar& s, void* _buf, int type, int unroll_to)
         CV_Error(CV_StsUnsupportedFormat,"");
     }
 }
+
+    
+/*************************************************************************************************\
+                                        Input/Output Array
+\*************************************************************************************************/
+
+InputArray::InputArray() : flags(0), obj(0) {}
+InputArray::InputArray(const Mat& m) : flags(MAT), obj((void*)&m) {}
+InputArray::InputArray(const vector<Mat>& vec) : flags(STD_VECTOR_MAT), obj((void*)&vec) {}
+InputArray::InputArray(const double& val) : flags(MATX+CV_64F), obj((void*)&val), sz(Size(1,1)) {}
+InputArray::InputArray(const MatExpr& expr) : flags(EXPR), obj((void*)&expr) {}
+Mat InputArray::getMat(int i) const
+{
+    int k = kind();
+    
+    if( k == MAT )
+    {
+        CV_Assert( i < 0 );
+        return *(const Mat*)obj;
+    }
+    
+    if( k == EXPR )
+    {
+        CV_Assert( i < 0 );
+        return (Mat)*((const MatExpr*)obj);
+    }
+    
+    if( k == MATX )
+    {
+        CV_Assert( i < 0 );
+        return Mat(sz, flags, obj);
+    }
+    
+    if( k == STD_VECTOR )
+    {
+        CV_Assert( i < 0 );
+        int t = CV_MAT_TYPE(flags);
+        const vector<uchar>& v = *(const vector<uchar>*)obj;
+        
+        return !v.empty() ? Mat(size(), t, (void*)&v[0]) : Mat();
+    }
+    
+    if( k == NONE )
+        return Mat();
+    
+    if( k == STD_VECTOR_VECTOR )
+    {
+        int t = type(i);
+        const vector<vector<uchar> >& vv = *(const vector<vector<uchar> >*)obj;
+        CV_Assert( 0 <= i && i < (int)vv.size() );
+        const vector<uchar>& v = vv[i];
+        
+        return !v.empty() ? Mat(size(i), t, (void*)&v[0]) : Mat();
+    }
+    
+    CV_Assert( k == STD_VECTOR_MAT );
+    //if( k == STD_VECTOR_MAT )
+    {
+        const vector<Mat>& v = *(const vector<Mat>*)obj;
+        CV_Assert( 0 <= i && i < (int)v.size() );
+        
+        return v[i];
+    }        
+}
+    
+    
+void InputArray::getMatVector(vector<Mat>& mv) const
+{
+    int k = kind();
+    
+    if( k == MAT )
+    {
+        const Mat& m = *(const Mat*)obj;
+        size_t i, n = m.size[0];
+        mv.resize(n);
+        
+        for( i = 0; i < n; i++ )
+            mv[i] = m.dims == 2 ? Mat(1, m.cols, m.type(), (void*)m.ptr(i)) :
+                Mat(m.dims-1, &m.size[1], m.type(), (void*)m.ptr(i), &m.step[1]);
+        return;
+    }
+    
+    if( k == EXPR )
+    {
+        Mat m = *(const MatExpr*)obj;
+        size_t i, n = m.size[0];
+        mv.resize(n);
+        
+        for( i = 0; i < n; i++ )
+            mv[i] = m.row(i);
+        return;
+    }
+    
+    if( k == MATX )
+    {
+        size_t i, n = sz.height, esz = CV_ELEM_SIZE(flags);
+        mv.resize(n);
+        
+        for( i = 0; i < n; i++ )
+            mv[i] = Mat(1, sz.width, CV_MAT_TYPE(flags), (uchar*)obj + esz*sz.width*i);
+        return;
+    }
+    
+    if( k == STD_VECTOR )
+    {
+        const vector<uchar>& v = *(const vector<uchar>*)obj;
+        
+        size_t i, n = v.size(), esz = CV_ELEM_SIZE(flags);
+        int t = CV_MAT_DEPTH(flags), cn = CV_MAT_CN(flags);
+        mv.resize(n);
+        
+        for( i = 0; i < n; i++ )
+            mv[i] = Mat(1, cn, t, (void*)(&v[0] + esz*i));
+        return;
+    }
+    
+    if( k == NONE )
+    {
+        mv.clear();
+        return;
+    }
+    
+    if( k == STD_VECTOR_VECTOR )
+    {
+        const vector<vector<uchar> >& vv = *(const vector<vector<uchar> >*)obj;
+        size_t i, n = vv.size();
+        int t = CV_MAT_TYPE(flags);
+        mv.resize(n);
+        
+        for( i = 0; i < n; i++ )
+        {
+            const vector<uchar>& v = vv[i];
+            mv[i] = Mat(size(i), t, (void*)&v[0]);
+        }
+        return;
+    }
+    
+    CV_Assert( k == STD_VECTOR_MAT );
+    //if( k == STD_VECTOR_MAT )
+    {
+        const vector<Mat>& v = *(const vector<Mat>*)obj;
+        mv.resize(v.size());
+        std::copy(v.begin(), v.end(), mv.begin());
+        return;
+    }
+}
+    
+int InputArray::kind() const
+{
+    return flags & -(1 << KIND_SHIFT);
+}
+    
+Size InputArray::size(int i) const
+{
+    int k = kind();
+    
+    if( k == MAT )
+    {
+        CV_Assert( i < 0 );
+        return ((const Mat*)obj)->size();
+    }
+    
+    if( k == EXPR )
+    {
+        CV_Assert( i < 0 );
+        return ((const MatExpr*)obj)->size();
+    }
+    
+    if( k == MATX )
+    {
+        CV_Assert( i < 0 );
+        return sz;
+    }
+    
+    if( k == STD_VECTOR )
+    {
+        CV_Assert( i < 0 );
+        const vector<uchar>& v = *(const vector<uchar>*)obj;
+        const vector<int>& iv = *(const vector<int>*)obj;
+        size_t szb = v.size(), szi = iv.size();
+        return szb == szi ? Size((int)szb, 1) : Size((int)(szb/CV_ELEM_SIZE(flags)), 1);
+    }
+    
+    if( k == NONE )
+        return Size();
+    
+    if( k == STD_VECTOR_VECTOR )
+    {
+        const vector<vector<uchar> >& vv = *(const vector<vector<uchar> >*)obj;
+        if( i < 0 )
+            return vv.empty() ? Size() : Size((int)vv.size(), 1);
+        CV_Assert( i < (int)vv.size() );
+        const vector<vector<int> >& ivv = *(const vector<vector<int> >*)obj;
+        
+        size_t szb = vv[i].size(), szi = ivv[i].size();
+        return szb == szi ? Size((int)szb, 1) : Size((int)(szb/CV_ELEM_SIZE(flags)), 1);
+    }
+    
+    CV_Assert( k == STD_VECTOR_MAT );
+    //if( k == STD_VECTOR_MAT )
+    {
+        const vector<Mat>& vv = *(const vector<Mat>*)obj;
+        if( i < 0 )
+            return vv.empty() ? Size() : Size((int)vv.size(), 1);
+        CV_Assert( i < (int)vv.size() );
+        
+        return vv[i].size();
+    }
+}
+
+size_t InputArray::total(int i) const
+{
+    return size(i).area();
+}
+    
+int InputArray::type(int i) const
+{
+    int k = kind();
+    
+    if( k == MAT )
+        return ((const Mat*)obj)->type();
+    
+    if( k == EXPR )
+        return ((const MatExpr*)obj)->type();
+    
+    if( k == MATX || k == STD_VECTOR || k == STD_VECTOR_VECTOR )
+        return CV_MAT_TYPE(flags);
+    
+    if( k == NONE )
+        return -1;
+    
+    CV_Assert( k == STD_VECTOR_MAT );
+    //if( k == STD_VECTOR_MAT )
+    {
+        const vector<Mat>& vv = *(const vector<Mat>*)obj;
+        CV_Assert( i < (int)vv.size() );
+        
+        return vv[i >= 0 ? i : 0].type();
+    }
+}
+    
+int InputArray::depth(int i) const
+{
+    return CV_MAT_DEPTH(type(i));
+}
+    
+int InputArray::channels(int i) const
+{
+    return CV_MAT_CN(type(i));
+}
+    
+bool InputArray::empty() const
+{
+    int k = kind();
+    
+    if( k == MAT )
+        return ((const Mat*)obj)->empty();
+    
+    if( k == EXPR )
+        return false;
+    
+    if( k == MATX )
+        return false;
+    
+    if( k == STD_VECTOR )
+    {
+        const vector<uchar>& v = *(const vector<uchar>*)obj;
+        return v.empty();
+    }
+    
+    if( k == NONE )
+        return true;
+    
+    if( k == STD_VECTOR_VECTOR )
+    {
+        const vector<vector<uchar> >& vv = *(const vector<vector<uchar> >*)obj;
+        return vv.empty();
+    }
+    
+    CV_Assert( k == STD_VECTOR_MAT );
+    //if( k == STD_VECTOR_MAT )
+    {
+        const vector<Mat>& vv = *(const vector<Mat>*)obj;
+        return vv.empty();
+    }
+}
+    
+    
+OutputArray::OutputArray() {}
+OutputArray::OutputArray(Mat& m) : InputArray(m) {}
+OutputArray::OutputArray(vector<Mat>& vec) : InputArray(vec) {}
+    
+bool OutputArray::fixedSize() const
+{
+    int k = kind();
+    return k == MATX;
+}
+
+bool OutputArray::fixedType() const
+{
+    int k = kind();
+    return k != MAT && k != STD_VECTOR_MAT;
+}
+    
+void OutputArray::create(Size _sz, int type, int i, bool allowTransposed, int fixedDepthMask)
+{
+    int k = kind();
+    if( k == MAT && i < 0 && !allowTransposed && fixedDepthMask == 0 )
+    {
+        ((Mat*)obj)->create(_sz, type);
+        return;
+    }
+    int sz[] = {_sz.height, _sz.width};
+    create(2, sz, type, i, allowTransposed, fixedDepthMask);
+}
+
+void OutputArray::create(int rows, int cols, int type, int i, bool allowTransposed, int fixedDepthMask)
+{
+    int k = kind();
+    if( k == MAT && i < 0 && !allowTransposed && fixedDepthMask == 0 )
+    {
+        ((Mat*)obj)->create(rows, cols, type);
+        return;
+    }
+    int sz[] = {rows, cols};
+    create(2, sz, type, i, allowTransposed, fixedDepthMask);
+}
+    
+void OutputArray::create(int dims, const int* size, int type, int i, bool allocateVector, int fixedDepthMask)
+{
+    int k = kind();
+    type = CV_MAT_TYPE(type);
+    
+    if( k == MAT )
+    {
+        CV_Assert( i < 0 );
+        Mat& m = *(Mat*)obj;
+        if( allocateVector && dims == 2 && m.dims == 2 &&
+            m.type() == type && m.rows == size[1] && m.cols == size[0] && m.isContinuous())
+            return;
+        if( !m.isContinuous() )
+            m.release();
+        m.create(dims, size, type);
+        return;
+    }
+    
+    if( k == MATX )
+    {
+        CV_Assert( i < 0 );
+        int type0 = CV_MAT_TYPE(flags);
+        CV_Assert( type == type0 || (CV_MAT_CN(type) == 1 && ((1 << type0) & fixedDepthMask) != 0) );
+        CV_Assert( dims == 2 && ((size[0] == sz.height && size[1] == sz.width) ||
+                                 (allocateVector && size[0] == sz.width && size[1] == sz.height)));
+        return;
+    }
+    
+    if( k == STD_VECTOR || k == STD_VECTOR_VECTOR )
+    {
+        CV_Assert( dims == 2 && (size[0] == 1 || size[1] == 1 || size[0]*size[1] == 0) );
+        size_t len = size[0]*size[1] > 0 ? size[0] + size[1] - 1 : 0;
+        vector<uchar>* v = (vector<uchar>*)obj;
+        
+        if( k == STD_VECTOR_VECTOR )
+        {
+            vector<vector<uchar> >& vv = *(vector<vector<uchar> >*)obj;
+            if( i < 0 )
+            {
+                vv.resize(len);
+                return;
+            }
+            CV_Assert( i < (int)vv.size() );
+            v = &vv[i];
+        }
+        else
+            CV_Assert( i < 0 );
+        
+        int type0 = CV_MAT_TYPE(flags);
+        CV_Assert( type == type0 || (CV_MAT_CN(type) == CV_MAT_CN(type0) && ((1 << type0) & fixedDepthMask) != 0) );
+        
+        int esz = CV_ELEM_SIZE(type0);
+        switch( esz )
+        {
+        case 1:
+            ((vector<uchar>*)v)->resize(len);
+            break;
+        case 2:
+            ((vector<Vec2b>*)v)->resize(len);
+            break;
+        case 3:
+            ((vector<Vec3b>*)v)->resize(len);
+            break;
+        case 4:
+            ((vector<int>*)v)->resize(len);
+            break;
+        case 6:
+            ((vector<Vec3s>*)v)->resize(len);
+            break;
+        case 8:
+            ((vector<Vec2i>*)v)->resize(len);
+            break;
+        case 12:
+            ((vector<Vec3i>*)v)->resize(len);
+            break;
+        case 16:
+            ((vector<Vec4i>*)v)->resize(len);
+            break;
+        case 24:
+            ((vector<Vec6i>*)v)->resize(len);
+            break;
+        case 32:
+            ((vector<Vec8i>*)v)->resize(len);
+            break;
+        case 36:
+            ((vector<Vec<int, 9> >*)v)->resize(len);
+            break;
+        case 48:
+            ((vector<Vec<int, 12> >*)v)->resize(len);
+            break;
+        case 64:
+            ((vector<Vec<int, 16> >*)v)->resize(len);
+            break;
+        case 128:
+            ((vector<Vec<int, 32> >*)v)->resize(len);
+            break;
+        case 256:
+            ((vector<Vec<int, 64> >*)v)->resize(len);
+            break;
+        case 512:
+            ((vector<Vec<int, 128> >*)v)->resize(len);
+            break;
+        default:
+            CV_Error_(CV_StsBadArg, ("Vectors with element size %d are not supported. Please, modify OutputArray::create()\n", esz));
+        }
+        return;
+    }
+    
+    if( k == NONE )
+    {
+        CV_Error(CV_StsNullPtr, "create() called for the missing output array" ); 
+        return;
+    }
+    
+    CV_Assert( k == STD_VECTOR_MAT );
+    //if( k == STD_VECTOR_MAT )
+    {
+        vector<Mat>& v = *(vector<Mat>*)obj;
+        
+        if( i < 0 )
+        {
+            CV_Assert( dims == 2 && (size[0] == 1 || size[1] == 1 || size[0]*size[1] == 0) );
+            size_t len = size[0]*size[1] > 0 ? size[0] + size[1] - 1 : 0;
+            
+            v.resize(len);
+            return;
+        }
+        
+        CV_Assert( i < (int)v.size() );
+        Mat& m = v[i];
+        
+        if( allocateVector && dims == 2 && m.dims == 2 &&
+            m.type() == type && m.rows == size[1] && m.cols == size[0] && m.isContinuous())
+            return;
+        if(!m.isContinuous())
+            m.release();
+        m.create(dims, size, type);
+    }
+}
+    
+void OutputArray::release()
+{
+    int k = kind();
+    
+    if( k == MAT )
+    {
+        ((Mat*)obj)->release();
+        return;
+    }
+    
+    if( k == NONE )
+        return;
+    
+    if( k == STD_VECTOR )
+    {
+        create(Size(), CV_MAT_TYPE(flags));
+        return;
+    }
+    
+    if( k == STD_VECTOR_VECTOR )
+    {
+        ((vector<vector<uchar> >*)obj)->clear();
+        return;
+    }
+    
+    CV_Assert( k == STD_VECTOR_MAT );
+    //if( k == STD_VECTOR_MAT )
+    {
+        ((vector<Mat>*)obj)->clear();
+    }    
+}
+
+void OutputArray::clear()
+{
+    int k = kind();
+    
+    if( k == MAT )
+    {
+        ((Mat*)obj)->resize(0);
+        return;
+    }
+    
+    release();
+}
+    
+bool OutputArray::needed() const
+{
+    return kind() != NONE;
+}
+
+Mat& OutputArray::getMatRef(int i)
+{
+    int k = kind();
+    if( i < 0 )
+    {
+        CV_Assert( k == MAT );
+        return *(Mat*)obj;
+    }
+    else
+    {
+        CV_Assert( k == STD_VECTOR_MAT );
+        vector<Mat>& v = *(vector<Mat>*)obj;
+        CV_Assert( i < (int)v.size() );
+        return v[i];
+    }
+}
     
+}
+
 /*************************************************************************************************\
                                         Matrix Operations
 \*************************************************************************************************/
 
-void hconcat(const Mat* src, size_t nsrc, Mat& dst)
+void cv::hconcat(const Mat* src, size_t nsrc, OutputArray _dst)
 {
     if( nsrc == 0 || !src )
     {
-        dst.release();
+        _dst.release();
         return;
     }
     
@@ -872,31 +1409,34 @@ void hconcat(const Mat* src, size_t nsrc, Mat& dst)
                    src[i].type() == src[0].type());
         totalCols += src[i].cols;
     }
-    dst.create( src[0].rows, totalCols, src[0].type());
+    _dst.create( src[0].rows, totalCols, src[0].type());
+    Mat dst = _dst.getMat();
     for( i = 0; i < nsrc; i++ )
     {
-        Mat dpart(dst, Rect(cols, 0, src[i].cols, src[i].rows));
+        Mat dpart = dst(Rect(cols, 0, src[i].cols, src[i].rows));
         src[i].copyTo(dpart);
         cols += src[i].cols;
     }
 }
     
-void hconcat(const Mat& src1, const Mat& src2, Mat& dst)
+void cv::hconcat(const InputArray& src1, const InputArray& src2, OutputArray dst)
 {
-    Mat src[] = {src1, src2};
+    Mat src[] = {src1.getMat(), src2.getMat()};
     hconcat(src, 2, dst);
 }
     
-void hconcat(const vector<Mat>& src, CV_OUT Mat& dst)
+void cv::hconcat(const InputArray& _src, OutputArray dst)
 {
+    vector<Mat> src;
+    _src.getMatVector(src);
     hconcat(!src.empty() ? &src[0] : 0, src.size(), dst);
 }
 
-void vconcat(const Mat* src, size_t nsrc, Mat& dst)
+void cv::vconcat(const Mat* src, size_t nsrc, OutputArray _dst)
 {
     if( nsrc == 0 || !src )
     {
-        dst.release();
+        _dst.release();
         return;
     }
     
@@ -909,7 +1449,8 @@ void vconcat(const Mat* src, size_t nsrc, Mat& dst)
                   src[i].type() == src[0].type());
         totalRows += src[i].rows;
     }
-    dst.create( totalRows, src[0].cols, src[0].type());
+    _dst.create( totalRows, src[0].cols, src[0].type());
+    Mat dst = _dst.getMat();
     for( i = 0; i < nsrc; i++ )
     {
         Mat dpart(dst, Rect(0, rows, src[i].cols, src[i].rows));
@@ -918,20 +1459,23 @@ void vconcat(const Mat* src, size_t nsrc, Mat& dst)
     }
 }
     
-void vconcat(const Mat& src1, const Mat& src2, Mat& dst)
+void cv::vconcat(const InputArray& src1, const InputArray& src2, OutputArray dst)
 {
-    Mat src[] = {src1, src2};
+    Mat src[] = {src1.getMat(), src2.getMat()};
     vconcat(src, 2, dst);
 }        
 
-void vconcat(const vector<Mat>& src, CV_OUT Mat& dst)
+void cv::vconcat(const InputArray& _src, OutputArray dst)
 {
+    vector<Mat> src;
+    _src.getMatVector(src);
     vconcat(!src.empty() ? &src[0] : 0, src.size(), dst);
 }
     
 //////////////////////////////////////// set identity ////////////////////////////////////////////
-void setIdentity( Mat& m, const Scalar& s )
+void cv::setIdentity( InputOutputArray _m, const Scalar& s )
 {
+    Mat m = _m.getMat();
     CV_Assert( m.dims <= 2 );
     int i, j, rows = m.rows, cols = m.cols, type = m.type();
     
@@ -970,8 +1514,9 @@ void setIdentity( Mat& m, const Scalar& s )
 
 //////////////////////////////////////////// trace ///////////////////////////////////////////    
     
-Scalar trace( const Mat& m )
+cv::Scalar cv::trace( const InputArray& _m )
 {
+    Mat m = _m.getMat();
     CV_Assert( m.dims <= 2 );
     int i, type = m.type();
     int nm = std::min(m.rows, m.cols);
@@ -1000,107 +1545,141 @@ Scalar trace( const Mat& m )
 }
 
 ////////////////////////////////////// transpose /////////////////////////////////////////
-    
+
+namespace cv
+{
+
 template<typename T> static void
-transposeI_( Mat& mat )
+transpose_( const uchar* src, size_t sstep, uchar* dst, size_t dstep, Size sz )
 {
-    int rows = mat.rows, cols = mat.cols;
-    uchar* data = mat.data;
-    size_t step = mat.step;
+    int i, j, m = sz.width, n = sz.height;
+    
+    for( i = 0; i <= m - 4; i += 4 )
+    {
+        T* d0 = (T*)(dst + dstep*i);
+        T* d1 = (T*)(dst + dstep*(i+1));
+        T* d2 = (T*)(dst + dstep*(i+2));
+        T* d3 = (T*)(dst + dstep*(i+3));
+        
+        for( j = 0; j <= n - 4; j += 4 )
+        {
+            const T* s0 = (const T*)(src + i*sizeof(T) + sstep*j);
+            const T* s1 = (const T*)(src + i*sizeof(T) + sstep*(j+1));
+            const T* s2 = (const T*)(src + i*sizeof(T) + sstep*(j+2));
+            const T* s3 = (const T*)(src + i*sizeof(T) + sstep*(j+3));
+            
+            d0[j] = s0[0]; d0[j+1] = s1[0]; d0[j+2] = s2[0]; d0[j+3] = s3[0];
+            d1[j] = s0[1]; d1[j+1] = s1[1]; d1[j+2] = s2[1]; d1[j+3] = s3[1];
+            d2[j] = s0[2]; d2[j+1] = s1[2]; d2[j+2] = s2[2]; d2[j+3] = s3[2];
+            d3[j] = s0[3]; d3[j+1] = s1[3]; d3[j+2] = s2[3]; d3[j+3] = s3[3];
+        }
+        
+        for( ; j < n; j++ )
+        {
+            const T* s0 = (const T*)(src + i*sizeof(T) + j*sstep);
+            d0[j] = s0[0]; d1[j] = s0[1]; d2[j] = s0[2]; d3[j] = s0[3];
+        }
+    }
+    
+    for( ; i < m; i++ )
+    {
+        T* d0 = (T*)(dst + dstep*i);
+        
+        for( j = 0; j <= n - 4; j += 4 )
+        {
+            const T* s0 = (const T*)(src + i*sizeof(T) + sstep*j);
+            const T* s1 = (const T*)(src + i*sizeof(T) + sstep*(j+1));
+            const T* s2 = (const T*)(src + i*sizeof(T) + sstep*(j+2));
+            const T* s3 = (const T*)(src + i*sizeof(T) + sstep*(j+3));
+            
+            d0[j] = s0[0]; d0[j+1] = s1[0]; d0[j+2] = s2[0]; d0[j+3] = s3[0];
+        }
+        
+        for( ; j < n; j++ )
+        {
+            const T* s0 = (const T*)(src + i*sizeof(T) + j*sstep);
+            d0[j] = s0[0];
+        }
+    }
+}
 
-    for( int i = 0; i < rows; i++ )
+template<typename T> static void
+transposeI_( uchar* data, size_t step, int n )
+{
+    int i, j;
+    for( i = 0; i < n; i++ )
     {
         T* row = (T*)(data + step*i);
         uchar* data1 = data + i*sizeof(T);
-        for( int j = i+1; j < cols; j++ )
+        for( j = i+1; j < n; j++ )
             std::swap( row[j], *(T*)(data1 + step*j) );
     }
 }
+    
+typedef void (*TransposeFunc)( const uchar* src, size_t sstep, uchar* dst, size_t dstep, Size sz );
+typedef void (*TransposeInplaceFunc)( uchar* data, size_t step, int n );
+    
+#define DEF_TRANSPOSE_FUNC(suffix, type) \
+static void transpose_##suffix( const uchar* src, size_t sstep, uchar* dst, size_t dstep, Size sz ) \
+{ transpose_<type>(src, sstep, dst, dstep, sz); } \
+\
+static void transposeI_##suffix( uchar* data, size_t step, int n ) \
+{ transposeI_<type>(data, step, n); }
 
-template<typename T> static void
-transpose_( const Mat& src, Mat& dst )
-{
-    int rows = dst.rows, cols = dst.cols;
-    uchar* data = src.data;
-    size_t step = src.step;
+DEF_TRANSPOSE_FUNC(8u, uchar)
+DEF_TRANSPOSE_FUNC(16u, ushort)
+DEF_TRANSPOSE_FUNC(8uC3, Vec3b)
+DEF_TRANSPOSE_FUNC(32s, int)
+DEF_TRANSPOSE_FUNC(16uC3, Vec3s)
+DEF_TRANSPOSE_FUNC(32sC2, Vec2i)
+DEF_TRANSPOSE_FUNC(32sC3, Vec3i)
+DEF_TRANSPOSE_FUNC(32sC4, Vec4i)
+DEF_TRANSPOSE_FUNC(32sC6, Vec6i)
+DEF_TRANSPOSE_FUNC(32sC8, Vec8i)
 
-    for( int i = 0; i < rows; i++ )
-    {
-        T* row = (T*)(dst.data + dst.step*i);
-        uchar* data1 = data + i*sizeof(T);
-        for( int j = 0; j < cols; j++ )
-            row[j] = *(T*)(data1 + step*j);
-    }
-}
-
-typedef void (*TransposeInplaceFunc)( Mat& mat );
-typedef void (*TransposeFunc)( const Mat& src, Mat& dst );
-
-void transpose( const Mat& src, Mat& dst )
-{
-    TransposeInplaceFunc itab[] =
-    {
-        0,
-        transposeI_<uchar>, // 1
-        transposeI_<ushort>, // 2
-        transposeI_<Vec<uchar,3> >, // 3
-        transposeI_<int>, // 4
-        0,
-        transposeI_<Vec<ushort,3> >, // 6
-        0,
-        transposeI_<Vec<int,2> >, // 8
-        0, 0, 0,
-        transposeI_<Vec<int,3> >, // 12
-        0, 0, 0,
-        transposeI_<Vec<int,4> >, // 16
-        0, 0, 0, 0, 0, 0, 0,
-        transposeI_<Vec<int,6> >, // 24
-        0, 0, 0, 0, 0, 0, 0,
-        transposeI_<Vec<int,8> > // 32
-    };
+static TransposeFunc transposeTab[] =
+{
+    0, transpose_8u, transpose_16u, transpose_8uC3, transpose_32s, 0, transpose_16uC3, 0,
+    transpose_32sC2, 0, 0, 0, transpose_32sC3, 0, 0, 0, transpose_32sC4,
+    0, 0, 0, 0, 0, 0, 0, transpose_32sC6, 0, 0, 0, 0, 0, 0, 0, transpose_32sC8
+};
 
-    TransposeFunc tab[] =
-    {
-        0,
-        transpose_<uchar>, // 1
-        transpose_<ushort>, // 2
-        transpose_<Vec<uchar,3> >, // 3
-        transpose_<int>, // 4
-        0,
-        transpose_<Vec<ushort,3> >, // 6
-        0,
-        transpose_<Vec<int,2> >, // 8
-        0, 0, 0,
-        transpose_<Vec<int,3> >, // 12
-        0, 0, 0,
-        transpose_<Vec<int,4> >, // 16
-        0, 0, 0, 0, 0, 0, 0,
-        transpose_<Vec<int,6> >, // 24
-        0, 0, 0, 0, 0, 0, 0,
-        transpose_<Vec<int,8> > // 32
-    };
+static TransposeInplaceFunc transposeInplaceTab[] =
+{
+    0, transposeI_8u, transposeI_16u, transposeI_8uC3, transposeI_32s, 0, transposeI_16uC3, 0,
+    transposeI_32sC2, 0, 0, 0, transposeI_32sC3, 0, 0, 0, transposeI_32sC4,
+    0, 0, 0, 0, 0, 0, 0, transposeI_32sC6, 0, 0, 0, 0, 0, 0, 0, transposeI_32sC8
+};
 
+}
+    
+void cv::transpose( const InputArray& _src, OutputArray _dst )
+{
+    Mat src = _src.getMat();
     size_t esz = src.elemSize();
     CV_Assert( src.dims <= 2 && esz <= (size_t)32 );
 
-    if( dst.data == src.data && dst.cols == dst.rows )
+    _dst.create(src.cols, src.rows, src.type());
+    Mat dst = _dst.getMat();
+    
+    if( dst.data == src.data )
     {
-        TransposeInplaceFunc func = itab[esz];
+        TransposeInplaceFunc func = transposeInplaceTab[esz];
         CV_Assert( func != 0 );
-        func( dst );
+        func( dst.data, dst.step, dst.rows );
     }
     else
     {
-        dst.create( src.cols, src.rows, src.type() );
-        TransposeFunc func = tab[esz];
+        TransposeFunc func = transposeTab[esz];
         CV_Assert( func != 0 );
-        func( src, dst );
+        func( src.data, src.step, dst.data, dst.step, src.size() );
     }
 }
 
 
-void completeSymm( Mat& m, bool LtoR )
+void cv::completeSymm( InputOutputArray _m, bool LtoR )
 {
+    Mat m = _m.getMat();
     CV_Assert( m.dims <= 2 );
     
     int i, j, nrows = m.rows, type = m.type();
@@ -1134,8 +1713,9 @@ void completeSymm( Mat& m, bool LtoR )
 }
 
     
-Mat Mat::cross(const Mat& m) const
+cv::Mat cv::Mat::cross(const InputArray& _m) const
 {
+    Mat m = _m.getMat();
     int t = type(), d = CV_MAT_DEPTH(t);
     CV_Assert( dims <= 2 && m.dims <= 2 && size() == m.size() && t == m.type() &&
         ((rows == 3 && cols == 1) || (cols*channels() == 3 && rows == 1)));
@@ -1170,6 +1750,9 @@ Mat Mat::cross(const Mat& m) const
 
 ////////////////////////////////////////// reduce ////////////////////////////////////////////
 
+namespace cv
+{
+
 template<typename T, typename ST, class Op> static void
 reduceR_( const Mat& srcmat, Mat& dstmat )
 {
@@ -1253,17 +1836,21 @@ reduceC_( const Mat& srcmat, Mat& dstmat )
 
 typedef void (*ReduceFunc)( const Mat& src, Mat& dst );
 
-void reduce(const Mat& src, Mat& dst, int dim, int op, int dtype)
+}
+    
+void cv::reduce(const InputArray& _src, OutputArray _dst, int dim, int op, int dtype)
 {
+    Mat src = _src.getMat();
     CV_Assert( src.dims <= 2 );
     int op0 = op;
-    int stype = src.type(), sdepth = src.depth();
+    int stype = src.type(), sdepth = src.depth(), cn = src.channels();
     if( dtype < 0 )
-        dtype = stype;
+        dtype = _dst.fixedType() ? _dst.type() : stype;
     int ddepth = CV_MAT_DEPTH(dtype);
 
-    dst.create(dim == 0 ? 1 : src.rows, dim == 0 ? src.cols : 1, dtype >= 0 ? dtype : stype);
-    Mat temp = dst;
+    _dst.create(dim == 0 ? 1 : src.rows, dim == 0 ? src.cols : 1,
+                CV_MAKETYPE(dtype >= 0 ? dtype : stype, cn));
+    Mat dst = _dst.getMat(), temp = dst;
     
     CV_Assert( op == CV_REDUCE_SUM || op == CV_REDUCE_MAX ||
         op == CV_REDUCE_MIN || op == CV_REDUCE_AVG );
@@ -1273,7 +1860,7 @@ void reduce(const Mat& src, Mat& dst, int dim, int op, int dtype)
     {
         op = CV_REDUCE_SUM;
         if( sdepth < CV_32S && ddepth < CV_32S )
-            temp.create(dst.rows, dst.cols, CV_32SC(src.channels()));
+            temp.create(dst.rows, dst.cols, CV_32SC(cn));
     }
 
     ReduceFunc func = 0;
@@ -1379,6 +1966,9 @@ void reduce(const Mat& src, Mat& dst, int dim, int op, int dtype)
     
 //////////////////////////////////////// sort ///////////////////////////////////////////
 
+namespace cv
+{
+
 template<typename T> static void sort_( const Mat& src, Mat& dst, int flags )
 {
     AutoBuffer<T> buf;
@@ -1479,38 +2069,48 @@ template<typename T> static void sortIdx_( const Mat& src, Mat& dst, int flags )
 
 typedef void (*SortFunc)(const Mat& src, Mat& dst, int flags);
 
-void sort( const Mat& src, Mat& dst, int flags )
+}
+    
+void cv::sort( const InputArray& _src, OutputArray _dst, int flags )
 {
     static SortFunc tab[] =
     {
         sort_<uchar>, sort_<schar>, sort_<ushort>, sort_<short>,
         sort_<int>, sort_<float>, sort_<double>, 0
     };
+    Mat src = _src.getMat();
     SortFunc func = tab[src.depth()];
     CV_Assert( src.dims <= 2 && src.channels() == 1 && func != 0 );
-    dst.create( src.size(), src.type() );
+    _dst.create( src.size(), src.type() );
+    Mat dst = _dst.getMat();
     func( src, dst, flags );
 }
 
-void sortIdx( const Mat& src, Mat& dst, int flags )
+void cv::sortIdx( const InputArray& _src, OutputArray _dst, int flags )
 {
     static SortFunc tab[] =
     {
         sortIdx_<uchar>, sortIdx_<schar>, sortIdx_<ushort>, sortIdx_<short>,
         sortIdx_<int>, sortIdx_<float>, sortIdx_<double>, 0
     };
+    Mat src = _src.getMat();
     SortFunc func = tab[src.depth()];
     CV_Assert( src.dims <= 2 && src.channels() == 1 && func != 0 );
+    
+    Mat dst = _dst.getMat();
     if( dst.data == src.data )
-        dst.release();
-    dst.create( src.size(), CV_32S );
+        _dst.release();
+    _dst.create( src.size(), CV_32S );
+    dst = _dst.getMat();
     func( src, dst, flags );
 }
-
     
     
 ////////////////////////////////////////// kmeans ////////////////////////////////////////////
-    
+
+namespace cv
+{
+
 static void generateRandomCenter(const vector<Vec2f>& box, float* center, RNG& rng)
 {
     size_t j, dims = box.size();
@@ -1520,11 +2120,11 @@ static void generateRandomCenter(const vector<Vec2f>& box, float* center, RNG& r
 }
 
 
-static inline float distance(const float* a, const float* b, int n, bool simd)
+static inline float distance(const float* a, const float* b, int n)
 {
     int j = 0; float d = 0.f;
 #if CV_SSE
-    if( simd )
+    if( USE_SSE2 )
     {
         float CV_DECL_ALIGNED(16) buf[4];
         __m128 d0 = _mm_setzero_ps(), d1 = _mm_setzero_ps();
@@ -1572,13 +2172,12 @@ static void generateCentersPP(const Mat& _data, Mat& _out_centers,
     vector<float> _dist(N*3);
     float* dist = &_dist[0], *tdist = dist + N, *tdist2 = tdist + N;
     double sum0 = 0;
-    bool simd = checkHardwareSupport(CV_CPU_SSE);
 
     centers[0] = (unsigned)rng % N;
 
     for( i = 0; i < N; i++ )
     {
-        dist[i] = distance(data + step*i, data + step*centers[0], dims, simd);
+        dist[i] = distance(data + step*i, data + step*centers[0], dims);
         sum0 += dist[i];
     }
     
@@ -1596,7 +2195,7 @@ static void generateCentersPP(const Mat& _data, Mat& _out_centers,
             int ci = i;
             for( i = 0; i < N; i++ )
             {
-                tdist2[i] = std::min(distance(data + step*i, data + step*ci, dims, simd), dist[i]);
+                tdist2[i] = std::min(distance(data + step*i, data + step*ci, dims), dist[i]);
                 s += tdist2[i];
             }
             
@@ -1621,20 +2220,25 @@ static void generateCentersPP(const Mat& _data, Mat& _out_centers,
     }
 }
 
-double kmeans( const Mat& data, int K, Mat& best_labels,
-               TermCriteria criteria, int attempts,
-               int flags, Mat* _centers )
+}
+    
+double cv::kmeans( const InputArray& _data, int K,
+                   InputOutputArray _bestLabels,
+                   TermCriteria criteria, int attempts,
+                   int flags, OutputArray _centers )
 {
     const int SPP_TRIALS = 3;
+    Mat data = _data.getMat();
     int N = data.rows > 1 ? data.rows : data.cols;
     int dims = (data.rows > 1 ? data.cols : 1)*data.channels();
     int type = data.depth();
-    bool simd = checkHardwareSupport(CV_CPU_SSE);
 
     attempts = std::max(attempts, 1);
     CV_Assert( data.dims <= 2 && type == CV_32F && K > 0 );
 
-    Mat _labels;
+    _bestLabels.create(N, 1, CV_32S, -1, true);
+    
+    Mat _labels, best_labels = _bestLabels.getMat();
     if( flags & CV_KMEANS_USE_INITIAL_LABELS )
     {
         CV_Assert( (best_labels.cols == 1 || best_labels.rows == 1) &&
@@ -1789,7 +2393,7 @@ double kmeans( const Mat& data, int K, Mat& best_labels,
                 for( k = 0; k < K; k++ )
                 {
                     const float* center = centers.ptr<float>(k);
-                    double dist = distance(sample, center, dims, simd);
+                    double dist = distance(sample, center, dims);
 
                     if( min_dist > dist )
                     {
@@ -1806,8 +2410,8 @@ double kmeans( const Mat& data, int K, Mat& best_labels,
         if( compactness < best_compactness )
         {
             best_compactness = compactness;
-            if( _centers )
-                centers.copyTo(*_centers);
+            if( _centers.needed() )
+                centers.copyTo(_centers);
             _labels.copyTo(best_labels);
         }
     }
@@ -1815,8 +2419,6 @@ double kmeans( const Mat& data, int K, Mat& best_labels,
     return best_compactness;
 }
 
-}
-
 
 CV_IMPL void cvSetIdentity( CvArr* arr, CvScalar value )
 {
@@ -1975,8 +2577,9 @@ cvKMeans2( const CvArr* _samples, int cluster_count, CvArr* _labels,
     CV_Assert( labels.isContinuous() && labels.type() == CV_32S &&
         (labels.cols == 1 || labels.rows == 1) &&
         labels.cols + labels.rows - 1 == data.rows );
+    
     double compactness = cv::kmeans(data, cluster_count, labels, termcrit, attempts,
-                                    flags, _centers ? &centers : 0 );
+                                    flags, _centers ? cv::OutputArray(centers) : cv::OutputArray() );
     if( _compactness )
         *_compactness = compactness;
     return 1;
@@ -2006,25 +2609,33 @@ Mat::operator CvMatND() const
 }
 
 NAryMatIterator::NAryMatIterator()
-    : arrays(0), planes(0), narrays(0), nplanes(0), iterdepth(0), idx(0)
+    : arrays(0), planes(0), ptrs(0), narrays(0), nplanes(0), size(0), iterdepth(0), idx(0)
 {
 }
-    
+
 NAryMatIterator::NAryMatIterator(const Mat** _arrays, Mat* _planes, int _narrays)
-    : arrays(0), planes(0), narrays(0), nplanes(0), iterdepth(0), idx(0)
+: arrays(0), planes(0), ptrs(0), narrays(0), nplanes(0), size(0), iterdepth(0), idx(0)
+{
+    init(_arrays, _planes, 0, _narrays);
+}    
+    
+NAryMatIterator::NAryMatIterator(const Mat** _arrays, uchar** _ptrs, int _narrays)
+    : arrays(0), planes(0), ptrs(0), narrays(0), nplanes(0), size(0), iterdepth(0), idx(0)
 {
-    init(_arrays, _planes, _narrays);
+    init(_arrays, 0, _ptrs, _narrays);
 }
     
-void NAryMatIterator::init(const Mat** _arrays, Mat* _planes, int _narrays)
+void NAryMatIterator::init(const Mat** _arrays, Mat* _planes, uchar** _ptrs, int _narrays)
 {
-    CV_Assert( _arrays && _planes );
-    int i, j, d1=0, i0 = -1, d = -1, total = 0;
+    CV_Assert( _arrays && (_ptrs || _planes) );
+    int i, j, d1=0, i0 = -1, d = -1;
     
     arrays = _arrays;
+    ptrs = _ptrs;
     planes = _planes;
     narrays = _narrays;
     nplanes = 0;
+    size = 0;
     
     if( narrays < 0 )
     {
@@ -2039,9 +2650,12 @@ void NAryMatIterator::init(const Mat** _arrays, Mat* _planes, int _narrays)
     for( i = 0; i < narrays; i++ )
     {
         CV_Assert(arrays[i] != 0);
-        if( !arrays[i]->data )
-            continue;
         const Mat& A = *arrays[i];
+        if( ptrs )
+            ptrs[i] = A.data;
+        
+        if( !A.data )
+            continue;
         
         if( i0 < 0 )
         {
@@ -2069,13 +2683,13 @@ void NAryMatIterator::init(const Mat** _arrays, Mat* _planes, int _narrays)
 
     if( i0 >= 0 )
     {
-        total = arrays[i0]->size[d-1];
+        size = arrays[i0]->size[d-1];
         for( j = d-1; j > iterdepth; j-- )
         {
-            int64 total1 = (int64)total*arrays[i0]->size[j-1];
+            int64 total1 = (int64)size*arrays[i0]->size[j-1];
             if( total1 != (int)total1 )
                 break;
-            total = (int)total1;
+            size = (int)total1;
         }
 
         iterdepth = j;
@@ -2087,21 +2701,26 @@ void NAryMatIterator::init(const Mat** _arrays, Mat* _planes, int _narrays)
             nplanes *= arrays[i0]->size[j];
     }
     else
-        iterdepth = nplanes = 0;
+        iterdepth = 0;
+    
+    idx = 0;
+    
+    if( !planes )
+        return;
 
     for( i = 0; i < narrays; i++ )
     {
-        if( !arrays[i]->data )
+        CV_Assert(arrays[i] != 0);
+        const Mat& A = *arrays[i];
+        
+        if( !A.data )
         {
             planes[i] = Mat();
             continue;
         }
-        planes[i] = Mat( 1, total, arrays[i]->type(), arrays[i]->data );
-        planes[i].datastart = arrays[i]->datastart;
-        planes[i].dataend = arrays[i]->dataend;
+        
+        planes[i] = Mat(1, (int)size, A.type(), A.data); 
     }
-
-    idx = 0;
 }
 
 
@@ -2110,22 +2729,48 @@ NAryMatIterator& NAryMatIterator::operator ++()
     if( idx >= nplanes-1 )
         return *this;
     ++idx;
-
-    for( int i = 0; i < narrays; i++ )
+    
+    if( iterdepth == 1 )
     {
-        const Mat& A = *arrays[i];
-        Mat& M = planes[i];
-        if( !A.data )
-            continue;
-        int _idx = idx;
-        uchar* data = A.data;
-        for( int j = iterdepth-1; j >= 0 && _idx > 0; j-- )
+        if( ptrs )
         {
-            int szi = A.size[j], t = _idx/szi;
-            data += (_idx - t * szi)*A.step[j];
-            _idx = t;
+            for( int i = 0; i < narrays; i++ )
+            {
+                if( !ptrs[i] )
+                    continue;
+                ptrs[i] = arrays[i]->data + arrays[i]->step[0]*idx;
+            }
+        }
+        if( planes )
+        {
+            for( int i = 0; i < narrays; i++ )
+            {
+                if( !planes[i].data )
+                    continue;
+                planes[i].data = arrays[i]->data + arrays[i]->step[0]*idx;
+            }
+        }
+    }
+    else
+    {
+        for( int i = 0; i < narrays; i++ )
+        {
+            const Mat& A = *arrays[i];
+            if( !A.data )
+                continue;
+            int _idx = idx;
+            uchar* data = A.data;
+            for( int j = iterdepth-1; j >= 0 && _idx > 0; j-- )
+            {
+                int szi = A.size[j], t = _idx/szi;
+                data += (_idx - t * szi)*A.step[j];
+                _idx = t;
+            }
+            if( ptrs )
+                ptrs[i] = data;
+            if( planes )
+                planes[i].data = data;
         }
-        M.data = data;
     }
     
     return *this;
index ed96556..09711b6 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 
-#define CV_MEMCPY_CHAR( dst, src, len )                 \
-{                                                       \
-    size_t _icv_memcpy_i_, _icv_memcpy_len_ = (len);    \
-    char* _icv_memcpy_dst_ = (char*)(dst);              \
-    const char* _icv_memcpy_src_ = (const char*)(src);  \
-                                                        \
-    for( _icv_memcpy_i_ = 0; _icv_memcpy_i_ < _icv_memcpy_len_; _icv_memcpy_i_++ )  \
-        _icv_memcpy_dst_[_icv_memcpy_i_] = _icv_memcpy_src_[_icv_memcpy_i_];        \
-}
-
-
-#define CV_MEMCPY_INT( dst, src, len )                  \
-{                                                       \
-    size_t _icv_memcpy_i_, _icv_memcpy_len_ = (len);    \
-    int* _icv_memcpy_dst_ = (int*)(dst);                \
-    const int* _icv_memcpy_src_ = (const int*)(src);    \
-    assert( ((size_t)_icv_memcpy_src_&(sizeof(int)-1)) == 0 && \
-    ((size_t)_icv_memcpy_dst_&(sizeof(int)-1)) == 0 );  \
-                                                        \
-    for(_icv_memcpy_i_=0;_icv_memcpy_i_<_icv_memcpy_len_;_icv_memcpy_i_++)  \
-        _icv_memcpy_dst_[_icv_memcpy_i_] = _icv_memcpy_src_[_icv_memcpy_i_];\
-}
-
-
-#define CV_MEMCPY_AUTO( dst, src, len )                                             \
-{                                                                                   \
-    size_t _icv_memcpy_i_, _icv_memcpy_len_ = (len);                                \
-    char* _icv_memcpy_dst_ = (char*)(dst);                                          \
-    const char* _icv_memcpy_src_ = (const char*)(src);                              \
-    if( (_icv_memcpy_len_ & (sizeof(int)-1)) == 0 )                                 \
-    {                                                                               \
-        assert( ((size_t)_icv_memcpy_src_&(sizeof(int)-1)) == 0 &&                  \
-                ((size_t)_icv_memcpy_dst_&(sizeof(int)-1)) == 0 );                  \
-        for( _icv_memcpy_i_ = 0; _icv_memcpy_i_ < _icv_memcpy_len_;                 \
-            _icv_memcpy_i_+=sizeof(int) )                                           \
-        {                                                                           \
-            *(int*)(_icv_memcpy_dst_+_icv_memcpy_i_) =                              \
-            *(const int*)(_icv_memcpy_src_+_icv_memcpy_i_);                         \
-        }                                                                           \
-    }                                                                               \
-    else                                                                            \
-    {                                                                               \
-        for(_icv_memcpy_i_ = 0; _icv_memcpy_i_ < _icv_memcpy_len_; _icv_memcpy_i_++)\
-            _icv_memcpy_dst_[_icv_memcpy_i_] = _icv_memcpy_src_[_icv_memcpy_i_];    \
-    }                                                                               \
-}
-
-
-#define CV_ZERO_CHAR( dst, len )                        \
-{                                                       \
-    size_t _icv_memcpy_i_, _icv_memcpy_len_ = (len);    \
-    char* _icv_memcpy_dst_ = (char*)(dst);              \
-                                                        \
-    for( _icv_memcpy_i_ = 0; _icv_memcpy_i_ < _icv_memcpy_len_; _icv_memcpy_i_++ )  \
-        _icv_memcpy_dst_[_icv_memcpy_i_] = '\0';        \
-}
-
-
-#define CV_ZERO_INT( dst, len )                                                     \
-{                                                                                   \
-    size_t _icv_memcpy_i_, _icv_memcpy_len_ = (len);                                \
-    int* _icv_memcpy_dst_ = (int*)(dst);                                            \
-    assert( ((size_t)_icv_memcpy_dst_&(sizeof(int)-1)) == 0 );                      \
-                                                                                    \
-    for(_icv_memcpy_i_=0;_icv_memcpy_i_<_icv_memcpy_len_;_icv_memcpy_i_++)          \
-        _icv_memcpy_dst_[_icv_memcpy_i_] = 0;                                       \
-}
-
 namespace cv
 {
 
@@ -150,23 +82,11 @@ extern const uchar g_Saturate8u[];
 #define CV_MIN_8U(a,b)       ((a) - CV_FAST_CAST_8U((a) - (b)))
 #define CV_MAX_8U(a,b)       ((a) + CV_FAST_CAST_8U((b) - (a)))
 
-typedef void (*CopyMaskFunc)(const Mat& src, Mat& dst, const Mat& mask);
-
-extern CopyMaskFunc g_copyMaskFuncTab[];
-
-static inline CopyMaskFunc getCopyMaskFunc(int esz)
-{
-    CV_Assert( (unsigned)esz <= 32U );
-    CopyMaskFunc func = g_copyMaskFuncTab[esz];
-    CV_Assert( func != 0 );
-    return func;
-}
 
 #if defined WIN32 || defined _WIN32
 void deleteThreadAllocData();
 void deleteThreadRNGData();
 #endif
-
     
 template<typename T1, typename T2=T1, typename T3=T1> struct OpAdd
 {
@@ -192,22 +112,6 @@ template<typename T1, typename T2=T1, typename T3=T1> struct OpRSub
     T3 operator ()(T1 a, T2 b) const { return saturate_cast<T3>(b - a); }
 };
 
-template<typename T1, typename T2=T1, typename T3=T1> struct OpMul
-{
-    typedef T1 type1;
-    typedef T2 type2;
-    typedef T3 rtype;
-    T3 operator ()(T1 a, T2 b) const { return saturate_cast<T3>(a * b); }
-};
-
-template<typename T1, typename T2=T1, typename T3=T1> struct OpDiv
-{
-    typedef T1 type1;
-    typedef T2 type2;
-    typedef T3 rtype;
-    T3 operator ()(T1 a, T2 b) const { return saturate_cast<T3>(a / b); }
-};
-
 template<typename T> struct OpMin
 {
     typedef T type1;
@@ -261,155 +165,35 @@ inline Size getContinuousSize( const Mat& m1, const Mat& m2,
 
 struct NoVec
 {
-    int operator()(const void*, const void*, void*, int) const { return 0; }
+    size_t operator()(const void*, const void*, void*, size_t) const { return 0; }
 };
-    
-    
-template<class Op, class VecOp> static void
-binaryOpC1_( const Mat& srcmat1, const Mat& srcmat2, Mat& dstmat )
-{
-    Op op; VecOp vecOp;
-    typedef typename Op::type1 T1;
-    typedef typename Op::type2 T2;
-    typedef typename Op::rtype DT;
-
-    const T1* src1 = (const T1*)srcmat1.data;
-    const T2* src2 = (const T2*)srcmat2.data;
-    DT* dst = (DT*)dstmat.data;
-    size_t step1 = srcmat1.step/sizeof(src1[0]);
-    size_t step2 = srcmat2.step/sizeof(src2[0]);
-    size_t step  = dstmat.step/sizeof(dst[0]);
-    Size size = getContinuousSize( srcmat1, srcmat2, dstmat, dstmat.channels() );
-
-    if( size.width == 1 )
-    {
-        for( ; size.height--; src1 += step1, src2 += step2, dst += step )
-            dst[0] = op( src1[0], src2[0] );
-        return;
-    }
-
-    for( ; size.height--; src1 += step1, src2 += step2, dst += step )
-    {
-        int x;
-        x = vecOp(src1, src2, dst, size.width);
-        for( ; x <= size.width - 4; x += 4 )
-        {
-            DT f0, f1;
-            f0 = op( src1[x], src2[x] );
-            f1 = op( src1[x+1], src2[x+1] );
-            dst[x] = f0;
-            dst[x+1] = f1;
-            f0 = op(src1[x+2], src2[x+2]);
-            f1 = op(src1[x+3], src2[x+3]);
-            dst[x+2] = f0;
-            dst[x+3] = f1;
-        }
-
-        for( ; x < size.width; x++ )
-            dst[x] = op( src1[x], src2[x] );
-    }
-}
-
-typedef void (*BinaryFunc)(const Mat& src1, const Mat& src2, Mat& dst);
-
-template<class Op> static void
-binarySOpCn_( const Mat& srcmat, Mat& dstmat, const Scalar& _scalar )
-{
-    Op op;
-    typedef typename Op::type1 T;
-    typedef typename Op::type2 WT;
-    typedef typename Op::rtype DT;
-    const T* src0 = (const T*)srcmat.data;
-    DT* dst0 = (DT*)dstmat.data;
-    size_t step1 = srcmat.step/sizeof(src0[0]);
-    size_t step = dstmat.step/sizeof(dst0[0]);
-    int cn = dstmat.channels();
-    Size size = getContinuousSize( srcmat, dstmat, cn );
-    WT scalar[12];
-    scalarToRawData(_scalar, scalar, CV_MAKETYPE(DataType<WT>::depth,cn), 12);
-
-    for( ; size.height--; src0 += step1, dst0 += step )
-    {
-        int i, len = size.width;
-        const T* src = src0;
-        T* dst = dst0;
 
-        for( ; (len -= 12) >= 0; dst += 12, src += 12 )
-        {
-            DT t0 = op(src[0], scalar[0]);
-            DT t1 = op(src[1], scalar[1]);
-            dst[0] = t0; dst[1] = t1;
+extern volatile bool USE_SSE2;
 
-            t0 = op(src[2], scalar[2]);
-            t1 = op(src[3], scalar[3]);
-            dst[2] = t0; dst[3] = t1;
+typedef void (*BinaryFunc)(const uchar* src1, size_t step1,
+                           const uchar* src2, size_t step2,
+                           uchar* dst, size_t step, Size sz,
+                           void*);
 
-            t0 = op(src[4], scalar[4]);
-            t1 = op(src[5], scalar[5]);
-            dst[4] = t0; dst[5] = t1;
+BinaryFunc getConvertFunc(int sdepth, int ddepth);
+BinaryFunc getConvertScaleFunc(int sdepth, int ddepth);  
+BinaryFunc getCopyMaskFunc(size_t esz);
 
-            t0 = op(src[6], scalar[6]);
-            t1 = op(src[7], scalar[7]);
-            dst[6] = t0; dst[7] = t1;
-
-            t0 = op(src[8], scalar[8]);
-            t1 = op(src[9], scalar[9]);
-            dst[8] = t0; dst[9] = t1;
-
-            t0 = op(src[10], scalar[10]);
-            t1 = op(src[11], scalar[11]);
-            dst[10] = t0; dst[11] = t1;
-        }
-
-        for( (len) += 12, i = 0; i < (len); i++ )
-            dst[i] = op((WT)src[i], scalar[i]);
-    }
-}
-
-template<class Op> static void
-binarySOpC1_( const Mat& srcmat, Mat& dstmat, double _scalar )
-{
-    Op op;
-    typedef typename Op::type1 T;
-    typedef typename Op::type2 WT;
-    typedef typename Op::rtype DT;
-    WT scalar = saturate_cast<WT>(_scalar);
-    const T* src = (const T*)srcmat.data;
-    DT* dst = (DT*)dstmat.data;
-    size_t step1 = srcmat.step/sizeof(src[0]);
-    size_t step = dstmat.step/sizeof(dst[0]);
-    Size size = srcmat.size();
-
-    size.width *= srcmat.channels();
-    if( srcmat.isContinuous() && dstmat.isContinuous() )
-    {
-        size.width *= size.height;
-        size.height = 1;
-    }
-
-    for( ; size.height--; src += step1, dst += step )
-    {
-        int x;
-        for( x = 0; x <= size.width - 4; x += 4 )
-        {
-            DT f0 = op( src[x], scalar );
-            DT f1 = op( src[x+1], scalar );
-            dst[x] = f0;
-            dst[x+1] = f1;
-            f0 = op( src[x+2], scalar );
-            f1 = op( src[x+3], scalar );
-            dst[x+2] = f0;
-            dst[x+3] = f1;
-        }
-
-        for( ; x < size.width; x++ )
-            dst[x] = op( src[x], scalar );
-    }
-}
-
-typedef void (*BinarySFuncCn)(const Mat& src1, Mat& dst, const Scalar& scalar);
-typedef void (*BinarySFuncC1)(const Mat& src1, Mat& dst, double scalar);
+enum { BLOCK_SIZE = 1024 };
 
+#ifdef HAVE_IPP
+static inline IppiSize ippiSize(int width, int height) { IppiSize sz={width, height}; return sz; }
+static inline IppiSize ippiSize(Size _sz) { reIppiSize sz={_sz.width, _sz.height}; return sz; }
+#endif
+    
+#if defined HAVE_IPP && (IPP_VERSION_MAJOR >= 7)
+#define ARITHM_USE_IPP 1
+#define IF_IPP(then_call, else_call) then_call
+#else
+#define ARITHM_USE_IPP 0
+#define IF_IPP(then_call, else_call) else_call
+#endif    
+    
 }
 
 #endif /*_CXCORE_INTERNAL_H_*/
index 69b5b85..f0701e8 100644 (file)
@@ -67,82 +67,60 @@ namespace cv
 \***************************************************************************************/
 
 template<typename T> static void
-RandBits_( Mat& _arr, uint64* state, const void* _param )
+randBits_( T* arr, int len, uint64* state, const Vec2i* p, bool small_flag )
 {
     uint64 temp = *state;
-    const int* param = (const int*)_param;
-    int small_flag = (param[12]|param[13]|param[14]|param[15]) <= 255;
-    Size size = getContinuousSize(_arr,_arr.channels());
+    int i;
 
-    for( int y = 0; y < size.height; y++ )
+    if( !small_flag )
     {
-        T* arr = (T*)(_arr.data + _arr.step*y);
-        int i, k = 3;
-        const int* p = param;
-
-        if( !small_flag )
-        {
-            for( i = 0; i <= size.width - 4; i += 4 )
-            {
-                int t0, t1;
-
-                temp = RNG_NEXT(temp);
-                t0 = ((int)temp & p[i + 12]) + p[i];
-                temp = RNG_NEXT(temp);
-                t1 = ((int)temp & p[i + 13]) + p[i+1];
-                arr[i] = saturate_cast<T>(t0);
-                arr[i+1] = saturate_cast<T>(t1);
-
-                temp = RNG_NEXT(temp);
-                t0 = ((int)temp & p[i + 14]) + p[i+2];
-                temp = RNG_NEXT(temp);
-                t1 = ((int)temp & p[i + 15]) + p[i+3];
-                arr[i+2] = saturate_cast<T>(t0);
-                arr[i+3] = saturate_cast<T>(t1);
-
-                if( !--k )
-                {
-                    k = 3;
-                    p -= 12;
-                }
-            }
-        }
-        else
+        for( i = 0; i <= len - 4; i += 4 )
         {
-            for( i = 0; i <= size.width - 4; i += 4 )
-            {
-                int t0, t1, t;
-
-                temp = RNG_NEXT(temp);
-                t = (int)temp;
-                t0 = (t & p[i + 12]) + p[i];
-                t1 = ((t >> 8) & p[i + 13]) + p[i+1];
-                arr[i] = saturate_cast<T>(t0);
-                arr[i+1] = saturate_cast<T>(t1);
+            int t0, t1;
 
-                t0 = ((t >> 16) & p[i + 14]) + p[i + 2];
-                t1 = ((t >> 24) & p[i + 15]) + p[i + 3];
-                arr[i+2] = saturate_cast<T>(t0);
-                arr[i+3] = saturate_cast<T>(t1);
+            temp = RNG_NEXT(temp);
+            t0 = ((int)temp & p[i][0]) + p[i][1];
+            temp = RNG_NEXT(temp);
+            t1 = ((int)temp & p[i+1][0]) + p[i+1][1];
+            arr[i] = saturate_cast<T>(t0);
+            arr[i+1] = saturate_cast<T>(t1);
 
-                if( !--k )
-                {
-                    k = 3;
-                    p -= 12;
-                }
-            }
+            temp = RNG_NEXT(temp);
+            t0 = ((int)temp & p[i+2][0]) + p[i+2][1];
+            temp = RNG_NEXT(temp);
+            t1 = ((int)temp & p[i+3][0]) + p[i+3][1];
+            arr[i+2] = saturate_cast<T>(t0);
+            arr[i+3] = saturate_cast<T>(t1);
         }
-
-        for( ; i < size.width; i++ )
+    }
+    else
+    {
+        for( i = 0; i <= len - 4; i += 4 )
         {
-            int t0;
+            int t0, t1, t;
             temp = RNG_NEXT(temp);
-
-            t0 = ((int)temp & p[i + 12]) + p[i];
+            t = (int)temp;
+            t0 = (t & p[i][0]) + p[i][1];
+            t1 = ((t >> 8) & p[i+1][0]) + p[i+1][1];
             arr[i] = saturate_cast<T>(t0);
+            arr[i+1] = saturate_cast<T>(t1);
+
+            t0 = ((t >> 16) & p[i+2][0]) + p[i+2][1];
+            t1 = ((t >> 24) & p[i+3][0]) + p[i+3][1];
+            arr[i+2] = saturate_cast<T>(t0);
+            arr[i+3] = saturate_cast<T>(t1);
         }
     }
 
+    for( ; i < len; i++ )
+    {
+        int t0;
+        temp = RNG_NEXT(temp);
+
+        t0 = ((int)temp & p[i][0]) + p[i][1];
+        arr[i] = saturate_cast<T>(t0);
+    }
+
     *state = temp;
 }
 
@@ -155,124 +133,96 @@ struct DivStruct
 };
 
 template<typename T> static void
-Randi_( Mat& _arr, uint64* state, const void* _param )
+randi_( T* arr, int len, uint64* state, const DivStruct* p )
 {
     uint64 temp = *state;
-    const int* param = (const int*)_param;
-    Size size = getContinuousSize(_arr,_arr.channels());
-    int i, k, cn = _arr.channels();
-    DivStruct ds[12];
-    
-    for( k = 0; k < cn; k++ )
+    int i = 0;
+    unsigned t0, t1, v0, v1;
+
+    for( i = 0; i <= len - 4; i += 4 )
     {
-        ds[k].delta = param[k];
-        ds[k].d = (unsigned)(param[k+12] - param[k]);
-        int l = 0;
-        while(((uint64)1 << l) < ds[k].d)
-            l++;
-        ds[k].M = (unsigned)(((uint64)1 << 32)*(((uint64)1 << l) - ds[k].d)/ds[k].d) + 1;
-        ds[k].sh1 = min(l, 1);
-        ds[k].sh2 = max(l - 1, 0);
+        temp = RNG_NEXT(temp);
+        t0 = (unsigned)temp;
+        temp = RNG_NEXT(temp);
+        t1 = (unsigned)temp;
+        v0 = (unsigned)(((uint64)t0 * p[i].M) >> 32);
+        v1 = (unsigned)(((uint64)t1 * p[i+1].M) >> 32);
+        v0 = (v0 + ((t0 - v0) >> p[i].sh1)) >> p[i].sh2;
+        v1 = (v1 + ((t1 - v1) >> p[i+1].sh1)) >> p[i+1].sh2;
+        v0 = t0 - v0*p[i].d + p[i].delta;
+        v1 = t1 - v1*p[i+1].d + p[i+1].delta;
+        arr[i] = saturate_cast<T>((int)v0);
+        arr[i+1] = saturate_cast<T>((int)v1);
+        
+        temp = RNG_NEXT(temp);
+        t0 = (unsigned)temp;
+        temp = RNG_NEXT(temp);
+        t1 = (unsigned)temp;
+        v0 = (unsigned)(((uint64)t0 * p[i+2].M) >> 32);
+        v1 = (unsigned)(((uint64)t1 * p[i+3].M) >> 32);
+        v0 = (v0 + ((t0 - v0) >> p[i+2].sh1)) >> p[i+2].sh2;
+        v1 = (v1 + ((t1 - v1) >> p[i+3].sh1)) >> p[i+3].sh2;
+        v0 = t0 - v0*p[i+2].d + p[i+2].delta;
+        v1 = t1 - v1*p[i+3].d + p[i+3].delta;
+        arr[i+2] = saturate_cast<T>((int)v0);
+        arr[i+3] = saturate_cast<T>((int)v1);
     }
-    
-    for( ; k < 12; k++ )
-        ds[k] = ds[k - cn];
 
-    for( int y = 0; y < size.height; y++ )
+    for( ; i < len; i++ )
     {
-        T* arr = (T*)(_arr.data + _arr.step*y);
-        const DivStruct* p = ds;
-        unsigned t0, t1, v0, v1;
-
-        for( i = 0, k = 3; i <= size.width - 4; i += 4 )
-        {
-            temp = RNG_NEXT(temp);
-            t0 = (unsigned)temp;
-            temp = RNG_NEXT(temp);
-            t1 = (unsigned)temp;
-            v0 = (unsigned)(((uint64)t0 * p[i].M) >> 32);
-            v1 = (unsigned)(((uint64)t1 * p[i+1].M) >> 32);
-            v0 = (v0 + ((t0 - v0) >> p[i].sh1)) >> p[i].sh2;
-            v1 = (v1 + ((t1 - v1) >> p[i+1].sh1)) >> p[i+1].sh2;
-            v0 = t0 - v0*p[i].d + p[i].delta;
-            v1 = t1 - v1*p[i+1].d + p[i+1].delta;
-            arr[i] = saturate_cast<T>((int)v0);
-            arr[i+1] = saturate_cast<T>((int)v1);
-            
-            temp = RNG_NEXT(temp);
-            t0 = (unsigned)temp;
-            temp = RNG_NEXT(temp);
-            t1 = (unsigned)temp;
-            v0 = (unsigned)(((uint64)t0 * p[i+2].M) >> 32);
-            v1 = (unsigned)(((uint64)t1 * p[i+3].M) >> 32);
-            v0 = (v0 + ((t0 - v0) >> p[i+2].sh1)) >> p[i+2].sh2;
-            v1 = (v1 + ((t1 - v1) >> p[i+3].sh1)) >> p[i+3].sh2;
-            v0 = t0 - v0*p[i+2].d + p[i+2].delta;
-            v1 = t1 - v1*p[i+3].d + p[i+3].delta;
-            arr[i+2] = saturate_cast<T>((int)v0);
-            arr[i+3] = saturate_cast<T>((int)v1);
-
-            if( !--k )
-            {
-                k = 3;
-                p -= 12;
-            }
-        }
-
-        for( ; i < size.width; i++ )
-        {
-            temp = RNG_NEXT(temp);
-            t0 = (unsigned)temp;
-            v0 = (unsigned)(((uint64)t0 * p[i].M) >> 32);
-            v0 = (v0 + ((t0 - v0) >> p[i].sh1)) >> p[i].sh2;
-            v0 = t0 - v0*p[i].d + p[i].delta;
-            arr[i] = saturate_cast<T>((int)v0);
-        }
+        temp = RNG_NEXT(temp);
+        t0 = (unsigned)temp;
+        v0 = (unsigned)(((uint64)t0 * p[i].M) >> 32);
+        v0 = (v0 + ((t0 - v0) >> p[i].sh1)) >> p[i].sh2;
+        v0 = t0 - v0*p[i].d + p[i].delta;
+        arr[i] = saturate_cast<T>((int)v0);
     }
 
     *state = temp;
 }
 
-
-static void Randf_( Mat& _arr, uint64* state, const void* _param )
+    
+#define DEF_RANDI_FUNC(suffix, type) \
+static void randBits_##suffix(type* arr, int len, uint64* state, \
+                              const Vec2i* p, bool small_flag) \
+{ randBits_(arr, len, state, p, small_flag); } \
+\
+static void randi_##suffix(type* arr, int len, uint64* state, \
+                           const DivStruct* p, bool ) \
+{ randi_(arr, len, state, p); }
+
+DEF_RANDI_FUNC(8u, uchar)
+DEF_RANDI_FUNC(8s, schar)
+DEF_RANDI_FUNC(16u, ushort)
+DEF_RANDI_FUNC(16s, short)
+DEF_RANDI_FUNC(32s, int)
+    
+static void randf_32f( float* arr, int len, uint64* state, const Vec2f* p, bool )
 {
     uint64 temp = *state;
-    const float* param = (const float*)_param;
-    Size size = getContinuousSize(_arr,_arr.channels());
+    int i;
 
-    for( int y = 0; y < size.height; y++ )
+    for( i = 0; i <= len - 4; i += 4 )
     {
-        float* arr = (float*)(_arr.data + _arr.step*y);
-        int i, k = 3;
-        const float* p = param;
-        for( i = 0; i <= size.width - 4; i += 4 )
-        {
-            float f0, f1;
-
-            temp = RNG_NEXT(temp);
-            f0 = (int)temp*p[i+12] + p[i];
-            temp = RNG_NEXT(temp);
-            f1 = (int)temp*p[i+13] + p[i+1];
-            arr[i] = f0; arr[i+1] = f1;
-
-            temp = RNG_NEXT(temp);
-            f0 = (int)temp*p[i+14] + p[i+2];
-            temp = RNG_NEXT(temp);
-            f1 = (int)temp*p[i+15] + p[i+3];
-            arr[i+2] = f0; arr[i+3] = f1;
-
-            if( !--k )
-            {
-                k = 3;
-                p -= 12;
-            }
-        }
+        float f0, f1;
+
+        temp = RNG_NEXT(temp);
+        f0 = (int)temp*p[i][0] + p[i][1];
+        temp = RNG_NEXT(temp);
+        f1 = (int)temp*p[i+1][0] + p[i+1][1];
+        arr[i] = f0; arr[i+1] = f1;
+
+        temp = RNG_NEXT(temp);
+        f0 = (int)temp*p[i+2][0] + p[i+2][1];
+        temp = RNG_NEXT(temp);
+        f1 = (int)temp*p[i+3][0] + p[i+3][1];
+        arr[i+2] = f0; arr[i+3] = f1;
+    }
 
-        for( ; i < size.width; i++ )
-        {
-            temp = RNG_NEXT(temp);
-            arr[i] = (int)temp*p[i+12] + p[i];
-        }
+    for( ; i < len; i++ )
+    {
+        temp = RNG_NEXT(temp);
+        arr[i] = (int)temp*p[i][0] + p[i][1];
     }
 
     *state = temp;
@@ -280,65 +230,65 @@ static void Randf_( Mat& _arr, uint64* state, const void* _param )
 
 
 static void
-Randd_( Mat& _arr, uint64* state, const void* _param )
+randf_64f( double* arr, int len, uint64* state, const Vec2d* p, bool )
 {
     uint64 temp = *state;
-    const double* param = (const double*)_param;
-    Size size = getContinuousSize(_arr,_arr.channels());
     int64 v = 0;
+    int i;
 
-    for( int y = 0; y < size.height; y++ )
+    for( i = 0; i <= len - 4; i += 4 )
     {
-        double* arr = (double*)(_arr.data + _arr.step*y);
-        int i, k = 3;
-        const double* p = param;
-        
-        for( i = 0; i <= size.width - 4; i += 4 )
-        {
-            double f0, f1;
-
-            temp = RNG_NEXT(temp);
-            v = (temp >> 32)|(temp << 32);
-            f0 = v*p[i+12] + p[i];
-            temp = RNG_NEXT(temp);
-            v = (temp >> 32)|(temp << 32);
-            f1 = v*p[i+13] + p[i+1];
-            arr[i] = f0; arr[i+1] = f1;
-
-            temp = RNG_NEXT(temp);
-            v = (temp >> 32)|(temp << 32);
-            f0 = v*p[i+14] + p[i+2];
-            temp = RNG_NEXT(temp);
-            v = (temp >> 32)|(temp << 32);
-            f1 = v*p[i+15] + p[i+3];
-            arr[i+2] = f0; arr[i+3] = f1;
-
-            if( !--k )
-            {
-                k = 3;
-                p -= 12;
-            }
-        }
+        double f0, f1;
+
+        temp = RNG_NEXT(temp);
+        v = (temp >> 32)|(temp << 32);
+        f0 = v*p[i][0] + p[i][1];
+        temp = RNG_NEXT(temp);
+        v = (temp >> 32)|(temp << 32);
+        f1 = v*p[i+1][0] + p[i+1][1];
+        arr[i] = f0; arr[i+1] = f1;
+
+        temp = RNG_NEXT(temp);
+        v = (temp >> 32)|(temp << 32);
+        f0 = v*p[i+2][0] + p[i+2][1];
+        temp = RNG_NEXT(temp);
+        v = (temp >> 32)|(temp << 32);
+        f1 = v*p[i+3][0] + p[i+3][1];
+        arr[i+2] = f0; arr[i+3] = f1;
+    }
 
-        for( ; i < size.width; i++ )
-        {
-            temp = RNG_NEXT(temp);
-            v = (temp >> 32)|(temp << 32);
-            arr[i] = v*p[i+12] + p[i];
-        }
+    for( ; i < len; i++ )
+    {
+        temp = RNG_NEXT(temp);
+        v = (temp >> 32)|(temp << 32);
+        arr[i] = v*p[i][0] + p[i][1];
     }
 
     *state = temp;
 }
 
-   
+typedef void (*RandFunc)(uchar* arr, int len, uint64* state, const void* p, bool small_flag);    
+
+    
+static RandFunc randTab[][8] =
+{
+    {
+        (RandFunc)randi_8u, (RandFunc)randi_8s, (RandFunc)randi_16u, (RandFunc)randi_16s,
+        (RandFunc)randi_32s, (RandFunc)randf_32f, (RandFunc)randf_64f, 0
+    },
+    {
+        (RandFunc)randBits_8u, (RandFunc)randBits_8s, (RandFunc)randBits_16u, (RandFunc)randBits_16s,
+        (RandFunc)randBits_32s, 0, 0, 0
+    }
+};    
+    
 /*
    The code below implements the algorithm described in
    "The Ziggurat Method for Generating Random Variables"
    by Marsaglia and Tsang, Journal of Statistical Software.
 */
 static void
-Randn_0_1_32f_C1R( float* arr, int len, uint64* state )
+randn_0_1_32f( float* arr, int len, uint64* state )
 {
     const float r = 3.442620f; // The start of the right tail
     const float rng_flt = 2.3283064365386962890625e-10f; // 2^-32
@@ -416,115 +366,163 @@ Randn_0_1_32f_C1R( float* arr, int len, uint64* state )
 double RNG::gaussian(double sigma)
 {
     float temp;
-    Randn_0_1_32f_C1R( &temp, 1, &state );
+    randn_0_1_32f( &temp, 1, &state );
     return temp*sigma;
 }
-    
 
+    
 template<typename T, typename PT> static void
-Randn_( Mat& _arr, uint64* state, const void* _param )
+randnScale_( const float* src, T* dst, int len, int cn, const PT* mean, const PT* stddev, bool stdmtx )
 {
-    const int RAND_BUF_SIZE = 96;
-    float buffer[RAND_BUF_SIZE];
-    int pidx[RAND_BUF_SIZE];    
-    const PT* param = (const PT*)_param;
-    Size size = getContinuousSize(_arr, _arr.channels());
-    
-    int i, n = std::min(size.width, RAND_BUF_SIZE);
-    for( i = 0; i < 12; i++ )
-        pidx[i] = i;
-    for( ; i < n; i++ )
-        pidx[i] = pidx[i - 12];
-
-    for( int y = 0; y < size.height; y++ )
+    int i, j, k;
+    if( !stdmtx )
     {
-        T* arr = (T*)(_arr.data + _arr.step*y);
-        int len = RAND_BUF_SIZE;
-        for( i = 0; i < size.width; i += RAND_BUF_SIZE )
+        if( cn == 1 )
         {
-            if( i + len > size.width )
-                len = size.width - i;
-
-            Randn_0_1_32f_C1R( buffer, len, state );
-
-            for( int j = 0; j < len; j++ )
-                arr[i+j] = saturate_cast<T>(buffer[j]*param[pidx[j]+12] + param[pidx[j]]);
+            PT b = mean[0], a = stddev[0];
+            for( i = 0; i < len; i++ )
+                dst[i] = saturate_cast<T>(src[i]*a + b);
+        }
+        else
+        {
+            for( i = 0; i < len; i++, src += cn, dst += cn )
+                for( k = 0; k < cn; k++ )
+                    dst[k] = saturate_cast<T>(src[k]*stddev[k] + mean[k]);
+        }
+    }
+    else
+    {
+        for( i = 0; i < len; i++, src += cn, dst += cn )
+        {
+            for( j = 0; j < cn; j++ )
+            {
+                PT s = mean[j];
+                for( k = 0; k < cn; k++ )
+                    s += src[k]*stddev[j*cn + k];
+                dst[j] = saturate_cast<T>(s);
+            }
         }
     }
 }
+    
+static void randnScale_8u( const float* src, uchar* dst, int len, int cn,
+                            const float* mean, const float* stddev, bool stdmtx )
+{ randnScale_(src, dst, len, cn, mean, stddev, stdmtx); }
+
+static void randnScale_8s( const float* src, schar* dst, int len, int cn,
+                            const float* mean, const float* stddev, bool stdmtx )
+{ randnScale_(src, dst, len, cn, mean, stddev, stdmtx); }
 
+static void randnScale_16u( const float* src, ushort* dst, int len, int cn,
+                             const float* mean, const float* stddev, bool stdmtx )
+{ randnScale_(src, dst, len, cn, mean, stddev, stdmtx); }
 
-typedef void (*RandFunc)(Mat& dst, uint64* state, const void* param);
+static void randnScale_16s( const float* src, short* dst, int len, int cn,
+                             const float* mean, const float* stddev, bool stdmtx )
+{ randnScale_(src, dst, len, cn, mean, stddev, stdmtx); }
 
-void RNG::fill( Mat& mat, int disttype, const Scalar& param1, const Scalar& param2 )
+static void randnScale_32s( const float* src, int* dst, int len, int cn,
+                             const float* mean, const float* stddev, bool stdmtx )
+{ randnScale_(src, dst, len, cn, mean, stddev, stdmtx); }
+
+static void randnScale_32f( const float* src, float* dst, int len, int cn,
+                             const float* mean, const float* stddev, bool stdmtx )
+{ randnScale_(src, dst, len, cn, mean, stddev, stdmtx); }
+
+static void randnScale_64f( const float* src, double* dst, int len, int cn,
+                             const double* mean, const double* stddev, bool stdmtx )
+{ randnScale_(src, dst, len, cn, mean, stddev, stdmtx); }
+
+typedef void (*RandnScaleFunc)(const float* src, uchar* dst, int len, int cn,
+                               const uchar*, const uchar*, bool);
+
+static RandnScaleFunc randnScaleTab[] =
 {
-    static RandFunc rngtab[3][8] =
-    {
-        {
-        RandBits_<uchar>, 
-        RandBits_<schar>,
-        RandBits_<ushort>,
-        RandBits_<short>,
-        RandBits_<int>, 0, 0, 0},
-
-        {Randi_<uchar>,
-        Randi_<schar>,
-        Randi_<ushort>,
-        Randi_<short>,
-        Randi_<int>,
-        Randf_, Randd_, 0},
-
-        {Randn_<uchar,float>,
-        Randn_<schar,float>,
-        Randn_<ushort,float>,
-        Randn_<short,float>,
-        Randn_<int,float>,
-        Randn_<float,float>,
-        Randn_<double,double>, 0}
-    };
+    (RandnScaleFunc)randnScale_8u, (RandnScaleFunc)randnScale_8s, (RandnScaleFunc)randnScale_16u,
+    (RandnScaleFunc)randnScale_16s, (RandnScaleFunc)randnScale_32s, (RandnScaleFunc)randnScale_32f,
+    (RandnScaleFunc)randnScale_64f, 0 
+};
     
-    int depth = mat.depth(), channels = mat.channels();
-    double dparam[2][12];
-    float fparam[2][12];
-    int iparam[2][12];
-    void* param = dparam;
-    int i, fast_int_mode = 0;
+void RNG::fill( InputOutputArray _mat, int disttype, const InputArray& _param1arg, const InputArray& _param2arg )
+{
+    Mat mat = _mat.getMat(), _param1 = _param1arg.getMat(), _param2 = _param2arg.getMat();
+    int depth = mat.depth(), cn = mat.channels();
+    AutoBuffer<double> _parambuf;
+    int j, k, fast_int_mode = 0, smallFlag = 1;
     RandFunc func = 0;
-
-    CV_Assert( channels <= 4 );
+    RandnScaleFunc scaleFunc = 0;
+    
+    CV_Assert(_param1.channels() == 1 && (_param1.rows == 1 || _param1.cols == 1) &&
+              (_param1.rows + _param1.cols - 1 == cn ||
+               (_param1.size() == Size(1, 4) && _param1.type() == CV_64F && cn <= 4)));
+    CV_Assert( _param2.channels() == 1 &&
+               (((_param2.rows == 1 || _param2.cols == 1) && 
+                (_param2.rows + _param2.cols - 1 == cn ||
+                (_param1.size() == Size(1, 4) && _param1.type() == CV_64F && cn <= 4))) ||
+                (_param2.rows == cn && _param2.cols == cn && disttype == NORMAL)));
+    
+    Vec2i* ip = 0;
+    Vec2d* dp = 0;
+    Vec2f* fp = 0;
+    DivStruct* ds = 0;
+    uchar* mean = 0;
+    uchar* stddev = 0;
+    bool stdmtx = false;
 
     if( disttype == UNIFORM )
     {
+        _parambuf.allocate(cn*8);
+        double* parambuf = _parambuf;
+        const double* p1 = (const double*)_param1.data;
+        const double* p2 = (const double*)_param2.data;
+        
+        if( !_param1.isContinuous() || _param1.type() != CV_64F )
+        {
+            Mat tmp(_param1.size(), CV_64F, parambuf);
+            _param1.convertTo(tmp, CV_64F);
+            p1 = parambuf;
+        }
+        
+        if( !_param2.isContinuous() || _param2.type() != CV_64F )
+        {
+            Mat tmp(_param2.size(), CV_64F, parambuf + cn);
+            _param2.convertTo(tmp, CV_64F);
+            p2 = parambuf + cn;
+        }
+        
         if( depth <= CV_32S )
         {
-            for( i = 0, fast_int_mode = 1; i < channels; i++ )
+            ip = (Vec2i*)(parambuf + cn*2);
+            for( j = 0, fast_int_mode = 1; j < cn; j++ )
             {
-                double a = min(param1.val[i], param2.val[i]);
-                double b = max(param1.val[i], param2.val[i]);
-                int t0 = iparam[0][i] = cvCeil(a);
-                int t1 = iparam[1][i] = cvFloor(b);
+                double a = min(p1[j], p2[j]);
+                double b = max(p1[j], p2[j]);
+                ip[j][1] = cvCeil(a);
+                int idiff = ip[j][0] = cvFloor(b) - ip[j][1] - 1;
                 double diff = b - a;
 
-                fast_int_mode &= diff <= 4294967296. && ((t1-t0) & (t1-t0-1)) == 0;
+                fast_int_mode &= diff <= 4294967296. && (idiff & (idiff+1)) == 0;
+                if( fast_int_mode )
+                    smallFlag &= idiff <= 255;
             }
             
-            if( fast_int_mode )
-            {
-                for( i = 0; i < channels; i++ )
-                    iparam[1][i] = iparam[1][i] > iparam[0][i] ? iparam[1][i] - iparam[0][i] - 1 : 0;
-            }
-                
-            for( ; i < 12; i++ )
+            if( !fast_int_mode )
             {
-                int t0 = iparam[0][i - channels];
-                int t1 = iparam[1][i - channels];
-                
-                iparam[0][i] = t0;
-                iparam[1][i] = t1;
+                ds = (DivStruct*)(ip + cn);
+                for( j = 0; j < cn; j++ )
+                {
+                    ds[j].delta = ip[j][1];
+                    unsigned d = ds[j].d = (unsigned)(ip[j][0]+1);
+                    int l = 0;
+                    while(((uint64)1 << l) < d)
+                        l++;
+                    ds[j].M = (unsigned)(((uint64)1 << 32)*(((uint64)1 << l) - d)/d) + 1;
+                    ds[j].sh1 = min(l, 1);
+                    ds[j].sh2 = max(l - 1, 0);
+                }            
             }
             
-            func = rngtab[!fast_int_mode][depth];
-            param = iparam;
+            func = randTab[fast_int_mode][depth];
         }
         else
         {
@@ -536,70 +534,128 @@ void RNG::fill( Mat& mat, int disttype, const Scalar& param1, const Scalar& para
             // so that a signed 32/64-bit integer X is transformed to
             // the range [param1.val[i], param2.val[i]) using
             // dparam[1][i]*X + dparam[0][i]
-            for( i = 0; i < channels; i++ )
+            if( depth == CV_32F )
             {
-                double t0 = param1.val[i];
-                double t1 = param2.val[i];
-                dparam[0][i] = (t1 + t0)*0.5;
-                dparam[1][i] = (t1 - t0)*scale;
+                fp = (Vec2f*)(parambuf + cn*2);
+                for( j = 0; j < cn; j++ )
+                {
+                    fp[j][0] = (float)((p2[j] - p1[j])*scale);
+                    fp[j][1] = (float)((p2[j] + p1[j])*0.5);
+                }
+            }
+            else
+            {
+                dp = (Vec2d*)(parambuf + cn*2);
+                for( j = 0; j < cn; j++ )
+                {
+                    dp[j][0] = ((p2[j] - p1[j])*scale);
+                    dp[j][1] = ((p2[j] + p1[j])*0.5);
+                }
             }
             
-            func = rngtab[1][depth];
-            param = dparam;
+            func = randTab[0][depth];                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
         }
+        CV_Assert( func != 0 );
     }
     else if( disttype == CV_RAND_NORMAL )
     {
-        for( i = 0; i < channels; i++ )
+        _parambuf.allocate(_param1.total() + _param2.total());
+        double* parambuf = _parambuf;
+        
+        int ptype = depth == CV_64F ? CV_64F : CV_32F;
+        if( _param1.isContinuous() && _param1.type() == ptype )
+            mean = _param1.data;
+        else
         {
-            double t0 = param1.val[i];
-            double t1 = param2.val[i];
-
-            dparam[0][i] = t0;
-            dparam[1][i] = t1;
+            Mat tmp(_param1.size(), ptype, parambuf);
+            _param1.convertTo(tmp, ptype);
+            mean = (uchar*)parambuf;
         }
-
-        func = rngtab[2][depth];
-        param = dparam;
+        
+        if( _param2.isContinuous() && _param2.type() == ptype )
+            stddev = _param2.data;
+        else
+        {
+            Mat tmp(_param2.size(), ptype, parambuf + cn);
+            _param2.convertTo(tmp, ptype);
+            stddev = (uchar*)(parambuf + cn);
+        }
+        
+        stdmtx = _param2.rows == cn && _param2.cols == cn;
+        scaleFunc = randnScaleTab[depth];
+        CV_Assert( scaleFunc != 0 );
     }
     else
         CV_Error( CV_StsBadArg, "Unknown distribution type" );
 
-    if( param == dparam )
+    const Mat* arrays[] = {&mat, 0};
+    uchar* ptr;
+    NAryMatIterator it(arrays, &ptr);
+    int total = (int)it.size, blockSize = std::min((BLOCK_SIZE + cn - 1)/cn, total);
+    size_t esz = mat.elemSize();
+    AutoBuffer<double> buf;
+    uchar* param = 0;
+    float* nbuf = 0;
+    
+    if( disttype == UNIFORM )
     {
-        for( i = channels; i < 12; i++ )
-        {
-            double t0 = dparam[0][i - channels];
-            double t1 = dparam[1][i - channels];
-
-            dparam[0][i] = t0;
-            dparam[1][i] = t1;
-        }
-
-        if( depth != CV_64F )
+        buf.allocate(blockSize*cn*4);
+        param = (uchar*)(double*)buf;
+        
+        if( ip )
         {
-            for( i = 0; i < 12; i++ )
+            if( ds )
+            {
+                DivStruct* p = (DivStruct*)param;
+                for( j = 0; j < blockSize*cn; j += cn )
+                    for( k = 0; k < cn; k++ )
+                        p[j + k] = ds[k];
+            }
+            else
             {
-                fparam[0][i] = (float)dparam[0][i];
-                fparam[1][i] = (float)dparam[1][i];
+                Vec2i* p = (Vec2i*)param;
+                for( j = 0; j < blockSize*cn; j += cn )
+                    for( k = 0; k < cn; k++ )
+                        p[j + k] = ip[k];
             }
-            param = fparam;
+        }
+        else if( fp )
+        {
+            Vec2f* p = (Vec2f*)param;
+            for( j = 0; j < blockSize*cn; j += cn )
+                for( k = 0; k < cn; k++ )
+                    p[j + k] = fp[k];
+        }
+        else
+        {
+            Vec2d* p = (Vec2d*)param;
+            for( j = 0; j < blockSize*cn; j += cn )
+                for( k = 0; k < cn; k++ )
+                    p[j + k] = dp[k];
         }
     }
-
-    CV_Assert( func != 0);
+    else
+    {
+        buf.allocate((blockSize*cn+1)/2);
+        nbuf = (float*)(double*)buf;
+    }
     
-    if( mat.dims > 2 )
+    for( size_t i = 0; i < it.nplanes; i++, ++it )
     {
-        const Mat* arrays[] = {&mat, 0};
-        Mat planes[1];
-        NAryMatIterator it(arrays, planes);
-        
-        for( int i = 0; i < it.nplanes; i++, ++it )
-            func( it.planes[0], &state, param );
+        for( j = 0; j < total; j += blockSize )
+        {
+            int len = std::min(total - j, blockSize);
+            
+            if( disttype == CV_RAND_UNI )
+                func( ptr, len*cn, &state, param, smallFlag != 0 );
+            else
+            {
+                randn_0_1_32f(nbuf, len*cn, &state);
+                scaleFunc(nbuf, ptr, len, cn, mean, stddev, stdmtx);
+            }
+            ptr += len*esz;
+        }
     }
-    else
-        func( mat, &state, param );
 }
 
 #ifdef WIN32
@@ -657,16 +713,21 @@ RNG& theRNG()
 
 #endif
 
-void randu(CV_OUT Mat& dst, const Scalar& low, const Scalar& high)
+}
+    
+void cv::randu(InputOutputArray dst, const InputArray& low, const InputArray& high)
 {
     theRNG().fill(dst, RNG::UNIFORM, low, high);
 }
 
-void randn(CV_OUT Mat& dst, const Scalar& mean, const Scalar& stddev)
+void cv::randn(InputOutputArray dst, const InputArray& mean, const InputArray& stddev)
 {
     theRNG().fill(dst, RNG::NORMAL, mean, stddev);
 }    
-    
+namespace cv
+{
+
 template<typename T> static void
 randShuffle_( Mat& _arr, RNG& rng, double iterFactor )
 {
@@ -697,7 +758,9 @@ randShuffle_( Mat& _arr, RNG& rng, double iterFactor )
 
 typedef void (*RandShuffleFunc)( Mat& dst, RNG& rng, double iterFactor );
 
-void randShuffle( Mat& dst, double iterFactor, RNG* _rng )
+}
+    
+void cv::randShuffle( InputOutputArray _dst, double iterFactor, RNG* _rng )
 {
     RandShuffleFunc tab[] =
     {
@@ -719,7 +782,8 @@ void randShuffle( Mat& dst, double iterFactor, RNG* _rng )
         0, 0, 0, 0, 0, 0, 0,
         randShuffle_<Vec<int,8> > // 32
     };
-
+    
+    Mat dst = _dst.getMat();
     RNG& rng = _rng ? *_rng : theRNG();
     CV_Assert( dst.elemSize() <= 32 );
     RandShuffleFunc func = tab[dst.elemSize()];
@@ -727,8 +791,6 @@ void randShuffle( Mat& dst, double iterFactor, RNG* _rng )
     func( dst, rng, iterFactor );
 }
 
-}
-
 CV_IMPL void
 cvRandArr( CvRNG* _rng, CvArr* arr, int disttype, CvScalar param1, CvScalar param2 )
 {
@@ -736,7 +798,7 @@ cvRandArr( CvRNG* _rng, CvArr* arr, int disttype, CvScalar param1, CvScalar para
     // !!! this will only work for current 64-bit MWC RNG !!!
     cv::RNG& rng = _rng ? (cv::RNG&)*_rng : cv::theRNG();
     rng.fill(mat, disttype == CV_RAND_NORMAL ?
-        cv::RNG::NORMAL : cv::RNG::UNIFORM, param1, param2 );
+        cv::RNG::NORMAL : cv::RNG::UNIFORM, (cv::Scalar&)param1, (cv::Scalar&)param2 );
 }
 
 CV_IMPL void cvRandShuffle( CvArr* arr, CvRNG* _rng, double iter_factor )
index 44f981a..b35d1cf 100644 (file)
@@ -11,7 +11,7 @@
 //                For Open Source Computer Vision Library
 //
 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
-// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
 // Third party copyrights are property of their respective owners.
 //
 // Redistribution and use in source and binary forms, with or without modification,
@@ -59,608 +59,611 @@ template<typename T> static inline Scalar rawToScalar(const T& v)
 *                                        sum                                             *
 \****************************************************************************************/
 
-template<typename T, typename WT, typename ST, int BLOCK_SIZE>
-static Scalar sumBlock_( const Mat& srcmat )
+template<typename T, typename ST>
+static size_t sum_(const T* src0, const uchar* mask, ST* dst, int len, int cn )
 {
-    assert( DataType<T>::type == srcmat.type() );
-    Size size = getContinuousSize( srcmat );
-    ST s0 = 0;
-    WT s = 0;
-    int y, remaining = BLOCK_SIZE;
-
-    for( y = 0; y < size.height; y++ )
+    const T* src = src0;
+    if( !mask )
     {
-        const T* src = (const T*)(srcmat.data + srcmat.step*y);
-        int x = 0;
-        while( x < size.width )
+        int i;
+        int k = cn % 4;
+        if( k == 1 )
+        {
+            ST s0 = dst[0];
+            for( i = 0; i <= len - 4; i += 4, src += cn*4 )
+                s0 += src[0] + src[cn] + src[cn*2] + src[cn*3];
+            for( ; i < len; i++, src += cn )
+                s0 += src[0];
+            dst[0] = s0;
+        }
+        else if( k == 2 )
         {
-            int limit = std::min( remaining, size.width - x );
-            remaining -= limit;
-            limit += x;
-            for( ; x <= limit - 4; x += 4 )
+            ST s0 = dst[0], s1 = dst[1];
+            for( i = 0; i < len; i++, src += cn )
             {
-                s += src[x];
-                s += src[x+1];
-                s += src[x+2];
-                s += src[x+3];
+                s0 += src[0];
+                s1 += src[1];
             }
-            for( ; x < limit; x++ )
-                s += src[x];
-            if( remaining == 0 || (x == size.width && y == size.height-1) )
+            dst[0] = s0;
+            dst[1] = s1;
+        }
+        else if( k == 3 )
+        {
+            ST s0 = dst[0], s1 = dst[1], s2 = dst[2];
+            for( i = 0; i < len; i++, src += cn )
             {
-                s0 += s;
-                s = 0;
-                remaining = BLOCK_SIZE;
+                s0 += src[0];
+                s1 += src[1];
+                s2 += src[2];
             }
+            dst[0] = s0;
+            dst[1] = s1;
+            dst[2] = s2;
         }
-    }
-    return rawToScalar(s0);
-}
-
-template<typename T, typename ST>
-static Scalar sum_( const Mat& srcmat )
-{
-    assert( DataType<T>::type == srcmat.type() );
-    Size size = getContinuousSize( srcmat );
-    ST s = 0;
-
-    for( int y = 0; y < size.height; y++ )
-    {
-        const T* src = (const T*)(srcmat.data + srcmat.step*y);
-        int x = 0;
-        for( ; x <= size.width - 4; x += 4 )
+        
+        for( ; k < cn; k += 4 )
         {
-            s += src[x];
-            s += src[x+1];
-            s += src[x+2];
-            s += src[x+3];
+            src = src0 + k;
+            ST s0 = dst[k], s1 = dst[k+1], s2 = dst[k+2], s3 = dst[k+3];
+            for( i = 0; i < len; i++, src += cn )
+            {
+                s0 += src[0]; s1 += src[1];
+                s2 += src[2]; s3 += src[3];
+            }
+            dst[k] = s0;
+            dst[k+1] = s1;
+            dst[k+2] = s2;
+            dst[k+3] = s3;
         }
-        for( ; x < size.width; x++ )
-            s += src[x];
+        return len;
     }
-    return rawToScalar(s);
-}
-
-typedef Scalar (*SumFunc)(const Mat& src);
-
-Scalar sum( const Mat& m )
-{
-    static SumFunc tab[]=
+    
+    int i, nzm = 0;
+    if( cn == 1 )
     {
-        sumBlock_<uchar, unsigned, double, 1<<24>,
-        sumBlock_<schar, int, double, 1<<24>,
-        sumBlock_<ushort, unsigned, double, 1<<16>,
-        sumBlock_<short, int, double, 1<<16>,
-        sum_<int, double>,
-        sum_<float, double>,
-        sum_<double, double>, 0,
-
-        sumBlock_<Vec<uchar, 2>, Vec<int, 2>, Vec<double, 2>, 1<<23>,
-        sumBlock_<Vec<schar, 2>, Vec<int, 2>, Vec<double, 2>, 1<<24>,
-        sumBlock_<Vec<ushort, 2>, Vec<int, 2>, Vec<double, 2>, 1<<15>,
-        sumBlock_<Vec<short, 2>, Vec<int, 2>, Vec<double, 2>, 1<<16>,
-        sum_<Vec<int, 2>, Vec<double, 2> >,
-        sum_<Vec<float, 2>, Vec<double, 2> >,
-        sum_<Vec<double, 2>, Vec<double, 2> >, 0,
-
-        sumBlock_<Vec<uchar, 3>, Vec<int, 3>, Vec<double, 3>, 1<<23>,
-        sumBlock_<Vec<schar, 3>, Vec<int, 3>, Vec<double, 3>, 1<<24>,
-        sumBlock_<Vec<ushort, 3>, Vec<int, 3>, Vec<double, 3>, 1<<15>,
-        sumBlock_<Vec<short, 3>, Vec<int, 3>, Vec<double, 3>, 1<<16>,
-        sum_<Vec<int, 3>, Vec<double, 3> >,
-        sum_<Vec<float, 3>, Vec<double, 3> >,
-        sum_<Vec<double, 3>, Vec<double, 3> >, 0,
-
-        sumBlock_<Vec<uchar, 4>, Vec<int, 4>, Vec<double, 4>, 1<<23>,
-        sumBlock_<Vec<schar, 4>, Vec<int, 4>, Vec<double, 4>, 1<<24>,
-        sumBlock_<Vec<ushort, 4>, Vec<int, 4>, Vec<double, 4>, 1<<15>,
-        sumBlock_<Vec<short, 4>, Vec<int, 4>, Vec<double, 4>, 1<<16>,
-        sum_<Vec<int, 4>, Vec<double, 4> >,
-        sum_<Vec<float, 4>, Vec<double, 4> >,
-        sum_<Vec<double, 4>, Vec<double, 4> >, 0
-    };
-
-    CV_Assert( m.channels() <= 4 );
-
-    SumFunc func = tab[m.type()];
-    CV_Assert( func != 0 );
-
-    if( m.dims > 2 )
+        ST s = dst[0];
+        for( i = 0; i < len; i++ )
+            if( mask[i] )
+            {
+                s += src[i];
+                nzm++;
+            }
+        dst[0] = s;
+    }
+    else if( cn == 3 )
     {
-        const Mat* arrays[] = {&m, 0};
-        Mat planes[1];
-        NAryMatIterator it(arrays, planes);
-        Scalar s;
-        
-        for( int i = 0; i < it.nplanes; i++, ++it )
-            s += func(it.planes[0]);
-        return s;
+        ST s0 = dst[0], s1 = dst[1], s2 = dst[2];
+        for( i = 0; i < len; i++, src += 3 )
+            if( mask[i] )
+            {
+                s0 += src[0];
+                s1 += src[1];
+                s2 += src[2];
+                nzm++;
+            }
+        dst[0] = s0;
+        dst[1] = s1;
+        dst[2] = s2;
     }
-    
-    return func(m);
+    else
+    {
+        for( i = 0; i < len; i++, src += cn )
+            if( mask[i] )
+            {
+                int k = 0;
+                for( ; k <= cn - 4; k += 4 )
+                {
+                    ST s0, s1;
+                    s0 = dst[k] + src[k];
+                    s1 = dst[k+1] + src[k+1];
+                    dst[k] = s0; dst[k+1] = s1;
+                    s0 = dst[k+2] + src[k+2];
+                    s1 = dst[k+3] + src[k+3];
+                    dst[k+2] = s0; dst[k+3] = s1;
+                }
+                for( ; k < cn; k++ )
+                    dst[k] += src[k];
+                nzm++;
+            }
+    }
+    return nzm;
 }
 
-/****************************************************************************************\
-*                                     countNonZero                                       *
-\****************************************************************************************/
+    
+static int sum8u( const uchar* src, const uchar* mask, int* dst, int len, int cn )
+{ return sum_(src, mask, dst, len, cn); }
 
-template<typename T>
-static int countNonZero_( const Mat& srcmat )
-{
-    //assert( DataType<T>::type == srcmat.type() );
-    const T* src = (const T*)srcmat.data;
-    size_t step = srcmat.step/sizeof(src[0]);
-    Size size = getContinuousSize( srcmat );
-    int nz = 0;
+static int sum8s( const schar* src, const uchar* mask, int* dst, int len, int cn )
+{ return sum_(src, mask, dst, len, cn); }
 
-    for( ; size.height--; src += step )
-    {
-        int x = 0;
-        for( ; x <= size.width - 4; x += 4 )
-            nz += (src[x] != 0) + (src[x+1] != 0) + (src[x+2] != 0) + (src[x+3] != 0);
-        for( ; x < size.width; x++ )
-            nz += src[x] != 0;
-    }
-    return nz;
-}
+static int sum16u( const ushort* src, const uchar* mask, int* dst, int len, int cn )
+{ return sum_(src, mask, dst, len, cn); }
 
-typedef int (*CountNonZeroFunc)(const Mat& src);
+static int sum16s( const short* src, const uchar* mask, int* dst, int len, int cn )
+{ return sum_(src, mask, dst, len, cn); }
 
-int countNonZero( const Mat& m )
-{
-    static CountNonZeroFunc tab[] =
-    {
-        countNonZero_<uchar>, countNonZero_<uchar>, countNonZero_<ushort>,
-        countNonZero_<ushort>, countNonZero_<int>, countNonZero_<float>,
-        countNonZero_<double>, 0
-    };
-    
-    CountNonZeroFunc func = tab[m.depth()];
-    CV_Assert( m.channels() == 1 && func != 0 );
-    
-    if( m.dims > 2 )
-    {
-        const Mat* arrays[] = {&m, 0};
-        Mat planes[1];
-        NAryMatIterator it(arrays, planes);
-        int nz = 0;
-        
-        for( int i = 0; i < it.nplanes; i++, ++it )
-            nz += func(it.planes[0]);
-        return nz;
-    }
-    
-    return func(m);
-}
+static int sum32s( const int* src, const uchar* mask, double* dst, int len, int cn )
+{ return sum_(src, mask, dst, len, cn); }
 
+static int sum32f( const float* src, const uchar* mask, double* dst, int len, int cn )
+{ return sum_(src, mask, dst, len, cn); }
 
-/****************************************************************************************\
-*                                         mean                                           *
-\****************************************************************************************/
+static int sum64f( const double* src, const uchar* mask, double* dst, int len, int cn )
+{ return sum_(src, mask, dst, len, cn); }
 
-template<typename T, typename WT, typename ST, int BLOCK_SIZE>
-static Scalar meanBlock_( const Mat& srcmat, const Mat& maskmat )
+typedef int (*SumFunc)(const uchar*, const uchar* mask, uchar*, int, int);
+
+static SumFunc sumTab[] =
 {
-    assert( DataType<T>::type == srcmat.type() &&
-        CV_8U == maskmat.type() && srcmat.size() == maskmat.size() );
-    Size size = getContinuousSize( srcmat, maskmat );
-    ST s0 = 0;
-    WT s = 0;
-    int y, remaining = BLOCK_SIZE, pix = 0;
-
-    for( y = 0; y < size.height; y++ )
-    {
-        const T* src = (const T*)(srcmat.data + srcmat.step*y);
-        const uchar* mask = maskmat.data + maskmat.step*y;
-        int x = 0;
-        while( x < size.width )
-        {
-            int limit = std::min( remaining, size.width - x );
-            remaining -= limit;
-            limit += x;
-            for( ; x < limit; x++ )
-                if( mask[x] )
-                    s += src[x], pix++;
-            if( remaining == 0 || (x == size.width && y == size.height-1) )
-            {
-                s0 += s;
-                s = 0;
-                remaining = BLOCK_SIZE;
-            }
-        }
-    }
-    return rawToScalar(s0)*(1./std::max(pix, 1));
+    (SumFunc)sum8u, (SumFunc)sum8s, (SumFunc)sum16u, (SumFunc)sum16s,
+    (SumFunc)sum32s, (SumFunc)sum32f, (SumFunc)sum64f, 0
+};
+
+        
+template<typename T>
+static int countNonZero_(const T* src, int len )
+{
+    int i, nz = 0;
+    for( i = 0; i <= len - 4; i += 4 )
+        nz += (src[i] != 0) + (src[i+1] != 0) + (src[i+2] != 0) + (src[i+3] != 0);
+    for( ; i < len; i++ )
+        nz += src[i] != 0;
+    return nz;
 }
 
+static int countNonZero8u( const uchar* src, int len )
+{ return countNonZero_(src, len); }
 
-template<typename T, typename ST>
-static Scalar mean_( const Mat& srcmat, const Mat& maskmat )
-{
-    assert( DataType<T>::type == srcmat.type() &&
-        CV_8U == maskmat.type() && srcmat.size() == maskmat.size() );
-    Size size = getContinuousSize( srcmat, maskmat );
-    ST s = 0;
-    int y, pix = 0;
+static int countNonZero16u( const ushort* src, int len )
+{ return countNonZero_(src, len); }
 
-    for( y = 0; y < size.height; y++ )
-    {
-        const T* src = (const T*)(srcmat.data + srcmat.step*y);
-        const uchar* mask = maskmat.data + maskmat.step*y;
-        for( int x = 0; x < size.width; x++ )
-            if( mask[x] )
-                s += src[x], pix++;
-    }
-    return rawToScalar(s)*(1./std::max(pix, 1));
-}
+static int countNonZero32s( const int* src, int len )
+{ return countNonZero_(src, len); }
+
+static int countNonZero32f( const float* src, int len )
+{ return countNonZero_(src, len); }
 
-typedef Scalar (*MeanMaskFunc)(const Mat& src, const Mat& mask);
+static int countNonZero64f( const double* src, int len )
+{ return countNonZero_(src, len); }
 
-Scalar mean(const Mat& m)
+typedef int (*CountNonZeroFunc)(const uchar*, int);
+    
+static CountNonZeroFunc countNonZeroTab[] =
 {
-    return sum(m)*(1./m.total());
-}
+    (CountNonZeroFunc)countNonZero8u, (CountNonZeroFunc)countNonZero8u,
+    (CountNonZeroFunc)countNonZero16u, (CountNonZeroFunc)countNonZero16u,
+    (CountNonZeroFunc)countNonZero32s, (CountNonZeroFunc)countNonZero32f,
+    (CountNonZeroFunc)countNonZero64f, 0
+};
 
-Scalar mean( const Mat& m, const Mat& mask )
+    
+template<typename T, typename ST, typename SQT>
+static int sumsqr_(const T* src0, const uchar* mask, ST* sum, SQT* sqsum, int len, int cn )
 {
-    static MeanMaskFunc tab[]=
-    {
-        meanBlock_<uchar, int, double, 1<<23>, 0,
-        meanBlock_<ushort, int, double, 1<<15>,
-        meanBlock_<short, int, double, 1<<16>,
-        mean_<int, double>,
-        mean_<float, double>,
-        mean_<double, double>, 0,
-
-        meanBlock_<Vec<uchar, 2>, Vec<int, 2>, Vec<double, 2>, 1<<23>, 0,
-        meanBlock_<Vec<ushort, 2>, Vec<int, 2>, Vec<double, 2>, 1<<15>,
-        meanBlock_<Vec<short, 2>, Vec<int, 2>, Vec<double, 2>, 1<<16>,
-        mean_<Vec<int, 2>, Vec<double, 2> >,
-        mean_<Vec<float, 2>, Vec<double, 2> >,
-        mean_<Vec<double, 2>, Vec<double, 2> >, 0,
-
-        meanBlock_<Vec<uchar, 3>, Vec<int, 3>, Vec<double, 3>, 1<<23>, 0,
-        meanBlock_<Vec<ushort, 3>, Vec<int, 3>, Vec<double, 3>, 1<<15>,
-        meanBlock_<Vec<short, 3>, Vec<int, 3>, Vec<double, 3>, 1<<16>,
-        mean_<Vec<int, 3>, Vec<double, 3> >,
-        mean_<Vec<float, 3>, Vec<double, 3> >,
-        mean_<Vec<double, 3>, Vec<double, 3> >, 0,
-
-        meanBlock_<Vec<uchar, 4>, Vec<int, 4>, Vec<double, 4>, 1<<23>, 0,
-        meanBlock_<Vec<ushort, 4>, Vec<int, 4>, Vec<double, 4>, 1<<15>,
-        meanBlock_<Vec<short, 4>, Vec<int, 4>, Vec<double, 4>, 1<<16>,
-        mean_<Vec<int, 4>, Vec<double, 4> >,
-        mean_<Vec<float, 4>, Vec<double, 4> >,
-        mean_<Vec<double, 4>, Vec<double, 4> >, 0
-    };
-    
-    if( !mask.data )
-        return mean(m);
-
-    CV_Assert( m.channels() <= 4 && mask.type() == CV_8U );
-
-    MeanMaskFunc func = tab[m.type()];
-    CV_Assert( func != 0 );
+    const T* src = src0;
     
-    if( m.dims > 2 )
+    if( !mask )
     {
-        const Mat* arrays[] = {&m, &mask, 0};
-        Mat planes[2];
-        NAryMatIterator it(arrays, planes);
-        double total = 0;
-        Scalar s;
-        for( int i = 0; i < it.nplanes; i++, ++it )
+        int i;
+        int k = cn % 4;
+        
+        if( k == 1 )
+        {
+            ST s0 = sum[0];
+            SQT sq0 = sqsum[0];
+            for( i = 0; i < len; i++, src += cn )
+            {
+                T v = src[0];
+                s0 += v; sq0 += (SQT)v*v;
+            }
+            sum[0] = s0;
+            sqsum[0] = sq0;
+        }
+        else if( k == 2 )
+        {
+            ST s0 = sum[0], s1 = sum[1];
+            SQT sq0 = sqsum[0], sq1 = sqsum[1];
+            for( i = 0; i < len; i++, src += cn )
+            {
+                T v0 = src[0], v1 = src[1];
+                s0 += v0; sq0 += (SQT)v0*v0;
+                s1 += v1; sq1 += (SQT)v1*v1;
+            }
+            sum[0] = s0; sum[1] = s1;
+            sqsum[0] = sq0; sqsum[1] = sq1;
+        }
+        else if( k == 3 )
+        {
+            ST s0 = sum[0], s1 = sum[1], s2 = sum[2];
+            SQT sq0 = sqsum[0], sq1 = sqsum[1], sq2 = sqsum[2];
+            for( i = 0; i < len; i++, src += cn )
+            {
+                T v0 = src[0], v1 = src[1], v2 = src[2];
+                s0 += v0; sq0 += (SQT)v0*v0;
+                s1 += v1; sq1 += (SQT)v1*v1;
+                s2 += v2; sq2 += (SQT)v2*v2;
+            }
+            sum[0] = s0; sum[1] = s1; sum[2] = s2;
+            sqsum[0] = sq0; sqsum[1] = sq1; sqsum[2] = sq2;
+        }
+        
+        for( ; k < cn; k += 4 )
         {
-            int n = countNonZero(it.planes[1]);
-            s += mean(it.planes[0], it.planes[1])*(double)n;
-            total += n;
+            src = src0 + k;
+            ST s0 = sum[k], s1 = sum[k+1], s2 = sum[k+2], s3 = sum[k+3];
+            SQT sq0 = sqsum[k], sq1 = sqsum[k+1], sq2 = sqsum[k+2], sq3 = sqsum[k+3];
+            for( i = 0; i < len; i++, src += cn )
+            {
+                T v0, v1;
+                v0 = src[0], v1 = src[1];
+                s0 += v0; sq0 += (SQT)v0*v0;
+                s1 += v1; sq1 += (SQT)v1*v1;
+                v0 = src[2], v1 = src[3];
+                s2 += v0; sq2 += (SQT)v0*v0;
+                s3 += v1; sq3 += (SQT)v1*v1;
+            }
+            sum[k] = s0; sum[k+1] = s1;
+            sum[k+2] = s2; sum[k+3] = s3;
+            sqsum[k] = sq0; sqsum[k+1] = sq1;
+            sqsum[k+2] = sq2; sqsum[k+3] = sq3;
         }
-        return (s * 1./std::max(total, 1.));
+        return len;
     }
     
-    CV_Assert( m.size() == mask.size() );
-    return func( m, mask );
-}
+    int i, nzm = 0;
 
-/****************************************************************************************\
-*                                       meanStdDev                                       *
-\****************************************************************************************/
+    if( cn == 1 )
+    {
+        ST s0 = sum[0];
+        SQT sq0 = sqsum[0];
+        for( i = 0; i < len; i++ )
+            if( mask[i] )
+            {
+                T v = src[i];
+                s0 += v; sq0 += (SQT)v*v;
+                nzm++;
+            }
+        sum[0] = s0;
+        sqsum[0] = sq0;
+    }
+    else if( cn == 3 )
+    {
+        ST s0 = sum[0], s1 = sum[1], s2 = sum[2];
+        SQT sq0 = sqsum[0], sq1 = sqsum[1], sq2 = sqsum[2];
+        for( i = 0; i < len; i++, src += 3 )
+            if( mask[i] )
+            {
+                T v0 = src[0], v1 = src[1], v2 = src[2];
+                s0 += v0; sq0 += (SQT)v0*v0;
+                s1 += v1; sq1 += (SQT)v1*v1;
+                s2 += v2; sq2 += (SQT)v2*v2;
+                nzm++;
+            }
+        sum[0] = s0; sum[1] = s1; sum[2] = s2;
+        sqsum[0] = sq0; sqsum[1] = sq1; sqsum[2] = sq2;
+    }
+    else
+    {
+        for( i = 0; i < len; i++, src += cn )
+            if( mask[i] )
+            {
+                for( int k = 0; k < cn; k++ )
+                {
+                    T v = src[k];
+                    ST s = sum[k] + v;
+                    SQT sq = sqsum[k] + (SQT)v*v;
+                    sum[k] = s; sqsum[k] = sq;
+                }
+                nzm++;
+            }
+    }
+    return nzm;
+}    
 
-template<typename T, typename SqT> struct SqrC1
-{
-    typedef T type1;
-    typedef SqT rtype;
-    rtype operator()(type1 x) const { return (SqT)x*x; }
-};
 
-template<typename T, typename SqT> struct SqrC2
-{
-    typedef Vec<T, 2> type1;
-    typedef Vec<SqT, 2> rtype;
-    rtype operator()(const type1& x) const { return rtype((SqT)x[0]*x[0], (SqT)x[1]*x[1]); }
-};
+static int sqsum8u( const uchar* src, const uchar* mask, int* sum, int* sqsum, int len, int cn )
+{ return sumsqr_(src, mask, sum, sqsum, len, cn); }
 
-template<typename T, typename SqT> struct SqrC3
-{
-    typedef Vec<T, 3> type1;
-    typedef Vec<SqT, 3> rtype;
-    rtype operator()(const type1& x) const
-    { return rtype((SqT)x[0]*x[0], (SqT)x[1]*x[1], (SqT)x[2]*x[2]); }
-};
+static int sqsum8s( const schar* src, const uchar* mask, int* sum, int* sqsum, int len, int cn )
+{ return sumsqr_(src, mask, sum, sqsum, len, cn); }
 
-template<typename T, typename SqT> struct SqrC4
-{
-    typedef Vec<T, 4> type1;
-    typedef Vec<SqT, 4> rtype;
-    rtype operator()(const type1& x) const
-    { return rtype((SqT)x[0]*x[0], (SqT)x[1]*x[1], (SqT)x[2]*x[2], (SqT)x[3]*x[3]); }
-};
+static int sqsum16u( const ushort* src, const uchar* mask, int* sum, double* sqsum, int len, int cn )
+{ return sumsqr_(src, mask, sum, sqsum, len, cn); }
 
-template<> inline double SqrC1<uchar, double>::operator()(uchar x) const
-{ return CV_SQR_8U(x); }
+static int sqsum16s( const short* src, const uchar* mask, int* sum, double* sqsum, int len, int cn )
+{ return sumsqr_(src, mask, sum, sqsum, len, cn); }
 
-template<> inline Vec<double, 2> SqrC2<uchar, double>::operator()(const Vec<uchar, 2>& x) const
-{ return Vec<double, 2>(CV_SQR_8U(x[0]), CV_SQR_8U(x[1])); }
+static int sqsum32s( const int* src, const uchar* mask, double* sum, double* sqsum, int len, int cn )
+{ return sumsqr_(src, mask, sum, sqsum, len, cn); }
 
-template<> inline Vec<double, 3> SqrC3<uchar, double>::operator() (const Vec<uchar, 3>& x) const
-{ return Vec<double, 3>(CV_SQR_8U(x[0]), CV_SQR_8U(x[1]), CV_SQR_8U(x[2])); }
+static int sqsum32f( const float* src, const uchar* mask, double* sum, double* sqsum, int len, int cn )
+{ return sumsqr_(src, mask, sum, sqsum, len, cn); }
 
-template<> inline Vec<double, 4> SqrC4<uchar, double>::operator() (const Vec<uchar, 4>& x) const
-{ return Vec<double, 4>(CV_SQR_8U(x[0]), CV_SQR_8U(x[1]), CV_SQR_8U(x[2]), CV_SQR_8U(x[3])); }
+static int sqsum64f( const double* src, const uchar* mask, double* sum, double* sqsum, int len, int cn )
+{ return sumsqr_(src, mask, sum, sqsum, len, cn); }
 
+typedef int (*SumSqrFunc)(const uchar*, const uchar* mask, uchar*, uchar*, int, int);
 
-template<class SqrOp> static void
-meanStdDev_( const Mat& srcmat, Scalar& _sum, Scalar& _sqsum )
+static SumSqrFunc sumSqrTab[] =
 {
-    SqrOp sqr;
-    typedef typename SqrOp::type1 T;
-    typedef typename SqrOp::rtype ST;
-    typedef typename DataType<ST>::channel_type ST1;
-    
-    assert( DataType<T>::type == srcmat.type() );
-    Size size = getContinuousSize( srcmat );
-    ST s = 0, sq = 0;
+    (SumSqrFunc)sqsum8u, (SumSqrFunc)sqsum8s, (SumSqrFunc)sqsum16u, (SumSqrFunc)sqsum16s,
+    (SumSqrFunc)sqsum32s, (SumSqrFunc)sqsum32f, (SumSqrFunc)sqsum64f, 0
+};
 
-    for( int y = 0; y < size.height; y++ )
+}
+    
+cv::Scalar cv::sum( const InputArray& _src )
+{
+    Mat src = _src.getMat();
+    int k, cn = src.channels(), depth = src.depth();
+    SumFunc func = sumTab[depth];
+    
+    CV_Assert( cn <= 4 && func != 0 );
+    
+    const Mat* arrays[] = {&src, 0};
+    uchar* ptrs[1];
+    NAryMatIterator it(arrays, ptrs);
+    Scalar s;
+    int total = (int)it.size, blockSize = total, intSumBlockSize = 0;
+    int j, count = 0;
+    AutoBuffer<int> _buf;
+    int* buf = (int*)&s[0];
+    size_t esz = 0;
+    bool blockSum = depth < CV_32S;
+    
+    if( blockSum )
     {
-        const T* src = (const T*)(srcmat.data + srcmat.step*y);
-        for( int x = 0; x < size.width; x++ )
+        intSumBlockSize = depth <= CV_8S ? (1 << 23) : (1 << 15);
+        blockSize = std::min(blockSize, intSumBlockSize);
+        _buf.allocate(cn);
+        buf = _buf;
+    
+        for( k = 0; k < cn; k++ )
+            buf[k] = 0;
+        esz = src.elemSize();
+    }
+        
+    for( size_t i = 0; i < it.nplanes; i++, ++it )
+    {
+        for( j = 0; j < total; j += blockSize )
         {
-            T v = src[x];
-            s += v;
-            sq += sqr(v);
+            int bsz = std::min(total - j, blockSize);
+            func( ptrs[0], 0, (uchar*)buf, bsz, cn );
+            count += bsz;
+            if( blockSum && (count + blockSize >= intSumBlockSize || (i+1 >= it.nplanes && j+bsz >= total)) )
+            {
+                for( k = 0; k < cn; k++ )
+                {
+                    s[k] += buf[k];
+                    buf[k] = 0;
+                }
+                count = 0;
+            }
+            ptrs[0] += bsz*esz;
         }
     }
-    _sum = rawToScalar(s);
-    _sqsum = rawToScalar(sq);
+    return s;
 }
 
-template<class SqrOp> static void
-meanStdDevMask_( const Mat& srcmat, const Mat& maskmat,
-                 Scalar& _sum, Scalar& _sqsum, int& _nz )
+int cv::countNonZero( const InputArray& _src )
+{
+    Mat src = _src.getMat();
+    CountNonZeroFunc func = countNonZeroTab[src.depth()];
+    
+    CV_Assert( src.channels() == 1 && func != 0 );
+    
+    const Mat* arrays[] = {&src, 0};
+    uchar* ptrs[1];
+    NAryMatIterator it(arrays, ptrs);
+    int total = (int)it.size, nz = 0;
+    
+    for( size_t i = 0; i < it.nplanes; i++, ++it )
+        nz += func( ptrs[0], total );
+    
+    return nz;
+}    
+    
+cv::Scalar cv::mean( const InputArray& _src, const InputArray& _mask )
 {
-    SqrOp sqr;
-    typedef typename SqrOp::type1 T;
-    typedef typename SqrOp::rtype ST;
-    typedef typename DataType<ST>::channel_type ST1;
-
-    assert( DataType<T>::type == srcmat.type() &&
-            CV_8U == maskmat.type() &&
-            srcmat.size() == maskmat.size() );
-    Size size = getContinuousSize( srcmat, maskmat );
-    ST s = 0, sq = 0;
-    int pix = 0;
-
-    for( int y = 0; y < size.height; y++ )
+    Mat src = _src.getMat(), mask = _mask.getMat();
+    if( !mask.empty() )
+        CV_Assert( mask.type() == CV_8U );
+    
+    int k, cn = src.channels(), depth = src.depth();
+    SumFunc func = sumTab[depth];
+    
+    CV_Assert( cn <= 4 && func != 0 );
+    
+    const Mat* arrays[] = {&src, &mask, 0};
+    uchar* ptrs[2];
+    NAryMatIterator it(arrays, ptrs);
+    Scalar s;
+    int total = (int)it.size, blockSize = total, intSumBlockSize = 0;
+    int j, count = 0;
+    AutoBuffer<int> _buf;
+    int* buf = (int*)&s[0];
+    bool blockSum = depth <= CV_16S;
+    size_t esz = 0, nz0 = 0;
+    
+    if( blockSum )
+    {
+        intSumBlockSize = depth <= CV_8S ? (1 << 23) : (1 << 15);
+        blockSize = std::min(blockSize, intSumBlockSize);
+        _buf.allocate(cn);
+        buf = _buf;
+        
+        for( k = 0; k < cn; k++ )
+            buf[k] = 0;
+        esz = src.elemSize();
+    }
+    
+    for( size_t i = 0; i < it.nplanes; i++, ++it )
     {
-        const T* src = (const T*)(srcmat.data + srcmat.step*y);
-        const uchar* mask = maskmat.data + maskmat.step*y;
-        for( int x = 0; x < size.width; x++ )
-            if( mask[x] )
+        for( j = 0; j < total; j += blockSize )
+        {
+            int bsz = std::min(total - j, blockSize);
+            int nz = func( ptrs[0], ptrs[1], (uchar*)buf, bsz, cn );
+            count += nz;
+            nz0 += nz;
+            if( blockSum && (count + blockSize >= intSumBlockSize || (i+1 >= it.nplanes && j+bsz >= total)) )
             {
-                T v = src[x];
-                s += v;
-                sq += sqr(v);
-                pix++;
+                for( k = 0; k < cn; k++ )
+                {
+                    s[k] += buf[k];
+                    buf[k] = 0;
+                }
+                count = 0;
             }
+            ptrs[0] += bsz*esz;
+            if( ptrs[1] )
+                ptrs[1] += bsz;
+        }
     }
-    _sum = rawToScalar(s);
-    _sqsum = rawToScalar(sq);
-    _nz = pix;
-}
-
-typedef void (*MeanStdDevFunc)(const Mat& src, Scalar& s, Scalar& sq);
-
-typedef void (*MeanStdDevMaskFunc)(const Mat& src, const Mat& mask,
-                                   Scalar& s, Scalar& sq, int& nz);
+    return s*(nz0 ? 1./nz0 : 0);
+}    
 
-void meanStdDev( const Mat& m, Scalar& mean, Scalar& stddev, const Mat& mask )
+    
+void cv::meanStdDev( const InputArray& _src, OutputArray _mean, OutputArray _sdv, const InputArray& _mask )
 {
-    static MeanStdDevFunc tab[]=
-    {
-        meanStdDev_<SqrC1<uchar, double> >, 0,
-        meanStdDev_<SqrC1<ushort, double> >,
-        meanStdDev_<SqrC1<short, double> >,
-        meanStdDev_<SqrC1<int, double> >,
-        meanStdDev_<SqrC1<float, double> >,
-        meanStdDev_<SqrC1<double, double> >, 0,
-
-        meanStdDev_<SqrC2<uchar, double> >, 0,
-        meanStdDev_<SqrC2<ushort, double> >,
-        meanStdDev_<SqrC2<short, double> >,
-        meanStdDev_<SqrC2<int, double> >,
-        meanStdDev_<SqrC2<float, double> >,
-        meanStdDev_<SqrC2<double, double> >, 0,
-
-        meanStdDev_<SqrC3<uchar, double> >, 0,
-        meanStdDev_<SqrC3<ushort, double> >,
-        meanStdDev_<SqrC3<short, double> >,
-        meanStdDev_<SqrC3<int, double> >,
-        meanStdDev_<SqrC3<float, double> >,
-        meanStdDev_<SqrC3<double, double> >, 0,
-
-        meanStdDev_<SqrC4<uchar, double> >, 0,
-        meanStdDev_<SqrC4<ushort, double> >,
-        meanStdDev_<SqrC4<short, double> >,
-        meanStdDev_<SqrC4<int, double> >,
-        meanStdDev_<SqrC4<float, double> >,
-        meanStdDev_<SqrC4<double, double> >, 0
-    };
-
-    static MeanStdDevMaskFunc mtab[]=
+    Mat src = _src.getMat(), mask = _mask.getMat();
+    if( !mask.empty() )
+        CV_Assert( mask.type() == CV_8U );
+    
+    int k, cn = src.channels(), depth = src.depth();
+    SumSqrFunc func = sumSqrTab[depth];
+    
+    CV_Assert( func != 0 );
+    
+    const Mat* arrays[] = {&src, &mask, 0};
+    uchar* ptrs[2];
+    NAryMatIterator it(arrays, ptrs);
+    int total = it.size, blockSize = total, intSumBlockSize = 0;
+    int j, count = 0, nz0 = 0;
+    AutoBuffer<double> _buf(cn*4);
+    double *s = (double*)_buf, *sq = s + cn;
+    int *sbuf = (int*)s, *sqbuf = (int*)sq;
+    bool blockSum = depth <= CV_16S, blockSqSum = depth <= CV_8S;
+    size_t esz = 0;
+    
+    for( k = 0; k < cn; k++ )
+        s[k] = sq[k] = 0;
+    
+    if( blockSum )
     {
-        meanStdDevMask_<SqrC1<uchar, double> >, 0,
-        meanStdDevMask_<SqrC1<ushort, double> >,
-        meanStdDevMask_<SqrC1<short, double> >,
-        meanStdDevMask_<SqrC1<int, double> >,
-        meanStdDevMask_<SqrC1<float, double> >,
-        meanStdDevMask_<SqrC1<double, double> >, 0,
-
-        meanStdDevMask_<SqrC2<uchar, double> >, 0,
-        meanStdDevMask_<SqrC2<ushort, double> >,
-        meanStdDevMask_<SqrC2<short, double> >,
-        meanStdDevMask_<SqrC2<int, double> >,
-        meanStdDevMask_<SqrC2<float, double> >,
-        meanStdDevMask_<SqrC2<double, double> >, 0,
-
-        meanStdDevMask_<SqrC3<uchar, double> >, 0,
-        meanStdDevMask_<SqrC3<ushort, double> >,
-        meanStdDevMask_<SqrC3<short, double> >,
-        meanStdDevMask_<SqrC3<int, double> >,
-        meanStdDevMask_<SqrC3<float, double> >,
-        meanStdDevMask_<SqrC3<double, double> >, 0,
-
-        meanStdDevMask_<SqrC4<uchar, double> >, 0,
-        meanStdDevMask_<SqrC4<ushort, double> >,
-        meanStdDevMask_<SqrC4<short, double> >,
-        meanStdDevMask_<SqrC4<int, double> >,
-        meanStdDevMask_<SqrC4<float, double> >,
-        meanStdDevMask_<SqrC4<double, double> >, 0
-    };
-
-    CV_Assert( m.channels() <= 4 && (mask.empty() || mask.type() == CV_8U) );
-    
-    Scalar sum, sqsum;
-    int total = 0;
-    MeanStdDevFunc func = tab[m.type()];
-    MeanStdDevMaskFunc mfunc = mtab[m.type()];
-    CV_Assert( func != 0 && mfunc != 0 );
-    
-    if( m.dims > 2 )
+        intSumBlockSize = 1 << 15;
+        blockSize = std::min(blockSize, intSumBlockSize);
+        sbuf = (int*)(sq + cn);
+        if( blockSqSum )
+            sqbuf = sbuf + cn;
+        for( k = 0; k < cn; k++ )
+            sbuf[k] = sqbuf[k] = 0;
+        esz = src.elemSize();
+    }
+    
+    for( size_t i = 0; i < it.nplanes; i++, ++it )
     {
-        const Mat* arrays[] = {&m, &mask, 0};
-        Mat planes[2];
-        NAryMatIterator it(arrays, planes);
-        int nz = (int)planes[0].total();
-        
-        for( int i = 0; i < it.nplanes; i++, ++it )
+        for( j = 0; j < total; j += blockSize )
         {
-            Scalar s, sq;
-            
-            if( mask.empty() )
-                func(it.planes[0], s, sq);
-            else
-                mfunc(it.planes[0], it.planes[1], s, sq, nz);
-            
-            total += nz;
-            sum += s;
-            sqsum += sq;
+            int bsz = std::min(total - j, blockSize);
+            int nz = func( ptrs[0], ptrs[1], (uchar*)sbuf, (uchar*)sqbuf, bsz, cn );
+            count += nz;
+            nz0 += nz;
+            if( blockSum && (count + blockSize >= intSumBlockSize || (i+1 >= it.nplanes && j+bsz >= total)) )
+            {
+                for( k = 0; k < cn; k++ )
+                {
+                    s[k] += sbuf[k];
+                    sbuf[k] = 0;
+                }
+                if( blockSqSum )
+                {
+                    for( k = 0; k < cn; k++ )
+                    {
+                        sq[k] += sqbuf[k];
+                        sqbuf[k] = 0;
+                    }
+                }
+                count = 0;
+            }
+            ptrs[0] += bsz*esz;
+            if( ptrs[1] )
+                ptrs[1] += bsz;
         }
     }
-    else
+    
+    double scale = nz0 ? 1./nz0 : 0.;
+    for( int k = 0; k < cn; k++ )
     {
-        if( mask.data )
-        {
-            CV_Assert( mask.size() == m.size() ); 
-            mfunc( m, mask, sum, sqsum, total );
-        }
-        else
-        {
-            func( m, sum, sqsum );
-            total = (int)m.total();
-        }
+        s[k] *= scale;
+        sq[k] = std::sqrt(std::max(sq[k]*scale - s[k]*s[k], 0.));
     }
     
-    double scale = 1./std::max(total, 1);
-    for( int k = 0; k < 4; k++ )
+    for( j = 0; j < 2; j++ )
     {
-        mean[k] = sum[k]*scale;
-        stddev[k] = std::sqrt(std::max(sqsum[k]*scale - mean[k]*mean[k], 0.));
+        const double* sptr = j == 0 ? s : sq;
+        OutputArray& _dst = j == 0 ? _mean : _sdv;
+        if( !_dst.needed() )
+            continue;
+
+        if( !_dst.fixedSize() )
+            _dst.create(cn, 1, CV_64F, -1, true);
+        Mat dst = _dst.getMat();
+        int dcn = (int)dst.total();
+        CV_Assert( dst.type() == CV_64F && dst.isContinuous() &&
+                  (dst.cols == 1 || dst.rows == 1) && dcn >= cn );
+        double* dptr = dst.ptr<double>();
+        for( k = 0; k < cn; k++ )
+            dptr[k] = sptr[k];
+        for( ; k < dcn; k++ )
+            dptr[k] = 0;
     }
 }
 
-
 /****************************************************************************************\
 *                                       minMaxLoc                                        *
 \****************************************************************************************/
 
+namespace cv
+{
+
 template<typename T, typename WT> static void
-minMaxIndx_( const Mat& srcmat, double* _minVal, double* _maxVal,
-             size_t startIdx, size_t* _minIdx, size_t* _maxIdx )
+minMaxIdx_( const T* src, const uchar* mask, WT* _minVal, WT* _maxVal,
+            size_t* _minIdx, size_t* _maxIdx, int len, size_t startIdx )
 {
-    assert( DataType<T>::type == srcmat.type() );
-    const T* src = (const T*)srcmat.data;
-    size_t step = srcmat.step/sizeof(src[0]);
-    WT minVal = saturate_cast<WT>(*_minVal), maxVal = saturate_cast<WT>(*_maxVal);
+    WT minVal = *_minVal, maxVal = *_maxVal;
     size_t minIdx = *_minIdx, maxIdx = *_maxIdx;
-    Size size = getContinuousSize( srcmat );
-
-    for( ; size.height--; src += step, startIdx += size.width )
+    
+    if( !mask )
     {
-        for( int x = 0; x < size.width; x++ )
+        for( int i = 0; i < len; i++ )
         {
-            T val = src[x];
+            T val = src[i];
             if( val < minVal )
             {
                 minVal = val;
-                minIdx = startIdx + x;
+                minIdx = startIdx + i;
             }
             if( val > maxVal )
             {
                 maxVal = val;
-                maxIdx = startIdx + x;
+                maxIdx = startIdx + i;
             }
         }
     }
-
-    *_minIdx = minIdx;
-    *_maxIdx = maxIdx;
-    *_minVal = minVal;
-    *_maxVal = maxVal;
-}
-
-
-template<typename T, typename WT> static void
-minMaxIndxMask_( const Mat& srcmat, const Mat& maskmat,
-                 double* _minVal, double* _maxVal,
-                 size_t startIdx, size_t* _minIdx, size_t* _maxIdx )
-{
-    assert( DataType<T>::type == srcmat.type() &&
-        CV_8U == maskmat.type() &&
-        srcmat.size() == maskmat.size() );
-    const T* src = (const T*)srcmat.data;
-    const uchar* mask = maskmat.data;
-    size_t step = srcmat.step/sizeof(src[0]);
-    size_t maskstep = maskmat.step;
-    WT minVal = saturate_cast<WT>(*_minVal), maxVal = saturate_cast<WT>(*_maxVal);
-    size_t minIdx = *_minIdx, maxIdx = *_maxIdx;
-    Size size = getContinuousSize( srcmat, maskmat );
-
-    for( ; size.height--; src += step, mask += maskstep, startIdx += size.width )
+    else
     {
-        for( int x = 0; x < size.width; x++ )
+        for( int i = 0; i < len; i++ )
         {
-            T val = src[x];
-            int m = mask[x];
-            
-            if( val < minVal && m )
+            T val = src[i];
+            if( mask[i] && val < minVal )
             {
                 minVal = val;
-                minIdx = startIdx + x;
+                minIdx = startIdx + i;
             }
-            if( val > maxVal && m )
+            if( mask[i] && val > maxVal )
             {
                 maxVal = val;
-                maxIdx = startIdx + x;
+                maxIdx = startIdx + i;
             }
         }
     }
@@ -671,79 +674,43 @@ minMaxIndxMask_( const Mat& srcmat, const Mat& maskmat,
     *_maxVal = maxVal;
 }
 
-typedef void (*MinMaxIndxFunc)(const Mat&, double*, double*, size_t, size_t*, size_t*);
+static void minMaxIdx_8u(const uchar* src, const uchar* mask, int* minval, int* maxval,
+                         size_t* minidx, size_t* maxidx, int len, size_t startidx )
+{ minMaxIdx_(src, mask, minval, maxval, minidx, maxidx, len, startidx ); }
 
-typedef void (*MinMaxIndxMaskFunc)(const Mat&, const Mat&, double*, double*,
-                                   size_t, size_t*, size_t*);
+static void minMaxIdx_8s(const schar* src, const uchar* mask, int* minval, int* maxval,
+                         size_t* minidx, size_t* maxidx, int len, size_t startidx )
+{ minMaxIdx_(src, mask, minval, maxval, minidx, maxidx, len, startidx ); }
 
-void minMaxLoc( const Mat& img, double* minVal, double* maxVal,
-                Point* minLoc, Point* maxLoc, const Mat& mask )
-{
-    CV_Assert(img.dims <= 2);
-    
-    static MinMaxIndxFunc tab[] =
-    {
-        minMaxIndx_<uchar, int>, 0, minMaxIndx_<ushort, int>, minMaxIndx_<short, int>,
-        minMaxIndx_<int, int>, minMaxIndx_<float, float>, minMaxIndx_<double, double>, 0
-    };
-    static MinMaxIndxMaskFunc tabm[] =
-    {
-        minMaxIndxMask_<uchar, int>, 0, minMaxIndxMask_<ushort, int>, minMaxIndxMask_<short, int>,
-        minMaxIndxMask_<int, int>, minMaxIndxMask_<float, float>, minMaxIndxMask_<double, double>, 0
-    };
+static void minMaxIdx_16u(const ushort* src, const uchar* mask, int* minval, int* maxval,
+                          size_t* minidx, size_t* maxidx, int len, size_t startidx )
+{ minMaxIdx_(src, mask, minval, maxval, minidx, maxidx, len, startidx ); }
 
-    int depth = img.depth();
-    double minval = depth < CV_32F ? INT_MAX : depth == CV_32F ? FLT_MAX : DBL_MAX;
-    double maxval = depth < CV_32F ? INT_MIN : depth == CV_32F ? -FLT_MAX : -DBL_MAX;
-    size_t minidx = 0, maxidx = 0, startidx = 1;
+static void minMaxIdx_16s(const short* src, const uchar* mask, int* minval, int* maxval,
+                          size_t* minidx, size_t* maxidx, int len, size_t startidx )
+{ minMaxIdx_(src, mask, minval, maxval, minidx, maxidx, len, startidx ); }
 
-    CV_Assert( img.channels() == 1 );
+static void minMaxIdx_32s(const int* src, const uchar* mask, int* minval, int* maxval,
+                          size_t* minidx, size_t* maxidx, int len, size_t startidx )
+{ minMaxIdx_(src, mask, minval, maxval, minidx, maxidx, len, startidx ); }
 
-    if( !mask.data )
-    {
-        MinMaxIndxFunc func = tab[depth];
-        CV_Assert( func != 0 );
-        func( img, &minval, &maxval, startidx, &minidx, &maxidx );
-    }
-    else
-    {
-        CV_Assert( img.size() == mask.size() && mask.type() == CV_8U );
-        MinMaxIndxMaskFunc func = tabm[depth];
-        CV_Assert( func != 0 );
-        func( img, mask, &minval, &maxval, startidx, &minidx, &maxidx );
-    }
+static void minMaxIdx_32f(const float* src, const uchar* mask, float* minval, float* maxval,
+                          size_t* minidx, size_t* maxidx, int len, size_t startidx )
+{ minMaxIdx_(src, mask, minval, maxval, minidx, maxidx, len, startidx ); }
 
-    if( minidx == 0 )
-        minVal = maxVal = 0;
+static void minMaxIdx_64f(const double* src, const uchar* mask, double* minval, double* maxval,
+                          size_t* minidx, size_t* maxidx, int len, size_t startidx )
+{ minMaxIdx_(src, mask, minval, maxval, minidx, maxidx, len, startidx ); }    
     
-    if( minVal )
-        *minVal = minval;
-    if( maxVal )
-        *maxVal = maxval;
-    if( minLoc )
-    {
-        if( minidx > 0 )
-        {
-            minidx--;
-            minLoc->y = minidx/img.cols;
-            minLoc->x = minidx - minLoc->y*img.cols;
-        }
-        else
-            minLoc->x = minLoc->y = -1;
-    }
-    if( maxLoc )
-    {
-        if( maxidx > 0 )
-        {
-            maxidx--;
-            maxLoc->y = maxidx/img.cols;
-            maxLoc->x = maxidx - maxLoc->y*img.cols;
-        }
-        else
-            maxLoc->x = maxLoc->y = -1;
-    }
-}
+typedef void (*MinMaxIdxFunc)(const uchar*, const uchar*, int*, int*, size_t*, size_t*, int, size_t);
 
+static MinMaxIdxFunc minmaxTab[] =
+{
+    (MinMaxIdxFunc)minMaxIdx_8u, (MinMaxIdxFunc)minMaxIdx_8s, (MinMaxIdxFunc)minMaxIdx_16u,
+    (MinMaxIdxFunc)minMaxIdx_16s, (MinMaxIdxFunc)minMaxIdx_32s, (MinMaxIdxFunc)minMaxIdx_32f, 
+    (MinMaxIdxFunc)minMaxIdx_64f, 0
+};
+    
 static void ofs2idx(const Mat& a, size_t ofs, int* idx)
 {
     int i, d = a.dims;
@@ -763,712 +730,482 @@ static void ofs2idx(const Mat& a, size_t ofs, int* idx)
             idx[i] = -1;
     }
 }
+    
+}
 
-void minMaxIdx(const Mat& a, double* minVal,
-                double* maxVal, int* minIdx, int* maxIdx,
-                const Mat& mask)
+void cv::minMaxIdx(const InputArray& _src, double* minVal,
+                   double* maxVal, int* minIdx, int* maxIdx,
+                   const InputArray& _mask)
 {
-    if( a.dims <= 2 )
-    {
-        Point minLoc, maxLoc;
-        minMaxLoc(a, minVal, maxVal, &minLoc, &maxLoc, mask);
-        if( minIdx )
-            minIdx[0] = minLoc.y, minIdx[1] = minLoc.x;
-        if( maxIdx )
-            maxIdx[0] = maxLoc.y, maxIdx[1] = maxLoc.x;
-        return;
-    }
-
-    static MinMaxIndxFunc tab[] =
-    {
-        minMaxIndx_<uchar, int>, 0, minMaxIndx_<ushort, int>, minMaxIndx_<short, int>,
-        minMaxIndx_<int, int>, minMaxIndx_<float, float>, minMaxIndx_<double, double>, 0
-    };
-    static MinMaxIndxMaskFunc tabm[] =
-    {
-        minMaxIndxMask_<uchar, int>, 0, minMaxIndxMask_<ushort, int>, minMaxIndxMask_<short, int>,
-        minMaxIndxMask_<int, int>, minMaxIndxMask_<float, float>, minMaxIndxMask_<double, double>, 0
-    };
+    Mat src = _src.getMat(), mask = _mask.getMat();
+    int depth = src.depth();
+    
+    CV_Assert( src.channels() == 1 && (mask.empty() || mask.type() == CV_8U) );
+    MinMaxIdxFunc func = minmaxTab[depth];
+    CV_Assert( func != 0 );
     
-    const Mat* arrays[] = {&a, &mask, 0};
-    Mat planes[2];
-    NAryMatIterator it(arrays, planes);
+    const Mat* arrays[] = {&src, &mask, 0};
+    uchar* ptrs[2];
+    NAryMatIterator it(arrays, ptrs);
     
-    int depth = a.depth();
-    double minval = depth < CV_32F ? INT_MAX : depth == CV_32F ? FLT_MAX : DBL_MAX;
-    double maxval = depth < CV_32F ? INT_MIN : depth == CV_32F ? -FLT_MAX : -DBL_MAX;
     size_t minidx = 0, maxidx = 0;
-    size_t startidx = 1, planeSize = planes[0].total();
-    MinMaxIndxFunc func = 0;
-    MinMaxIndxMaskFunc mfunc = 0;
+    int iminval = INT_MAX, imaxval = INT_MIN;
+    float fminval = FLT_MAX, fmaxval = -FLT_MAX;
+    double dminval = DBL_MAX, dmaxval = -DBL_MAX;
+    size_t startidx = 1;
+    int *minval = &iminval, *maxval = &imaxval;
+    int planeSize = (int)it.size;
     
-    if( mask.empty() )
-        func = tab[depth];
-    else
-        mfunc = tabm[depth];
-    CV_Assert( func != 0 || mfunc != 0 );
+    if( depth == CV_32F )
+        minval = (int*)&fminval, maxval = (int*)&fmaxval;
+    else if( depth == CV_64F )
+        minval = (int*)&dminval, maxval = (int*)&dmaxval;
     
-    for( int i = 0; i < it.nplanes; i++, ++it, startidx += planeSize )
-    {
-        if( func )
-            func( planes[0], &minval, &maxval, startidx, &minidx, &maxidx );
-        else
-            mfunc( planes[0], planes[1], &minval, &maxval, startidx, &minidx, &maxidx );
-    }
+    for( size_t i = 0; i < it.nplanes; i++, ++it, startidx += planeSize )
+        func( ptrs[0], ptrs[1], minval, maxval, &minidx, &maxidx, planeSize, startidx );
     
     if( minidx == 0 )
-        minVal = maxVal = 0;
+        dminval = dmaxval = 0;
+    else if( depth == CV_32F )
+        dminval = fminval, dmaxval = fmaxval;
+    else if( depth <= CV_32S )
+        dminval = iminval, dmaxval = imaxval;
     
     if( minVal )
-        *minVal = minval;
+        *minVal = dminval;
     if( maxVal )
-        *maxVal = maxval;
+        *maxVal = dmaxval;
+    
     if( minIdx )
-        ofs2idx(a, minidx, minIdx);
+        ofs2idx(src, minidx, minIdx);
     if( maxIdx )
-        ofs2idx(a, maxidx, maxIdx);
+        ofs2idx(src, maxidx, maxIdx);
 }    
+        
+void cv::minMaxLoc( const InputArray& _img, double* minVal, double* maxVal,
+                Point* minLoc, Point* maxLoc, const InputArray& mask )
+{
+    Mat img = _img.getMat();
+    CV_Assert(img.dims <= 2);
+    
+    minMaxIdx(_img, minVal, maxVal, (int*)minLoc, (int*)maxLoc, mask);
+    if( minLoc )
+        std::swap(minLoc->x, minLoc->y);
+    if( maxLoc )
+        std::swap(maxLoc->x, maxLoc->y);
+}
     
 /****************************************************************************************\
 *                                         norm                                           *
 \****************************************************************************************/
 
-template<typename T, typename WT=T> struct OpAbs
+namespace cv
 {
-    typedef T type1;
-    typedef WT rtype;
-    rtype operator()(type1 x) const { return (WT)std::abs(x); }
-};
-
-template<> inline uchar OpAbs<uchar, uchar>::operator()(uchar x) const { return x; }
-template<> inline ushort OpAbs<ushort, ushort>::operator()(ushort x) const { return x; }
 
-template<class ElemFunc, class UpdateFunc, class GlobUpdateFunc, int BLOCK_SIZE>
-static double normBlock_( const Mat& srcmat )
+template<typename T, typename ST> int
+normInf_(const T* src, const uchar* mask, ST* _result, int len, int cn)
 {
-    ElemFunc f;
-    UpdateFunc update;
-    GlobUpdateFunc globUpdate;
-    typedef typename ElemFunc::type1 T;
-    typedef typename UpdateFunc::rtype WT;
-    typedef typename GlobUpdateFunc::rtype ST;
-    
-    assert( DataType<T>::depth == srcmat.depth() );
-    Size size = getContinuousSize( srcmat, srcmat.channels() );
-    ST s0 = 0; // luckily, 0 is the correct starting value for both + and max update operations
-    WT s = 0;
-    int y, remaining = BLOCK_SIZE;
-
-    for( y = 0; y < size.height; y++ )
+    ST result = *_result;
+    if( !mask )
     {
-        const T* src = (const T*)(srcmat.data + srcmat.step*y);
-        int x = 0;
-        while( x < size.width )
-        {
-            int limit = std::min( remaining, size.width - x );
-            remaining -= limit;
-            limit += x;
-            for( ; x <= limit - 4; x += 4 )
+        len *= cn;
+        for( int i = 0; i < len; i++ )
+            result = std::max(result, std::abs(src[i]));
+    }
+    else
+    {
+        for( int i = 0; i < len; i++, src += cn )
+            if( mask[i] )
             {
-                s = update(s, (WT)f(src[x]));
-                s = update(s, (WT)f(src[x+1]));
-                s = update(s, (WT)f(src[x+2]));
-                s = update(s, (WT)f(src[x+3]));
+                for( int k = 0; k < cn; k++ )
+                    result = std::max(result, std::abs(src[k]));
             }
-            for( ; x < limit; x++ )
-                s = update(s, (WT)f(src[x]));
-            if( remaining == 0 || (x == size.width && y == size.height-1) )
+    }
+    *_result = result;
+    return 0;
+}
+    
+template<typename T, typename ST> int
+normL1_(const T* src, const uchar* mask, ST* _result, int len, int cn)
+{
+    ST result = *_result;
+    if( !mask )
+    {
+        len *= cn;
+        for( int i = 0; i < len; i++ )
+            result += std::abs(src[i]);
+    }
+    else
+    {
+        for( int i = 0; i < len; i++, src += cn )
+            if( mask[i] )
             {
-                s0 = globUpdate(s0, (ST)s);
-                s = 0;
-                remaining = BLOCK_SIZE;
+                for( int k = 0; k < cn; k++ )
+                    result += std::abs(src[k]);
             }
-        }
     }
-    return s0;
+    *_result = result;
+    return 0;
 }
 
-template<class ElemFunc, class UpdateFunc>
-static double norm_( const Mat& srcmat )
+template<typename T, typename ST> int
+normL2_(const T* src, const uchar* mask, ST* _result, int len, int cn)
 {
-    ElemFunc f;
-    UpdateFunc update;
-    typedef typename ElemFunc::type1 T;
-    typedef typename UpdateFunc::rtype ST;
-    
-    assert( DataType<T>::depth == srcmat.depth() );
-    Size size = getContinuousSize( srcmat, srcmat.channels() );
-    ST s = 0;
-
-    for( int y = 0; y < size.height; y++ )
+    ST result = *_result;
+    if( !mask )
     {
-        const T* src = (const T*)(srcmat.data + srcmat.step*y);
-        int x = 0;
-        for( ; x <= size.width - 4; x += 4 )
+        len *= cn;
+        for( int i = 0; i < len; i++ )
         {
-            s = update(s, (ST)f(src[x]));
-            s = update(s, (ST)f(src[x+1]));
-            s = update(s, (ST)f(src[x+2]));
-            s = update(s, (ST)f(src[x+3]));
+            T v = src[i];
+            result += (ST)v*v;
         }
-        for( ; x < size.width; x++ )
-            s = update(s, (ST)f(src[x]));
     }
-    return s;
-}
-
-template<class ElemFunc, class UpdateFunc, class GlobUpdateFunc, int BLOCK_SIZE>
-static double normMaskBlock_( const Mat& srcmat, const Mat& maskmat )
-{
-    ElemFunc f;
-    UpdateFunc update;
-    GlobUpdateFunc globUpdate;
-    typedef typename ElemFunc::type1 T;
-    typedef typename UpdateFunc::rtype WT;
-    typedef typename GlobUpdateFunc::rtype ST;
-    
-    assert( DataType<T>::depth == srcmat.depth() );
-    Size size = getContinuousSize( srcmat, maskmat );
-    ST s0 = 0;
-    WT s = 0;
-    int y, remaining = BLOCK_SIZE;
-    int cn = srcmat.channels();
-
-    for( y = 0; y < size.height; y++ )
+    else
     {
-        const T* src = (const T*)(srcmat.data + srcmat.step*y);
-        const uchar* mask = maskmat.data + maskmat.step*y;
-        int x = 0;
-        while( x < size.width )
-        {
-            int limit = std::min( remaining, size.width - x );
-            remaining -= limit;
-            limit += x;
-            int x0 = x;
-            for( int c = 0; c < cn; c++ )
+        for( int i = 0; i < len; i++, src += cn )
+            if( mask[i] )
             {
-                for( x = x0; x <= limit - 4; x += 4 )
-                {
-                    if( mask[x] )
-                        s = update(s, (WT)f(src[x*cn + c]));
-                    if( mask[x+1] )
-                        s = update(s, (WT)f(src[(x+1)*cn + c]));
-                    if( mask[x+2] )
-                        s = update(s, (WT)f(src[(x+2)*cn + c]));
-                    if( mask[x+3] )
-                        s = update(s, (WT)f(src[(x+3)*cn + c]));
-                }
-                for( ; x < limit; x++ )
+                for( int k = 0; k < cn; k++ )
                 {
-                    if( mask[x] )
-                        s = update(s, (WT)f(src[x*cn + c]));
+                    T v = src[k];
+                    result += (ST)v*v;
                 }
             }
-            if( remaining == 0 || (x == size.width && y == size.height-1) )
-            {
-                s0 = globUpdate(s0, (ST)s);
-                s = 0;
-                remaining = BLOCK_SIZE;
-            }
-        }
     }
-    return s0;
-}
-
-template<class ElemFunc, class UpdateFunc>
-static double normMask_( const Mat& srcmat, const Mat& maskmat )
-{
-    ElemFunc f;
-    UpdateFunc update;
-    typedef typename ElemFunc::type1 T;
-    typedef typename UpdateFunc::rtype ST;
-    
-    assert( DataType<T>::depth == srcmat.depth() );
-    Size size = getContinuousSize( srcmat, maskmat );
-    ST s = 0;
-    int cn = srcmat.channels();
+    *_result = result;
+    return 0;
+}    
     
-    for( int y = 0; y < size.height; y++ )
+template<typename T, typename ST> int
+normDiffInf_(const T* src1, const T* src2, const uchar* mask, ST* _result, int len, int cn)
+{
+    ST result = *_result;
+    if( !mask )
     {
-        const T* src = (const T*)(srcmat.data + srcmat.step*y);
-        const uchar* mask = maskmat.data + maskmat.step*y;
-        for( int c = 0; c < cn; c++ )
-        {
-            int x = 0;
-            for( ; x <= size.width - 4; x += 4 )
-            {
-                if( mask[x] )
-                    s = update(s, (ST)f(src[x*cn + c]));
-                if( mask[x+1] )
-                    s = update(s, (ST)f(src[(x+1)*cn + c]));
-                if( mask[x+2] )
-                    s = update(s, (ST)f(src[(x+2)*cn + c]));
-                if( mask[x+3] )
-                    s = update(s, (ST)f(src[(x+3)*cn + c]));
-            }
-            for( ; x < size.width; x++ )
+        len *= cn;
+        for( int i = 0; i < len; i++ )
+            result = std::max(result, std::abs(src1[i] - src2[i]));
+    }
+    else
+    {
+        for( int i = 0; i < len; i++, src1 += cn, src2 += cn )
+            if( mask[i] )
             {
-                if( mask[x] )
-                    s = update(s, (ST)f(src[x*cn + c]));
+                for( int k = 0; k < cn; k++ )
+                    result = std::max(result, std::abs(src1[k] - src2[k]));
             }
-        }
     }
-    return s;
+    *_result = result;
+    return 0;
 }
 
-template<typename T, class ElemFunc, class UpdateFunc, class GlobUpdateFunc, int BLOCK_SIZE>
-static double normDiffBlock_( const Mat& srcmat1, const Mat& srcmat2 )
+template<typename T, typename ST> int
+normDiffL1_(const T* src1, const T* src2, const uchar* mask, ST* _result, int len, int cn)
 {
-    ElemFunc f;
-    UpdateFunc update;
-    GlobUpdateFunc globUpdate;
-    typedef typename UpdateFunc::rtype WT;
-    typedef typename GlobUpdateFunc::rtype ST;
-    
-    assert( DataType<T>::depth == srcmat1.depth() );
-    Size size = getContinuousSize( srcmat1, srcmat2, srcmat1.channels() );
-    ST s0 = 0;
-    WT s = 0;
-    int y, remaining = BLOCK_SIZE;
-
-    for( y = 0; y < size.height; y++ )
+    ST result = *_result;
+    if( !mask )
     {
-        const T* src1 = (const T*)(srcmat1.data + srcmat1.step*y);
-        const T* src2 = (const T*)(srcmat2.data + srcmat2.step*y);
-        int x = 0;
-        while( x < size.width )
-        {
-            int limit = std::min( remaining, size.width - x );
-            remaining -= limit;
-            limit += x;
-            for( ; x <= limit - 4; x += 4 )
-            {
-                s = update(s, (WT)f(src1[x] - src2[x]));
-                s = update(s, (WT)f(src1[x+1] - src2[x+1]));
-                s = update(s, (WT)f(src1[x+2] - src2[x+2]));
-                s = update(s, (WT)f(src1[x+3] - src2[x+3]));
-            }
-            for( ; x < limit; x++ )
-                s = update(s, (WT)f(src1[x] - src2[x]));
-            if( remaining == 0 || (x == size.width && y == size.height-1) )
+        len *= cn;
+        for( int i = 0; i < len; i++ )
+            result += std::abs(src1[i] - src2[i]);
+    }
+    else
+    {
+        for( int i = 0; i < len; i++, src1 += cn, src2 += cn )
+            if( mask[i] )
             {
-                s0 = globUpdate(s0, (ST)s);
-                s = 0;
-                remaining = BLOCK_SIZE;
+                for( int k = 0; k < cn; k++ )
+                    result += std::abs(src1[k] - src2[k]);
             }
-        }
     }
-    return s0;
+    *_result = result;
+    return 0;
 }
 
-template<typename T, class ElemFunc, class UpdateFunc>
-static double normDiff_( const Mat& srcmat1, const Mat& srcmat2 )
+template<typename T, typename ST> int
+normDiffL2_(const T* src1, const T* src2, const uchar* mask, ST* _result, int len, int cn)
 {
-    ElemFunc f;
-    UpdateFunc update;
-    typedef typename UpdateFunc::rtype ST;
-    
-    assert( DataType<T>::depth == srcmat1.depth() );
-    Size size = getContinuousSize( srcmat1, srcmat2, srcmat1.channels() );
-    ST s = 0;
-
-    for( int y = 0; y < size.height; y++ )
+    ST result = *_result;
+    if( !mask )
     {
-        const T* src1 = (const T*)(srcmat1.data + srcmat1.step*y);
-        const T* src2 = (const T*)(srcmat2.data + srcmat2.step*y);
-        int x = 0;
-        for( ; x <= size.width - 4; x += 4 )
+        len *= cn;
+        for( int i = 0; i < len; i++ )
         {
-            s = update(s, (ST)f(src1[x] - src2[x]));
-            s = update(s, (ST)f(src1[x+1] - src2[x+1]));
-            s = update(s, (ST)f(src1[x+2] - src2[x+2]));
-            s = update(s, (ST)f(src1[x+3] - src2[x+3]));
+            ST v = src1[i] - src2[i];
+            result += v*v;
         }
-        for( ; x < size.width; x++ )
-            s = update(s, (ST)f(src1[x] - src2[x]));
     }
-    return s;
-}
-
-template<typename T, class ElemFunc, class UpdateFunc, class GlobUpdateFunc, int BLOCK_SIZE>
-static double normDiffMaskBlock_( const Mat& srcmat1, const Mat& srcmat2, const Mat& maskmat )
-{
-    ElemFunc f;
-    UpdateFunc update;
-    GlobUpdateFunc globUpdate;
-    typedef typename UpdateFunc::rtype WT;
-    typedef typename GlobUpdateFunc::rtype ST;
-    
-    assert( DataType<T>::depth == srcmat1.depth() );
-    Size size = getContinuousSize( srcmat1, srcmat2, maskmat );
-    ST s0 = 0;
-    WT s = 0;
-    int y, remaining = BLOCK_SIZE;
-    int cn = srcmat1.channels();
-
-    for( y = 0; y < size.height; y++ )
+    else
     {
-        const T* src1 = (const T*)(srcmat1.data + srcmat1.step*y);
-        const T* src2 = (const T*)(srcmat2.data + srcmat2.step*y);
-        const uchar* mask = maskmat.data + maskmat.step*y;
-        int x = 0;
-        while( x < size.width )
-        {
-            int limit = std::min( remaining, size.width - x );
-            remaining -= limit;
-            limit += x;
-            int x0 = x;
-            for( int c = 0; c < cn; c++ )
+        for( int i = 0; i < len; i++, src1 += cn, src2 += cn )
+            if( mask[i] )
             {
-                for( x = x0; x <= limit - 4; x += 4 )
+                for( int k = 0; k < cn; k++ )
                 {
-                    if( mask[x] )
-                        s = update(s, (WT)f(src1[x*cn + c] - src2[x*cn + c]));
-                    if( mask[x+1] )
-                        s = update(s, (WT)f(src1[(x+1)*cn + c] - src2[(x+1)*cn + c]));
-                    if( mask[x+2] )
-                        s = update(s, (WT)f(src1[(x+2)*cn + c] - src2[(x+2)*cn + c]));
-                    if( mask[x+3] )
-                        s = update(s, (WT)f(src1[(x+3)*cn + c] - src2[(x+3)*cn + c]));
+                    ST v = src1[k] - src2[k];
+                    result += v*v;
                 }
-                for( ; x < limit; x++ )
-                    if( mask[x] )
-                        s = update(s, (WT)f(src1[x*cn + c] - src2[x*cn + c]));
             }
-            if( remaining == 0 || (x == size.width && y == size.height-1) )
-            {
-                s0 = globUpdate(s0, (ST)s);
-                s = 0;
-                remaining = BLOCK_SIZE;
-            }
-        }
     }
-    return s0;
-}
+    *_result = result;
+    return 0;
+}    
 
-template<typename T, class ElemFunc, class UpdateFunc>
-static double normDiffMask_( const Mat& srcmat1, const Mat& srcmat2, const Mat& maskmat )
-{
-    ElemFunc f;
-    UpdateFunc update;
-    typedef typename UpdateFunc::rtype ST;
+
+#define CV_DEF_NORM_FUNC(L, suffix, type, ntype) \
+static int norm##L##_##suffix(const type* src, const uchar* mask, ntype* r, size_t len, int cn) \
+{ return norm##L##_(src, mask, r, len, cn); } \
+static int normDiff##L##_##suffix(const type* src1, const type* src2, \
+                               const uchar* mask, ntype* r, size_t len, int cn) \
+{ return normDiff##L##_(src1, src2, mask, r, len, cn); }
     
-    assert( DataType<T>::depth == srcmat1.depth() );
-    Size size = getContinuousSize( srcmat1, srcmat2, maskmat );
-    ST s = 0;
-    int cn = srcmat1.channels();
+#define CV_DEF_NORM_ALL(suffix, type, inftype, l1type, l2type) \
+CV_DEF_NORM_FUNC(Inf, suffix, type, inftype) \
+CV_DEF_NORM_FUNC(L1, suffix, type, l1type) \
+CV_DEF_NORM_FUNC(L2, suffix, type, l2type)
+
+CV_DEF_NORM_ALL(8u, uchar, int, int, int)
+CV_DEF_NORM_ALL(8s, schar, int, int, int)
+CV_DEF_NORM_ALL(16u, ushort, int, int, double)
+CV_DEF_NORM_ALL(16s, short, int, int, double)
+CV_DEF_NORM_ALL(32s, int, int, double, double)
+CV_DEF_NORM_ALL(32f, float, float, double, double)
+CV_DEF_NORM_ALL(64f, double, double, double, double)
 
-    for( int y = 0; y < size.height; y++ )
+    
+typedef int (*NormFunc)(const uchar*, const uchar*, uchar*, int, int);
+typedef int (*NormDiffFunc)(const uchar*, const uchar*, const uchar*, uchar*, int, int);    
+
+static NormFunc normTab[3][8] =
+{
     {
-        const T* src1 = (const T*)(srcmat1.data + srcmat1.step*y);
-        const T* src2 = (const T*)(srcmat2.data + srcmat2.step*y);
-        const uchar* mask = maskmat.data + maskmat.step*y;
-        for( int c = 0; c < cn; c++ )
-        {
-            int x = 0;
-            for( ; x <= size.width - 4; x += 4 )
-            {
-                if( mask[x] )
-                    s = update(s, (ST)f(src1[x*cn + c] - src2[x*cn + c]));
-                if( mask[x+1] )
-                    s = update(s, (ST)f(src1[(x+1)*cn + c] - src2[(x+1)*cn + c]));
-                if( mask[x+2] )
-                    s = update(s, (ST)f(src1[(x+2)*cn + c] - src2[(x+2)*cn + c]));
-                if( mask[x+3] )
-                    s = update(s, (ST)f(src1[(x+3)*cn + c] - src2[(x+3)*cn + c]));
-            }
-            for( ; x < size.width; x++ )
-                if( mask[x] )
-                    s = update(s, (ST)f(src1[x*cn + c] - src2[x*cn + c]));
-        }
+        (NormFunc)normInf_8u, (NormFunc)normInf_8s, (NormFunc)normInf_16u, (NormFunc)normInf_16s,
+        (NormFunc)normInf_32s, (NormFunc)normInf_32f, (NormFunc)normInf_64f, 0
+    },
+    {
+        (NormFunc)normL1_8u, (NormFunc)normL1_8s, (NormFunc)normL1_16u, (NormFunc)normL1_16s,
+        (NormFunc)normL1_32s, (NormFunc)normL1_32f, (NormFunc)normL1_64f, 0
+    },
+    {
+        (NormFunc)normL2_8u, (NormFunc)normL2_8s, (NormFunc)normL2_16u, (NormFunc)normL2_16s,
+        (NormFunc)normL2_32s, (NormFunc)normL2_32f, (NormFunc)normL2_64f, 0
     }
-    return s;
-}
-
-typedef double (*NormFunc)(const Mat& src);
-typedef double (*NormDiffFunc)(const Mat& src1, const Mat& src2);
-typedef double (*NormMaskFunc)(const Mat& src1, const Mat& mask);
-typedef double (*NormDiffMaskFunc)(const Mat& src1, const Mat& src2, const Mat& mask);
+};
 
-double norm( const Mat& a, int normType )
+static NormDiffFunc normDiffTab[3][8] =
 {
-    static NormFunc tab[3][8] =
     {
-        {
-            norm_<OpAbs<uchar>, OpMax<int> >,
-            norm_<OpAbs<schar>, OpMax<int> >,
-            norm_<OpAbs<ushort>, OpMax<int> >,
-            norm_<OpAbs<short, int>, OpMax<int> >,
-            norm_<OpAbs<int>, OpMax<int> >,
-            norm_<OpAbs<float>, OpMax<float> >,
-            norm_<OpAbs<double>, OpMax<double> >
-        },
-        
-        { 
-            normBlock_<OpAbs<uchar>, OpAdd<unsigned>, OpAdd<double>, 1<<24>,
-            normBlock_<OpAbs<schar>, OpAdd<unsigned>, OpAdd<double>, 1<<24>,
-            normBlock_<OpAbs<ushort>, OpAdd<unsigned>, OpAdd<double>, 1<<16>,
-            normBlock_<OpAbs<short, int>, OpAdd<unsigned>, OpAdd<double>, 1<<16>,
-            norm_<OpAbs<int>, OpAdd<double> >,
-            norm_<OpAbs<float>, OpAdd<double> >,
-            norm_<OpAbs<double>, OpAdd<double> >
-        },
-
-        { 
-            normBlock_<SqrC1<uchar, unsigned>, OpAdd<unsigned>, OpAdd<double>, 1<<16>,
-            normBlock_<SqrC1<schar, unsigned>, OpAdd<unsigned>, OpAdd<double>, 1<<16>,
-            norm_<SqrC1<ushort, double>, OpAdd<double> >,
-            norm_<SqrC1<short, double>, OpAdd<double> >,
-            norm_<SqrC1<int, double>, OpAdd<double> >,
-            norm_<SqrC1<float, double>, OpAdd<double> >,
-            norm_<SqrC1<double, double>, OpAdd<double> >
-        }
-    };
+        (NormDiffFunc)normDiffInf_8u, (NormDiffFunc)normDiffInf_8s,
+        (NormDiffFunc)normDiffInf_16u, (NormDiffFunc)normDiffInf_16s,
+        (NormDiffFunc)normDiffInf_32s, (NormDiffFunc)normDiffInf_32f,
+        (NormDiffFunc)normDiffInf_64f, 0
+    },
+    {
+        (NormDiffFunc)normDiffL1_8u, (NormDiffFunc)normDiffL1_8s,
+        (NormDiffFunc)normDiffL1_16u, (NormDiffFunc)normDiffL1_16s,
+        (NormDiffFunc)normDiffL1_32s, (NormDiffFunc)normDiffL1_32f,
+        (NormDiffFunc)normDiffL1_64f, 0
+    },
+    {
+        (NormDiffFunc)normDiffL2_8u, (NormDiffFunc)normDiffL2_8s,
+        (NormDiffFunc)normDiffL2_16u, (NormDiffFunc)normDiffL2_16s,
+        (NormDiffFunc)normDiffL2_32s, (NormDiffFunc)normDiffL2_32f,
+        (NormDiffFunc)normDiffL2_64f, 0
+    }
+};
 
+}
+    
+double cv::norm( const InputArray& _src, int normType, const InputArray& _mask )
+{
+    Mat src = _src.getMat(), mask = _mask.getMat();
+    int depth = src.depth(), cn = src.channels();
+    
     normType &= 7;
-    CV_Assert(normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2);
-    NormFunc func = tab[normType >> 1][a.depth()];
-    CV_Assert(func != 0);
+    CV_Assert( normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2 );
     
-    double r = 0;
-    if( a.dims > 2 )
+    if( depth == CV_32F && src.isContinuous() && mask.empty() )
     {
-        const Mat* arrays[] = {&a, 0};
-        Mat planes[1];
-        NAryMatIterator it(arrays, planes);
-    
-        for( int i = 0; i < it.nplanes; i++, ++it )
+        size_t len = src.total()*cn;
+        if( len == (size_t)(int)len )
         {
-            double n = func(it.planes[0]);
-            if( normType == NORM_INF )
-                r = std::max(r, n);
-            else
-                r += n;
+            const float* data = src.ptr<float>();
+            
+            if( normType == NORM_L2 )
+            {
+                double result = 0;
+                normL2_32f(data, 0, &result, (int)len, 1);
+                return std::sqrt(result);
+            }
+            if( normType == NORM_L1 )
+            {
+                double result = 0;
+                normL1_32f(data, 0, &result, (int)len, 1);
+                return result;
+            }
+            {
+                float result = 0;
+                normInf_32f(data, 0, &result, (int)len, 1);
+                return result;
+            }
         }
     }
-    else
-        r = func(a);
     
-    return normType == NORM_L2 ? std::sqrt(r) : r;
-}
-
-
-double norm( const Mat& a, int normType, const Mat& mask )
-{
-    static NormMaskFunc tab[3][8] =
+    CV_Assert( mask.empty() || mask.type() == CV_8U );
+    
+    NormFunc func = normTab[normType >> 1][depth];
+    CV_Assert( func != 0 );
+    
+    const Mat* arrays[] = {&src, &mask, 0};
+    uchar* ptrs[2];
+    double result = 0;
+    NAryMatIterator it(arrays, ptrs);
+    int j, total = (int)it.size, blockSize = total, intSumBlockSize = 0, count = 0;
+    bool blockSum = (normType == NORM_L1 && depth <= CV_16S) ||
+                    (normType == NORM_L2 && depth <= CV_8S);
+    int isum = 0;
+    int *ibuf = (int*)&result;
+    size_t esz = 0;
+    
+    if( blockSum )
     {
-        {
-            normMask_<OpAbs<uchar>, OpMax<int> >,
-            normMask_<OpAbs<schar>, OpMax<int> >,
-            normMask_<OpAbs<ushort>, OpMax<int> >,
-            normMask_<OpAbs<short, int>, OpMax<int> >,
-            normMask_<OpAbs<int>, OpMax<int> >,
-            normMask_<OpAbs<float>, OpMax<float> >,
-            normMask_<OpAbs<double>, OpMax<double> >
-        },
-        
-        { 
-            normMaskBlock_<OpAbs<uchar>, OpAdd<unsigned>, OpAdd<double>, 1<<24>,
-            normMaskBlock_<OpAbs<schar>, OpAdd<unsigned>, OpAdd<double>, 1<<24>,
-            normMaskBlock_<OpAbs<ushort>, OpAdd<unsigned>, OpAdd<double>, 1<<16>,
-            normMaskBlock_<OpAbs<short, int>, OpAdd<unsigned>, OpAdd<double>, 1<<16>,
-            normMask_<OpAbs<int>, OpAdd<double> >,
-            normMask_<OpAbs<float>, OpAdd<double> >,
-            normMask_<OpAbs<double>, OpAdd<double> >
-        },
-
-        { 
-            normMaskBlock_<SqrC1<uchar, unsigned>, OpAdd<unsigned>, OpAdd<double>, 1<<16>,
-            normMaskBlock_<SqrC1<schar, unsigned>, OpAdd<unsigned>, OpAdd<double>, 1<<16>,
-            normMask_<SqrC1<ushort, double>, OpAdd<double> >,
-            normMask_<SqrC1<short, double>, OpAdd<double> >,
-            normMask_<SqrC1<int, double>, OpAdd<double> >,
-            normMask_<SqrC1<float, double>, OpAdd<double> >,
-            normMask_<SqrC1<double, double>, OpAdd<double> >
-        }
-    };
-
-    if( !mask.data )
-        return norm(a, normType);
-
-    normType &= 7;
-    CV_Assert((normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2) && mask.type() == CV_8U);
-    NormMaskFunc func = tab[normType >> 1][a.depth()];
-    CV_Assert(func != 0);
+        intSumBlockSize = (normType == NORM_L1 && depth <= CV_8S ? (1 << 23) : (1 << 15))/cn;
+        blockSize = std::min(blockSize, intSumBlockSize);
+        ibuf = &isum;
+        esz = src.elemSize();
+    }
     
-    double r = 0;
-    if( a.dims > 2 )
+    for( size_t i = 0; i < it.nplanes; i++, ++it )
     {
-        const Mat* arrays[] = {&a, &mask, 0};
-        Mat planes[2];
-        NAryMatIterator it(arrays, planes);
-        
-        for( int i = 0; i < it.nplanes; i++, ++it )
+        for( j = 0; j < total; j += blockSize )
         {
-            double n = func(it.planes[0], it.planes[1]);
-            if( normType == NORM_INF )
-                r = std::max(r, n);
-            else
-                r += n;
+            int bsz = std::min(total - j, blockSize);
+            func( ptrs[0], ptrs[1], (uchar*)ibuf, bsz, cn );
+            count += bsz;
+            if( blockSum && (count + blockSize >= intSumBlockSize || (i+1 >= it.nplanes && j+bsz >= total)) )
+            {
+                result += isum;
+                isum = 0;
+                count = 0;
+            }
+            ptrs[0] += bsz*esz;
+            if( ptrs[1] )
+                ptrs[1] += bsz;
         }
     }
-    else
+    
+    if( normType == NORM_INF )
     {
-        CV_Assert( a.size() == mask.size() );
-        r = func(a, mask);
+        if( depth == CV_64F )
+            ;
+        else if( depth == CV_32F )
+            result = (float&)result;
+        else
+            result = (int&)result;
     }
+    else if( normType == NORM_L2 )
+        result = std::sqrt(result);
     
-    return normType == NORM_L2 ? std::sqrt(r) : r;
+    return result;
 }
 
-
-double norm( const Mat& a, const Mat& b, int normType )
+    
+double cv::norm( const InputArray& _src1, const InputArray& _src2, int normType, const InputArray& _mask )
 {
-    static NormDiffFunc tab[3][8] =
-    {
-        {
-            normDiff_<uchar, OpAbs<int>, OpMax<int> >,
-            normDiff_<schar, OpAbs<int>, OpMax<int> >,
-            normDiff_<ushort, OpAbs<int>, OpMax<int> >,
-            normDiff_<short, OpAbs<int>, OpMax<int> >,
-            normDiff_<int, OpAbs<int>, OpMax<int> >,
-            normDiff_<float, OpAbs<float>, OpMax<float> >,
-            normDiff_<double, OpAbs<double>, OpMax<double> >
-        },
-        
-        { 
-            normDiffBlock_<uchar, OpAbs<int>, OpAdd<unsigned>, OpAdd<double>, 1<<24>,
-            normDiffBlock_<schar, OpAbs<int>, OpAdd<unsigned>, OpAdd<double>, 1<<24>,
-            normDiffBlock_<ushort, OpAbs<int>, OpAdd<unsigned>, OpAdd<double>, 1<<16>,
-            normDiffBlock_<short, OpAbs<int>, OpAdd<unsigned>, OpAdd<double>, 1<<16>,
-            normDiff_<int, OpAbs<int>, OpAdd<double> >,
-            normDiff_<float, OpAbs<float>, OpAdd<double> >,
-            normDiff_<double, OpAbs<double>, OpAdd<double> >
-        },
-
-        { 
-            normDiffBlock_<uchar, SqrC1<int, int>, OpAdd<unsigned>, OpAdd<double>, 1<<16>,
-            normDiffBlock_<schar, SqrC1<int, int>, OpAdd<unsigned>, OpAdd<double>, 1<<16>,
-            normDiff_<ushort, SqrC1<int, double>, OpAdd<double> >,
-            normDiff_<short, SqrC1<int, double>, OpAdd<double> >,
-            normDiff_<int, SqrC1<int, double>, OpAdd<double> >,
-            normDiff_<float, SqrC1<float, double>, OpAdd<double> >,
-            normDiff_<double, SqrC1<double, double>, OpAdd<double> >
-        }
-    };
+    Mat src1 = _src1.getMat(), src2 = _src2.getMat(), mask = _mask.getMat();
+    int depth = src1.depth(), cn = src1.channels();
+    
+    CV_Assert( src1.size == src2.size && src1.type() == src2.type() );
     
-    CV_Assert( a.type() == b.type() );
-    bool isRelative = (normType & NORM_RELATIVE) != 0;
     normType &= 7;
-    CV_Assert(normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2);
-    NormDiffFunc func = tab[normType >> 1][a.depth()];
-    CV_Assert(func != 0);
+    CV_Assert( normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2 );
     
-    double r = 0.;
-    if( a.dims > 2 )
+    if( src1.depth() == CV_32F && src1.isContinuous() && src2.isContinuous() && mask.empty() )
     {
-        const Mat* arrays[] = {&a, &b, 0};
-        Mat planes[2];
-        NAryMatIterator it(arrays, planes);
-        
-        for( int i = 0; i < it.nplanes; i++, ++it )
+        size_t len = src1.total()*src1.channels();
+        if( len == (size_t)(int)len )
         {
-            double n = func(it.planes[0], it.planes[1]);
-                
-            if( normType == NORM_INF )
-                r = std::max(r, n);
-            else
-                r += n;
+            const float* data1 = src1.ptr<float>();
+            const float* data2 = src2.ptr<float>();
+            
+            if( normType == NORM_L2 )
+            {
+                double result = 0;
+                normDiffL2_32f(data1, data2, 0, &result, (int)len, 1);
+                return std::sqrt(result);
+            }
+            if( normType == NORM_L1 )
+            {
+                double result = 0;
+                normDiffL1_32f(data1, data2, 0, &result, (int)len, 1);
+                return result;
+            }
+            {
+                float result = 0;
+                normDiffInf_32f(data1, data2, 0, &result, (int)len, 1);
+                return result;
+            }
         }
     }
-    else
+    
+    CV_Assert( mask.empty() || mask.type() == CV_8U );
+    
+    NormDiffFunc func = normDiffTab[normType >> 1][depth];
+    CV_Assert( func != 0 );
+    
+    const Mat* arrays[] = {&src1, &src2, &mask, 0};
+    uchar* ptrs[3];
+    double result = 0;
+    NAryMatIterator it(arrays, ptrs);
+    int j, total = (int)it.size, blockSize = total, intSumBlockSize = 0, count = 0;
+    bool blockSum = (normType == NORM_L1 && depth <= CV_16S) ||
+    (normType == NORM_L2 && depth <= CV_8S);
+    int isum = 0;
+    int *ibuf = (int*)&result;
+    size_t esz = 0;
+    
+    if( blockSum )
     {
-        CV_Assert( a.size() == b.size() );
-        r = func( a, b );
+        intSumBlockSize = normType == NORM_L1 && depth <= CV_8S ? (1 << 23) : (1 << 15);
+        blockSize = std::min(blockSize, intSumBlockSize);
+        ibuf = &isum;
+        esz = src1.elemSize();
     }
-    if( normType == NORM_L2 )
-        r = std::sqrt(r);
-    if( isRelative )
-        r /= norm(b, normType);
-    return r;
-}
-
-double norm( const Mat& a, const Mat& b, int normType, const Mat& mask )
-{
-    static NormDiffMaskFunc tab[3][8] =
-    {
-        {
-            normDiffMask_<uchar, OpAbs<int>, OpMax<int> >,
-            normDiffMask_<schar, OpAbs<int>, OpMax<int> >,
-            normDiffMask_<ushort, OpAbs<int>, OpMax<int> >,
-            normDiffMask_<short, OpAbs<int>, OpMax<int> >,
-            normDiffMask_<int, OpAbs<int>, OpMax<int> >,
-            normDiffMask_<float, OpAbs<float>, OpMax<float> >,
-            normDiffMask_<double, OpAbs<double>, OpMax<double> >
-        },
-        
-        { 
-            normDiffMaskBlock_<uchar, OpAbs<int>, OpAdd<unsigned>, OpAdd<double>, 1<<24>,
-            normDiffMaskBlock_<schar, OpAbs<int>, OpAdd<unsigned>, OpAdd<double>, 1<<24>,
-            normDiffMaskBlock_<ushort, OpAbs<int>, OpAdd<unsigned>, OpAdd<double>, 1<<16>,
-            normDiffMaskBlock_<short, OpAbs<int>, OpAdd<unsigned>, OpAdd<double>, 1<<16>,
-            normDiffMask_<int, OpAbs<int>, OpAdd<double> >,
-            normDiffMask_<float, OpAbs<float>, OpAdd<double> >,
-            normDiffMask_<double, OpAbs<double>, OpAdd<double> >
-        },
-
-        { 
-            normDiffMaskBlock_<uchar, SqrC1<int, int>, OpAdd<unsigned>, OpAdd<double>, 1<<16>,
-            normDiffMaskBlock_<schar, SqrC1<int, int>, OpAdd<unsigned>, OpAdd<double>, 1<<16>,
-            normDiffMask_<ushort, SqrC1<int, double>, OpAdd<double> >,
-            normDiffMask_<short, SqrC1<int, double>, OpAdd<double> >,
-            normDiffMask_<int, SqrC1<int, double>, OpAdd<double> >,
-            normDiffMask_<float, SqrC1<float, double>, OpAdd<double> >,
-            normDiffMask_<double, SqrC1<double, double>, OpAdd<double> >
-        }
-    };
     
-    if( !mask.data )
-        return norm(a, b, normType);
-
-    CV_Assert( a.type() == b.type() && mask.type() == CV_8U);
-    bool isRelative = (normType & NORM_RELATIVE) != 0;
-    normType &= 7;
-    CV_Assert(normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2);
-
-    NormDiffMaskFunc func = tab[normType >> 1][a.depth()];
-    CV_Assert(func != 0);
-    
-    double r = 0.;
-    if( a.dims > 2 )
+    for( size_t i = 0; i < it.nplanes; i++, ++it )
     {
-        const Mat* arrays[] = {&a, &b, &mask, 0};
-        Mat planes[3];
-        NAryMatIterator it(arrays, planes);
-        
-        for( int i = 0; i < it.nplanes; i++, ++it )
+        for( j = 0; j < total; j += blockSize )
         {
-            double n = func(it.planes[0], it.planes[1], it.planes[2]);
-            
-            if( normType == NORM_INF )
-                r = std::max(r, n);
-            else
-                r += n;
+            int bsz = std::min(total - j, blockSize);
+            func( ptrs[0], ptrs[1], ptrs[2], (uchar*)ibuf, bsz, cn );
+            count += bsz;
+            if( blockSum && (count + blockSize >= intSumBlockSize || (i+1 >= it.nplanes && j+bsz >= total)) )
+            {
+                result += isum;
+                isum = 0;
+                count = 0;
+            }
+            ptrs[0] += bsz*esz;
+            ptrs[1] += bsz*esz;
+            if( ptrs[2] )
+                ptrs[2] += bsz;
         }
     }
-    else
+    
+    if( normType == NORM_INF )
     {
-        CV_Assert( a.size() == b.size() && a.size() == mask.size() );
-        r = func( a, b, mask );
+        if( depth == CV_64F )
+            ;
+        else if( depth == CV_32F )
+            result = (float&)result;
+        else
+            result = (int&)result;
     }
+    else if( normType == NORM_L2 )
+        result = std::sqrt(result);
     
-    if( normType == NORM_L2 )
-        r = std::sqrt(r);
-    if( isRelative )
-        r /= std::max(norm(b, normType, mask), DBL_EPSILON);
-    return r;
-}
-
+    return result;
 }
 
 
index 1d1ef19..24c5148 100644 (file)
@@ -170,12 +170,14 @@ struct IPPInitializer
 IPPInitializer ippInitializer;
 #else
 volatile bool useOptimizedFlag = false;
+volatile bool USE_SSE2 = false;
 #endif
 
 void setUseOptimized( bool flag )
 {
     useOptimizedFlag = flag;
     currentFeatures = flag ? &featuresEnabled : &featuresDisabled;
+    USE_SSE2 = currentFeatures->have[CV_CPU_SSE2];
 }
 
 bool useOptimized(void)
index 258b4bd..aa638cf 100644 (file)
@@ -35,7 +35,7 @@ struct BaseElemWiseOp
     
     virtual int getRandomType(RNG& rng)
     {
-        return cvtest::randomType(rng, cvtest::TYPE_MASK_ALL_BUT_8S, 1,
+        return cvtest::randomType(rng, DEPTH_MASK_ALL_BUT_8S, 1,
                                   ninputs > 1 ? ARITHM_MAX_CHANNELS : 4);
     }
         
@@ -172,6 +172,10 @@ struct ScaleAddOp : public BaseAddOp
     {
         scaleAdd(src[0], alpha, src[1], dst);
     }
+    double getMaxErr(int depth)
+    {
+        return depth <= CV_32S ? 2 : depth < CV_64F ? 1e-4 : 1e-12;
+    }
 };
 
 
@@ -414,7 +418,7 @@ struct CmpOp : public BaseElemWiseOp
     }
     int getRandomType(RNG& rng)
     {
-        return cvtest::randomType(rng, cvtest::TYPE_MASK_ALL_BUT_8S, 1, 1);
+        return cvtest::randomType(rng, DEPTH_MASK_ALL_BUT_8S, 1, 1);
     }
         
     double getMaxErr(int)
@@ -431,6 +435,8 @@ struct CmpSOp : public BaseElemWiseOp
     {
         BaseElemWiseOp::generateScalars(depth, rng);
         cmpop = rng.uniform(0, 6);
+        if( depth < CV_32F )
+            gamma[0] = cvRound(gamma[0]);
     }
     void op(const vector<Mat>& src, Mat& dst, const Mat&)
     {
@@ -442,7 +448,7 @@ struct CmpSOp : public BaseElemWiseOp
     }
     int getRandomType(RNG& rng)
     {
-        return cvtest::randomType(rng, cvtest::TYPE_MASK_ALL_BUT_8S, 1, 1);
+        return cvtest::randomType(rng, DEPTH_MASK_ALL_BUT_8S, 1, 1);
     }
     double getMaxErr(int)
     {
@@ -465,7 +471,7 @@ struct CopyOp : public BaseElemWiseOp
     }
     int getRandomType(RNG& rng)
     {
-        return cvtest::randomType(rng, cvtest::TYPE_MASK_ALL, 1, ARITHM_MAX_CHANNELS);
+        return cvtest::randomType(rng, DEPTH_MASK_ALL, 1, ARITHM_MAX_CHANNELS);
     }
     double getMaxErr(int)
     {
@@ -488,7 +494,7 @@ struct SetOp : public BaseElemWiseOp
     }
     int getRandomType(RNG& rng)
     {
-        return cvtest::randomType(rng, cvtest::TYPE_MASK_ALL, 1, ARITHM_MAX_CHANNELS);
+        return cvtest::randomType(rng, DEPTH_MASK_ALL, 1, ARITHM_MAX_CHANNELS);
     }
     double getMaxErr(int)
     {
@@ -504,14 +510,14 @@ inRangeS_(const _Tp* src, const _WTp* a, const _WTp* b, uchar* dst, size_t total
     for( i = 0; i < total; i++ )
     {
         _Tp val = src[i*cn];
-        dst[i] = a[0] <= val && val < b[0] ? 255 : 0;
+        dst[i] = a[0] <= val && val <= b[0] ? 255 : 0;
     }
     for( c = 1; c < cn; c++ )
     {
         for( i = 0; i < total; i++ )
         {
             _Tp val = src[i*cn + c];
-            dst[i] = a[c] <= val && val < b[c] ? dst[i] : 0;
+            dst[i] = a[c] <= val && val <= b[c] ? dst[i] : 0;
         }
     }
 }
@@ -523,14 +529,14 @@ template<typename _Tp> static void inRange_(const _Tp* src, const _Tp* a, const
     for( i = 0; i < total; i++ )
     {
         _Tp val = src[i*cn];
-        dst[i] = a[i*cn] <= val && val < b[i*cn] ? 255 : 0;
+        dst[i] = a[i*cn] <= val && val <= b[i*cn] ? 255 : 0;
     }
     for( c = 1; c < cn; c++ )
     {
         for( i = 0; i < total; i++ )
         {
             _Tp val = src[i*cn + c];
-            dst[i] = a[i*cn + c] <= val && val < b[i*cn + c] ? dst[i] : 0;
+            dst[i] = a[i*cn + c] <= val && val <= b[i*cn + c] ? dst[i] : 0;
         }
     }
 }
@@ -703,13 +709,13 @@ struct ConvertScaleOp : public BaseElemWiseOp
     }
     int getRandomType(RNG& rng)
     {
-        int srctype = cvtest::randomType(rng, cvtest::TYPE_MASK_ALL, 1, ARITHM_MAX_CHANNELS);
-        ddepth = cvtest::randomType(rng, cvtest::TYPE_MASK_ALL, 1, 1);
+        int srctype = cvtest::randomType(rng, DEPTH_MASK_ALL, 1, ARITHM_MAX_CHANNELS);
+        ddepth = cvtest::randomType(rng, DEPTH_MASK_ALL, 1, 1);
         return srctype;
     }
     double getMaxErr(int)
     {
-        return ddepth <= CV_32S ? 2 : ddepth < CV_64F ? 1e-4 : 1e-12;
+        return ddepth <= CV_32S ? 2 : ddepth < CV_64F ? 1e-3 : 1e-12;
     }
     void generateScalars(int depth, RNG& rng)
     {
@@ -940,7 +946,7 @@ struct ExpOp : public BaseElemWiseOp
     ExpOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {};
     int getRandomType(RNG& rng)
     {
-        return cvtest::randomType(rng, cvtest::TYPE_MASK_FLT, 1, ARITHM_MAX_CHANNELS);
+        return cvtest::randomType(rng, DEPTH_MASK_FLT, 1, ARITHM_MAX_CHANNELS);
     }
     void getValueRange(int depth, double& minval, double& maxval)
     {
@@ -967,7 +973,7 @@ struct LogOp : public BaseElemWiseOp
     LogOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)) {};
     int getRandomType(RNG& rng)
     {
-        return cvtest::randomType(rng, cvtest::TYPE_MASK_FLT, 1, ARITHM_MAX_CHANNELS);
+        return cvtest::randomType(rng, DEPTH_MASK_FLT, 1, ARITHM_MAX_CHANNELS);
     }
     void getValueRange(int depth, double& minval, double& maxval)
     {
@@ -1052,7 +1058,7 @@ struct CartToPolarToCartOp : public BaseElemWiseOp
     }
     int getRandomType(RNG& rng)
     {
-        return cvtest::randomType(rng, cvtest::TYPE_MASK_FLT, 1, 1);
+        return cvtest::randomType(rng, DEPTH_MASK_FLT, 1, 1);
     }
     void op(const vector<Mat>& src, Mat& dst, const Mat&)
     {
@@ -1128,7 +1134,7 @@ struct SumOp : public BaseElemWiseOp
     }
     double getMaxErr(int)
     {
-        return 1e-6;
+        return 1e-5;
     }
 };    
 
@@ -1139,7 +1145,7 @@ struct CountNonZeroOp : public BaseElemWiseOp
     {}
     int getRandomType(RNG& rng)
     {
-        return cvtest::randomType(rng, cvtest::TYPE_MASK_ALL, 1, 1);
+        return cvtest::randomType(rng, DEPTH_MASK_ALL, 1, 1);
     }
     void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
     {
@@ -1208,7 +1214,7 @@ struct NormOp : public BaseElemWiseOp
     };
     int getRandomType(RNG& rng)
     {
-        return cvtest::randomType(rng, cvtest::TYPE_MASK_ALL_BUT_8S, 1, 4);
+        return cvtest::randomType(rng, DEPTH_MASK_ALL_BUT_8S, 1, 4);
     }
     void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
     {
@@ -1242,7 +1248,7 @@ struct MinMaxLocOp : public BaseElemWiseOp
     };
     int getRandomType(RNG& rng)
     {
-        return cvtest::randomType(rng, cvtest::TYPE_MASK_ALL_BUT_8S, 1, 1);
+        return cvtest::randomType(rng, DEPTH_MASK_ALL_BUT_8S, 1, 1);
     }
     void saveOutput(const vector<int>& minidx, const vector<int>& maxidx,
                     double minval, double maxval, Mat& dst)
@@ -1341,6 +1347,8 @@ INSTANTIATE_TEST_CASE_P(Core_SubRS, ElemWiseTest, ::testing::Values(ElemWiseOpPt
 INSTANTIATE_TEST_CASE_P(Core_ScaleAdd, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::ScaleAddOp)));
 INSTANTIATE_TEST_CASE_P(Core_AddWeighted, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::AddWeightedOp)));
 INSTANTIATE_TEST_CASE_P(Core_AbsDiff, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::AbsDiffOp)));
+
+
 INSTANTIATE_TEST_CASE_P(Core_AbsDiffS, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::AbsDiffSOp)));
 
 INSTANTIATE_TEST_CASE_P(Core_And, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::LogicOp('&'))));
@@ -1380,3 +1388,6 @@ INSTANTIATE_TEST_CASE_P(Core_Sum, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(
 INSTANTIATE_TEST_CASE_P(Core_Norm, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::NormOp)));
 INSTANTIATE_TEST_CASE_P(Core_MinMaxLoc, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::MinMaxLocOp)));
 INSTANTIATE_TEST_CASE_P(Core_CartToPolarToCart, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::CartToPolarToCartOp)));
+
+
+
index b6f7078..be6826e 100644 (file)
@@ -827,3 +827,4 @@ TEST(Core_DCT, accuracy) { CxCore_DCTTest test; test.safe_run(); }
 TEST(Core_DFT, accuracy) { CxCore_DFTTest test; test.safe_run(); }
 TEST(Core_MulSpectrums, accuracy) { CxCore_MulSpectrumsTest test; test.safe_run(); }
 
+
index ae5f442..1970876 100644 (file)
@@ -277,8 +277,6 @@ public:
 protected:
     void run(int)
     {
-        int code = cvtest::TS::OK;
-        
         double diffPrjEps, diffBackPrjEps,
         prjEps, backPrjEps,
         evalEps, evecEps;
@@ -327,26 +325,44 @@ protected:
             if( err > eigenEps )
             {
                 ts->printf( cvtest::TS::LOG, "bad accuracy of eigen(); err = %f\n", err );
-                code = cvtest::TS::FAIL_BAD_ACCURACY;
-                goto exit_func;
+                ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
+                return;
             }
         }
         // check pca eigenvalues
-        evalEps = 1e-6, evecEps = 1;
+        evalEps = 1e-6, evecEps = 1e-3;
         err = norm( rPCA.eigenvalues, subEval );
         if( err > evalEps )
         {
             ts->printf( cvtest::TS::LOG, "pca.eigenvalues is incorrect (CV_PCA_DATA_AS_ROW); err = %f\n", err );
-            code = cvtest::TS::FAIL_BAD_ACCURACY;
-            goto exit_func;
+            ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
+            return;
         }
         // check pca eigenvectors
-        err = norm( rPCA.eigenvectors, subEvec, CV_RELATIVE_L2 );
-        if( err > evecEps )
+        for(int i = 0; i < subEvec.rows; i++)
         {
-            ts->printf( cvtest::TS::LOG, "pca.eigenvectors is incorrect (CV_PCA_DATA_AS_ROW); err = %f\n", err );
-            code = cvtest::TS::FAIL_BAD_ACCURACY;
-            goto exit_func;
+            Mat r0 = rPCA.eigenvectors.row(i);
+            Mat r1 = subEvec.row(i);
+            err = norm( r0, r1, CV_L2 );
+            if( err > evecEps )
+            {
+                r1 *= -1;
+                double err2 = norm(r0, r1, CV_L2);
+                if( err2 > evecEps )
+                {
+                    Mat tmp;
+                    absdiff(rPCA.eigenvectors, subEvec, tmp);
+                    double mval = 0; Point mloc;
+                    minMaxLoc(tmp, 0, &mval, 0, &mloc);
+                    
+                    ts->printf( cvtest::TS::LOG, "pca.eigenvectors is incorrect (CV_PCA_DATA_AS_ROW); err = %f\n", err );
+                    ts->printf( cvtest::TS::LOG, "max diff is %g at (i=%d, j=%d) (%g vs %g)\n",
+                               mval, mloc.y, mloc.x, rPCA.eigenvectors.at<float>(mloc.y, mloc.x),
+                               subEvec.at<float>(mloc.y, mloc.x));
+                    ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
+                    return;
+                }
+            }
         }
         
         prjEps = 1.265, backPrjEps = 1.265;
@@ -359,8 +375,8 @@ protected:
             if( err > prjEps )
             {
                 ts->printf( cvtest::TS::LOG, "bad accuracy of project() (CV_PCA_DATA_AS_ROW); err = %f\n", err );
-                code = cvtest::TS::FAIL_BAD_ACCURACY;
-                goto exit_func;
+                ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
+                return;
             }
             // check pca backProject
             Mat backPrj = rPrjTestPoints.row(i) * subEvec + avg;
@@ -368,27 +384,28 @@ protected:
             if( err > backPrjEps )
             {
                 ts->printf( cvtest::TS::LOG, "bad accuracy of backProject() (CV_PCA_DATA_AS_ROW); err = %f\n", err );
-                code = cvtest::TS::FAIL_BAD_ACCURACY;
-                goto exit_func;
+                ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
+                return;
             }
         }
         
         // 2. check C++ PCA & COL
         cPCA( rPoints.t(), Mat(), CV_PCA_DATA_AS_COL, maxComponents );
         diffPrjEps = 1, diffBackPrjEps = 1;
-        err = norm(cPCA.project(rTestPoints.t()), rPrjTestPoints.t(), CV_RELATIVE_L2 );
+        Mat ocvPrjTestPoints = cPCA.project(rTestPoints.t());
+        err = norm(cv::abs(ocvPrjTestPoints), cv::abs(rPrjTestPoints.t()), CV_RELATIVE_L2 );
         if( err > diffPrjEps )
         {
             ts->printf( cvtest::TS::LOG, "bad accuracy of project() (CV_PCA_DATA_AS_COL); err = %f\n", err );
-            code = cvtest::TS::FAIL_BAD_ACCURACY;
-            goto exit_func;
+            ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
+            return;
         }
-        err = norm(cPCA.backProject(rPrjTestPoints.t()), rBackPrjTestPoints.t(), CV_RELATIVE_L2 );
+        err = norm(cPCA.backProject(ocvPrjTestPoints), rBackPrjTestPoints.t(), CV_RELATIVE_L2 );
         if( err > diffBackPrjEps )
         {
             ts->printf( cvtest::TS::LOG, "bad accuracy of backProject() (CV_PCA_DATA_AS_COL); err = %f\n", err );
-            code = cvtest::TS::FAIL_BAD_ACCURACY;
-            goto exit_func;
+            ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
+            return;
         }
         
     #ifdef CHECK_C
@@ -411,15 +428,15 @@ protected:
         if( err > diffPrjEps )
         {
             ts->printf( cvtest::TS::LOG, "bad accuracy of cvProjectPCA() (CV_PCA_DATA_AS_ROW); err = %f\n", err );
-            code = cvtest::TS::FAIL_BAD_ACCURACY;
-            goto exit_func;
+            ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
+            return;
         }
         err = norm(backPrjTestPoints, rBackPrjTestPoints, CV_RELATIVE_L2);
         if( err > diffBackPrjEps )
         {
             ts->printf( cvtest::TS::LOG, "bad accuracy of cvBackProjectPCA() (CV_PCA_DATA_AS_ROW); err = %f\n", err );
-            code = cvtest::TS::FAIL_BAD_ACCURACY;
-            goto exit_func;
+            ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
+            return;
         }
         
         // 3. check C PCA & COL
@@ -435,27 +452,21 @@ protected:
         cvProjectPCA( &_testPoints, &_avg, &_evec, &_prjTestPoints );
         cvBackProjectPCA( &_prjTestPoints, &_avg, &_evec, &_backPrjTestPoints );
         
-        err = norm(prjTestPoints, rPrjTestPoints.t(), CV_RELATIVE_L2 );
+        err = norm(cv::abs(prjTestPoints), cv::abs(rPrjTestPoints.t()), CV_RELATIVE_L2 );
         if( err > diffPrjEps )
         {
             ts->printf( cvtest::TS::LOG, "bad accuracy of cvProjectPCA() (CV_PCA_DATA_AS_COL); err = %f\n", err );
-            code = cvtest::TS::FAIL_BAD_ACCURACY;
-            goto exit_func;
+            ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
+            return;
         }
         err = norm(backPrjTestPoints, rBackPrjTestPoints.t(), CV_RELATIVE_L2);
         if( err > diffBackPrjEps )
         {
             ts->printf( cvtest::TS::LOG, "bad accuracy of cvBackProjectPCA() (CV_PCA_DATA_AS_COL); err = %f\n", err );
-            code = cvtest::TS::FAIL_BAD_ACCURACY;
-            goto exit_func;
+            ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
+            return;
         }
     #endif
-        
-    exit_func:
-        
-        RNG& _rng = ts->get_rng(); 
-        _rng = rng;
-        ts->set_failed_test_info( code );
     }
 };
 
@@ -790,7 +801,7 @@ void Core_ArrayOpTest::run( int /* start_from */)
             break;
         }
         
-        minMaxLoc(Md, &val1, &val2, idx1, idx2);
+        minMaxIdx(Md, &val1, &val2, idx1, idx2);
         s1 = idx2string(idx1, dims), s2 = idx2string(idx2, dims);
         if( (min_val < 0 && (val1 != min_val || s1 != min_sidx)) ||
            (max_val > 0 && (val2 != max_val || s2 != max_sidx)) )
@@ -809,3 +820,5 @@ void Core_ArrayOpTest::run( int /* start_from */)
 TEST(Core_PCA, accuracy) { Core_PCATest test; test.safe_run(); }
 TEST(Core_Reduce, accuracy) { Core_ReduceTest test; test.safe_run(); }
 TEST(Core_Array, basic_operations) { Core_ArrayOpTest test; test.safe_run(); }
+
+
index 92e0d84..384d2bc 100755 (executable)
@@ -113,7 +113,7 @@ BOWKMeansTrainer::~BOWKMeansTrainer()
 Mat BOWKMeansTrainer::cluster( const Mat& descriptors ) const
 {
     Mat labels, vocabulary;
-    kmeans( descriptors, clusterCount, labels, termcrit, attempts, flags, &vocabulary );
+    kmeans( descriptors, clusterCount, labels, termcrit, attempts, flags, vocabulary );
     return vocabulary;
 }
 
index 90c8b16..01d16c8 100644 (file)
@@ -281,7 +281,6 @@ void CV_KDTreeTest_CPP::createModel( const Mat& data )
 int CV_KDTreeTest_CPP::checkGetPoins( const Mat& data )
 {
     Mat res1( data.size(), data.type() ),
-        res2( data.size(), data.type() ),
         res3( data.size(), data.type() );
     Mat idxs( 1, data.rows, CV_32SC1 );
     for( int pi = 0; pi < data.rows; pi++ )
@@ -292,14 +291,11 @@ int CV_KDTreeTest_CPP::checkGetPoins( const Mat& data )
         for( int di = 0; di < data.cols; di++ )
             res1.at<float>(pi, di) = point[di];
     }
-    // 2nd way
-    tr->getPoints( idxs.ptr<int>(0), data.rows, res2 );
 
     // 3d way
     tr->getPoints( idxs, res3 );
 
     if( norm( res1, data, NORM_L1) != 0 ||
-        norm( res2, data, NORM_L1) != 0 ||
         norm( res3, data, NORM_L1) != 0)
         return cvtest::TS::FAIL_BAD_ACCURACY;
     return cvtest::TS::OK;
@@ -309,7 +305,7 @@ int CV_KDTreeTest_CPP::checkFindBoxed()
 {
     vector<float> min( dims, minValue), max(dims, maxValue);
     vector<int> indices;
-    tr->findOrthoRange( &min[0], &max[0], &indices );
+    tr->findOrthoRange( min, max, indices );
     // TODO check indices
     if( (int)indices.size() != featuresCount)
         return cvtest::TS::FAIL_BAD_ACCURACY;
@@ -326,11 +322,12 @@ int CV_KDTreeTest_CPP::findNeighbors( Mat& points, Mat& neighbors )
     for( int pi = 0; pi < points.rows; pi++ )
     {
         // 1st way
-        tr->findNearest( points.ptr<float>(pi), neighbors.cols, emax, neighbors.ptr<int>(pi) );
+        Mat nrow = neighbors.row(pi);
+        tr->findNearest( points.row(pi), neighbors.cols, emax, nrow );
 
         // 2nd way
         vector<int> neighborsIdx2( neighbors2.cols, 0 );
-        tr->findNearest( points.ptr<float>(pi), neighbors2.cols, emax, &neighborsIdx2 );
+        tr->findNearest( points.row(pi), neighbors2.cols, emax, neighborsIdx2 );
         vector<int>::const_iterator it2 = neighborsIdx2.begin();
         for( j = 0; it2 != neighborsIdx2.end(); ++it2, j++ )
             neighbors2.at<int>(pi,j) = *it2;
index c3e65b5..7fdca74 100644 (file)
@@ -344,7 +344,7 @@ protected:
             ts->printf(cvtest::TS::LOG, "Tesing %s\n", names[i]);\r
 \r
                cv::Mat cpuRes;\r
-            cv::morphologyEx(img, cpuRes, ops[i], kernel);\r
+            cv::morphologyEx(img, cpuRes, ops[i], (Mat)kernel);\r
 \r
                GpuMat gpuRes;\r
             cv::gpu::morphologyEx(GpuMat(img), gpuRes, ops[i], kernel);\r
index 4cbbc8c..c6089b0 100644 (file)
@@ -249,7 +249,7 @@ struct CV_GpuHogGetDescriptorsTestRunner: cv::gpu::HOGDescriptor
         cv::cvtColor(img_rgb, img, CV_BGR2BGRA);\r
         computeBlockHistograms(cv::gpu::GpuMat(img));\r
         // Everything is fine with interpolation for left top subimage\r
-        CHECK(cv::norm(block_hists, descriptors.rowRange(0, 1)) == 0.f, cvtest::TS::FAIL_INVALID_OUTPUT);\r
+        CHECK(cv::norm((cv::Mat)block_hists, (cv::Mat)descriptors.rowRange(0, 1)) == 0.f, cvtest::TS::FAIL_INVALID_OUTPUT);\r
 \r
         img_rgb = cv::imread(std::string(ts->get_data_path()) + "hog/positive2.png");\r
         CHECK(!img_rgb.empty(), cvtest::TS::FAIL_MISSING_TEST_DATA);\r
index 3445929..34843c7 100644 (file)
@@ -74,7 +74,7 @@ struct CV_AsyncGpuMatTest : public cvtest::BaseTest
         Mat cpu_gold0(100, 100, CV_8UC1, Scalar::all(255));
         Mat cpu_gold1(100, 100, CV_8UC1, Scalar::all(128));
 
-        if (norm(cpudst0, cpu_gold0, NORM_INF) > 0 || norm(cpudst1, cpu_gold1, NORM_INF) > 0)
+        if (norm((Mat)cpudst0, cpu_gold0, NORM_INF) > 0 || norm((Mat)cpudst1, cpu_gold1, NORM_INF) > 0)
             ts->set_failed_test_info(cvtest::TS::FAIL_GENERIC);
         else
             ts->set_failed_test_info(cvtest::TS::OK);
index b604de3..c5c55b3 100644 (file)
@@ -68,7 +68,7 @@ void CV_GpuMatOpConvertToTest::run(int /* start_from */)
     bool passed = true;
     int lastType = CV_32F;
 
-    if (TargetArchs::builtWith(NATIVE_DOUBLE) && DeviceInfo().supports(NATIVE_DOUBLE))\r
+    if (TargetArchs::builtWith(NATIVE_DOUBLE) && DeviceInfo().supports(NATIVE_DOUBLE))
         lastType = CV_64F;
 
     for (int i = 0; i <= lastType && passed; ++i)
@@ -92,7 +92,7 @@ void CV_GpuMatOpConvertToTest::run(int /* start_from */)
                 cpumatsrc.convertTo(cpumatdst, dst_type, 0.5, 3.0);
                 gpumatsrc.convertTo(gpumatdst, dst_type, 0.5, 3.0);
 
-                double r = norm(cpumatdst, gpumatdst, NORM_INF);
+                double r = norm(cpumatdst, (Mat)gpumatdst, NORM_INF);
                 if (r > 1)
                 {
                     ts->printf(cvtest::TS::LOG,
index fccf0ab..dc1e228 100644 (file)
@@ -106,7 +106,7 @@ bool CV_GpuMatOpCopyToTest::compare_matrix(cv::Mat & cpumat, gpu::GpuMat & gpuma
     cv::waitKey(0);
 #endif
 
-    double ret = norm(cmat, gmat);
+    double ret = norm(cmat, (Mat)gmat);
 
     if (ret < 1.0)
         return true;
@@ -123,7 +123,7 @@ void CV_GpuMatOpCopyToTest::run( int /* start_from */)
 
     int lastType = CV_32F;
 
-    if (TargetArchs::builtWith(NATIVE_DOUBLE) && DeviceInfo().supports(NATIVE_DOUBLE))\r
+    if (TargetArchs::builtWith(NATIVE_DOUBLE) && DeviceInfo().supports(NATIVE_DOUBLE))
         lastType = CV_64F;
 
     for (int i = 0 ; i <= lastType; i++)
index db0908c..f09f411 100644 (file)
@@ -78,7 +78,7 @@ bool CV_GpuMatOpSetToTest::testSetTo(cv::Mat& cpumat, gpu::GpuMat& gpumat, const
     cpumat.setTo(s, cpumask);
     gpumat.setTo(s, gpumask);
 
-    double ret = norm(cpumat, gpumat, NORM_INF);
+    double ret = norm(cpumat, (Mat)gpumat, NORM_INF);
 
     if (ret < std::numeric_limits<double>::epsilon())
         return true;
@@ -100,7 +100,7 @@ void CV_GpuMatOpSetToTest::run( int /* start_from */)
 
     int lastType = CV_32F;
 
-    if (TargetArchs::builtWith(NATIVE_DOUBLE) && DeviceInfo().supports(NATIVE_DOUBLE))\r
+    if (TargetArchs::builtWith(NATIVE_DOUBLE) && DeviceInfo().supports(NATIVE_DOUBLE))
         lastType = CV_64F;
 
     for (int i = 0; i <= lastType; i++)
index da925ca..7a4806e 100644 (file)
@@ -106,7 +106,7 @@ struct CV_GpuStereoBMTest : public cvtest::BaseTest
         bm(cv::gpu::GpuMat(img_l), cv::gpu::GpuMat(img_r), disp);
 
         disp.convertTo(disp, img_reference.type());
-        double norm = cv::norm(disp, img_reference, cv::NORM_INF);
+        double norm = cv::norm((Mat)disp, img_reference, cv::NORM_INF);
 
         //cv::imwrite(std::string(ts->get_data_path()) + "stereobm/aloe-disp.png", disp);
 
index 89afab8..f9632dd 100644 (file)
@@ -70,7 +70,7 @@ struct CV_AsyncStereoBMTest : public cvtest::BaseTest
 
         stream.waitForCompletion();
         disp.convertTo(disp, img_reference.type());
-        double norm = cv::norm(disp, img_reference, cv::NORM_INF);
+        double norm = cv::norm((Mat)disp, img_reference, cv::NORM_INF);
 
         if (norm >= 100)
         {
index cf277c2..7788917 100644 (file)
@@ -67,7 +67,7 @@ struct CV_GpuStereoBPTest : public cvtest::BaseTest
 \r
         disp.convertTo(disp, img_template.type());\r
 \r
-        double norm = cv::norm(disp, img_template, cv::NORM_INF);\r
+        double norm = cv::norm((cv::Mat)disp, img_template, cv::NORM_INF);\r
            if (norm >= 0.5)\r
         {\r
                ts->printf(cvtest::TS::LOG, "\nStereoBP norm = %f\n", norm);\r
index c2ff012..e9d7285 100644 (file)
@@ -67,7 +67,7 @@ struct CV_GpuStereoCSBPTest : public cvtest::BaseTest
 
         disp.convertTo(disp, img_template.type());
 
-        double norm = cv::norm(disp, img_template, cv::NORM_INF);
+        double norm = cv::norm((cv::Mat)disp, img_template, cv::NORM_INF);
         if (norm >= 0.5)
         {
             ts->printf(cvtest::TS::LOG, "\nConstantSpaceStereoBP norm = %f\n", norm);
index 9aa29af..b171d79 100644 (file)
@@ -66,7 +66,9 @@ CV_EXPORTS_W double getWindowProperty(const string& winname, int prop_id);//YV
 
 //Only for Qt
 //------------------------
-CV_EXPORTS CvFont fontQt(const string& nameFont, int pointSize CV_DEFAULT(-1), Scalar color CV_DEFAULT(Scalar::all(0)), int weight CV_DEFAULT(CV_FONT_NORMAL),  int style CV_DEFAULT(CV_STYLE_NORMAL), int spacing CV_DEFAULT(0));
+CV_EXPORTS CvFont fontQt(const string& nameFont, int pointSize CV_DEFAULT(-1),
+                         Scalar color CV_DEFAULT(Scalar::all(0)), int weight CV_DEFAULT(CV_FONT_NORMAL),
+                         int style CV_DEFAULT(CV_STYLE_NORMAL), int spacing CV_DEFAULT(0));
 CV_EXPORTS void addText( const Mat& img, const string& text, Point org, CvFont font);
 
 CV_EXPORTS void displayOverlay(const string& winname, const string& text, int delayms);
@@ -81,10 +83,12 @@ CV_EXPORTS  int startLoop(int (*pt2Func)(int argc, char *argv[]), int argc, char
 CV_EXPORTS  void stopLoop();
 
 typedef void (CV_CDECL *ButtonCallback)(int state, void* userdata);
-CV_EXPORTS int createButton( const string& bar_name, ButtonCallback on_change , void* userdata CV_DEFAULT(NULL), int type CV_DEFAULT(CV_PUSH_BUTTON), bool initial_button_state CV_DEFAULT(0));
+CV_EXPORTS int createButton( const string& bar_name, ButtonCallback on_change,
+                             void* userdata CV_DEFAULT(NULL), int type CV_DEFAULT(CV_PUSH_BUTTON),
+                             bool initial_button_state CV_DEFAULT(0));
 //-------------------------
 
-CV_EXPORTS_W void imshow( const string& winname, const Mat& mat );
+CV_EXPORTS_W void imshow( const string& winname, const InputArray& mat );
 
 typedef void (CV_CDECL *TrackbarCallback)(int pos, void* userdata);
 
@@ -102,12 +106,12 @@ typedef void (*MouseCallback )(int event, int x, int y, int flags, void* param);
 CV_EXPORTS void setMouseCallback( const string& windowName, MouseCallback onMouse, void* param=0);
     
 CV_EXPORTS_W Mat imread( const string& filename, int flags=1 );
-CV_EXPORTS_W bool imwrite( const string& filename, const Mat& img,
+CV_EXPORTS_W bool imwrite( const string& filename, const InputArray& img,
               const vector<int>& params=vector<int>());
-CV_EXPORTS_W Mat imdecode( const Mat& buf, int flags );
-CV_EXPORTS_W bool imencode( const string& ext, const Mat& img,
-                          CV_OUT vector<uchar>& buf,
-                          const vector<int>& params=vector<int>());
+CV_EXPORTS_W Mat imdecode( const InputArray& buf, int flags );
+CV_EXPORTS_W bool imencode( const string& ext, const InputArray& img,
+                            vector<uchar>& buf,
+                            const vector<int>& params=vector<int>());
 
 CV_EXPORTS_W int waitKey(int delay=0);
 
index 87d4963..87cf61a 100644 (file)
@@ -295,9 +295,10 @@ static bool imwrite_( const string& filename, const Mat& image,
     return code;
 }
 
-bool imwrite( const string& filename, const Mat& img,
+bool imwrite( const string& filename, const InputArray& _img,
               const vector<int>& params )
 {
+    Mat img = _img.getMat();
     return imwrite_(filename, img, params, false);
 }
 
@@ -388,17 +389,17 @@ imdecode_( const Mat& buf, int flags, int hdrtype, Mat* mat=0 )
 }
 
 
-Mat imdecode( const Mat& buf, int flags )
+Mat imdecode( const InputArray& _buf, int flags )
 {
-    Mat img;
+    Mat buf = _buf.getMat(), img;
     imdecode_( buf, flags, LOAD_MAT, &img );
     return img;
 }
     
-bool imencode( const string& ext, const Mat& image,
+bool imencode( const string& ext, const InputArray& _image,
                vector<uchar>& buf, const vector<int>& params )
 {
-    Mat temp;
+    Mat temp, image = _image.getMat();
     const Mat* pimage = &image;
 
     int channels = image.channels();
index 57b3f44..0fbca11 100644 (file)
@@ -126,41 +126,38 @@ CV_IMPL double cvGetWindowProperty(const char* name, int prop_id)
        }
 }
 
-namespace cv
-{
-
-void namedWindow( const string& winname, int flags )
+void cv::namedWindow( const string& winname, int flags )
 {
     cvNamedWindow( winname.c_str(), flags );
 }
 
-void destroyWindow( const string& winname )
+void cv::destroyWindow( const string& winname )
 {
     cvDestroyWindow( winname.c_str() );
 }
 
-void setWindowProperty(const string& winname, int prop_id, double prop_value)
+void cv::setWindowProperty(const string& winname, int prop_id, double prop_value)
 {
        cvSetWindowProperty( winname.c_str(),prop_id,prop_value);
 }
 
-double getWindowProperty(const string& winname, int prop_id)
+double cv::getWindowProperty(const string& winname, int prop_id)
 {
        return  cvGetWindowProperty(winname.c_str(),prop_id);
 }
 
-void imshow( const string& winname, const Mat& img )
+void cv::imshow( const string& winname, const InputArray& img )
 {
-    CvMat _img = img;
-    cvShowImage( winname.c_str(), &_img );
+    CvMat c_img = img.getMat();
+    cvShowImage( winname.c_str(), &c_img );
 }
 
-int waitKey(int delay)
+int cv::waitKey(int delay)
 {
     return cvWaitKey(delay);
 }
 
-int createTrackbar(const string& trackbarName, const string& winName,
+int cv::createTrackbar(const string& trackbarName, const string& winName,
                    int* value, int count, TrackbarCallback callback,
                    void* userdata)
 {
@@ -168,83 +165,81 @@ int createTrackbar(const string& trackbarName, const string& winName,
                              value, count, callback, userdata);
 }
 
-void setTrackbarPos( const string& trackbarName, const string& winName, int value )
+void cv::setTrackbarPos( const string& trackbarName, const string& winName, int value )
 {
     cvSetTrackbarPos(trackbarName.c_str(), winName.c_str(), value );
 }
 
-int getTrackbarPos( const string& trackbarName, const string& winName )
+int cv::getTrackbarPos( const string& trackbarName, const string& winName )
 {
        return cvGetTrackbarPos(trackbarName.c_str(), winName.c_str());
 }
     
-void setMouseCallback( const string& windowName, MouseCallback onMouse, void* param)
+void cv::setMouseCallback( const string& windowName, MouseCallback onMouse, void* param)
 {
     cvSetMouseCallback(windowName.c_str(), onMouse, param);
 }
     
-int startWindowThread()
+int cv::startWindowThread()
 {
     return cvStartWindowThread();
 }
 
 #if defined (HAVE_QT)
 
-CvFont fontQt(const string& nameFont, int pointSize, Scalar color, int weight,  int style, int spacing)
+CvFont cv::fontQt(const string& nameFont, int pointSize, Scalar color, int weight,  int style, int spacing)
 {
 return cvFontQt(nameFont.c_str(), pointSize,color,weight, style);
 }
 
-void addText( const Mat& img, const string& text, Point org, CvFont font)
+void cv::addText( const Mat& img, const string& text, Point org, CvFont font)
 {
        CvMat _img = img;
        cvAddText( &_img, text.c_str(), org,&font);
 }
 
-void displayStatusBar(const string& name,  const string& text, int delayms)
+void cv::displayStatusBar(const string& name,  const string& text, int delayms)
 {
        cvDisplayStatusBar(name.c_str(),text.c_str(), delayms);
 }
 
-void createOpenGLCallback(const string& name,  OpenGLCallback callback, void* param)
+void cv::createOpenGLCallback(const string& name,  OpenGLCallback callback, void* param)
 {
        cvCreateOpenGLCallback(name.c_str(),callback, param);
 }
 
-void displayOverlay(const string& name,  const string& text, int delayms)
+void cv::displayOverlay(const string& name,  const string& text, int delayms)
 {
        cvDisplayOverlay(name.c_str(),text.c_str(), delayms);
 }
 
-int startLoop(int (*pt2Func)(int argc, char *argv[]), int argc, char* argv[])
+int cv::startLoop(int (*pt2Func)(int argc, char *argv[]), int argc, char* argv[])
 {
        return cvStartLoop(pt2Func, argc, argv);
 }
 
-void stopLoop()
+void cv::stopLoop()
 {
        cvStopLoop();
 }
 
-void saveWindowParameters(const string& windowName)
+void cv::saveWindowParameters(const string& windowName)
 {
        cvSaveWindowParameters(windowName.c_str());
 }
 
-void loadWindowParameters(const string& windowName)
+void cv::loadWindowParameters(const string& windowName)
 {
        cvLoadWindowParameters(windowName.c_str());
 }
 
-int createButton(const string& button_name, ButtonCallback on_change, void* userdata, int button_type , bool initial_button_state  )
+int cv::createButton(const string& button_name, ButtonCallback on_change, void* userdata, int button_type , bool initial_button_state  )
 {
        return cvCreateButton(button_name.c_str(), on_change, userdata, button_type , initial_button_state );
 }
 
 #endif
 
-}
-
 #if   defined WIN32 || defined _WIN32         // see window_w32.cpp
 #elif defined (HAVE_GTK)      // see window_gtk.cpp
 #elif defined (HAVE_COCOA)   // see window_carbon.cpp
index 7f81b0d..89bed25 100644 (file)
@@ -61,7 +61,7 @@ namespace cv
 //! various border interpolation methods
 enum { BORDER_REPLICATE=IPL_BORDER_REPLICATE, BORDER_CONSTANT=IPL_BORDER_CONSTANT,
        BORDER_REFLECT=IPL_BORDER_REFLECT, BORDER_WRAP=IPL_BORDER_WRAP, 
-          BORDER_REFLECT_101=IPL_BORDER_REFLECT_101, BORDER_REFLECT101=BORDER_REFLECT_101,
+       BORDER_REFLECT_101=IPL_BORDER_REFLECT_101, BORDER_REFLECT101=BORDER_REFLECT_101,
        BORDER_TRANSPARENT=IPL_BORDER_TRANSPARENT,
        BORDER_DEFAULT=BORDER_REFLECT_101, BORDER_ISOLATED=16 };
 
@@ -287,28 +287,28 @@ enum { KERNEL_GENERAL=0, KERNEL_SYMMETRICAL=1, KERNEL_ASYMMETRICAL=2,
        KERNEL_SMOOTH=4, KERNEL_INTEGER=8 };
 
 //! returns type (one of KERNEL_*) of 1D or 2D kernel specified by its coefficients.
-CV_EXPORTS int getKernelType(const Mat& kernel, Point anchor);
+CV_EXPORTS int getKernelType(const InputArray& kernel, Point anchor);
 
 //! returns the primitive row filter with the specified kernel
 CV_EXPORTS Ptr<BaseRowFilter> getLinearRowFilter(int srcType, int bufType,
-                                            const Mat& kernel, int anchor,
+                                            const InputArray& kernel, int anchor,
                                             int symmetryType);
 
 //! returns the primitive column filter with the specified kernel
 CV_EXPORTS Ptr<BaseColumnFilter> getLinearColumnFilter(int bufType, int dstType,
-                                            const Mat& kernel, int anchor,
+                                            const InputArray& kernel, int anchor,
                                             int symmetryType, double delta=0,
                                             int bits=0);
 
 //! returns 2D filter with the specified kernel
 CV_EXPORTS Ptr<BaseFilter> getLinearFilter(int srcType, int dstType,
-                                           const Mat& kernel,
+                                           const InputArray& kernel,
                                            Point anchor=Point(-1,-1),
                                            double delta=0, int bits=0);
 
 //! returns the separable linear filter engine
 CV_EXPORTS Ptr<FilterEngine> createSeparableLinearFilter(int srcType, int dstType,
-                          const Mat& rowKernel, const Mat& columnKernel,
+                          const InputArray& rowKernel, const InputArray& columnKernel,
                           Point _anchor=Point(-1,-1), double delta=0,
                           int _rowBorderType=BORDER_DEFAULT,
                           int _columnBorderType=-1,
@@ -316,7 +316,7 @@ CV_EXPORTS Ptr<FilterEngine> createSeparableLinearFilter(int srcType, int dstTyp
 
 //! returns the non-separable linear filter engine
 CV_EXPORTS Ptr<FilterEngine> createLinearFilter(int srcType, int dstType,
-                 const Mat& kernel, Point _anchor=Point(-1,-1),
+                 const InputArray& kernel, Point _anchor=Point(-1,-1),
                  double delta=0, int _rowBorderType=BORDER_DEFAULT,
                  int _columnBorderType=-1, const Scalar& _borderValue=Scalar());
 
@@ -328,9 +328,9 @@ CV_EXPORTS Ptr<FilterEngine> createGaussianFilter( int type, Size ksize,
                                     double sigma1, double sigma2=0,
                                     int borderType=BORDER_DEFAULT);
 //! initializes kernels of the generalized Sobel operator
-CV_EXPORTS_W void getDerivKernels( CV_OUT Mat& kx, CV_OUT Mat& ky,
-                                 int dx, int dy, int ksize,
-                                 bool normalize=false, int ktype=CV_32F );
+CV_EXPORTS_W void getDerivKernels( OutputArray kx, OutputArray ky,
+                                   int dx, int dy, int ksize,
+                                   bool normalize=false, int ktype=CV_32F );
 //! returns filter engine for the generalized Sobel operator
 CV_EXPORTS Ptr<FilterEngine> createDerivFilter( int srcType, int dstType,
                                         int dx, int dy, int ksize,
@@ -358,14 +358,14 @@ CV_EXPORTS Ptr<BaseRowFilter> getMorphologyRowFilter(int op, int type, int ksize
 //! returns vertical 1D morphological filter
 CV_EXPORTS Ptr<BaseColumnFilter> getMorphologyColumnFilter(int op, int type, int ksize, int anchor=-1);
 //! returns 2D morphological filter
-CV_EXPORTS Ptr<BaseFilter> getMorphologyFilter(int op, int type, const Mat& kernel,
+CV_EXPORTS Ptr<BaseFilter> getMorphologyFilter(int op, int type, const InputArray& kernel,
                                                Point anchor=Point(-1,-1));
     
 //! returns "magic" border value for erosion and dilation. It is automatically transformed to Scalar::all(-DBL_MAX) for dilation.
 static inline Scalar morphologyDefaultBorderValue() { return Scalar::all(DBL_MAX); }
 
 //! returns morphological filter engine. Only MORPH_ERODE and MORPH_DILATE are supported.
-CV_EXPORTS Ptr<FilterEngine> createMorphologyFilter(int op, int type, const Mat& kernel,
+CV_EXPORTS Ptr<FilterEngine> createMorphologyFilter(int op, int type, const InputArray& kernel,
                     Point anchor=Point(-1,-1), int _rowBorderType=BORDER_CONSTANT,
                     int _columnBorderType=-1,
                     const Scalar& _borderValue=morphologyDefaultBorderValue());
@@ -378,126 +378,127 @@ CV_EXPORTS_W Mat getStructuringElement(int shape, Size ksize, Point anchor=Point
 template<> CV_EXPORTS void Ptr<IplConvKernel>::delete_obj();
 
 //! copies 2D array to a larger destination array with extrapolation of the outer part of src using the specified border mode 
-CV_EXPORTS_W void copyMakeBorder( const Mat& src, CV_OUT Mat& dst,
+CV_EXPORTS_W void copyMakeBorder( const InputArray& src, OutputArray dst,
                                 int top, int bottom, int left, int right,
                                 int borderType, const Scalar& value=Scalar() );
 
 //! smooths the image using median filter.
-CV_EXPORTS_W void medianBlur( const Mat& src, CV_OUT Mat& dst, int ksize );
+CV_EXPORTS_W void medianBlur( const InputArray& src, OutputArray dst, int ksize );
 //! smooths the image using Gaussian filter.
-CV_EXPORTS_AS(gaussianBlur) void GaussianBlur( const Mat& src, CV_OUT Mat& dst, Size ksize,
-                              double sigma1, double sigma2=0,
-                              int borderType=BORDER_DEFAULT );
+CV_EXPORTS_AS(gaussianBlur) void GaussianBlur( const InputArray& src,
+                                               OutputArray dst, Size ksize,
+                                               double sigma1, double sigma2=0,
+                                               int borderType=BORDER_DEFAULT );
 //! smooths the image using bilateral filter
-CV_EXPORTS_W void bilateralFilter( const Mat& src, CV_OUT Mat& dst, int d,
-                                 double sigmaColor, double sigmaSpace,
-                                 int borderType=BORDER_DEFAULT );
+CV_EXPORTS_W void bilateralFilter( const InputArray& src, OutputArray dst, int d,
+                                   double sigmaColor, double sigmaSpace,
+                                   int borderType=BORDER_DEFAULT );
 //! smooths the image using the box filter. Each pixel is processed in O(1) time
-CV_EXPORTS_W void boxFilter( const Mat& src, CV_OUT Mat& dst, int ddepth,
-                           Size ksize, Point anchor=Point(-1,-1),
-                           bool normalize=true,
-                           int borderType=BORDER_DEFAULT );
+CV_EXPORTS_W void boxFilter( const InputArray& src, OutputArray dst, int ddepth,
+                             Size ksize, Point anchor=Point(-1,-1),
+                             bool normalize=true,
+                             int borderType=BORDER_DEFAULT );
 //! a synonym for normalized box filter
-CV_EXPORTS_W void blur( const Mat& src, CV_OUT Mat& dst,
+CV_EXPORTS_W void blur( const InputArray& src, OutputArray dst,
                         Size ksize, Point anchor=Point(-1,-1),
                         int borderType=BORDER_DEFAULT );
 
 //! applies non-separable 2D linear filter to the image
-CV_EXPORTS_W void filter2D( const Mat& src, CV_OUT Mat& dst, int ddepth,
-                          const Mat& kernel, Point anchor=Point(-1,-1),
-                          double delta=0, int borderType=BORDER_DEFAULT );
+CV_EXPORTS_W void filter2D( const InputArray& src, OutputArray dst, int ddepth,
+                            const InputArray& kernel, Point anchor=Point(-1,-1),
+                            double delta=0, int borderType=BORDER_DEFAULT );
 
 //! applies separable 2D linear filter to the image
-CV_EXPORTS_W void sepFilter2D( const Mat& src, CV_OUT Mat& dst, int ddepth,
-                             const Mat& kernelX, const Mat& kernelY,
-                             Point anchor=Point(-1,-1),
-                             double delta=0, int borderType=BORDER_DEFAULT );
+CV_EXPORTS_W void sepFilter2D( const InputArray& src, OutputArray dst, int ddepth,
+                               const InputArray& kernelX, const InputArray& kernelY,
+                               Point anchor=Point(-1,-1),
+                               double delta=0, int borderType=BORDER_DEFAULT );
     
 //! applies generalized Sobel operator to the image
-CV_EXPORTS_AS(sobel) void Sobel( const Mat& src, CV_OUT Mat& dst, int ddepth,
-                       int dx, int dy, int ksize=3,
-                       double scale=1, double delta=0,
-                       int borderType=BORDER_DEFAULT );
+CV_EXPORTS_AS(sobel) void Sobel( const InputArray& src, OutputArray dst, int ddepth,
+                                 int dx, int dy, int ksize=3,
+                                 double scale=1, double delta=0,
+                                 int borderType=BORDER_DEFAULT );
 
 //! applies the vertical or horizontal Scharr operator to the image
-CV_EXPORTS_AS(scharr) void Scharr( const Mat& src, CV_OUT Mat& dst, int ddepth,
-                        int dx, int dy, double scale=1, double delta=0,
-                        int borderType=BORDER_DEFAULT );
+CV_EXPORTS_AS(scharr) void Scharr( const InputArray& src, OutputArray dst, int ddepth,
+                                   int dx, int dy, double scale=1, double delta=0,
+                                   int borderType=BORDER_DEFAULT );
 
 //! applies Laplacian operator to the image
-CV_EXPORTS_AS(laplacian) void Laplacian( const Mat& src, CV_OUT Mat& dst, int ddepth,
-                           int ksize=1, double scale=1, double delta=0,
-                           int borderType=BORDER_DEFAULT );
+CV_EXPORTS_AS(laplacian) void Laplacian( const InputArray& src, OutputArray dst, int ddepth,
+                                         int ksize=1, double scale=1, double delta=0,
+                                         int borderType=BORDER_DEFAULT );
 
 //! applies Canny edge detector and produces the edge map.
-CV_EXPORTS_AS(canny) void Canny( const Mat& image, CV_OUT Mat& edges,
-                       double threshold1, double threshold2,
-                       int apertureSize=3, bool L2gradient=false );
+CV_EXPORTS_AS(canny) void Canny( const InputArray& image, OutputArray edges,
+                                 double threshold1, double threshold2,
+                                 int apertureSize=3, bool L2gradient=false );
 
 //! computes minimum eigen value of 2x2 derivative covariation matrix at each pixel - the cornerness criteria
-CV_EXPORTS_W void cornerMinEigenVal( const Mat& src, CV_OUT Mat& dst,
+CV_EXPORTS_W void cornerMinEigenVal( const InputArray& src, OutputArray dst,
                                    int blockSize, int ksize=3,
                                    int borderType=BORDER_DEFAULT );
 
 //! computes Harris cornerness criteria at each image pixel
-CV_EXPORTS_W void cornerHarris( const Mat& src, CV_OUT Mat& dst, int blockSize,
-                              int ksize, double k,
-                              int borderType=BORDER_DEFAULT );
+CV_EXPORTS_W void cornerHarris( const InputArray& src, OutputArray dst, int blockSize,
+                                int ksize, double k,
+                                int borderType=BORDER_DEFAULT );
 
 //! computes both eigenvalues and the eigenvectors of 2x2 derivative covariation matrix  at each pixel. The output is stored as 6-channel matrix.
-CV_EXPORTS_W void cornerEigenValsAndVecs( const Mat& src, CV_OUT Mat& dst,
-                                        int blockSize, int ksize,
-                                        int borderType=BORDER_DEFAULT );
+CV_EXPORTS_W void cornerEigenValsAndVecs( const InputArray& src, OutputArray dst,
+                                          int blockSize, int ksize,
+                                          int borderType=BORDER_DEFAULT );
 
 //! computes another complex cornerness criteria at each pixel
-CV_EXPORTS_W void preCornerDetect( const Mat& src, CV_OUT Mat& dst, int ksize,
-                                 int borderType=BORDER_DEFAULT );
+CV_EXPORTS_W void preCornerDetect( const InputArray& src, OutputArray dst, int ksize,
+                                   int borderType=BORDER_DEFAULT );
 
 //! adjusts the corner locations with sub-pixel accuracy to maximize the certain cornerness criteria
-CV_EXPORTS void cornerSubPix( const Mat& image, vector<Point2f>& corners,
+CV_EXPORTS void cornerSubPix( const InputArray& image, InputOutputArray corners,
                               Size winSize, Size zeroZone,
                               TermCriteria criteria );
 
 //! finds the strong enough corners where the cornerMinEigenVal() or cornerHarris() report the local maxima
-CV_EXPORTS_W void goodFeaturesToTrack( const Mat& image, CV_OUT vector<Point2f>& corners,
+CV_EXPORTS_W void goodFeaturesToTrack( const InputArray& image, OutputArray corners,
                                      int maxCorners, double qualityLevel, double minDistance,
-                                     const Mat& mask=Mat(), int blockSize=3,
+                                     const InputArray& mask=InputArray(), int blockSize=3,
                                      bool useHarrisDetector=false, double k=0.04 );
 
 //! finds lines in the black-n-white image using the standard or pyramid Hough transform
-CV_EXPORTS_AS(houghLines) void HoughLines( const Mat& image, CV_OUT vector<Vec2f>& lines,
-                            double rho, double theta, int threshold,
-                            double srn=0, double stn=0 );
+CV_EXPORTS_AS(houghLines) void HoughLines( const InputArray& image, OutputArray lines,
+                                           double rho, double theta, int threshold,
+                                           double srn=0, double stn=0 );
 
 //! finds line segments in the black-n-white image using probabalistic Hough transform
-CV_EXPORTS_AS(houghLinesP) void HoughLinesP( Mat& image, CV_OUT vector<Vec4i>& lines,
-                             double rho, double theta, int threshold,
-                             double minLineLength=0, double maxLineGap=0 );
+CV_EXPORTS_AS(houghLinesP) void HoughLinesP( const InputArray& image, OutputArray lines,
+                                             double rho, double theta, int threshold,
+                                             double minLineLength=0, double maxLineGap=0 );
 
 //! finds circles in the grayscale image using 2+1 gradient Hough transform 
-CV_EXPORTS_AS(houghCircles) void HoughCircles( const Mat& image, CV_OUT vector<Vec3f>& circles,
-                              int method, double dp, double minDist,
-                              double param1=100, double param2=100,
-                              int minRadius=0, int maxRadius=0 );
+CV_EXPORTS_AS(houghCircles) void HoughCircles( const InputArray& image, OutputArray circles,
+                                               int method, double dp, double minDist,
+                                               double param1=100, double param2=100,
+                                               int minRadius=0, int maxRadius=0 );
 
 //! erodes the image (applies the local minimum operator)
-CV_EXPORTS_W void erode( const Mat& src, CV_OUT Mat& dst, const Mat& kernel,
-                       Point anchor=Point(-1,-1), int iterations=1,
-                       int borderType=BORDER_CONSTANT,
-                       const Scalar& borderValue=morphologyDefaultBorderValue() );
+CV_EXPORTS_W void erode( const InputArray& src, OutputArray dst, const InputArray& kernel,
+                         Point anchor=Point(-1,-1), int iterations=1,
+                         int borderType=BORDER_CONSTANT,
+                         const Scalar& borderValue=morphologyDefaultBorderValue() );
     
 //! dilates the image (applies the local maximum operator)
-CV_EXPORTS_W void dilate( const Mat& src, CV_OUT Mat& dst, const Mat& kernel,
-                        Point anchor=Point(-1,-1), int iterations=1,
-                        int borderType=BORDER_CONSTANT,
-                        const Scalar& borderValue=morphologyDefaultBorderValue() );
+CV_EXPORTS_W void dilate( const InputArray& src, OutputArray dst, const InputArray& kernel,
+                          Point anchor=Point(-1,-1), int iterations=1,
+                          int borderType=BORDER_CONSTANT,
+                          const Scalar& borderValue=morphologyDefaultBorderValue() );
     
 //! applies an advanced morphological operation to the image
-CV_EXPORTS_W void morphologyEx( const Mat& src, CV_OUT Mat& dst,
-                              int op, const Mat& kernel,
-                              Point anchor=Point(-1,-1), int iterations=1,
-                              int borderType=BORDER_CONSTANT,
-                              const Scalar& borderValue=morphologyDefaultBorderValue() );
+CV_EXPORTS_W void morphologyEx( const InputArray& src, OutputArray dst,
+                                int op, const InputArray& kernel,
+                                Point anchor=Point(-1,-1), int iterations=1,
+                                int borderType=BORDER_CONSTANT,
+                                const Scalar& borderValue=morphologyDefaultBorderValue() );
 
 //! interpolation algorithm
 enum
@@ -512,37 +513,41 @@ enum
 };
 
 //! resizes the image
-CV_EXPORTS_W void resize( const Mat& src, CV_OUT Mat& dst,
-                        Size dsize, double fx=0, double fy=0,
-                        int interpolation=INTER_LINEAR );
+CV_EXPORTS_W void resize( const InputArray& src, OutputArray dst,
+                          Size dsize, double fx=0, double fy=0,
+                          int interpolation=INTER_LINEAR );
 
 //! warps the image using affine transformation
-CV_EXPORTS_W void warpAffine( const Mat& src, CV_OUT Mat& dst,
-                            const Mat& M, Size dsize,
-                            int flags=INTER_LINEAR,
-                            int borderMode=BORDER_CONSTANT,
-                            const Scalar& borderValue=Scalar());
+CV_EXPORTS_W void warpAffine( const InputArray& src, OutputArray dst,
+                              const InputArray& M, Size dsize,
+                              int flags=INTER_LINEAR,
+                              int borderMode=BORDER_CONSTANT,
+                              const Scalar& borderValue=Scalar());
     
 //! warps the image using perspective transformation
-CV_EXPORTS_W void warpPerspective( const Mat& src, CV_OUT Mat& dst,
-                                 const Mat& M, Size dsize,
-                                 int flags=INTER_LINEAR,
-                                 int borderMode=BORDER_CONSTANT,
-                                 const Scalar& borderValue=Scalar());
+CV_EXPORTS_W void warpPerspective( const InputArray& src, OutputArray dst,
+                                   const InputArray& M, Size dsize,
+                                   int flags=INTER_LINEAR,
+                                   int borderMode=BORDER_CONSTANT,
+                                   const Scalar& borderValue=Scalar());
 
-enum { INTER_BITS=5, INTER_BITS2=INTER_BITS*2,
+enum
+{
+    INTER_BITS=5, INTER_BITS2=INTER_BITS*2,
     INTER_TAB_SIZE=(1<<INTER_BITS),
-    INTER_TAB_SIZE2=INTER_TAB_SIZE*INTER_TAB_SIZE };    
+    INTER_TAB_SIZE2=INTER_TAB_SIZE*INTER_TAB_SIZE
+};
 
 //! warps the image using the precomputed maps. The maps are stored in either floating-point or integer fixed-point format
-CV_EXPORTS_W void remap( const Mat& src, CV_OUT Mat& dst, const Mat& map1, const Mat& map2,
-                       int interpolation, int borderMode=BORDER_CONSTANT,
-                       const Scalar& borderValue=Scalar());
+CV_EXPORTS_W void remap( const InputArray& src, OutputArray dst,
+                         const InputArray& map1, const InputArray& map2,
+                         int interpolation, int borderMode=BORDER_CONSTANT,
+                         const Scalar& borderValue=Scalar());
 
 //! converts maps for remap from floating-point to fixed-point format or backwards
-CV_EXPORTS_W void convertMaps( const Mat& map1, const Mat& map2,
-                             CV_OUT Mat& dstmap1, CV_OUT Mat& dstmap2,
-                             int dstmap1type, bool nninterpolation=false );
+CV_EXPORTS_W void convertMaps( const InputArray& map1, const InputArray& map2,
+                               OutputArray dstmap1, OutputArray dstmap2,
+                               int dstmap1type, bool nninterpolation=false );
                              
 //! returns 2x3 affine transformation matrix for the planar rotation.
 CV_EXPORTS_W Mat getRotationMatrix2D( Point2f center, double angle, double scale );
@@ -551,29 +556,34 @@ CV_EXPORTS Mat getPerspectiveTransform( const Point2f src[], const Point2f dst[]
 //! returns 2x3 affine transformation for the corresponding 3 point pairs.
 CV_EXPORTS Mat getAffineTransform( const Point2f src[], const Point2f dst[] );
 //! computes 2x3 affine transformation matrix that is inverse to the specified 2x3 affine transformation.
-CV_EXPORTS_W void invertAffineTransform( const Mat& M, CV_OUT Mat& iM );
+CV_EXPORTS_W void invertAffineTransform( const InputArray& M, OutputArray iM );
 
 //! extracts rectangle from the image at sub-pixel location
-CV_EXPORTS_W void getRectSubPix( const Mat& image, Size patchSize,
-                               Point2f center, CV_OUT Mat& patch, int patchType=-1 );
+CV_EXPORTS_W void getRectSubPix( const InputArray& image, Size patchSize,
+                                 Point2f center, OutputArray patch, int patchType=-1 );
 
 //! computes the integral image
-CV_EXPORTS_W void integral( const Mat& src, CV_OUT Mat& sum, int sdepth=-1 );
+CV_EXPORTS_W void integral( const InputArray& src, OutputArray sum, int sdepth=-1 );
 //! computes the integral image and integral for the squared image
-CV_EXPORTS_AS(integral2) void integral( const Mat& src, CV_OUT Mat& sum, CV_OUT Mat& sqsum, int sdepth=-1 );
+CV_EXPORTS_AS(integral2) void integral( const InputArray& src, OutputArray sum,
+                                        OutputArray sqsum, int sdepth=-1 );
 //! computes the integral image, integral for the squared image and the tilted integral image
-CV_EXPORTS_AS(integral3) void integral( const Mat& src, CV_OUT Mat& sum, CV_OUT Mat& sqsum, CV_OUT Mat& tilted, int sdepth=-1 );
+CV_EXPORTS_AS(integral3) void integral( const InputArray& src, OutputArray sum,
+                                        OutputArray sqsum, OutputArray tilted,
+                                        int sdepth=-1 );
 
 //! adds image to the accumulator (dst += src). Unlike cv::add, dst and src can have different types.
-CV_EXPORTS_W void accumulate( const Mat& src, CV_IN_OUT Mat& dst, const Mat& mask=Mat() );
+CV_EXPORTS_W void accumulate( const InputArray& src, CV_IN_OUT InputOutputArray dst,
+                              const InputArray& mask=InputArray() );
 //! adds squared src image to the accumulator (dst += src*src).
-CV_EXPORTS_W void accumulateSquare( const Mat& src, CV_IN_OUT Mat& dst, const Mat& mask=Mat() );
+CV_EXPORTS_W void accumulateSquare( const InputArray& src, CV_IN_OUT InputOutputArray dst,
+                                    const InputArray& mask=InputArray() );
 //! adds product of the 2 images to the accumulator (dst += src1*src2).
-CV_EXPORTS_W void accumulateProduct( const Mat& src1, const Mat& src2,
-                                   CV_IN_OUT Mat& dst, const Mat& mask=Mat() );
+CV_EXPORTS_W void accumulateProduct( const InputArray& src1, const InputArray& src2,
+                                     CV_IN_OUT InputOutputArray dst, const InputArray& mask=InputArray() );
 //! updates the running average (dst = dst*(1-alpha) + src*alpha)
-CV_EXPORTS_W void accumulateWeighted( const Mat& src, CV_IN_OUT Mat& dst,
-                                      double alpha, const Mat& mask=Mat() );
+CV_EXPORTS_W void accumulateWeighted( const InputArray& src, CV_IN_OUT InputOutputArray dst,
+                                      double alpha, const InputArray& mask=InputArray() );
     
 //! type of the threshold operation
 enum { THRESH_BINARY=CV_THRESH_BINARY, THRESH_BINARY_INV=CV_THRESH_BINARY_INV,
@@ -582,30 +592,37 @@ enum { THRESH_BINARY=CV_THRESH_BINARY, THRESH_BINARY_INV=CV_THRESH_BINARY_INV,
        THRESH_OTSU=CV_THRESH_OTSU };
 
 //! applies fixed threshold to the image
-CV_EXPORTS_W double threshold( const Mat& src, CV_OUT Mat& dst, double thresh, double maxval, int type );
+CV_EXPORTS_W double threshold( const InputArray& src, OutputArray dst,
+                               double thresh, double maxval, int type );
 
 //! adaptive threshold algorithm
 enum { ADAPTIVE_THRESH_MEAN_C=0, ADAPTIVE_THRESH_GAUSSIAN_C=1 };
 
 //! applies variable (adaptive) threshold to the image
-CV_EXPORTS_W void adaptiveThreshold( const Mat& src, CV_OUT Mat& dst, double maxValue,
-                                   int adaptiveMethod, int thresholdType,
-                                   int blockSize, double C );
+CV_EXPORTS_W void adaptiveThreshold( const InputArray& src, OutputArray dst,
+                                     double maxValue, int adaptiveMethod,
+                                     int thresholdType, int blockSize, double C );
 
 //! smooths and downsamples the image
-CV_EXPORTS_W void pyrDown( const Mat& src, CV_OUT Mat& dst, const Size& dstsize=Size());
+CV_EXPORTS_W void pyrDown( const InputArray& src, OutputArray dst,
+                           const Size& dstsize=Size());
 //! upsamples and smoothes the image
-CV_EXPORTS_W void pyrUp( const Mat& src, CV_OUT Mat& dst, const Size& dstsize=Size());
+CV_EXPORTS_W void pyrUp( const InputArray& src, OutputArray dst,
+                         const Size& dstsize=Size());
+
 //! builds the gaussian pyramid using pyrDown() as a basic operation
-CV_EXPORTS void buildPyramid( const Mat& src, CV_OUT vector<Mat>& dst, int maxlevel );
+CV_EXPORTS void buildPyramid( const InputArray& src, OutputArrayOfArrays dst, int maxlevel );
 
 //! corrects lens distortion for the given camera matrix and distortion coefficients
-CV_EXPORTS_W void undistort( const Mat& src, CV_OUT Mat& dst, const Mat& cameraMatrix,
-                           const Mat& distCoeffs, const Mat& newCameraMatrix=Mat() );
+CV_EXPORTS_W void undistort( const InputArray& src, OutputArray dst,
+                             const InputArray& cameraMatrix,
+                             const InputArray& distCoeffs,
+                             const InputArray& newCameraMatrix=InputArray() );
+    
 //! initializes maps for cv::remap() to correct lens distortion and optionally rectify the image
-CV_EXPORTS_W void initUndistortRectifyMap( const Mat& cameraMatrix, const Mat& distCoeffs,
-                           const Mat& R, const Mat& newCameraMatrix,
-                           Size size, int m1type, CV_OUT Mat& map1, CV_OUT Mat& map2 );
+CV_EXPORTS_W void initUndistortRectifyMap( const InputArray& cameraMatrix, const InputArray& distCoeffs,
+                           const InputArray& R, const InputArray& newCameraMatrix,
+                           Size size, int m1type, OutputArray map1, OutputArray map2 );
 
 enum
 {
@@ -614,42 +631,39 @@ enum
 };    
     
 //! initializes maps for cv::remap() for wide-angle
-CV_EXPORTS_W float initWideAngleProjMap( const Mat& cameraMatrix, const Mat& distCoeffs,
-                                       Size imageSize, int destImageWidth,
-                                       int m1type, CV_OUT Mat& map1, CV_OUT Mat& map2,
-                                       int projType=PROJ_SPHERICAL_EQRECT, double alpha=0);
+CV_EXPORTS_W float initWideAngleProjMap( const InputArray& cameraMatrix, const InputArray& distCoeffs,
+                                         Size imageSize, int destImageWidth,
+                                         int m1type, OutputArray map1, OutputArray map2,
+                                         int projType=PROJ_SPHERICAL_EQRECT, double alpha=0);
     
 //! returns the default new camera matrix (by default it is the same as cameraMatrix unless centerPricipalPoint=true)
-CV_EXPORTS_W Mat getDefaultNewCameraMatrix( const Mat& cameraMatrix, Size imgsize=Size(),
-                                          bool centerPrincipalPoint=false );
-//! returns points' coordinates after lens distortion correction
-CV_EXPORTS void undistortPoints( const Mat& src, CV_OUT vector<Point2f>& dst,
-                                 const Mat& cameraMatrix, const Mat& distCoeffs,
-                                 const Mat& R=Mat(), const Mat& P=Mat());
+CV_EXPORTS_W Mat getDefaultNewCameraMatrix( const InputArray& cameraMatrix, Size imgsize=Size(),
+                                            bool centerPrincipalPoint=false );
+    
 //! returns points' coordinates after lens distortion correction
-CV_EXPORTS_W void undistortPoints( const Mat& src, CV_OUT Mat& dst,
-                                 const Mat& cameraMatrix, const Mat& distCoeffs,
-                                 const Mat& R=Mat(), const Mat& P=Mat());
+CV_EXPORTS void undistortPoints( const InputArray& src, OutputArray dst,
+                                 const InputArray& cameraMatrix, const InputArray& distCoeffs,
+                                 const InputArray& R=InputArray(), const InputArray& P=InputArray());
 
 template<> CV_EXPORTS void Ptr<CvHistogram>::delete_obj();
     
 //! computes the joint dense histogram for a set of images.
 CV_EXPORTS void calcHist( const Mat* images, int nimages,
-                          const int* channels, const Mat& mask,
-                          Mat& hist, int dims, const int* histSize,
+                          const int* channels, const InputArray& mask,
+                          OutputArray hist, int dims, const int* histSize,
                           const float** ranges, bool uniform=true, bool accumulate=false );
 
 //! computes the joint sparse histogram for a set of images.
 CV_EXPORTS void calcHist( const Mat* images, int nimages,
-                          const int* channels, const Mat& mask,
+                          const int* channels, const InputArray& mask,
                           SparseMat& hist, int dims,
                           const int* histSize, const float** ranges,
                           bool uniform=true, bool accumulate=false );
 
 //! computes back projection for the set of images
 CV_EXPORTS void calcBackProject( const Mat* images, int nimages,
-                                 const int* channels, const Mat& hist,
-                                 Mat& backProject, const float** ranges,
+                                 const int* channels, const InputArray& hist,
+                                 OutputArray backProject, const float** ranges,
                                  double scale=1, bool uniform=true );
 
 //! computes back projection for the set of images
@@ -659,25 +673,26 @@ CV_EXPORTS void calcBackProject( const Mat* images, int nimages,
                                  double scale=1, bool uniform=true );
 
 //! compares two histograms stored in dense arrays
-CV_EXPORTS_W double compareHist( const Mat& H1, const Mat& H2, int method );
+CV_EXPORTS_W double compareHist( const InputArray& H1, const InputArray& H2, int method );
 
 //! compares two histograms stored in sparse arrays
 CV_EXPORTS double compareHist( const SparseMat& H1, const SparseMat& H2, int method );
 
 //! normalizes the grayscale image brightness and contrast by normalizing its histogram
-CV_EXPORTS_W void equalizeHist( const Mat& src, CV_OUT Mat& dst );
+CV_EXPORTS_W void equalizeHist( const InputArray& src, OutputArray dst );
     
-CV_EXPORTS float EMD( const Mat& signature1, const Mat& signature2,
-                      int distType, const Mat& cost=Mat(),
-                      float* lowerBound=0, Mat* flow=0 );
+CV_EXPORTS float EMD( const InputArray& signature1, const InputArray& signature2,
+                      int distType, const InputArray& cost=InputArray(),
+                      float* lowerBound=0, OutputArray flow=OutputArray() );
 
 //! segments the image using watershed algorithm
-CV_EXPORTS_W void watershed( const Mat& image, Mat& markers );
+CV_EXPORTS_W void watershed( const InputArray& image, InputOutputArray markers );
 
 //! filters image using meanshift algorithm
-CV_EXPORTS_W void pyrMeanShiftFiltering( const Mat& src, CV_OUT Mat& dst,
-                    double sp, double sr, int maxLevel=1,
-                    TermCriteria termcrit=TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS,5,1) );
+CV_EXPORTS_W void pyrMeanShiftFiltering( const InputArray& src, OutputArray dst,
+                                         double sp, double sr, int maxLevel=1,
+                                         TermCriteria termcrit=TermCriteria(
+                                            TermCriteria::MAX_ITER+TermCriteria::EPS,5,1) );
 
 //! class of the pixel in GrabCut algorithm
 enum
@@ -697,9 +712,9 @@ enum
 };
 
 //! segments the image using GrabCut algorithm
-CV_EXPORTS_W void grabCut( const Mat& img, Mat& mask, Rect rect, 
-                         Mat& bgdModel, Mat& fgdModel,
-                         int iterCount, int mode = GC_EVAL );
+CV_EXPORTS_W void grabCut( const InputArray& img, InputOutputArray mask, Rect rect, 
+                           InputOutputArray bgdModel, InputOutputArray fgdModel,
+                           int iterCount, int mode = GC_EVAL );
 
 //! the inpainting algorithm
 enum
@@ -709,35 +724,33 @@ enum
 };
 
 //! restores the damaged image areas using one of the available intpainting algorithms
-CV_EXPORTS_W void inpaint( const Mat& src, const Mat& inpaintMask,
-                         CV_OUT Mat& dst, double inpaintRange, int flags );
+CV_EXPORTS_W void inpaint( const InputArray& src, const InputArray& inpaintMask,
+                           OutputArray dst, double inpaintRange, int flags );
 
 //! builds the discrete Voronoi diagram
-CV_EXPORTS_AS(distanceTransformWithLabels)
-    void distanceTransform( const Mat& src, CV_OUT Mat& dst, Mat& labels,
-                            int distanceType, int maskSize );
+CV_EXPORTS_W void distanceTransform( const InputArray& src, OutputArray dst,
+                                     OutputArray labels, int distanceType, int maskSize );
 
 //! computes the distance transform map
-CV_EXPORTS_W void distanceTransform( const Mat& src, CV_OUT Mat& dst,
+CV_EXPORTS void distanceTransform( const InputArray& src, OutputArray dst,
                                    int distanceType, int maskSize );
 
-enum { FLOODFILL_FIXED_RANGE = 1 << 16,
-       FLOODFILL_MASK_ONLY = 1 << 17 };
+enum { FLOODFILL_FIXED_RANGE = 1 << 16, FLOODFILL_MASK_ONLY = 1 << 17 };
 
 //! fills the semi-uniform image region starting from the specified seed point
-CV_EXPORTS_W int floodFill( Mat& image,
+CV_EXPORTS int floodFill( InputOutputArray image,
                           Point seedPoint, Scalar newVal, CV_OUT Rect* rect=0,
                           Scalar loDiff=Scalar(), Scalar upDiff=Scalar(),
                           int flags=4 );
 
 //! fills the semi-uniform image region and/or the mask starting from the specified seed point
-CV_EXPORTS_AS(floodFillMask) int floodFill( Mat& image, Mat& mask,
-                          Point seedPoint, Scalar newVal, CV_OUT Rect* rect=0,
-                          Scalar loDiff=Scalar(), Scalar upDiff=Scalar(),
-                          int flags=4 );
+CV_EXPORTS_W int floodFill( InputOutputArray image, InputOutputArray mask,
+                            Point seedPoint, Scalar newVal, CV_OUT Rect* rect=0,
+                            Scalar loDiff=Scalar(), Scalar upDiff=Scalar(),
+                            int flags=4 );
 
 //! converts image from one color space to another
-CV_EXPORTS_W void cvtColor( const Mat& src, CV_OUT Mat& dst, int code, int dstCn=0 );
+CV_EXPORTS_W void cvtColor( const InputArray& src, OutputArray dst, int code, int dstCn=0 );
 
 //! raster image moments
 class CV_EXPORTS_W_MAP Moments
@@ -762,7 +775,7 @@ public:
 };
 
 //! computes moments of the rasterized shape or a vector of points
-CV_EXPORTS_W Moments moments( const Mat& array, bool binaryImage=false );
+CV_EXPORTS_W Moments moments( const InputArray& array, bool binaryImage=false );
 
 //! computes 7 Hu invariants from the moments
 CV_EXPORTS void HuMoments( const Moments& moments, double hu[7] );
@@ -771,7 +784,8 @@ CV_EXPORTS void HuMoments( const Moments& moments, double hu[7] );
 enum { TM_SQDIFF=0, TM_SQDIFF_NORMED=1, TM_CCORR=2, TM_CCORR_NORMED=3, TM_CCOEFF=4, TM_CCOEFF_NORMED=5 };
 
 //! computes the proximity map for the raster template and the image where the template is searched for
-CV_EXPORTS_W void matchTemplate( const Mat& image, const Mat& templ, CV_OUT Mat& result, int method );
+CV_EXPORTS_W void matchTemplate( const InputArray& image, const InputArray& templ,
+                                 OutputArray result, int method );
 
 //! mode of the contour retrieval algorithm
 enum
@@ -786,80 +800,64 @@ enum
 enum
 {
     CHAIN_APPROX_NONE=CV_CHAIN_APPROX_NONE,
-       CHAIN_APPROX_SIMPLE=CV_CHAIN_APPROX_SIMPLE,
-       CHAIN_APPROX_TC89_L1=CV_CHAIN_APPROX_TC89_L1,
-       CHAIN_APPROX_TC89_KCOS=CV_CHAIN_APPROX_TC89_KCOS
+    CHAIN_APPROX_SIMPLE=CV_CHAIN_APPROX_SIMPLE,
+    CHAIN_APPROX_TC89_L1=CV_CHAIN_APPROX_TC89_L1,
+    CHAIN_APPROX_TC89_KCOS=CV_CHAIN_APPROX_TC89_KCOS
 };
 
 //! retrieves contours and the hierarchical information from black-n-white image.
-CV_EXPORTS void findContours( Mat& image, CV_OUT vector<vector<Point> >& contours,
-                              vector<Vec4i>& hierarchy, int mode,
+CV_EXPORTS void findContours( InputOutputArray image, OutputArrayOfArrays contours,
+                              OutputArray hierarchy, int mode,
                               int method, Point offset=Point());
 
 //! retrieves contours from black-n-white image.
-CV_EXPORTS void findContours( Mat& image, CV_OUT vector<vector<Point> >& contours,
+CV_EXPORTS void findContours( InputOutputArray image, OutputArrayOfArrays contours,
                               int mode, int method, Point offset=Point());
 
 //! draws contours in the image
-CV_EXPORTS void drawContours( Mat& image, const vector<vector<Point> >& contours,
+CV_EXPORTS void drawContours( InputOutputArray image, const InputArrayOfArrays& contours,
                               int contourIdx, const Scalar& color,
                               int thickness=1, int lineType=8,
-                              const vector<Vec4i>& hierarchy=vector<Vec4i>(),
+                              const InputArray& hierarchy=InputArray(),
                               int maxLevel=INT_MAX, Point offset=Point() );
 
 //! approximates contour or a curve using Douglas-Peucker algorithm
-CV_EXPORTS void approxPolyDP( const Mat& curve,
-                              CV_OUT vector<Point>& approxCurve,
-                              double epsilon, bool closed );
-//! approximates contour or a curve using Douglas-Peucker algorithm
-CV_EXPORTS void approxPolyDP( const Mat& curve,
-                              CV_OUT vector<Point2f>& approxCurve,
+CV_EXPORTS void approxPolyDP( const InputArray& curve,
+                              OutputArray approxCurve,
                               double epsilon, bool closed );
+
 //! computes the contour perimeter (closed=true) or a curve length
-CV_EXPORTS_W double arcLength( const Mat& curve, bool closed );
+CV_EXPORTS_W double arcLength( const InputArray& curve, bool closed );
 //! computes the bounding rectangle for a contour
-CV_EXPORTS_W Rect boundingRect( const Mat& points );
+CV_EXPORTS_W Rect boundingRect( const InputArray& points );
 //! computes the contour area
-CV_EXPORTS_W double contourArea( const Mat& contour, bool oriented=false );
+CV_EXPORTS_W double contourArea( const InputArray& contour, bool oriented=false );
 //! computes the minimal rotated rectangle for a set of points
-CV_EXPORTS_W RotatedRect minAreaRect( const Mat& points );
+CV_EXPORTS_W RotatedRect minAreaRect( const InputArray& points );
 //! computes the minimal enclosing circle for a set of points
-CV_EXPORTS_W void minEnclosingCircle( const Mat& points,
-                                    Point2f& center, float& radius );    
+CV_EXPORTS_W void minEnclosingCircle( const InputArray& points,
+                                      Point2f& center, float& radius );    
 //! matches two contours using one of the available algorithms
-CV_EXPORTS_W double matchShapes( const Mat& contour1,
-                               const Mat& contour2,
-                               int method, double parameter );
-//! computes convex hull for a set of 2D points.
-CV_EXPORTS void convexHull( const Mat& points, CV_OUT vector<int>& hull, bool clockwise=false );
-//! computes convex hull for a set of 2D points.
-CV_EXPORTS void convexHull( const Mat& points, CV_OUT vector<Point>& hull, bool clockwise=false );
+CV_EXPORTS_W double matchShapes( const InputArray& contour1, const InputArray& contour2,
+                                 int method, double parameter );
 //! computes convex hull for a set of 2D points.
-CV_EXPORTS void convexHull( const Mat& points, CV_OUT vector<Point2f>& hull, bool clockwise=false );
+CV_EXPORTS void convexHull( const InputArray& points, OutputArray hull,
+                            bool clockwise=false, bool returnPoints=true );
 
 //! returns true iff the contour is convex. Does not support contours with self-intersection
-CV_EXPORTS_W bool isContourConvex( const Mat& contour );
+CV_EXPORTS_W bool isContourConvex( const InputArray& contour );
 
 //! fits ellipse to the set of 2D points
-CV_EXPORTS_W RotatedRect fitEllipse( const Mat& points );
+CV_EXPORTS_W RotatedRect fitEllipse( const InputArray& points );
 
 //! fits line to the set of 2D points using M-estimator algorithm
-CV_EXPORTS void fitLine( const Mat& points, CV_OUT Vec4f& line, int distType,
-                           double param, double reps, double aeps );
-//! fits line to the set of 3D points using M-estimator algorithm
-CV_EXPORTS void fitLine( const Mat& points, CV_OUT Vec6f& line, int distType,
-                           double param, double reps, double aeps );
+CV_EXPORTS void fitLine( const InputArray& points, OutputArray line, int distType,
+                         double param, double reps, double aeps );
 //! checks if the point is inside the contour. Optionally computes the signed distance from the point to the contour boundary
-CV_EXPORTS_W double pointPolygonTest( const Mat& contour,
-                                    Point2f pt, bool measureDist );
-    
-//! estimates the best-fit affine transformation that maps one 2D point set to another or one image to another.
-CV_EXPORTS_W Mat estimateRigidTransform( const Mat& A, const Mat& B,
-                                       bool fullAffine );
-    
+CV_EXPORTS_W double pointPolygonTest( const InputArray& contour, Point2f pt, bool measureDist );
+        
 }
 
-
 // 2009-01-12, Xavier Delacour <xavier.delacour@gmail.com>
 
 struct lsh_hash {
index f19314b..243a476 100644 (file)
 namespace cv
 {
 
-inline float sqr(uchar a) { return CV_8TO32F_SQR(a); }
-inline float sqr(float a) { return a*a; }
-    
-inline double sqr(double a) { return a*a; }
-    
-inline Vec3f sqr(const Vec3b& a)
-{
-    return Vec3f(CV_8TO32F_SQR(a[0]), CV_8TO32F_SQR(a[1]), CV_8TO32F_SQR(a[2]));
-}
-inline Vec3f sqr(const Vec3f& a)
-{
-    return Vec3f(a[0]*a[0], a[1]*a[1], a[2]*a[2]);
-}
-inline Vec3d sqr(const Vec3d& a)
-{
-    return Vec3d(a[0]*a[0], a[1]*a[1], a[2]*a[2]);
-}   
-inline float multiply(uchar a, uchar b) { return CV_8TO32F(a)*CV_8TO32F(b); }
-inline float multiply(float a, float b) { return a*b; }
-inline double multiply(double a, double b) { return a*b; }    
-inline Vec3f multiply(const Vec3b& a, const Vec3b& b)
-{
-    return Vec3f(
-        CV_8TO32F(a[0])*CV_8TO32F(b[0]),
-        CV_8TO32F(a[1])*CV_8TO32F(b[1]),
-        CV_8TO32F(a[2])*CV_8TO32F(b[2]));
-}
-inline Vec3f multiply(const Vec3f& a, const Vec3f& b)
-{
-    return Vec3f(a[0]*b[0], a[1]*b[1], a[2]*b[2]);
-}
-inline Vec3d multiply(const Vec3d& a, const Vec3d& b)
-{
-    return Vec3d(a[0]*b[0], a[1]*b[1], a[2]*b[2]);
-}
-    
-inline float addw(uchar a, float alpha, float b, float beta)
-{
-    return b*beta + CV_8TO32F(a)*alpha;
-}
-inline float addw(float a, float alpha, float b, float beta)
-{
-    return b*beta + a*alpha;
-}
-inline double addw(uchar a, double alpha, double b, double beta)
-{
-    return b*beta + CV_8TO32F(a)*alpha;
-}
-inline double addw(float a, double alpha, double b, double beta)
-{
-    return b*beta + a*alpha;
-}
-inline double addw(double a, double alpha, double b, double beta)
-{
-    return b*beta + a*alpha;
-}
-    
-inline Vec3f addw(const Vec3b& a, float alpha, const Vec3f& b, float beta)
-{
-    return Vec3f(b[0]*beta + CV_8TO32F(a[0])*alpha,
-                 b[1]*beta + CV_8TO32F(a[1])*alpha,
-                 b[2]*beta + CV_8TO32F(a[2])*alpha);
-}
-inline Vec3f addw(const Vec3f& a, float alpha, const Vec3f& b, float beta)
-{
-    return Vec3f(b[0]*beta + a[0]*alpha, b[1]*beta + a[1]*alpha, b[2]*beta + a[2]*alpha);
-}
-inline Vec3d addw(const Vec3b& a, double alpha, const Vec3d& b, double beta)
-{
-    return Vec3d(b[0]*beta + CV_8TO32F(a[0])*alpha,
-                 b[1]*beta + CV_8TO32F(a[1])*alpha,
-                 b[2]*beta + CV_8TO32F(a[2])*alpha);
-}
-inline Vec3d addw(const Vec3f& a, double alpha, const Vec3d& b, double beta)
-{
-    return Vec3d(b[0]*beta + a[0]*alpha, b[1]*beta + a[1]*alpha, b[2]*beta + a[2]*alpha);
-}
-inline Vec3d addw(const Vec3d& a, double alpha, const Vec3d& b, double beta)
-{
-    return Vec3d(b[0]*beta + a[0]*alpha, b[1]*beta + a[1]*alpha, b[2]*beta + a[2]*alpha);
-}    
-
 template<typename T, typename AT> void
-acc_( const Mat& _src, Mat& _dst )
+acc_( const T* src, AT* dst, const uchar* mask, int len, int cn )
 {
-    Size size = _src.size();
-    size.width *= _src.channels();
-
-    if( _src.isContinuous() && _dst.isContinuous() )
-    {
-        size.width *= size.height;
-        size.height = 1;
-    }
-
-    int i, j;
-    for( i = 0; i < size.height; i++ )
+    int i = 0;
+    
+    if( !mask )
     {
-        const T* src = (const T*)(_src.data + _src.step*i);
-        AT* dst = (AT*)(_dst.data + _dst.step*i);
-
-        for( j = 0; j <= size.width - 4; j += 4 )
+        len *= cn;
+        for( ; i <= len - 4; i += 4 )
         {
-            AT t0 = dst[j] + src[j], t1 = dst[j+1] + src[j+1];
-            dst[j] = t0; dst[j+1] = t1;
-            t0 = dst[j+2] + src[j+2]; t1 = dst[j+3] + src[j+3];
-            dst[j+2] = t0; dst[j+3] = t1;
+            AT t0, t1;
+            t0 = src[i] + dst[i];
+            t1 = src[i+1] + dst[i+1];
+            dst[i] = t0; dst[i+1] = t1;
+            
+            t0 = src[i+2] + dst[i+2];
+            t1 = src[i+3] + dst[i+3];
+            dst[i+2] = t0; dst[i+3] = t1;
         }
-
-        for( ; j < size.width; j++ )
-            dst[j] += src[j];
+        
+        for( ; i < len; i++ )
+            dst[i] += src[i];
     }
-}
-
-
-template<typename T, typename AT> void
-accSqr_( const Mat& _src, Mat& _dst )
-{
-    Size size = _src.size();
-    size.width *= _src.channels();
-
-    if( _src.isContinuous() && _dst.isContinuous() )
+    else if( cn == 1 )
     {
-        size.width *= size.height;
-        size.height = 1;
+        for( ; i < len; i++ )
+        {
+            if( mask[i] )
+                dst[i] += src[i];
+        }
     }
-
-    int i, j;
-    for( i = 0; i < size.height; i++ )
+    else if( cn == 3 )
     {
-        const T* src = (const T*)(_src.data + _src.step*i);
-        AT* dst = (AT*)(_dst.data + _dst.step*i);
-
-        for( j = 0; j <= size.width - 4; j += 4 )
+        for( ; i < len; i++, src += 3, dst += 3 )
         {
-            AT t0 = dst[j] + sqr(src[j]), t1 = dst[j+1] + sqr(src[j+1]);
-            dst[j] = t0; dst[j+1] = t1;
-            t0 = dst[j+2] + sqr(src[j+2]); t1 = dst[j+3] + sqr(src[j+3]);
-            dst[j+2] = t0; dst[j+3] = t1;
+            if( mask[i] )
+            {
+                AT t0 = src[0] + dst[0];
+                AT t1 = src[1] + dst[1];
+                AT t2 = src[2] + dst[2];
+                
+                dst[0] = t0; dst[1] = t1; dst[2] = t2;
+            }
         }
-
-        for( ; j < size.width; j++ )
-            dst[j] += sqr(src[j]);
+    }
+    else
+    {
+        for( ; i < len; i++, src += cn, dst += cn )
+            if( mask[i] )
+            {
+                for( int k = 0; k < cn; k++ )
+                    dst[k] += src[k];
+            }
     }
 }
 
-
+    
 template<typename T, typename AT> void
-accProd_( const Mat& _src1, const Mat& _src2, Mat& _dst )
+accSqr_( const T* src, AT* dst, const uchar* mask, int len, int cn )
 {
-    Size size = _src1.size();
-    size.width *= _src1.channels();
-
-    if( _src1.isContinuous() && _src2.isContinuous() && _dst.isContinuous() )
-    {
-        size.width *= size.height;
-        size.height = 1;
-    }
-
-    int i, j;
-    for( i = 0; i < size.height; i++ )
+    int i = 0;
+    
+    if( !mask )
     {
-        const T* src1 = (const T*)(_src1.data + _src1.step*i);
-        const T* src2 = (const T*)(_src2.data + _src2.step*i);
-        AT* dst = (AT*)(_dst.data + _dst.step*i);
-
-        for( j = 0; j <= size.width - 4; j += 4 )
+        len *= cn;
+        for( ; i <= len - 4; i += 4 )
         {
             AT t0, t1;
-            t0 = dst[j] + multiply(src1[j], src2[j]);
-            t1 = dst[j+1] + multiply(src1[j+1], src2[j+1]);
-            dst[j] = t0; dst[j+1] = t1;
-            t0 = dst[j+2] + multiply(src1[j+2], src2[j+2]);
-            t1 = dst[j+3] + multiply(src1[j+3], src2[j+3]);
-            dst[j+2] = t0; dst[j+3] = t1;
+            t0 = (AT)src[i]*src[i] + dst[i];
+            t1 = (AT)src[i+1]*src[i+1] + dst[i+1];
+            dst[i] = t0; dst[i+1] = t1;
+            
+            t0 = (AT)src[i+2]*src[i+2] + dst[i+2];
+            t1 = (AT)src[i+3]*src[i+3] + dst[i+3];
+            dst[i+2] = t0; dst[i+3] = t1;
         }
-
-        for( ; j < size.width; j++ )
-            dst[j] += multiply(src1[j], src2[j]);
-    }
-}
-
-
-template<typename T, typename AT> void
-accW_( const Mat& _src, Mat& _dst, double _alpha )
-{
-    AT alpha = (AT)_alpha, beta = (AT)(1 - _alpha);
-    Size size = _src.size();
-    size.width *= _src.channels();
-
-    if( _src.isContinuous() && _dst.isContinuous() )
-    {
-        size.width *= size.height;
-        size.height = 1;
+        
+        for( ; i < len; i++ )
+            dst[i] += (AT)src[i]*src[i];
     }
-
-    int i, j;
-    for( i = 0; i < size.height; i++ )
+    else if( cn == 1 )
     {
-        const T* src = (const T*)(_src.data + _src.step*i);
-        AT* dst = (AT*)(_dst.data + _dst.step*i);
-
-        for( j = 0; j <= size.width - 4; j += 4 )
+        for( ; i < len; i++ )
         {
-            AT t0, t1;
-            t0 = addw(src[j], alpha, dst[j], beta);
-            t1 = addw(src[j+1], alpha, dst[j+1], beta);
-            dst[j] = t0; dst[j+1] = t1;
-            t0 = addw(src[j+2], alpha, dst[j+2], beta);
-            t1 = addw(src[j+3], alpha, dst[j+3], beta);
-            dst[j+2] = t0; dst[j+3] = t1;
+            if( mask[i] )
+                dst[i] += (AT)src[i]*src[i];
         }
-
-        for( ; j < size.width; j++ )
-            dst[j] = addw(src[j], alpha, dst[j], beta);
     }
-}
-
-
-template<typename T, typename AT> void
-accMask_( const Mat& _src, Mat& _dst, const Mat& _mask )
-{
-    Size size = _src.size();
-
-    if( _src.isContinuous() && _dst.isContinuous() && _mask.isContinuous() )
+    else if( cn == 3 )
     {
-        size.width *= size.height;
-        size.height = 1;
+        for( ; i < len; i++, src += 3, dst += 3 )
+        {
+            if( mask[i] )
+            {
+                AT t0 = (AT)src[0]*src[0] + dst[0];
+                AT t1 = (AT)src[1]*src[1] + dst[1];
+                AT t2 = (AT)src[2]*src[2] + dst[2];
+                
+                dst[0] = t0; dst[1] = t1; dst[2] = t2;
+            }
+        }
     }
-
-    int i, j;
-    for( i = 0; i < size.height; i++ )
+    else
     {
-        const T* src = (const T*)(_src.data + _src.step*i);
-        AT* dst = (AT*)(_dst.data + _dst.step*i);
-        const uchar* mask = _mask.data + _mask.step*i;
-
-        for( j = 0; j < size.width; j++ )
-            if( mask[j] )
-                dst[j] += src[j];
+        for( ; i < len; i++, src += cn, dst += cn )
+            if( mask[i] )
+            {
+                for( int k = 0; k < cn; k++ )
+                    dst[k] += (AT)src[k]*src[k];
+            }
     }
 }
-
-
+   
+    
 template<typename T, typename AT> void
-accSqrMask_( const Mat& _src, Mat& _dst, const Mat& _mask )
+accProd_( const T* src1, const T* src2, AT* dst, const uchar* mask, int len, int cn )
 {
-    Size size = _src.size();
-
-    if( _src.isContinuous() && _dst.isContinuous() && _mask.isContinuous() )
+    int i = 0;
+    
+    if( !mask )
     {
-        size.width *= size.height;
-        size.height = 1;
+        len *= cn;
+        for( ; i <= len - 4; i += 4 )
+        {
+            AT t0, t1;
+            t0 = (AT)src1[i]*src2[i] + dst[i];
+            t1 = (AT)src1[i+1]*src2[i+1] + dst[i+1];
+            dst[i] = t0; dst[i+1] = t1;
+            
+            t0 = (AT)src1[i+2]*src2[i+2] + dst[i+2];
+            t1 = (AT)src1[i+3]*src2[i+3] + dst[i+3];
+            dst[i+2] = t0; dst[i+3] = t1;
+        }
+        
+        for( ; i < len; i++ )
+            dst[i] += (AT)src1[i]*src2[i];
     }
-
-    int i, j;
-    for( i = 0; i < size.height; i++ )
+    else if( cn == 1 )
     {
-        const T* src = (const T*)(_src.data + _src.step*i);
-        AT* dst = (AT*)(_dst.data + _dst.step*i);
-        const uchar* mask = _mask.data + _mask.step*i;
-
-        for( j = 0; j < size.width; j++ )
-            if( mask[j] )
-                dst[j] += sqr(src[j]);
+        for( ; i < len; i++ )
+        {
+            if( mask[i] )
+                dst[i] += (AT)src1[i]*src2[i];
+        }
     }
-}
-
-
-template<typename T, typename AT> void
-accProdMask_( const Mat& _src1, const Mat& _src2, Mat& _dst, const Mat& _mask )
-{
-    Size size = _src1.size();
-
-    if( _src1.isContinuous() && _src2.isContinuous() &&
-        _dst.isContinuous() && _mask.isContinuous() )
+    else if( cn == 3 )
     {
-        size.width *= size.height;
-        size.height = 1;
+        for( ; i < len; i++, src1 += 3, src2 += 3, dst += 3 )
+        {
+            if( mask[i] )
+            {
+                AT t0 = (AT)src1[0]*src2[0] + dst[0];
+                AT t1 = (AT)src1[1]*src2[1] + dst[1];
+                AT t2 = (AT)src1[2]*src2[2] + dst[2];
+                
+                dst[0] = t0; dst[1] = t1; dst[2] = t2;
+            }
+        }
     }
-
-    int i, j;
-    for( i = 0; i < size.height; i++ )
+    else
     {
-        const T* src1 = (const T*)(_src1.data + _src1.step*i);
-        const T* src2 = (const T*)(_src2.data + _src2.step*i);
-        AT* dst = (AT*)(_dst.data + _dst.step*i);
-        const uchar* mask = _mask.data + _mask.step*i;
-
-        for( j = 0; j < size.width; j++ )
-            if( mask[j] )
-                dst[j] += multiply(src1[j], src2[j]);
+        for( ; i < len; i++, src1 += cn, src2 += cn, dst += cn )
+            if( mask[i] )
+            {
+                for( int k = 0; k < cn; k++ )
+                    dst[k] += (AT)src1[k]*src2[k];
+            }
     }
 }
 
-
+    
 template<typename T, typename AT> void
-accWMask_( const Mat& _src, Mat& _dst, double _alpha, const Mat& _mask )
+accW_( const T* src, AT* dst, const uchar* mask, int len, int cn, double alpha )
 {
-    typedef typename DataType<AT>::channel_type AT1;
-    AT1 alpha = (AT1)_alpha, beta = (AT1)(1 - _alpha);
-    Size size = _src.size();
-
-    if( _src.isContinuous() && _dst.isContinuous() && _mask.isContinuous() )
+    AT a = (AT)alpha, b = 1 - a;
+    int i = 0;
+    
+    if( !mask )
     {
-        size.width *= size.height;
-        size.height = 1;
+        len *= cn;
+        for( ; i <= len - 4; i += 4 )
+        {
+            AT t0, t1;
+            t0 = src[i]*a + dst[i]*b;
+            t1 = src[i+1]*a + dst[i+1]*b;
+            dst[i] = t0; dst[i+1] = t1;
+            
+            t0 = src[i+2]*a + dst[i+2]*b;
+            t1 = src[i+3]*a + dst[i+3]*b;
+            dst[i+2] = t0; dst[i+3] = t1;
+        }
+        
+        for( ; i < len; i++ )
+            dst[i] = src[i]*a + dst[i]*b;
     }
-
-    int i, j;
-    for( i = 0; i < size.height; i++ )
+    else if( cn == 1 )
     {
-        const T* src = (const T*)(_src.data + _src.step*i);
-        AT* dst = (AT*)(_dst.data + _dst.step*i);
-        const uchar* mask = _mask.data + _mask.step*i;
-
-        for( j = 0; j < size.width; j++ )
-            if( mask[j] )
-                dst[j] = addw(src[j], alpha, dst[j], beta);
+        for( ; i < len; i++ )
+        {
+            if( mask[i] )
+                dst[i] = src[i]*a + dst[i]*b;
+        }
     }
-}
-
-
-typedef void (*AccFunc)(const Mat&, Mat&);
-typedef void (*AccMaskFunc)(const Mat&, Mat&, const Mat&);
-typedef void (*AccProdFunc)(const Mat&, const Mat&, Mat&);
-typedef void (*AccProdMaskFunc)(const Mat&, const Mat&, Mat&, const Mat&);
-typedef void (*AccWFunc)(const Mat&, Mat&, double);
-typedef void (*AccWMaskFunc)(const Mat&, Mat&, double, const Mat&);
-
-void accumulate( const Mat& src, Mat& dst, const Mat& mask )
-{
-    CV_Assert( dst.size() == src.size() && dst.channels() == src.channels() );
-
-    if( !mask.data )
+    else if( cn == 3 )
     {
-        AccFunc func = 0;
-        if( src.depth() == CV_8U && dst.depth() == CV_32F )
-            func = acc_<uchar, float>;
-        else if( src.depth() == CV_8U && dst.depth() == CV_64F )
-            func = acc_<uchar, double>;
-        else if( src.depth() == CV_32F && dst.depth() == CV_32F )
-            func = acc_<float, float>;
-        else if( src.depth() == CV_32F && dst.depth() == CV_64F )
-            func = acc_<float, double>;
-        else if( src.depth() == CV_64F && dst.depth() == CV_64F )
-            func = acc_<double, double>;
-        else
-            CV_Error( CV_StsUnsupportedFormat, "" );
-
-        func( src, dst );
+        for( ; i < len; i++, src += 3, dst += 3 )
+        {
+            if( mask[i] )
+            {
+                AT t0 = src[0]*a + dst[0]*b;
+                AT t1 = src[1]*a + dst[1]*b;
+                AT t2 = src[2]*a + dst[2]*b;
+                
+                dst[0] = t0; dst[1] = t1; dst[2] = t2;
+            }
+        }
     }
     else
     {
-        CV_Assert( mask.size() == src.size() && mask.type() == CV_8UC1 );
-
-        AccMaskFunc func = 0;
-        if( src.type() == CV_8UC1 && dst.type() == CV_32FC1 )
-            func = accMask_<uchar, float>;
-        else if( src.type() == CV_8UC3 && dst.type() == CV_32FC3 )
-            func = accMask_<Vec3b, Vec3f>;
-        else if( src.type() == CV_8UC1 && dst.type() == CV_64FC1 )
-            func = accMask_<uchar, double>;
-        else if( src.type() == CV_8UC3 && dst.type() == CV_64FC3 )
-            func = accMask_<Vec3b, Vec3d>;
-        else if( src.type() == CV_32FC1 && dst.type() == CV_32FC1 )
-            func = accMask_<float, float>;
-        else if( src.type() == CV_32FC3 && dst.type() == CV_32FC3 )
-            func = accMask_<Vec3f, Vec3f>;
-        else if( src.type() == CV_32FC1 && dst.type() == CV_64FC1 )
-            func = accMask_<float, double>;
-        else if( src.type() == CV_32FC3 && dst.type() == CV_64FC3 )
-            func = accMask_<Vec3f, Vec3d>;
-        else if( src.type() == CV_64FC1 && dst.type() == CV_64FC1 )
-            func = accMask_<double, double>;
-        else if( src.type() == CV_64FC3 && dst.type() == CV_64FC3 )
-            func = accMask_<Vec3d, Vec3d>;
-        else
-            CV_Error( CV_StsUnsupportedFormat, "" );
-
-        func( src, dst, mask );
+        for( ; i < len; i++, src += cn, dst += cn )
+            if( mask[i] )
+            {
+                for( int k = 0; k < cn; k++ )
+                    dst[k] += src[k]*a + dst[k]*b;
+            }
     }
 }
 
 
-void accumulateSquare( const Mat& src, Mat& dst, const Mat& mask )
+#define DEF_ACC_FUNCS(suffix, type, acctype) \
+static void acc_##suffix(const type* src, acctype* dst, \
+                         const uchar* mask, int len, int cn) \
+{ acc_(src, dst, mask, len, cn); } \
+\
+static void accSqr_##suffix(const type* src, acctype* dst, \
+                            const uchar* mask, int len, int cn) \
+{ accSqr_(src, dst, mask, len, cn); } \
+\
+static void accProd_##suffix(const type* src1, const type* src2, \
+                             acctype* dst, const uchar* mask, int len, int cn) \
+{ accProd_(src1, src2, dst, mask, len, cn); } \
+\
+static void accW_##suffix(const type* src, acctype* dst, \
+                          const uchar* mask, int len, int cn, double alpha) \
+{ accW_(src, dst, mask, len, cn, alpha); }
+
+
+DEF_ACC_FUNCS(8u32f, uchar, float)
+DEF_ACC_FUNCS(8u64f, uchar, double)
+DEF_ACC_FUNCS(16u32f, ushort, float)
+DEF_ACC_FUNCS(16u64f, ushort, double)
+DEF_ACC_FUNCS(32f, float, float)
+DEF_ACC_FUNCS(32f64f, float, double)
+DEF_ACC_FUNCS(64f, double, double)
+    
+    
+typedef void (*AccFunc)(const uchar*, uchar*, const uchar*, int, int);
+typedef void (*AccProdFunc)(const uchar*, const uchar*, uchar*, const uchar*, int, int);
+typedef void (*AccWFunc)(const uchar*, uchar*, const uchar*, int, int, double);
+
+static AccFunc accTab[] =
+{
+    (AccFunc)acc_8u32f, (AccFunc)acc_8u64f,
+    (AccFunc)acc_16u32f, (AccFunc)acc_16u64f,
+    (AccFunc)acc_32f, (AccFunc)acc_32f64f,
+    (AccFunc)acc_64f
+};
+
+static AccFunc accSqrTab[] =
+{
+    (AccFunc)accSqr_8u32f, (AccFunc)accSqr_8u64f,
+    (AccFunc)accSqr_16u32f, (AccFunc)accSqr_16u64f,
+    (AccFunc)accSqr_32f, (AccFunc)accSqr_32f64f,
+    (AccFunc)accSqr_64f
+};
+
+static AccProdFunc accProdTab[] =
+{
+    (AccProdFunc)accProd_8u32f, (AccProdFunc)accProd_8u64f,
+    (AccProdFunc)accProd_16u32f, (AccProdFunc)accProd_16u64f,
+    (AccProdFunc)accProd_32f, (AccProdFunc)accProd_32f64f,
+    (AccProdFunc)accProd_64f
+};
+
+static AccWFunc accWTab[] =
+{
+    (AccWFunc)accW_8u32f, (AccWFunc)accW_8u64f,
+    (AccWFunc)accW_16u32f, (AccWFunc)accW_16u64f,
+    (AccWFunc)accW_32f, (AccWFunc)accW_32f64f,
+    (AccWFunc)accW_64f
+};
+
+inline int getAccTabIdx(int sdepth, int ddepth)
+{
+    return sdepth == CV_8U && ddepth == CV_32F ? 0 :
+           sdepth == CV_8U && ddepth == CV_64F ? 1 :
+           sdepth == CV_16U && ddepth == CV_32F ? 2 :
+           sdepth == CV_16U && ddepth == CV_64F ? 3 :
+           sdepth == CV_32F && ddepth == CV_32F ? 4 :
+           sdepth == CV_32F && ddepth == CV_64F ? 5 :
+           sdepth == CV_64F && ddepth == CV_64F ? 6 : -1;
+}    
+    
+}
+    
+void cv::accumulate( const InputArray& _src, InputOutputArray _dst, const InputArray& _mask )
 {
-    CV_Assert( dst.size() == src.size() && dst.channels() == src.channels() );
+    Mat src = _src.getMat(), dst = _dst.getMat(), mask = _mask.getMat();
+    int sdepth = src.depth(), ddepth = dst.depth(), cn = src.channels();
     
-    if( !mask.data )
-    {
-        AccFunc func = 0;
-        if( src.depth() == CV_8U && dst.depth() == CV_32F )
-            func = accSqr_<uchar, float>;
-        else if( src.depth() == CV_8U && dst.depth() == CV_64F )
-            func = accSqr_<uchar, double>;
-        else if( src.depth() == CV_32F && dst.depth() == CV_32F )
-            func = accSqr_<float, float>;
-        else if( src.depth() == CV_32F && dst.depth() == CV_64F )
-            func = accSqr_<float, double>;
-        else if( src.depth() == CV_64F && dst.depth() == CV_64F )
-            func = accSqr_<double, double>;
-        else
-            CV_Error( CV_StsUnsupportedFormat, "" );
-
-        func( src, dst );
-    }
-    else
-    {
-        CV_Assert( mask.size() == src.size() && mask.type() == CV_8UC1 );
-
-        AccMaskFunc func = 0;
-        if( src.type() == CV_8UC1 && dst.type() == CV_32FC1 )
-            func = accSqrMask_<uchar, float>;
-        else if( src.type() == CV_8UC3 && dst.type() == CV_32FC3 )
-            func = accSqrMask_<Vec3b, Vec3f>;
-        else if( src.type() == CV_8UC1 && dst.type() == CV_64FC1 )
-            func = accSqrMask_<uchar, double>;
-        else if( src.type() == CV_8UC3 && dst.type() == CV_64FC3 )
-            func = accSqrMask_<Vec3b, Vec3d>;
-        else if( src.type() == CV_32FC1 && dst.type() == CV_32FC1 )
-            func = accSqrMask_<float, float>;
-        else if( src.type() == CV_32FC3 && dst.type() == CV_32FC3 )
-            func = accSqrMask_<Vec3f, Vec3f>;
-        else if( src.type() == CV_32FC1 && dst.type() == CV_64FC1 )
-            func = accSqrMask_<float, double>;
-        else if( src.type() == CV_32FC3 && dst.type() == CV_64FC3 )
-            func = accSqrMask_<Vec3f, Vec3d>;
-        else if( src.type() == CV_64FC1 && dst.type() == CV_64FC1 )
-            func = accSqrMask_<double, double>;
-        else if( src.type() == CV_64FC3 && dst.type() == CV_64FC3 )
-            func = accSqrMask_<Vec3d, Vec3d>;
-        else
-            CV_Error( CV_StsUnsupportedFormat, "" );
-
-        func( src, dst, mask );
-    }
+    CV_Assert( dst.size == src.size && dst.channels() == cn );
+    
+    if( !mask.empty() )
+        CV_Assert( mask.size == src.size && mask.type() == CV_8U );
+    
+    int fidx = getAccTabIdx(sdepth, ddepth);
+    AccFunc func = fidx >= 0 ? accTab[fidx] : 0;
+    CV_Assert( func != 0 );
+    
+    const Mat* arrays[] = {&src, &dst, &mask, 0};
+    uchar* ptrs[3];
+    NAryMatIterator it(arrays, ptrs);
+    int len = (int)it.size;
+    
+    for( size_t i = 0; i < it.nplanes; i++, ++it )
+        func(ptrs[0], ptrs[1], ptrs[2], len, cn);
 }
 
 
-void accumulateProduct( const Mat& src1, const Mat& src2, Mat& dst, const Mat& mask )
+void cv::accumulateSquare( const InputArray& _src, InputOutputArray _dst, const InputArray& _mask )
 {
-    CV_Assert( dst.size() == src1.size() && dst.channels() == src1.channels() &&
-               src1.size() == src2.size() && src1.type() == src2.type() );
+    Mat src = _src.getMat(), dst = _dst.getMat(), mask = _mask.getMat();
+    int sdepth = src.depth(), ddepth = dst.depth(), cn = src.channels();
     
-    if( !mask.data )
-    {
-        AccProdFunc func = 0;
-        if( src1.depth() == CV_8U && dst.depth() == CV_32F )
-            func = accProd_<uchar, float>;
-        else if( src1.depth() == CV_8U && dst.depth() == CV_64F )
-            func = accProd_<uchar, double>;
-        else if( src1.depth() == CV_32F && dst.depth() == CV_32F )
-            func = accProd_<float, float>;
-        else if( src1.depth() == CV_32F && dst.depth() == CV_64F )
-            func = accProd_<float, double>;
-        else if( src1.depth() == CV_64F && dst.depth() == CV_64F )
-            func = accProd_<double, double>;
-        else
-            CV_Error( CV_StsUnsupportedFormat, "" );
-
-        func( src1, src2, dst );
-    }
-    else
-    {
-        CV_Assert( mask.size() == src1.size() && mask.type() == CV_8UC1 );
-
-        AccProdMaskFunc func = 0;
-        if( src1.type() == CV_8UC1 && dst.type() == CV_32FC1 )
-            func = accProdMask_<uchar, float>;
-        else if( src1.type() == CV_8UC3 && dst.type() == CV_32FC3 )
-            func = accProdMask_<Vec3b, Vec3f>;
-        else if( src1.type() == CV_8UC1 && dst.type() == CV_64FC1 )
-            func = accProdMask_<uchar, double>;
-        else if( src1.type() == CV_8UC3 && dst.type() == CV_64FC3 )
-            func = accProdMask_<Vec3b, Vec3d>;
-        else if( src1.type() == CV_32FC1 && dst.type() == CV_32FC1 )
-            func = accProdMask_<float, float>;
-        else if( src1.type() == CV_32FC3 && dst.type() == CV_32FC3 )
-            func = accProdMask_<Vec3f, Vec3f>;
-        else if( src1.type() == CV_32FC1 && dst.type() == CV_64FC1 )
-            func = accProdMask_<float, double>;
-        else if( src1.type() == CV_32FC3 && dst.type() == CV_64FC3 )
-            func = accProdMask_<Vec3f, Vec3d>;
-        else if( src1.type() == CV_64FC1 && dst.type() == CV_64FC1 )
-            func = accProdMask_<double, double>;
-        else if( src1.type() == CV_64FC3 && dst.type() == CV_64FC3 )
-            func = accProdMask_<Vec3d, Vec3d>;
-        else
-            CV_Error( CV_StsUnsupportedFormat, "" );
-
-        func( src1, src2, dst, mask );
-    }
+    CV_Assert( dst.size == src.size && dst.channels() == cn );
+    
+    if( !mask.empty() )
+        CV_Assert( mask.size == src.size && mask.type() == CV_8U );
+    
+    int fidx = getAccTabIdx(sdepth, ddepth);
+    AccFunc func = fidx >= 0 ? accSqrTab[fidx] : 0;
+    CV_Assert( func != 0 );
+    
+    const Mat* arrays[] = {&src, &dst, &mask, 0};
+    uchar* ptrs[3];
+    NAryMatIterator it(arrays, ptrs);
+    int len = (int)it.size;
+    
+    for( size_t i = 0; i < it.nplanes; i++, ++it )
+        func(ptrs[0], ptrs[1], ptrs[2], len, cn);
 }
 
-
-void accumulateWeighted( const Mat& src, Mat& dst, double alpha, const Mat& mask )
+void cv::accumulateProduct( const InputArray& _src1, const InputArray& _src2,
+                            InputOutputArray _dst, const InputArray& _mask )
 {
-    CV_Assert( dst.size() == src.size() && dst.channels() == src.channels() );
+    Mat src1 = _src1.getMat(), src2 = _src2.getMat(), dst = _dst.getMat(), mask = _mask.getMat();
+    int sdepth = src1.depth(), ddepth = dst.depth(), cn = src1.channels();
     
-    if( !mask.data )
-    {
-        AccWFunc func = 0;
-        if( src.depth() == CV_8U && dst.depth() == CV_32F )
-            func = accW_<uchar, float>;
-        else if( src.depth() == CV_8U && dst.depth() == CV_64F )
-            func = accW_<uchar, double>;
-        else if( src.depth() == CV_32F && dst.depth() == CV_32F )
-            func = accW_<float, float>;
-        else if( src.depth() == CV_32F && dst.depth() == CV_64F )
-            func = accW_<float, double>;
-        else if( src.depth() == CV_64F && dst.depth() == CV_64F )
-            func = accW_<double, double>;
-        else
-            CV_Error( CV_StsUnsupportedFormat, "" );
-
-        func( src, dst, alpha );
-    }
-    else
-    {
-        CV_Assert( mask.size() == src.size() && mask.type() == CV_8UC1 );
-
-        AccWMaskFunc func = 0;
-        if( src.type() == CV_8UC1 && dst.type() == CV_32FC1 )
-            func = accWMask_<uchar, float>;
-        else if( src.type() == CV_8UC3 && dst.type() == CV_32FC3 )
-            func = accWMask_<Vec3b, Vec3f>;
-        else if( src.type() == CV_8UC1 && dst.type() == CV_64FC1 )
-            func = accWMask_<uchar, double>;
-        else if( src.type() == CV_8UC3 && dst.type() == CV_64FC3 )
-            func = accWMask_<Vec3b, Vec3d>;
-        else if( src.type() == CV_32FC1 && dst.type() == CV_32FC1 )
-            func = accWMask_<float, float>;
-        else if( src.type() == CV_32FC3 && dst.type() == CV_32FC3 )
-            func = accWMask_<Vec3f, Vec3f>;
-        else if( src.type() == CV_32FC1 && dst.type() == CV_64FC1 )
-            func = accWMask_<float, double>;
-        else if( src.type() == CV_32FC3 && dst.type() == CV_64FC3 )
-            func = accWMask_<Vec3f, Vec3d>;
-        else if( src.type() == CV_64FC1 && dst.type() == CV_64FC1 )
-            func = accWMask_<double, double>;
-        else if( src.type() == CV_64FC3 && dst.type() == CV_64FC3 )
-            func = accWMask_<Vec3d, Vec3d>;
-        else
-            CV_Error( CV_StsUnsupportedFormat, "" );
-
-        func( src, dst, alpha, mask );
-    }
+    CV_Assert( src2.size && src1.size && src2.type() == src1.type() );
+    CV_Assert( dst.size == src1.size && dst.channels() == cn );
+    
+    if( !mask.empty() )
+        CV_Assert( mask.size == src1.size && mask.type() == CV_8U );
+    
+    int fidx = getAccTabIdx(sdepth, ddepth);
+    AccProdFunc func = fidx >= 0 ? accProdTab[fidx] : 0;
+    CV_Assert( func != 0 );
+    
+    const Mat* arrays[] = {&src1, &src2, &dst, &mask, 0};
+    uchar* ptrs[4];
+    NAryMatIterator it(arrays, ptrs);
+    int len = (int)it.size;
+    
+    for( size_t i = 0; i < it.nplanes; i++, ++it )
+        func(ptrs[0], ptrs[1], ptrs[2], ptrs[3], len, cn);
 }
 
+
+void cv::accumulateWeighted( const InputArray& _src, CV_IN_OUT InputOutputArray _dst,
+                             double alpha, const InputArray& _mask )
+{
+    Mat src = _src.getMat(), dst = _dst.getMat(), mask = _mask.getMat();
+    int sdepth = src.depth(), ddepth = dst.depth(), cn = src.channels();
+    
+    CV_Assert( dst.size == src.size && dst.channels() == cn );
+    
+    if( !mask.empty() )
+        CV_Assert( mask.size == src.size && mask.type() == CV_8U );
+    
+    int fidx = getAccTabIdx(sdepth, ddepth);
+    AccWFunc func = fidx >= 0 ? accWTab[fidx] : 0;
+    CV_Assert( func != 0 );
+    
+    const Mat* arrays[] = {&src, &dst, &mask, 0};
+    uchar* ptrs[3];
+    NAryMatIterator it(arrays, ptrs);
+    int len = (int)it.size;
+    
+    for( size_t i = 0; i < it.nplanes; i++, ++it )
+        func(ptrs[0], ptrs[1], ptrs[2], len, cn, alpha);
 }
 
 
index 49ed796..bca30be 100644 (file)
@@ -335,14 +335,14 @@ CV_IMPL void cvCanny( const void* srcarr, void* dstarr,
     }
 }
 
-void cv::Canny( const Mat& image, Mat& edges,
+void cv::Canny( const InputArray& image, OutputArray _edges,
                 double threshold1, double threshold2,
                 int apertureSize, bool L2gradient )
 {
-    Mat src = image;
-    edges.create(src.size(), CV_8U);
-    CvMat _src = src, _dst = edges;
-    cvCanny( &_src, &_dst, threshold1, threshold2,
+    Mat src = image.getMat();
+    _edges.create(src.size(), CV_8U);
+    CvMat c_src = src, c_dst = _edges.getMat();
+    cvCanny( &c_src, &c_dst, threshold1, threshold2,
         apertureSize + (L2gradient ? CV_CANNY_L2_GRADIENT : 0));
 }
 
index d830433..bbf033b 100644 (file)
@@ -2618,13 +2618,15 @@ static void Bayer2RGB_VNG_8u( const Mat& srcmat, Mat& dstmat, int code )
     }
 }
 
+}
 
 //////////////////////////////////////////////////////////////////////////////////////////
 //                                   The main function                                  // 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-void cvtColor( const Mat& src, Mat& dst, int code, int dcn )
+void cv::cvtColor( const InputArray& _src, OutputArray _dst, int code, int dcn )
 {
+    Mat src = _src.getMat(), dst;
     Size sz = src.size();
     int scn = src.channels(), depth = src.depth(), bidx;
     
@@ -2638,7 +2640,9 @@ void cvtColor( const Mat& src, Mat& dst, int code, int dcn )
             dcn = code == CV_BGR2BGRA || code == CV_RGB2BGRA || code == CV_BGRA2RGBA ? 4 : 3;
             bidx = code == CV_BGR2BGRA || code == CV_BGRA2BGR ? 0 : 2;
             
-            dst.create( sz, CV_MAKETYPE(depth, dcn));
+            _dst.create( sz, CV_MAKETYPE(depth, dcn));
+            dst = _dst.getMat();
+            
             if( depth == CV_8U )
                 CvtColorLoop(src, dst, RGB2RGB<uchar>(scn, dcn, bidx));
             else if( depth == CV_16U )
@@ -2650,7 +2654,8 @@ void cvtColor( const Mat& src, Mat& dst, int code, int dcn )
         case CV_BGR2BGR565: case CV_BGR2BGR555: case CV_RGB2BGR565: case CV_RGB2BGR555:
         case CV_BGRA2BGR565: case CV_BGRA2BGR555: case CV_RGBA2BGR565: case CV_RGBA2BGR555:
             CV_Assert( (scn == 3 || scn == 4) && depth == CV_8U );
-            dst.create(sz, CV_8UC2);
+            _dst.create(sz, CV_8UC2);
+            dst = _dst.getMat();
         
             CvtColorLoop(src, dst, RGB2RGB5x5(scn,
                       code == CV_BGR2BGR565 || code == CV_BGR2BGR555 ||
@@ -2664,7 +2669,8 @@ void cvtColor( const Mat& src, Mat& dst, int code, int dcn )
         case CV_BGR5652BGRA: case CV_BGR5552BGRA: case CV_BGR5652RGBA: case CV_BGR5552RGBA:
             if(dcn <= 0) dcn = 3;
             CV_Assert( (dcn == 3 || dcn == 4) && scn == 2 && depth == CV_8U );
-            dst.create(sz, CV_MAKETYPE(depth, dcn));
+            _dst.create(sz, CV_MAKETYPE(depth, dcn));
+            dst = _dst.getMat();
             
             CvtColorLoop(src, dst, RGB5x52RGB(dcn,
                       code == CV_BGR5652BGR || code == CV_BGR5552BGR ||
@@ -2676,7 +2682,9 @@ void cvtColor( const Mat& src, Mat& dst, int code, int dcn )
                     
         case CV_BGR2GRAY: case CV_BGRA2GRAY: case CV_RGB2GRAY: case CV_RGBA2GRAY:
             CV_Assert( scn == 3 || scn == 4 );
-            dst.create(sz, CV_MAKETYPE(depth, 1));
+            _dst.create(sz, CV_MAKETYPE(depth, 1));
+            dst = _dst.getMat();
+            
             bidx = code == CV_BGR2GRAY || code == CV_BGRA2GRAY ? 0 : 2;
             
             if( depth == CV_8U )
@@ -2689,14 +2697,17 @@ void cvtColor( const Mat& src, Mat& dst, int code, int dcn )
         
         case CV_BGR5652GRAY: case CV_BGR5552GRAY:
             CV_Assert( scn == 2 && depth == CV_8U );
-            dst.create(sz, CV_8UC1);
+            _dst.create(sz, CV_8UC1);
+            dst = _dst.getMat();
+            
             CvtColorLoop(src, dst, RGB5x52Gray(code == CV_BGR5652GRAY ? 6 : 5));
             break;
         
         case CV_GRAY2BGR: case CV_GRAY2BGRA:
             if( dcn <= 0 ) dcn = 3;
             CV_Assert( scn == 1 && (dcn == 3 || dcn == 4));
-            dst.create(sz, CV_MAKETYPE(depth, dcn));
+            _dst.create(sz, CV_MAKETYPE(depth, dcn));
+            dst = _dst.getMat();
             
             if( depth == CV_8U )
                 CvtColorLoop(src, dst, Gray2RGB<uchar>(dcn));
@@ -2708,7 +2719,8 @@ void cvtColor( const Mat& src, Mat& dst, int code, int dcn )
             
         case CV_GRAY2BGR565: case CV_GRAY2BGR555:
             CV_Assert( scn == 1 && depth == CV_8U );
-            dst.create(sz, CV_8UC2);
+            _dst.create(sz, CV_8UC2);
+            dst = _dst.getMat();
             
             CvtColorLoop(src, dst, Gray2RGB5x5(code == CV_GRAY2BGR565 ? 6 : 5));
             break;
@@ -2723,7 +2735,8 @@ void cvtColor( const Mat& src, Mat& dst, int code, int dcn )
             const float* coeffs_f = code == CV_BGR2YCrCb || code == CV_RGB2YCrCb ? 0 : yuv_f;
             const int* coeffs_i = code == CV_BGR2YCrCb || code == CV_RGB2YCrCb ? 0 : yuv_i;
                 
-            dst.create(sz, CV_MAKETYPE(depth, 3));
+            _dst.create(sz, CV_MAKETYPE(depth, 3));
+            dst = _dst.getMat();
             
             if( depth == CV_8U )
                 CvtColorLoop(src, dst, RGB2YCrCb_i<uchar>(scn, bidx, coeffs_i));
@@ -2745,7 +2758,8 @@ void cvtColor( const Mat& src, Mat& dst, int code, int dcn )
             const float* coeffs_f = code == CV_YCrCb2BGR || code == CV_YCrCb2RGB ? 0 : yuv_f;
             const int* coeffs_i = code == CV_YCrCb2BGR || code == CV_YCrCb2RGB ? 0 : yuv_i;
             
-            dst.create(sz, CV_MAKETYPE(depth, dcn));
+            _dst.create(sz, CV_MAKETYPE(depth, dcn));
+            dst = _dst.getMat();
             
             if( depth == CV_8U )
                 CvtColorLoop(src, dst, YCrCb2RGB_i<uchar>(dcn, bidx, coeffs_i));
@@ -2760,7 +2774,8 @@ void cvtColor( const Mat& src, Mat& dst, int code, int dcn )
             CV_Assert( scn == 3 || scn == 4 );
             bidx = code == CV_BGR2XYZ ? 0 : 2;
             
-            dst.create(sz, CV_MAKETYPE(depth, 3));
+            _dst.create(sz, CV_MAKETYPE(depth, 3));
+            dst = _dst.getMat();
             
             if( depth == CV_8U )
                 CvtColorLoop(src, dst, RGB2XYZ_i<uchar>(scn, bidx, 0));
@@ -2775,7 +2790,8 @@ void cvtColor( const Mat& src, Mat& dst, int code, int dcn )
             CV_Assert( scn == 3 && (dcn == 3 || dcn == 4) );
             bidx = code == CV_XYZ2BGR ? 0 : 2;
             
-            dst.create(sz, CV_MAKETYPE(depth, dcn));
+            _dst.create(sz, CV_MAKETYPE(depth, dcn));
+            dst = _dst.getMat();
             
             if( depth == CV_8U )
                 CvtColorLoop(src, dst, XYZ2RGB_i<uchar>(dcn, bidx, 0));
@@ -2794,8 +2810,9 @@ void cvtColor( const Mat& src, Mat& dst, int code, int dcn )
             int hrange = depth == CV_32F ? 360 : code == CV_BGR2HSV || code == CV_RGB2HSV ||
                 code == CV_BGR2HLS || code == CV_RGB2HLS ? 180 : 255;
             
-            dst.create(sz, CV_MAKETYPE(depth, 3));
-            
+            _dst.create(sz, CV_MAKETYPE(depth, 3));
+            dst = _dst.getMat();
+                
             if( code == CV_BGR2HSV || code == CV_RGB2HSV ||
                 code == CV_BGR2HSV_FULL || code == CV_RGB2HSV_FULL )
             {
@@ -2824,8 +2841,9 @@ void cvtColor( const Mat& src, Mat& dst, int code, int dcn )
             int hrange = depth == CV_32F ? 360 : code == CV_HSV2BGR || code == CV_HSV2RGB ||
                 code == CV_HLS2BGR || code == CV_HLS2RGB ? 180 : 255;
             
-            dst.create(sz, CV_MAKETYPE(depth, dcn));
-            
+            _dst.create(sz, CV_MAKETYPE(depth, dcn));
+            dst = _dst.getMat();
+                
             if( code == CV_HSV2BGR || code == CV_HSV2RGB ||
                 code == CV_HSV2BGR_FULL || code == CV_HSV2RGB_FULL )
             {
@@ -2853,8 +2871,9 @@ void cvtColor( const Mat& src, Mat& dst, int code, int dcn )
             bool srgb = code == CV_BGR2Lab || code == CV_RGB2Lab ||
                         code == CV_BGR2Luv || code == CV_RGB2Luv;
             
-            dst.create(sz, CV_MAKETYPE(depth, 3));
-            
+            _dst.create(sz, CV_MAKETYPE(depth, 3));
+            dst = _dst.getMat();
+                
             if( code == CV_BGR2Lab || code == CV_RGB2Lab ||
                 code == CV_LBGR2Lab || code == CV_LRGB2Lab )
             {
@@ -2883,8 +2902,9 @@ void cvtColor( const Mat& src, Mat& dst, int code, int dcn )
             bool srgb = code == CV_Lab2BGR || code == CV_Lab2RGB ||
                     code == CV_Luv2BGR || code == CV_Luv2RGB;
             
-            dst.create(sz, CV_MAKETYPE(depth, dcn));
-            
+            _dst.create(sz, CV_MAKETYPE(depth, dcn));
+            dst = _dst.getMat();
+                
             if( code == CV_Lab2BGR || code == CV_Lab2RGB ||
                 code == CV_Lab2LBGR || code == CV_Lab2LRGB )
             {
@@ -2906,7 +2926,10 @@ void cvtColor( const Mat& src, Mat& dst, int code, int dcn )
         case CV_BayerBG2GRAY: case CV_BayerGB2GRAY: case CV_BayerRG2GRAY: case CV_BayerGR2GRAY:
             if(dcn <= 0) dcn = 1;
             CV_Assert( scn == 1 && dcn == 1 && depth == CV_8U );
-            dst.create(sz, depth);
+            
+            _dst.create(sz, depth);
+            dst = _dst.getMat();
+            
             Bayer2Gray_8u(src, dst, code);
             break;    
             
@@ -2914,7 +2937,9 @@ void cvtColor( const Mat& src, Mat& dst, int code, int dcn )
         case CV_BayerBG2BGR_VNG: case CV_BayerGB2BGR_VNG: case CV_BayerRG2BGR_VNG: case CV_BayerGR2BGR_VNG:
             if(dcn <= 0) dcn = 3;
             CV_Assert( scn == 1 && dcn == 3 && depth == CV_8U );
-            dst.create(sz, CV_MAKETYPE(depth, dcn));
+            
+            _dst.create(sz, CV_MAKETYPE(depth, dcn));
+            dst = _dst.getMat();
             
             if( code == CV_BayerBG2BGR || code == CV_BayerGB2BGR ||
                 code == CV_BayerRG2BGR || code == CV_BayerGR2BGR )
@@ -2926,8 +2951,6 @@ void cvtColor( const Mat& src, Mat& dst, int code, int dcn )
             CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" );
     }
 }
-
-}
     
 CV_IMPL void
 cvCvtColor( const CvArr* srcarr, CvArr* dstarr, int code )
index 3aa37ff..bc57a01 100644 (file)
@@ -1469,37 +1469,40 @@ cvFindContours( void*  img,  CvMemStorage*  storage,
     return count;
 }
 
-namespace cv
-{
-static void
-_findContours( Mat& image, vector<vector<Point> >& contours,
-               vector<Vec4i>* hierarchy, int mode, int method, Point offset )
+void cv::findContours( const InputOutputArray _image, OutputArrayOfArrays _contours,
+                   OutputArray _hierarchy, int mode, int method, Point offset )
 {
+    Mat image = _image.getMat();
     MemStorage storage(cvCreateMemStorage());
-    CvMat _image = image;
-    CvSeq* _contours = 0;
-    if( hierarchy )
-        hierarchy->clear();
-    cvFindContours(&_image, storage, &_contours, sizeof(CvContour), mode, method, offset);
-    if( !_contours )
+    CvMat _cimage = image;
+    CvSeq* _ccontours = 0;
+    if( _hierarchy.needed() )
+        _hierarchy.clear();
+    cvFindContours(&_cimage, storage, &_ccontours, sizeof(CvContour), mode, method, offset);
+    if( !_ccontours )
     {
-        contours.clear();
+        _contours.clear();
         return;
     }
-    Seq<CvSeq*> all_contours(cvTreeToNodeSeq( _contours, sizeof(CvSeq), storage ));
+    Seq<CvSeq*> all_contours(cvTreeToNodeSeq( _ccontours, sizeof(CvSeq), storage ));
     size_t i, total = all_contours.size();
-    contours.resize(total);
+    _contours.create(total, 1, 0, -1, true);
     SeqIterator<CvSeq*> it = all_contours.begin();
     for( i = 0; i < total; i++, ++it )
     {
         CvSeq* c = *it;
         ((CvContour*)c)->color = (int)i;
-        Seq<Point>(c).copyTo(contours[i]);
+        _contours.create(c->total, 1, CV_32SC2, i, true);
+        Mat ci = _contours.getMat(i);
+        CV_Assert( ci.isContinuous() );
+        cvCvtSeqToArray(c, ci.data);
     }
 
-    if( hierarchy )
+    if( _hierarchy.needed() )
     {
-        hierarchy->resize(total);
+        _hierarchy.create(1, total, CV_32SC4, -1, true);
+        Vec4i* hierarchy = _hierarchy.getMat().ptr<Vec4i>();
+        
         it = all_contours.begin();
         for( i = 0; i < total; i++, ++it )
         {
@@ -1508,62 +1511,57 @@ _findContours( Mat& image, vector<vector<Point> >& contours,
             int h_prev = c->h_prev ? ((CvContour*)c->h_prev)->color : -1;
             int v_next = c->v_next ? ((CvContour*)c->v_next)->color : -1;
             int v_prev = c->v_prev ? ((CvContour*)c->v_prev)->color : -1;
-            (*hierarchy)[i] = Vec4i(h_next, h_prev, v_next, v_prev);
+            hierarchy[i] = Vec4i(h_next, h_prev, v_next, v_prev);
         }
     }
 }
-}
 
-void cv::findContours( Mat& image, vector<vector<Point> >& contours,
-                   vector<Vec4i>& hierarchy, int mode, int method, Point offset )
+void cv::findContours( InputOutputArray _image, OutputArrayOfArrays _contours,
+                       int mode, int method, Point offset)
 {
-    _findContours(image, contours, &hierarchy, mode, method, offset);
-}
-
-void cv::findContours( Mat& image, vector<vector<Point> >& contours,
-                   int mode, int method, Point offset)
-{
-    _findContours(image, contours, 0, mode, method, offset);
+    findContours(_image, _contours, OutputArrayOfArrays(), mode, method, offset);
 }
 
 namespace cv
 {
 
-static void addChildContour(const vector<vector<Point> >& contours,
-                            const vector<Vec4i>& hierarchy,
+static void addChildContour(const InputArrayOfArrays& contours,
+                            size_t ncontours,
+                            const Vec4i* hierarchy,
                             int i, vector<CvSeq>& seq,
                             vector<CvSeqBlock>& block)
 {
-    size_t count = contours.size();
     for( ; i >= 0; i = hierarchy[i][0] )
     {
-        const vector<Point>& ci = contours[i];
+        Mat ci = contours.getMat(i);
         cvMakeSeqHeaderForArray(CV_SEQ_POLYGON, sizeof(CvSeq), sizeof(Point),
-                                !ci.empty() ? (void*)&ci[0] : 0, (int)ci.size(),
+                                !ci.empty() ? (void*)ci.data : 0, (int)ci.total(),
                                 &seq[i], &block[i] );
         
         int h_next = hierarchy[i][0], h_prev = hierarchy[i][1],
             v_next = hierarchy[i][2], v_prev = hierarchy[i][3];
-        seq[i].h_next = (size_t)h_next < count ? &seq[h_next] : 0;
-        seq[i].h_prev = (size_t)h_prev < count ? &seq[h_prev] : 0;
-        seq[i].v_next = (size_t)v_next < count ? &seq[v_next] : 0;
-        seq[i].v_prev = (size_t)v_prev < count ? &seq[v_prev] : 0;
+        seq[i].h_next = (size_t)h_next < ncontours ? &seq[h_next] : 0;
+        seq[i].h_prev = (size_t)h_prev < ncontours ? &seq[h_prev] : 0;
+        seq[i].v_next = (size_t)v_next < ncontours ? &seq[v_next] : 0;
+        seq[i].v_prev = (size_t)v_prev < ncontours ? &seq[v_prev] : 0;
         
         if( v_next >= 0 )
-            addChildContour(contours, hierarchy, v_next, seq, block);
+            addChildContour(contours, ncontours, hierarchy, v_next, seq, block);
     }
 }
     
 }
 
-void cv::drawContours( Mat& image, const vector<vector<Point> >& contours,
+void cv::drawContours( InputOutputArray _image, const InputArrayOfArrays& _contours,
                    int contourIdx, const Scalar& color, int thickness,
-                   int lineType, const vector<Vec4i>& hierarchy,
+                   int lineType, const InputArray& _hierarchy,
                    int maxLevel, Point offset )
 {
-    CvMat _image = image;
+    Mat image = _image.getMat(), hierarchy = _hierarchy.getMat();
+    CvMat _cimage = image;
 
-    size_t i = 0, first = 0, last = contours.size();
+    size_t ncontours = _contours.total();
+    size_t i = 0, first = 0, last = ncontours;
     vector<CvSeq> seq;
     vector<CvSeqBlock> block;
 
@@ -1585,9 +1583,13 @@ void cv::drawContours( Mat& image, const vector<vector<Point> >& contours,
     
     for( i = first; i < last; i++ )
     {
-        const vector<Point>& ci = contours[i];
-        cvMakeSeqHeaderForArray(CV_SEQ_POLYGON, sizeof(CvSeq), sizeof(Point),
-            !ci.empty() ? (void*)&ci[0] : 0, (int)ci.size(), &seq[i], &block[i] );
+        Mat ci = _contours.getMat(i);
+        if( ci.empty() )
+            continue;
+        int npoints = ci.checkVector(2, CV_32S);
+        CV_Assert( npoints > 0 );
+        cvMakeSeqHeaderForArray( CV_SEQ_POLYGON, sizeof(CvSeq), sizeof(Point),
+                                 ci.data, npoints, &seq[i], &block[i] );
     }
 
     if( hierarchy.empty() || maxLevel == 0 )
@@ -1599,13 +1601,15 @@ void cv::drawContours( Mat& image, const vector<vector<Point> >& contours,
     else
     {
         size_t count = last - first;
-        CV_Assert(hierarchy.size() == contours.size());
-        if( count == contours.size() )
+        CV_Assert(hierarchy.total() == ncontours && hierarchy.type() == CV_32SC4 );
+        const Vec4i* h = hierarchy.ptr<Vec4i>();
+        
+        if( count == ncontours )
         {
             for( i = first; i < last; i++ )
             {
-                int h_next = hierarchy[i][0], h_prev = hierarchy[i][1],
-                    v_next = hierarchy[i][2], v_prev = hierarchy[i][3];
+                int h_next = h[i][0], h_prev = h[i][1],
+                    v_next = h[i][2], v_prev = h[i][3];
                 seq[i].h_next = (size_t)h_next < count ? &seq[h_next] : 0;
                 seq[i].h_prev = (size_t)h_prev < count ? &seq[h_prev] : 0;
                 seq[i].v_next = (size_t)v_next < count ? &seq[v_next] : 0;
@@ -1614,85 +1618,88 @@ void cv::drawContours( Mat& image, const vector<vector<Point> >& contours,
         }
         else
         {
-            int child = hierarchy[first][2];
+            int child = h[first][2];
             if( child >= 0 )
             {
-                addChildContour(contours, hierarchy, child, seq, block);
+                addChildContour(_contours, ncontours, h, child, seq, block);
                 seq[first].v_next = &seq[child];
             }
         }
     }
 
-    cvDrawContours( &_image, &seq[first], color, color, contourIdx >= 0 ?
+    cvDrawContours( &_cimage, &seq[first], color, color, contourIdx >= 0 ?
                    -maxLevel : maxLevel, thickness, lineType, offset );
 }
 
 
-void cv::approxPolyDP( const Mat& curve, vector<Point>& approxCurve,
+void cv::approxPolyDP( const InputArray& _curve, OutputArray _approxCurve,
                        double epsilon, bool closed )
 {
-    CV_Assert(curve.checkVector(2, CV_32S) >= 0);
-    CvMat _curve = curve;
+    Mat curve = _curve.getMat();
+    int npoints = curve.checkVector(2), depth = curve.depth();
+    CV_Assert( npoints >= 0 && (depth == CV_32S || depth == CV_32F));
+    CvMat _ccurve = curve;
     MemStorage storage(cvCreateMemStorage());
-    Seq<Point> seq(cvApproxPoly(&_curve, sizeof(CvContour), storage, CV_POLY_APPROX_DP, epsilon, closed));
-    seq.copyTo(approxCurve);
+    CvSeq* result = cvApproxPoly(&_ccurve, sizeof(CvContour), storage, CV_POLY_APPROX_DP, epsilon, closed);
+    if( result->total > 0 )
+    {
+        _approxCurve.create(result->total, 1, CV_MAKETYPE(curve.depth(), 2), -1, true);
+        cvCvtSeqToArray(result, _approxCurve.getMat().data );
+    }
 }
 
-void cv::approxPolyDP( const Mat& curve, vector<Point2f>& approxCurve,
-                       double epsilon, bool closed )
-{
-    CV_Assert(curve.checkVector(2, CV_32F) >= 0);
-    CvMat _curve = curve;
-    MemStorage storage(cvCreateMemStorage());
-    Seq<Point2f> seq(cvApproxPoly(&_curve, sizeof(CvContour), storage, CV_POLY_APPROX_DP, epsilon, closed));
-    seq.copyTo(approxCurve);
-}
 
-double cv::arcLength( const Mat& curve, bool closed )
+double cv::arcLength( const InputArray& _curve, bool closed )
 {
+    Mat curve = _curve.getMat();
     CV_Assert(curve.checkVector(2) >= 0 && (curve.depth() == CV_32F || curve.depth() == CV_32S));
-    CvMat _curve = curve;
-    return cvArcLength(&_curve, CV_WHOLE_SEQ, closed);
+    CvMat _ccurve = curve;
+    return cvArcLength(&_ccurve, CV_WHOLE_SEQ, closed);
 }
 
 
-cv::Rect cv::boundingRect( const Mat& points )
+cv::Rect cv::boundingRect( const InputArray& _points )
 {
+    Mat points = _points.getMat();
     CV_Assert(points.checkVector(2) >= 0 && (points.depth() == CV_32F || points.depth() == CV_32S));
-    CvMat _points = points;
-    return cvBoundingRect(&_points, 0);
+    CvMat _cpoints = points;
+    return cvBoundingRect(&_cpoints, 0);
 }
 
 
-double cv::contourArea( const Mat& contour, bool oriented )
+double cv::contourArea( const InputArray& _contour, bool oriented )
 {
+    Mat contour = _contour.getMat();
     CV_Assert(contour.checkVector(2) >= 0 && (contour.depth() == CV_32F || contour.depth() == CV_32S));
-    CvMat _contour = contour;
-    return cvContourArea(&_contour, CV_WHOLE_SEQ, oriented);
+    CvMat _ccontour = contour;
+    return cvContourArea(&_ccontour, CV_WHOLE_SEQ, oriented);
 }
 
 
-cv::RotatedRect cv::minAreaRect( const Mat& points )
+cv::RotatedRect cv::minAreaRect( const InputArray& _points )
 {
+    Mat points = _points.getMat();
     CV_Assert(points.checkVector(2) >= 0 && (points.depth() == CV_32F || points.depth() == CV_32S));
-    CvMat _points = points;
-    return cvMinAreaRect2(&_points, 0);
+    CvMat _cpoints = points;
+    return cvMinAreaRect2(&_cpoints, 0);
 }
 
 
-void cv::minEnclosingCircle( const Mat& points,
+void cv::minEnclosingCircle( const InputArray& _points,
                              Point2f& center, float& radius )
 {
+    Mat points = _points.getMat();
     CV_Assert(points.checkVector(2) >= 0 && (points.depth() == CV_32F || points.depth() == CV_32S));
-    CvMat _points = points;
-    cvMinEnclosingCircle( &_points, (CvPoint2D32f*)&center, &radius );
+    CvMat _cpoints = points;
+    cvMinEnclosingCircle( &_cpoints, (CvPoint2D32f*)&center, &radius );
 }
 
 
-double cv::matchShapes( const Mat& contour1,
-                        const Mat& contour2,
+double cv::matchShapes( const InputArray& _contour1,
+                        const InputArray& _contour2,
                         int method, double parameter )
 {
+    Mat contour1 = _contour1.getMat(), contour2 = _contour2.getMat();
     CV_Assert(contour1.checkVector(2) >= 0 && contour2.checkVector(2) >= 0 &&
               (contour1.depth() == CV_32F || contour1.depth() == CV_32S) &&
               contour1.depth() == contour2.depth());
@@ -1702,79 +1709,68 @@ double cv::matchShapes( const Mat& contour1,
 }
 
 
-void cv::convexHull( const Mat& points, vector<int>& hull, bool clockwise )
-{
-    int nelems = points.checkVector(2);
-    CV_Assert(nelems >= 0 && (points.depth() == CV_32F || points.depth() == CV_32S));
-    hull.resize(nelems);
-    CvMat _points = Mat(points), _hull=Mat(hull);
-    cvConvexHull2(&_points, &_hull, clockwise ? CV_CLOCKWISE : CV_COUNTER_CLOCKWISE, 0);
-    hull.resize(_hull.cols + _hull.rows - 1);
-}
-
-
-void cv::convexHull( const Mat& points,
-                     vector<Point>& hull, bool clockwise )
-{
-    int nelems = points.checkVector(2, CV_32S);
-    CV_Assert(nelems >= 0);
-    hull.resize(nelems);
-    CvMat _points = Mat(points), _hull=Mat(hull);
-    cvConvexHull2(&_points, &_hull, clockwise ? CV_CLOCKWISE : CV_COUNTER_CLOCKWISE, 1);
-    hull.resize(_hull.cols + _hull.rows - 1);
-}
-
-
-void cv::convexHull( const Mat& points,
-                     vector<Point2f>& hull, bool clockwise )
+void cv::convexHull( const InputArray& _points, OutputArray _hull, bool clockwise, bool returnPoints )
 {
-    int nelems = points.checkVector(2, CV_32F);
-    CV_Assert(nelems >= 0);
-    hull.resize(nelems);
-    CvMat _points = Mat(points), _hull=Mat(hull);
-    cvConvexHull2(&_points, &_hull, clockwise ? CV_CLOCKWISE : CV_COUNTER_CLOCKWISE, 1);
-    hull.resize(_hull.cols + _hull.rows - 1);
+    Mat points = _points.getMat();
+    int nelems = points.checkVector(2), depth = points.depth();
+    CV_Assert(nelems >= 0 && (depth == CV_32F || depth == CV_32S));
+    
+    if( nelems == 0 )
+    {
+        _hull.release();
+        return;
+    }
+    
+    returnPoints = !_hull.fixedType() ? returnPoints : _hull.type() != CV_32S;
+    Mat hull(nelems, 1, returnPoints ? CV_MAKETYPE(depth, 2) : CV_32S);
+    CvMat _cpoints = points, _chull = hull;
+    cvConvexHull2(&_cpoints, &_chull, clockwise ? CV_CLOCKWISE : CV_COUNTER_CLOCKWISE, returnPoints);
+    _hull.create(_chull.rows, 1, hull.type(), -1, true);
+    Mat dhull = _hull.getMat(), shull(dhull.size(), dhull.type(), hull.data);
+    shull.copyTo(dhull);
 }
 
-bool cv::isContourConvex( const Mat& contour )
+bool cv::isContourConvex( const InputArray& _contour )
 {
+    Mat contour = _contour.getMat();
     CV_Assert(contour.checkVector(2) >= 0 &&
               (contour.depth() == CV_32F || contour.depth() == CV_32S));
     CvMat c = Mat(contour);
     return cvCheckContourConvexity(&c) > 0;
 }
 
-cv::RotatedRect cv::fitEllipse( const Mat& points )
+cv::RotatedRect cv::fitEllipse( const InputArray& _points )
 {
+    Mat points = _points.getMat();
     CV_Assert(points.checkVector(2) >= 0 &&
               (points.depth() == CV_32F || points.depth() == CV_32S));
-    CvMat _points = points;
-    return cvFitEllipse2(&_points);
+    CvMat _cpoints = points;
+    return cvFitEllipse2(&_cpoints);
 }
 
 
-void cv::fitLine( const Mat& points, Vec4f& line, int distType,
+void cv::fitLine( const InputArray& _points, OutputArray _line, int distType,
                   double param, double reps, double aeps )
 {
-    CV_Assert(points.checkVector(2) >= 0 &&
-              (points.depth() == CV_32F || points.depth() == CV_32S));
-    CvMat _points = points;
-    cvFitLine(&_points, distType, param, reps, aeps, &line[0]);
+    Mat points = _points.getMat();
+    bool is3d = points.checkVector(3) >= 0, is2d = is3d ? false : points.checkVector(2) >= 0;
+    
+    CV_Assert((is2d || is3d) && (points.depth() == CV_32F || points.depth() == CV_32S));
+    CvMat _cpoints = points;
+    float line[6];
+    cvFitLine(&_cpoints, distType, param, reps, aeps, &line[0]);
+    
+    _line.create(is2d ? 4 : 6, 1, CV_32F, -1, true);
+    Mat l = _line.getMat();
+    CV_Assert( l.isContinuous() );
+    memcpy( l.data, line, (is2d ? 4 : 6)*sizeof(line[0]) );
 }
 
 
-void cv::fitLine( const Mat& points, Vec6f& line, int distType,
-                  double param, double reps, double aeps )
-{
-    CV_Assert(points.checkVector(3) >= 0 &&
-              (points.depth() == CV_32F || points.depth() == CV_32S));
-    CvMat _points = points;
-    cvFitLine(&_points, distType, param, reps, aeps, &line[0]);
-}
-
-double cv::pointPolygonTest( const Mat& contour,
+double cv::pointPolygonTest( const InputArray& _contour,
                              Point2f pt, bool measureDist )
 {
+    Mat contour = _contour.getMat();
     CV_Assert(contour.checkVector(2) >= 0 &&
               (contour.depth() == CV_32F || contour.depth() == CV_32S));
     CvMat c = Mat(contour);
index 31a1351..469f6aa 100644 (file)
@@ -297,36 +297,47 @@ cornerEigenValsVecs( const Mat& src, Mat& eigenv, int block_size,
         calcEigenValsVecs( cov, eigenv );
 }
 
+}
 
-void cornerMinEigenVal( const Mat& src, Mat& dst, int blockSize, int ksize, int borderType )
+void cv::cornerMinEigenVal( const InputArray& _src, OutputArray _dst, int blockSize, int ksize, int borderType )
 {
-    dst.create( src.size(), CV_32F );
+    Mat src = _src.getMat();
+    _dst.create( src.size(), CV_32F );
+    Mat dst = _dst.getMat();
     cornerEigenValsVecs( src, dst, blockSize, ksize, MINEIGENVAL, 0, borderType );
 }
 
 
-void cornerHarris( const Mat& src, Mat& dst, int blockSize, int ksize, double k, int borderType )
+void cv::cornerHarris( const InputArray& _src, OutputArray _dst, int blockSize, int ksize, double k, int borderType )
 {
-    dst.create( src.size(), CV_32F );
+    Mat src = _src.getMat();
+    _dst.create( src.size(), CV_32F );
+    Mat dst = _dst.getMat();
     cornerEigenValsVecs( src, dst, blockSize, ksize, HARRIS, k, borderType );
 }
 
 
-void cornerEigenValsAndVecs( const Mat& src, Mat& dst, int blockSize, int ksize, int borderType )
+void cv::cornerEigenValsAndVecs( const InputArray& _src, OutputArray _dst, int blockSize, int ksize, int borderType )
 {
-    if( dst.rows != src.rows || dst.cols*dst.channels() != src.cols*6 || dst.depth() != CV_32F )
-        dst.create( src.size(), CV_32FC(6) );
+    Mat src = _src.getMat();
+    Size dsz = _dst.size();
+    int dtype = _dst.type();
+    
+    if( dsz.height != src.rows || dsz.width*CV_MAT_CN(dtype) != src.cols*6 || CV_MAT_DEPTH(dtype) != CV_32F )
+        _dst.create( src.size(), CV_32FC(6) );
+    Mat dst = _dst.getMat();
     cornerEigenValsVecs( src, dst, blockSize, ksize, EIGENVALSVECS, 0, borderType );
 }
 
 
-void preCornerDetect( const Mat& src, Mat& dst, int ksize, int borderType )
+void cv::preCornerDetect( const InputArray& _src, OutputArray _dst, int ksize, int borderType )
 {
-    Mat Dx, Dy, D2x, D2y, Dxy;
+    Mat Dx, Dy, D2x, D2y, Dxy, src = _src.getMat();
 
     CV_Assert( src.type() == CV_8UC1 || src.type() == CV_32FC1 );
-    dst.create( src.size(), CV_32F );
-
+    _dst.create( src.size(), CV_32F );
+    Mat dst = _dst.getMat();
+    
     Sobel( src, Dx, CV_32F, 1, 0, ksize, 1, 0, borderType );
     Sobel( src, Dy, CV_32F, 0, 1, ksize, 1, 0, borderType );
     Sobel( src, D2x, CV_32F, 2, 0, ksize, 1, 0, borderType );
@@ -358,9 +369,6 @@ void preCornerDetect( const Mat& src, Mat& dst, int ksize, int borderType )
     }
 }
 
-
-}
-
 CV_IMPL void
 cvCornerMinEigenVal( const CvArr* srcarr, CvArr* dstarr,
                      int block_size, int aperture_size )
index c4c77f3..6d32608 100644 (file)
@@ -254,13 +254,17 @@ cvFindCornerSubPix( const void* srcarr, CvPoint2D32f* corners,
     }
 }
 
-void cv::cornerSubPix( const Mat& image, vector<Point2f>& corners,
+void cv::cornerSubPix( const InputArray& _image, InputOutputArray _corners,
                        Size winSize, Size zeroZone,
                        TermCriteria criteria )
 {
-    CvMat _image = image;
-    cvFindCornerSubPix(&_image, (CvPoint2D32f*)&corners[0], (int)corners.size(),
-                       winSize, zeroZone, criteria );
+    Mat corners = _corners.getMat();
+    int ncorners = corners.checkVector(2);
+    CV_Assert( ncorners >= 0 && corners.depth() == CV_32F );
+    CvMat c_image = _image.getMat();
+    
+    cvFindCornerSubPix( &c_image, (CvPoint2D32f*)corners.data, ncorners,
+                        winSize, zeroZone, criteria );
 }
 
 /* End of file. */
index 3f5bfbb..1f2177e 100644 (file)
@@ -111,16 +111,16 @@ void icvSepConvSmall3_32f( float* src, int src_step, float* dst, int dst_step,
 namespace cv
 {
 
-static void getScharrKernels( Mat& kx, Mat& ky, int dx, int dy, bool normalize, int ktype )
+static void getScharrKernels( OutputArray _kx, OutputArray _ky,
+                              int dx, int dy, bool normalize, int ktype )
 {
     const int ksize = 3;
 
     CV_Assert( ktype == CV_32F || ktype == CV_64F );
-
-    if( kx.cols != ksize || kx.rows != 1 || kx.type() != ktype )
-        kx.create( ksize, 1, ktype );
-    if( ky.cols != ksize || ky.rows != 1 || ky.type() != ktype )
-        ky.create( ksize, 1, ktype );
+    _kx.create(ksize, 1, ktype, -1, true);
+    _ky.create(ksize, 1, ktype, -1, true);
+    Mat kx = _kx.getMat();
+    Mat ky = _ky.getMat();
 
     CV_Assert( dx >= 0 && dy >= 0 && dx+dy == 1 );
 
@@ -142,7 +142,8 @@ static void getScharrKernels( Mat& kx, Mat& ky, int dx, int dy, bool normalize,
 }
 
 
-static void getSobelKernels( Mat& kx, Mat& ky, int dx, int dy, int _ksize, bool normalize, int ktype )
+static void getSobelKernels( OutputArray _kx, OutputArray _ky,
+                             int dx, int dy, int _ksize, bool normalize, int ktype )
 {
     int i, j, ksizeX = _ksize, ksizeY = _ksize;
     if( ksizeX == 1 && dx > 0 )
@@ -152,10 +153,10 @@ static void getSobelKernels( Mat& kx, Mat& ky, int dx, int dy, int _ksize, bool
 
     CV_Assert( ktype == CV_32F || ktype == CV_64F );
 
-    if( kx.cols != ksizeX || kx.rows != 1 || kx.type() != ktype )
-        kx.create( ksizeX, 1, ktype );
-    if( ky.cols != ksizeY || ky.rows != 1 || ky.type() != ktype )
-        ky.create( ksizeY, 1, ktype );
+    _kx.create(ksizeX, 1, ktype, -1, true);
+    _ky.create(ksizeY, 1, ktype, -1, true);
+    Mat kx = _kx.getMat();
+    Mat ky = _ky.getMat();    
 
     if( _ksize % 2 == 0 || _ksize > 31 )
         CV_Error( CV_StsOutOfRange, "The kernel size must be odd and not larger than 31" );
@@ -218,9 +219,10 @@ static void getSobelKernels( Mat& kx, Mat& ky, int dx, int dy, int _ksize, bool
     }
 }
 
+}
 
-void getDerivKernels( Mat& kx, Mat& ky, int dx, int dy,
-                      int ksize, bool normalize, int ktype )
+void cv::getDerivKernels( OutputArray kx, OutputArray ky, int dx, int dy,
+                          int ksize, bool normalize, int ktype )
 {
     if( ksize <= 0 )
         getScharrKernels( kx, ky, dx, dy, normalize, ktype );
@@ -229,8 +231,8 @@ void getDerivKernels( Mat& kx, Mat& ky, int dx, int dy,
 }
 
 
-Ptr<FilterEngine> createDerivFilter(int srcType, int dstType,
-                                    int dx, int dy, int ksize, int borderType )
+cv::Ptr<cv::FilterEngine> cv::createDerivFilter(int srcType, int dstType,
+                                                int dx, int dy, int ksize, int borderType )
 {
     Mat kx, ky;
     getDerivKernels( kx, ky, dx, dy, ksize, false, CV_32F );
@@ -238,9 +240,11 @@ Ptr<FilterEngine> createDerivFilter(int srcType, int dstType,
         kx, ky, Point(-1,-1), 0, borderType );
 }
 
-
 #if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
 
+namespace cv
+{
+
 static bool IPPDerivScharr(const Mat& src, Mat& dst, int ddepth, int dx, int dy, double scale)
 {
    int bufSize = 0;
@@ -344,9 +348,7 @@ static bool IPPDeriv(const Mat& src, Mat& dst, int ddepth, int dx, int dy, int k
    if(ksize == 3 || ksize == 5)
    {
       if( ddepth < 0 )
-        ddepth = src.depth();
-
-      dst.create( src.size(), CV_MAKETYPE(ddepth, src.channels()) );
+          ddepth = src.depth();
 
       if(src.type() == CV_8U && dst.type() == CV_16S && scale == 1)
       {
@@ -462,21 +464,25 @@ static bool IPPDeriv(const Mat& src, Mat& dst, int ddepth, int dx, int dy, int k
       return IPPDerivScharr(src, dst, ddepth, dx, dy, scale);
 
    return false;
-
 }
 
+}
+    
 #endif
 
-
-void Sobel( const Mat& src, Mat& dst, int ddepth, int dx, int dy,
-            int ksize, double scale, double delta, int borderType )
+void cv::Sobel( const InputArray& _src, OutputArray _dst, int ddepth, int dx, int dy,
+                int ksize, double scale, double delta, int borderType )
 {
+    Mat src = _src.getMat();
+    _dst.create( src.size(), CV_MAKETYPE(ddepth, src.channels()) );
+    Mat dst = _dst.getMat();
+    
 #if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
-   if(dx < 3 && dy < 3 && src.channels() == 1 && borderType == 1)
-   {
-      if(IPPDeriv(src, dst, ddepth, dx, dy, ksize,scale) == true)
-         return;
-   }
+    if(dx < 3 && dy < 3 && src.channels() == 1 && borderType == 1)
+    {
+        if(IPPDeriv(src, dst, ddepth, dx, dy, ksize,scale))
+            return;
+    }
 #endif
     int ktype = std::max(CV_32F, std::max(ddepth, src.depth()));
 
@@ -495,15 +501,19 @@ void Sobel( const Mat& src, Mat& dst, int ddepth, int dx, int dy,
 }
 
 
-void Scharr( const Mat& src, Mat& dst, int ddepth, int dx, int dy,
-             double scale, double delta, int borderType )
+void cv::Scharr( const InputArray& _src, OutputArray _dst, int ddepth, int dx, int dy,
+                 double scale, double delta, int borderType )
 {
+    Mat src = _src.getMat();
+    _dst.create( src.size(), CV_MAKETYPE(ddepth, src.channels()) );
+    Mat dst = _dst.getMat();
+    
 #if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
-   if(dx < 2 && dy < 2 && src.channels() == 1 && borderType == 1)
-   {
-      if(IPPDerivScharr(src, dst, ddepth, dx, dy, scale) == true)
-         return;
-   }
+    if(dx < 2 && dy < 2 && src.channels() == 1 && borderType == 1)
+    {
+        if(IPPDerivScharr(src, dst, ddepth, dx, dy, scale))
+            return;
+    }
 #endif
     int ktype = std::max(CV_32F, std::max(ddepth, src.depth()));
 
@@ -522,9 +532,13 @@ void Scharr( const Mat& src, Mat& dst, int ddepth, int dx, int dy,
 }
 
 
-void Laplacian( const Mat& src, Mat& dst, int ddepth, int ksize,
-                double scale, double delta, int borderType )
+void cv::Laplacian( const InputArray& _src, OutputArray _dst, int ddepth, int ksize,
+                    double scale, double delta, int borderType )
 {
+    Mat src = _src.getMat();
+    _dst.create( src.size(), CV_MAKETYPE(ddepth, src.channels()) );
+    Mat dst = _dst.getMat();
+    
     if( ksize == 1 || ksize == 3 )
     {
         float K[2][9] =
@@ -548,7 +562,6 @@ void Laplacian( const Mat& src, Mat& dst, int ddepth, int ksize,
         if( ddepth < 0 )
             ddepth = src.depth();
         int dtype = CV_MAKETYPE(ddepth, src.channels());
-        dst.create( src.size(), dtype );
 
         int dy0 = std::min(std::max((int)(STRIPE_SIZE/(getElemSize(src.type())*src.cols)), 1), src.rows);
         Ptr<FilterEngine> fx = createSeparableLinearFilter(src.type(),
@@ -578,8 +591,6 @@ void Laplacian( const Mat& src, Mat& dst, int ddepth, int ksize,
     }
 }
 
-}
-
 /////////////////////////////////////////////////////////////////////////////////////////
 
 CV_IMPL void
index a4e0f9d..a52780e 100644 (file)
@@ -850,21 +850,24 @@ cvDistTransform( const void* srcarr, void* dstarr,
     }
 }
 
-void cv::distanceTransform( const Mat& src, Mat& dst, Mat& labels,
+void cv::distanceTransform( const InputArray& _src, OutputArray _dst, OutputArray _labels,
                             int distanceType, int maskSize )
 {
-    dst.create(src.size(), CV_32F);
-    labels.create(src.size(), CV_32S);
-    CvMat _src = src, _dst = dst, _labels = labels;
-    cvDistTransform(&_src, &_dst, distanceType, maskSize, 0, &_labels);
+    Mat src = _src.getMat();
+    _dst.create(src.size(), CV_32F);
+    _labels.create(src.size(), CV_32S);
+    CvMat c_src = src, c_dst = _dst.getMat(), c_labels = _labels.getMat();
+    cvDistTransform(&c_src, &c_dst, distanceType, maskSize, 0, &c_labels);
 }
 
-void cv::distanceTransform( const Mat& src, Mat& dst,
+void cv::distanceTransform( const InputArray& _src, OutputArray _dst,
                             int distanceType, int maskSize )
 {
-    dst.create(src.size(), CV_32F);
-    CvMat _src = src, _dst = dst;
-    cvDistTransform(&_src, &_dst, distanceType, maskSize, 0, 0);
+    Mat src = _src.getMat();
+    _dst.create(src.size(), CV_32F);
+    Mat dst = _dst.getMat();
+    CvMat c_src = src, c_dst = _dst.getMat();
+    cvDistTransform(&c_src, &c_dst, distanceType, maskSize, 0, 0);
 }
 
 /* End of file. */
index d6cbf80..ec52ded 100644 (file)
@@ -1138,22 +1138,25 @@ icvDistC( const float *x, const float *y, void *user_param )
 }
 
 
-namespace cv
+float cv::EMD( const InputArray& _signature1, const InputArray& _signature2,
+               int distType, const InputArray& _cost,
+               float* lowerBound, OutputArray _flow )
 {
+    Mat signature1 = _signature1.getMat(), signature2 = _signature2.getMat();
+    Mat cost = _cost.getMat(), flow;
     
-float EMD( const Mat& signature1, const Mat& signature2,
-           int distType, const Mat& cost, float* lowerBound, Mat* flow )
-{
-    CvMat _signature1 = signature1;
-    CvMat _signature2 = signature2;
-    CvMat _cost = cost, _flow;
-    if( flow )
-        _flow = *flow;
+    CvMat _csignature1 = signature1;
+    CvMat _csignature2 = signature2;
+    CvMat _ccost = cost, _cflow;
+    if( _flow.needed() )
+    {
+        _flow.create((int)signature1.total(), (int)signature2.total(), CV_32F);
+        flow = _flow.getMat();
+        _cflow = flow;
+    }
     
-    return cvCalcEMD2( &_signature1, &_signature2, distType, 0, cost.empty() ? 0 : &_cost,
-                       flow ? &_flow : 0, lowerBound, 0 );
-}
-
+    return cvCalcEMD2( &_csignature1, &_csignature2, distType, 0, cost.empty() ? 0 : &_ccost,
+                       _flow.needed() ? &_cflow : 0, lowerBound, 0 );
 }
 
 /* End of file. */
index b469db5..92ce27f 100644 (file)
@@ -50,13 +50,16 @@ template<typename T> struct greaterThanPtr
     bool operator()(const T* a, const T* b) const { return *a > *b; }
 };
 
-void goodFeaturesToTrack( const Mat& image, vector<Point2f>& corners,
-                          int maxCorners, double qualityLevel, double minDistance,
-                          const Mat& mask, int blockSize,
-                          bool useHarrisDetector, double harrisK )
+}
+    
+void cv::goodFeaturesToTrack( const InputArray& _image, OutputArray _corners,
+                              int maxCorners, double qualityLevel, double minDistance,
+                              const InputArray& _mask, int blockSize,
+                              bool useHarrisDetector, double harrisK )
 {
+    Mat image = _image.getMat(), mask = _mask.getMat();
+    
     CV_Assert( qualityLevel > 0 && minDistance >= 0 && maxCorners >= 0 );
-
     CV_Assert( mask.empty() || (mask.type() == CV_8UC1 && mask.size() == image.size()) );
 
     Mat eig, tmp;
@@ -90,7 +93,7 @@ void goodFeaturesToTrack( const Mat& image, vector<Point2f>& corners,
     }
 
     sort( tmpCorners, greaterThanPtr<float>() );
-    corners.clear();
+    vector<Point2f> corners;
     size_t i, j, total = tmpCorners.size(), ncorners = 0;
 
     if(minDistance >= 1)
@@ -182,7 +185,10 @@ void goodFeaturesToTrack( const Mat& image, vector<Point2f>& corners,
                 break;
         }
     }
-/*
+    
+    Mat(corners).convertTo(_corners, _corners.fixedType() ? _corners.type() : CV_32F);
+
+    /*
     for( i = 0; i < total; i++ )
     {
         int ofs = (int)((const uchar*)tmpCorners[i] - eig.data);
@@ -209,8 +215,6 @@ void goodFeaturesToTrack( const Mat& image, vector<Point2f>& corners,
     }
 */
 }
-    
-}
 
 CV_IMPL void
 cvGoodFeaturesToTrack( const void* _image, void*, void*,
index 27fb2a0..786f7a6 100644 (file)
                                     Base Image Filter
 \****************************************************************************************/
 
-namespace cv
-{
-
-BaseRowFilter::BaseRowFilter() { ksize = anchor = -1; }
-BaseRowFilter::~BaseRowFilter() {}
-
-BaseColumnFilter::BaseColumnFilter() { ksize = anchor = -1; }
-BaseColumnFilter::~BaseColumnFilter() {}
-void BaseColumnFilter::reset() {}
-
-BaseFilter::BaseFilter() { ksize = Size(-1,-1); anchor = Point(-1,-1); }
-BaseFilter::~BaseFilter() {}
-void BaseFilter::reset() {}
-
 /*
  Various border types, image boundaries are denoted with '|'
  
   * BORDER_REPLICATE:     aaaaaa|abcdefgh|hhhhhhh
   * BORDER_REFLECT:       fedcba|abcdefgh|hgfedcb
   * BORDER_REFLECT_101:   gfedcb|abcdefgh|gfedcba
   * BORDER_WRAP:          cdefgh|abcdefgh|abcdefg        
   * BORDER_CONSTANT:      iiiiii|abcdefgh|iiiiiii  with some specified 'i'
-*/
-int borderInterpolate( int p, int len, int borderType )
+ * BORDER_REPLICATE:     aaaaaa|abcdefgh|hhhhhhh
+ * BORDER_REFLECT:       fedcba|abcdefgh|hgfedcb
+ * BORDER_REFLECT_101:   gfedcb|abcdefgh|gfedcba
+ * BORDER_WRAP:          cdefgh|abcdefgh|abcdefg        
+ * BORDER_CONSTANT:      iiiiii|abcdefgh|iiiiiii  with some specified 'i'
+ */
+int cv::borderInterpolate( int p, int len, int borderType )
 {
     if( (unsigned)p < (unsigned)len )
         ;
@@ -104,6 +90,20 @@ int borderInterpolate( int p, int len, int borderType )
 }
 
 
+namespace cv
+{
+
+BaseRowFilter::BaseRowFilter() { ksize = anchor = -1; }
+BaseRowFilter::~BaseRowFilter() {}
+
+BaseColumnFilter::BaseColumnFilter() { ksize = anchor = -1; }
+BaseColumnFilter::~BaseColumnFilter() {}
+void BaseColumnFilter::reset() {}
+
+BaseFilter::BaseFilter() { ksize = Size(-1,-1); anchor = Point(-1,-1); }
+BaseFilter::~BaseFilter() {}
+void BaseFilter::reset() {}
+
 FilterEngine::FilterEngine()
 {
     srcType = dstType = bufType = -1;
@@ -454,13 +454,15 @@ void FilterEngine::apply(const Mat& src, Mat& dst,
              dst.data + dstOfs.y*dst.step + dstOfs.x*dst.elemSize(), (int)dst.step );
 }
 
+}
 
 /****************************************************************************************\
 *                                 Separable linear filter                                *
 \****************************************************************************************/
 
-int getKernelType(const Mat& _kernel, Point anchor)
+int cv::getKernelType(const InputArray& __kernel, Point anchor)
 {
+    Mat _kernel = __kernel.getMat();
     CV_Assert( _kernel.channels() == 1 );
     int i, sz = _kernel.rows*_kernel.cols;
 
@@ -495,6 +497,9 @@ int getKernelType(const Mat& _kernel, Point anchor)
 }
 
 
+namespace cv
+{
+
 struct RowNoVec
 {
     RowNoVec() {}
@@ -2527,10 +2532,13 @@ template<typename ST, typename DT> struct FixedPtCastEx
     int SHIFT, DELTA;
 };
 
-Ptr<BaseRowFilter> getLinearRowFilter( int srcType, int bufType,
-                                          const Mat& kernel, int anchor,
-                                          int symmetryType )
+}
+    
+cv::Ptr<cv::BaseRowFilter> cv::getLinearRowFilter( int srcType, int bufType,
+                                                   const InputArray& _kernel, int anchor,
+                                                   int symmetryType )
 {
+    Mat kernel = _kernel.getMat();
     int sdepth = CV_MAT_DEPTH(srcType), ddepth = CV_MAT_DEPTH(bufType);
     int cn = CV_MAT_CN(srcType);
     CV_Assert( cn == CV_MAT_CN(bufType) &&
@@ -2577,11 +2585,12 @@ Ptr<BaseRowFilter> getLinearRowFilter( int srcType, int bufType,
 }
 
 
-Ptr<BaseColumnFilter> getLinearColumnFilter( int bufType, int dstType,
-                                             const Mat& kernel, int anchor,
+cv::Ptr<cv::BaseColumnFilter> cv::getLinearColumnFilter( int bufType, int dstType,
+                                             const InputArray& _kernel, int anchor,
                                              int symmetryType, double delta, 
                                              int bits )
 {
+    Mat kernel = _kernel.getMat();
     int sdepth = CV_MAT_DEPTH(bufType), ddepth = CV_MAT_DEPTH(dstType);
     int cn = CV_MAT_CN(dstType);
     CV_Assert( cn == CV_MAT_CN(bufType) &&
@@ -2672,13 +2681,14 @@ Ptr<BaseColumnFilter> getLinearColumnFilter( int bufType, int dstType,
 }
 
 
-Ptr<FilterEngine> createSeparableLinearFilter(
+cv::Ptr<cv::FilterEngine> cv::createSeparableLinearFilter(
     int _srcType, int _dstType,
-    const Mat& _rowKernel, const Mat& _columnKernel,
+    const InputArray& __rowKernel, const InputArray& __columnKernel,
     Point _anchor, double _delta,
     int _rowBorderType, int _columnBorderType,
     const Scalar& _borderValue )
 {
+    Mat _rowKernel = __rowKernel.getMat(), _columnKernel = __columnKernel.getMat();
     _srcType = CV_MAT_TYPE(_srcType);
     _dstType = CV_MAT_TYPE(_dstType);
     int sdepth = CV_MAT_DEPTH(_srcType), ddepth = CV_MAT_DEPTH(_dstType);
@@ -2742,6 +2752,9 @@ Ptr<FilterEngine> createSeparableLinearFilter(
 *                               Non-separable linear filter                              *
 \****************************************************************************************/
 
+namespace cv
+{
+
 void preprocess2DKernel( const Mat& kernel, vector<Point>& coords, vector<uchar>& coeffs )
 {
     int i, j, k, nz = countNonZero(kernel), ktype = kernel.type();
@@ -2868,11 +2881,13 @@ template<typename ST, class CastOp, class VecOp> struct Filter2D : public BaseFi
     VecOp vecOp;
 };
 
+}
 
-Ptr<BaseFilter> getLinearFilter(int srcType, int dstType,
-                                const Mat& _kernel, Point anchor,
+cv::Ptr<cv::BaseFilter> cv::getLinearFilter(int srcType, int dstType,
+                                const InputArray& __kernel, Point anchor,
                                 double delta, int bits)
 {
+    Mat _kernel = __kernel.getMat();
     int sdepth = CV_MAT_DEPTH(srcType), ddepth = CV_MAT_DEPTH(dstType);
     int cn = CV_MAT_CN(srcType), kdepth = _kernel.depth();
     CV_Assert( cn == CV_MAT_CN(dstType) && ddepth >= sdepth );
@@ -2946,11 +2961,13 @@ Ptr<BaseFilter> getLinearFilter(int srcType, int dstType,
 }
 
 
-Ptr<FilterEngine> createLinearFilter( int _srcType, int _dstType, const Mat& _kernel,
-                         Point _anchor, double _delta,
-                         int _rowBorderType, int _columnBorderType,
-                         const Scalar& _borderValue )
+cv::Ptr<cv::FilterEngine> cv::createLinearFilter( int _srcType, int _dstType,
+                                              const InputArray& __kernel,
+                                              Point _anchor, double _delta,
+                                              int _rowBorderType, int _columnBorderType,
+                                              const Scalar& _borderValue )
 {
+    Mat _kernel = __kernel.getMat();
     _srcType = CV_MAT_TYPE(_srcType);
     _dstType = CV_MAT_TYPE(_dstType);    
     int cn = CV_MAT_CN(_srcType);
@@ -2977,10 +2994,12 @@ Ptr<FilterEngine> createLinearFilter( int _srcType, int _dstType, const Mat& _ke
 }
 
 
-void filter2D( const Mat& src, Mat& dst, int ddepth,
-               const Mat& kernel, Point anchor,
-               double delta, int borderType )
+void cv::filter2D( const InputArray& _src, OutputArray _dst, int ddepth,
+                   const InputArray& _kernel, Point anchor,
+                   double delta, int borderType )
 {
+    Mat src = _src.getMat(), kernel = _kernel.getMat();
+    
     if( ddepth < 0 )
         ddepth = src.depth();
 
@@ -2991,7 +3010,8 @@ void filter2D( const Mat& src, Mat& dst, int ddepth,
     int dft_filter_size = 50;
 #endif
 
-    dst.create( src.size(), CV_MAKETYPE(ddepth, src.channels()) );
+    _dst.create( src.size(), CV_MAKETYPE(ddepth, src.channels()) );
+    Mat dst = _dst.getMat();
     anchor = normalizeAnchor(anchor, kernel.size());
 
     if( kernel.cols*kernel.rows >= dft_filter_size )
@@ -3015,22 +3035,23 @@ void filter2D( const Mat& src, Mat& dst, int ddepth,
 }
 
 
-void sepFilter2D( const Mat& src, Mat& dst, int ddepth,
-                  const Mat& kernelX, const Mat& kernelY, Point anchor,
-                  double delta, int borderType )
+void cv::sepFilter2D( const InputArray& _src, OutputArray _dst, int ddepth,
+                      const InputArray& _kernelX, const InputArray& _kernelY, Point anchor,
+                      double delta, int borderType )
 {
+    Mat src = _src.getMat(), kernelX = _kernelX.getMat(), kernelY = _kernelY.getMat();
+    
     if( ddepth < 0 )
         ddepth = src.depth();
 
-    dst.create( src.size(), CV_MAKETYPE(ddepth, src.channels()) );
+    _dst.create( src.size(), CV_MAKETYPE(ddepth, src.channels()) );
+    Mat dst = _dst.getMat();
 
     Ptr<FilterEngine> f = createSeparableLinearFilter(src.type(),
         dst.type(), kernelX, kernelY, anchor, delta, borderType & ~BORDER_ISOLATED );
     f->apply(src, dst, Rect(0,0,-1,-1), Point(), (borderType & BORDER_ISOLATED) != 0 );
 }
 
-}
-
 
 CV_IMPL void
 cvFilter2D( const CvArr* srcarr, CvArr* dstarr, const CvMat* _kernel, CvPoint anchor )
index de5d07e..6ddf196 100644 (file)
@@ -1114,25 +1114,25 @@ cvFloodFill( CvArr* arr, CvPoint seed_point,
 }
 
 
-int cv::floodFill( Mat& image, Point seedPoint,
+int cv::floodFill( InputOutputArray _image, Point seedPoint,
                    Scalar newVal, Rect* rect,
                    Scalar loDiff, Scalar upDiff, int flags )
 {
     CvConnectedComp ccomp;
-    CvMat _image = image;
-    cvFloodFill(&_image, seedPoint, newVal, loDiff, upDiff, &ccomp, flags, 0);
+    CvMat c_image = _image.getMat();
+    cvFloodFill(&c_image, seedPoint, newVal, loDiff, upDiff, &ccomp, flags, 0);
     if( rect )
         *rect = ccomp.rect;
     return cvRound(ccomp.area);
 }
 
-int cv::floodFill( Mat& image, Mat& mask,
+int cv::floodFill( InputOutputArray _image, InputOutputArray _mask,
                    Point seedPoint, Scalar newVal, Rect* rect, 
                    Scalar loDiff, Scalar upDiff, int flags )
 {
     CvConnectedComp ccomp;
-    CvMat _image = image, _mask = mask;
-    cvFloodFill(&_image, seedPoint, newVal, loDiff, upDiff, &ccomp, flags, &_mask);
+    CvMat c_image = _image.getMat(), c_mask = _mask.getMat();
+    cvFloodFill(&c_image, seedPoint, newVal, loDiff, upDiff, &ccomp, flags, &c_mask);
     if( rect )
         *rect = ccomp.rect;
     return cvRound(ccomp.area);
index d224475..9cd8c77 100644 (file)
@@ -375,10 +375,10 @@ void initGMMs( const Mat& img, const Mat& mask, GMM& bgdGMM, GMM& fgdGMM )
     CV_Assert( !bgdSamples.empty() && !fgdSamples.empty() );
     Mat _bgdSamples( (int)bgdSamples.size(), 3, CV_32FC1, &bgdSamples[0][0] );
     kmeans( _bgdSamples, GMM::componentsCount, bgdLabels,
-            TermCriteria( CV_TERMCRIT_ITER, kMeansItCount, 0.0), 0, kMeansType, 0 );
+            TermCriteria( CV_TERMCRIT_ITER, kMeansItCount, 0.0), 0, kMeansType );
     Mat _fgdSamples( (int)fgdSamples.size(), 3, CV_32FC1, &fgdSamples[0][0] );
     kmeans( _fgdSamples, GMM::componentsCount, fgdLabels,
-            TermCriteria( CV_TERMCRIT_ITER, kMeansItCount, 0.0), 0, kMeansType, 0 );
+            TermCriteria( CV_TERMCRIT_ITER, kMeansItCount, 0.0), 0, kMeansType );
 
     bgdGMM.initLearning();
     for( int i = 0; i < (int)bgdSamples.size(); i++ )
@@ -521,10 +521,15 @@ void estimateSegmentation( GCGraph<double>& graph, Mat& mask )
     }
 }
 
-void cv::grabCut( const Mat& img, Mat& mask, Rect rect,
-             Mat& bgdModel, Mat& fgdModel,
-             int iterCount, int mode )
+void cv::grabCut( const InputArray& _img, InputOutputArray _mask, Rect rect,
+                  InputOutputArray _bgdModel, InputOutputArray _fgdModel,
+                  int iterCount, int mode )
 {
+    Mat img = _img.getMat();
+    Mat& mask = _mask.getMatRef();
+    Mat& bgdModel = _bgdModel.getMatRef();
+    Mat& fgdModel = _fgdModel.getMatRef();
+    
     if( img.empty() )
         CV_Error( CV_StsBadArg, "image is empty" );
     if( img.type() != CV_8UC3 )
index 5f60ff4..6070e1e 100644 (file)
 namespace cv
 {
 
+template<> void Ptr<CvHistogram>::delete_obj()
+{ cvReleaseHist(&obj); }
+
+    
 ////////////////// Helper functions //////////////////////
 
 static const size_t OUT_OF_RANGE = (size_t)1 << (sizeof(size_t)*8 - 2);
@@ -586,18 +590,22 @@ calcHist_8u( vector<uchar*>& _ptrs, const vector<int>& _deltas,
     }
 }
 
+}
 
-void calcHist( const Mat* images, int nimages, const int* channels,
-               const Mat& mask, Mat& hist, int dims, const int* histSize,
-               const float** ranges, bool uniform, bool accumulate )
+void cv::calcHist( const Mat* images, int nimages, const int* channels,
+                   const InputArray& _mask, OutputArray _hist, int dims, const int* histSize,
+                   const float** ranges, bool uniform, bool accumulate )
 {
+    Mat mask = _mask.getMat();
+    
     CV_Assert(dims > 0 && histSize);
-    hist.create(dims, histSize, CV_32F);    
-        
-    Mat ihist = hist;
+    
+    uchar* histdata = _hist.getMat().data;
+    _hist.create(dims, histSize, CV_32F);
+    Mat hist = _hist.getMat(), ihist = hist;
     ihist.flags = (ihist.flags & ~CV_MAT_TYPE_MASK)|CV_32S;
     
-    if( !accumulate )
+    if( !accumulate || histdata != hist.data )
         hist = Scalar(0.);
     else
         hist.convertTo(ihist, CV_32S);
@@ -626,7 +634,9 @@ void calcHist( const Mat* images, int nimages, const int* channels,
     ihist.convertTo(hist, CV_32F);
 }
 
-    
+namespace cv
+{
+
 template<typename T> static void
 calcSparseHist_( vector<uchar*>& _ptrs, const vector<int>& _deltas,
                  Size imsize, SparseMat& hist, int dims, const float** _ranges,
@@ -803,11 +813,13 @@ static void calcHist( const Mat* images, int nimages, const int* channels,
     }
 }
     
+}
     
-void calcHist( const Mat* images, int nimages, const int* channels,
-               const Mat& mask, SparseMat& hist, int dims, const int* histSize,
+void cv::calcHist( const Mat* images, int nimages, const int* channels,
+               const InputArray& _mask, SparseMat& hist, int dims, const int* histSize,
                const float** ranges, bool uniform, bool accumulate )
 {
+    Mat mask = _mask.getMat();
     calcHist( images, nimages, channels, mask, hist, dims, histSize,
               ranges, uniform, accumulate, false );
 }
@@ -815,6 +827,8 @@ void calcHist( const Mat* images, int nimages, const int* channels,
     
 /////////////////////////////////////// B A C K   P R O J E C T ////////////////////////////////////    
     
+namespace cv
+{
 
 template<typename T, typename BT> static void
 calcBackProj_( vector<uchar*>& _ptrs, const vector<int>& _deltas,
@@ -1102,12 +1116,14 @@ calcBackProj_8u( vector<uchar*>& _ptrs, const vector<int>& _deltas,
         }
     }
 }    
+
+}
     
-    
-void calcBackProject( const Mat* images, int nimages, const int* channels,
-                      const Mat& hist, Mat& backProject,
-                      const float** ranges, double scale, bool uniform )
+void cv::calcBackProject( const Mat* images, int nimages, const int* channels,
+                          const InputArray& _hist, OutputArray _backProject,
+                          const float** ranges, double scale, bool uniform )
 {
+    Mat hist = _hist.getMat();
     vector<uchar*> ptrs;
     vector<int> deltas;
     vector<double> uniranges;
@@ -1115,7 +1131,8 @@ void calcBackProject( const Mat* images, int nimages, const int* channels,
     int dims = hist.dims == 2 && hist.size[1] == 1 ? 1 : hist.dims;
     
     CV_Assert( dims > 0 && hist.data );
-    backProject.create( images[0].size(), images[0].depth() );
+    _backProject.create( images[0].size(), images[0].depth() );
+    Mat backProject = _backProject.getMat();
     histPrepareImages( images, nimages, channels, backProject, dims, hist.size, ranges,
                        uniform, ptrs, deltas, imsize, uniranges );
     const double* _uniranges = uniform ? &uniranges[0] : 0;
@@ -1131,7 +1148,10 @@ void calcBackProject( const Mat* images, int nimages, const int* channels,
         CV_Error(CV_StsUnsupportedFormat, "");
 }
 
-    
+
+namespace cv
+{
+
 template<typename T, typename BT> static void
 calcSparseBackProj_( vector<uchar*>& _ptrs, const vector<int>& _deltas,
                      Size imsize, const SparseMat& hist, int dims, const float** _ranges,
@@ -1259,11 +1279,12 @@ calcSparseBackProj_8u( vector<uchar*>& _ptrs, const vector<int>& _deltas,
             ptrs[i] += deltas[i*2 + 1];
     }
 }    
-    
 
-void calcBackProject( const Mat* images, int nimages, const int* channels,
-                      const SparseMat& hist, Mat& backProject,
-                      const float** ranges, double scale, bool uniform )
+}
+
+void cv::calcBackProject( const Mat* images, int nimages, const int* channels,
+                          const SparseMat& hist, Mat& backProject,
+                          const float** ranges, double scale, bool uniform )
 {
     vector<uchar*> ptrs;
     vector<int> deltas;
@@ -1295,13 +1316,14 @@ void calcBackProject( const Mat* images, int nimages, const int* channels,
     
 ////////////////// C O M P A R E   H I S T O G R A M S ////////////////////////    
 
-double compareHist( const Mat& H1, const Mat& H2, int method )
+double cv::compareHist( const InputArray& _H1, const InputArray& _H2, int method )
 {
+    Mat H1 = _H1.getMat(), H2 = _H2.getMat();
     const Mat* arrays[] = {&H1, &H2, 0};
     Mat planes[2];
     NAryMatIterator it(arrays, planes);
     double result = 0;
-    int i, len;
+    int j, len = (int)it.size;
     
     CV_Assert( H1.type() == H2.type() && H1.type() == CV_32F );
     
@@ -1309,7 +1331,7 @@ double compareHist( const Mat& H1, const Mat& H2, int method )
     
     CV_Assert( it.planes[0].isContinuous() && it.planes[1].isContinuous() );
     
-    for( i = 0; i < it.nplanes; i++, ++it )
+    for( size_t i = 0; i < it.nplanes; i++, ++it )
     {
         const float* h1 = (const float*)it.planes[0].data;
         const float* h2 = (const float*)it.planes[1].data;
@@ -1317,20 +1339,20 @@ double compareHist( const Mat& H1, const Mat& H2, int method )
         
         if( method == CV_COMP_CHISQR )
         {
-            for( i = 0; i < len; i++ )
+            for( j = 0; j < len; j++ )
             {
-                double a = h1[i] - h2[i];
-                double b = h1[i] + h2[i];
+                double a = h1[j] - h2[j];
+                double b = h1[j] + h2[j];
                 if( fabs(b) > FLT_EPSILON )
                     result += a*a/b;
             }
         }
         else if( method == CV_COMP_CORREL )
         {
-            for( i = 0; i < len; i++ )
+            for( j = 0; j < len; j++ )
             {
-                double a = h1[i];
-                double b = h2[i];
+                double a = h1[j];
+                double b = h2[j];
                 
                 s12 += a*b;
                 s1 += a;
@@ -1341,15 +1363,15 @@ double compareHist( const Mat& H1, const Mat& H2, int method )
         }
         else if( method == CV_COMP_INTERSECT )
         {
-            for( i = 0; i < len; i++ )
-                result += std::min(h1[i], h2[i]);
+            for( j = 0; j < len; j++ )
+                result += std::min(h1[j], h2[j]);
         }
         else if( method == CV_COMP_BHATTACHARYYA )
         {
-            for( i = 0; i < len; i++ )
+            for( j = 0; j < len; j++ )
             {
-                double a = h1[i];
-                double b = h2[i];
+                double a = h1[j];
+                double b = h2[j];
                 result += std::sqrt(a*b);
                 s1 += a;
                 s2 += b;
@@ -1361,9 +1383,7 @@ double compareHist( const Mat& H1, const Mat& H2, int method )
     
     if( method == CV_COMP_CORREL )
     {
-        size_t total = 1;
-        for( i = 0; i < H1.dims; i++ )
-            total *= H1.size[i];
+        size_t total = H1.total();
         double scale = 1./total;
         double num = s12 - s1*s2*scale;
         double denom2 = (s11 - s1*s1*scale)*(s22 - s2*s2*scale);
@@ -1380,7 +1400,7 @@ double compareHist( const Mat& H1, const Mat& H2, int method )
 }
 
     
-double compareHist( const SparseMat& H1, const SparseMat& H2, int method )
+double cv::compareHist( const SparseMat& H1, const SparseMat& H2, int method )
 {
     double result = 0;
     int i, dims = H1.dims();
@@ -1491,12 +1511,6 @@ double compareHist( const SparseMat& H1, const SparseMat& H2, int method )
 }
 
     
-template<> void Ptr<CvHistogram>::delete_obj()
-{ cvReleaseHist(&obj); }
-    
-}
-
-    
 const int CV_HIST_DEFAULT_TYPE = CV_32F;
 
 /* Creates new histogram */
@@ -2395,11 +2409,13 @@ CV_IMPL void cvEqualizeHist( const CvArr* srcarr, CvArr* dstarr )
 }
 
 
-void cv::equalizeHist( const Mat& src, Mat& dst )
+void cv::equalizeHist( const InputArray& _src, OutputArray _dst )
 {
-    dst.create( src.size(), src.type() );
-    CvMat _src = src, _dst = dst;
-    cvEqualizeHist( &_src, &_dst );
+    Mat src = _src.getMat();
+    _dst.create( src.size(), src.type() );
+    Mat dst = _dst.getMat();
+    CvMat _csrc = src, _cdst = dst;
+    cvEqualizeHist( &_csrc, &_cdst );
 }
 
 /* Implementation of RTTI and Generic Functions for CvHistogram */
index a83d821..51d3260 100644 (file)
@@ -1090,44 +1090,53 @@ namespace cv
 
 const int STORAGE_SIZE = 1 << 12;
 
-void HoughLines( const Mat& image, vector<Vec2f>& lines,
-                 double rho, double theta, int threshold,
-                 double srn, double stn )
+static void seqToMat(const CvSeq* seq, OutputArray& _arr)
 {
-    CvMemStorage* storage = cvCreateMemStorage(STORAGE_SIZE);
-    CvMat _image = image;
-    CvSeq* seq = cvHoughLines2( &_image, storage, srn == 0 && stn == 0 ?
+    if( seq )
+    {
+        _arr.create(1, seq->total, seq->flags, -1, true);
+        Mat arr = _arr.getMat();
+        cvCvtSeqToArray(seq, arr.data);
+    }
+    else
+        _arr.release();
+}
+    
+}
+    
+void cv::HoughLines( const InputArray& _image, OutputArray _lines,
+                     double rho, double theta, int threshold,
+                     double srn, double stn )
+{
+    Ptr<CvMemStorage> storage = cvCreateMemStorage(STORAGE_SIZE);
+    CvMat c_image = _image.getMat();
+    CvSeq* seq = cvHoughLines2( &c_image, storage, srn == 0 && stn == 0 ?
                     CV_HOUGH_STANDARD : CV_HOUGH_MULTI_SCALE,
                     rho, theta, threshold, srn, stn );
-    Seq<Vec2f>(seq).copyTo(lines);
-       cvReleaseMemStorage(&storage);
+    seqToMat(seq, _lines);
 }
 
-void HoughLinesP( Mat& image, vector<Vec4i>& lines,
-                  double rho, double theta, int threshold,
-                  double minLineLength, double maxGap )
+void cv::HoughLinesP( const InputArray& _image, OutputArray _lines,
+                      double rho, double theta, int threshold,
+                      double minLineLength, double maxGap )
 {
-    CvMemStorage* storage = cvCreateMemStorage(STORAGE_SIZE);
-    CvMat _image = image;
-    CvSeq* seq = cvHoughLines2( &_image, storage, CV_HOUGH_PROBABILISTIC,
+    Ptr<CvMemStorage> storage = cvCreateMemStorage(STORAGE_SIZE);
+    CvMat c_image = _image.getMat();
+    CvSeq* seq = cvHoughLines2( &c_image, storage, CV_HOUGH_PROBABILISTIC,
                     rho, theta, threshold, minLineLength, maxGap );
-    Seq<Vec4i>(seq).copyTo(lines);
-       cvReleaseMemStorage(&storage);
+    seqToMat(seq, _lines);
 }
 
-void HoughCircles( const Mat& image, vector<Vec3f>& circles,
-                   int method, double dp, double min_dist,
-                   double param1, double param2,
-                   int minRadius, int maxRadius )
+void cv::HoughCircles( const InputArray& _image, OutputArray _circles,
+                       int method, double dp, double min_dist,
+                       double param1, double param2,
+                       int minRadius, int maxRadius )
 {
-    CvMemStorage* storage = cvCreateMemStorage(STORAGE_SIZE);
-    CvMat _image = image;
-    CvSeq* seq = cvHoughCircles( &_image, storage, method,
+    Ptr<CvMemStorage> storage = cvCreateMemStorage(STORAGE_SIZE);
+    CvMat c_image = _image.getMat();
+    CvSeq* seq = cvHoughCircles( &c_image, storage, method,
                     dp, min_dist, param1, param2, minRadius, maxRadius );
-    Seq<Vec3f>(seq).copyTo(circles);
-       cvReleaseMemStorage(&storage);
-}
-
+    seqToMat(seq, _circles);
 }
 
 /* End of file. */
index 3846717..2839f30 100644 (file)
@@ -1313,10 +1313,12 @@ typedef void (*ResizeAreaFastFunc)( const Mat& src, Mat& dst,
 typedef void (*ResizeAreaFunc)( const Mat& src, Mat& dst,
                                 const DecimateAlpha* xofs, int xofs_count );
 
+}
+    
 //////////////////////////////////////////////////////////////////////////////////////////
 
-void resize( const Mat& src, Mat& dst, Size dsize,
-             double inv_scale_x, double inv_scale_y, int interpolation )
+void cv::resize( const InputArray& _src, OutputArray _dst, Size dsize,
+                 double inv_scale_x, double inv_scale_y, int interpolation )
 {
     static ResizeFunc linear_tab[] =
     {
@@ -1420,6 +1422,7 @@ void resize( const Mat& src, Mat& dst, Size dsize,
         0, resizeArea_<float, float>, resizeArea_<double, double>, 0
     };
 
+    Mat src = _src.getMat();
     Size ssize = src.size();
     
     CV_Assert( ssize.area() > 0 );
@@ -1434,7 +1437,8 @@ void resize( const Mat& src, Mat& dst, Size dsize,
         inv_scale_x = (double)dsize.width/src.cols;
         inv_scale_y = (double)dsize.height/src.rows;
     }
-    dst.create(dsize, src.type());
+    _dst.create(dsize, src.type());
+    Mat dst = _dst.getMat();
 
     int depth = src.depth(), cn = src.channels();
     double scale_x = 1./inv_scale_x, scale_y = 1./inv_scale_y;
@@ -1653,6 +1657,9 @@ void resize( const Mat& src, Mat& dst, Size dsize,
 *                       General warping (affine, perspective, remap)                     *
 \****************************************************************************************/
 
+namespace cv
+{
+
 template<typename T>
 static void remapNearest( const Mat& _src, Mat& _dst, const Mat& _xy,
                           int borderType, const Scalar& _borderValue )
@@ -2392,8 +2399,11 @@ typedef void (*RemapFunc)(const Mat& _src, Mat& _dst, const Mat& _xy,
                           const Mat& _fxy, const void* _wtab,
                           int borderType, const Scalar& _borderValue);
 
-void remap( const Mat& src, Mat& dst, const Mat& map1, const Mat& map2,
-            int interpolation, int borderType, const Scalar& borderValue )
+}
+    
+void cv::remap( const InputArray& _src, OutputArray _dst,
+                const InputArray& _map1, const InputArray& _map2,
+                int interpolation, int borderType, const Scalar& borderValue )
 {
     static RemapNNFunc nn_tab[] =
     {
@@ -2425,8 +2435,12 @@ void remap( const Mat& src, Mat& dst, const Mat& map1, const Mat& map2,
         remapLanczos4<Cast<float, float>, float, 1>, 0, 0
     };
 
+    Mat src = _src.getMat(), map1 = _map1.getMat(), map2 = _map2.getMat();
+    
     CV_Assert( (!map2.data || map2.size() == map1.size()));
-    dst.create( map1.size(), src.type() );
+    
+    _dst.create( map1.size(), src.type() );
+    Mat dst = _dst.getMat();
     CV_Assert(dst.data != src.data);
 
     int depth = src.depth(), map_depth = map1.depth();
@@ -2650,9 +2664,11 @@ void remap( const Mat& src, Mat& dst, const Mat& map1, const Mat& map2,
 }
 
 
-void convertMaps( const Mat& map1, const Mat& map2, Mat& dstmap1, Mat& dstmap2,
-                  int dstm1type, bool nninterpolate )
+void cv::convertMaps( const InputArray& _map1, const InputArray& _map2,
+                      OutputArray _dstmap1, OutputArray _dstmap2,
+                      int dstm1type, bool nninterpolate )
 {
+    Mat map1 = _map1.getMat(), map2 = _map2.getMat(), dstmap1, dstmap2;
     Size size = map1.size();
     const Mat *m1 = &map1, *m2 = &map2;
     int m1type = m1->type(), m2type = m2->type();
@@ -2671,11 +2687,16 @@ void convertMaps( const Mat& map1, const Mat& map2, Mat& dstmap1, Mat& dstmap2,
     if( dstm1type <= 0 )
         dstm1type = m1type == CV_16SC2 ? CV_32FC2 : CV_16SC2;
     CV_Assert( dstm1type == CV_16SC2 || dstm1type == CV_32FC1 || dstm1type == CV_32FC2 );
-    dstmap1.create( size, dstm1type );
+    _dstmap1.create( size, dstm1type );
+    dstmap1 = _dstmap1.getMat();
+    
     if( !nninterpolate && dstm1type != CV_32FC2 )
-        dstmap2.create( size, dstm1type == CV_16SC2 ? CV_16UC1 : CV_32FC1 );
+    {
+        _dstmap2.create( size, dstm1type == CV_16SC2 ? CV_16UC1 : CV_32FC1 );
+        dstmap2 = _dstmap2.getMat();
+    }
     else
-        dstmap2.release();
+        _dstmap2.release();
 
     if( m1type == dstm1type || (nninterpolate &&
         ((m1type == CV_16SC2 && dstm1type == CV_32FC2) ||
@@ -2782,10 +2803,13 @@ void convertMaps( const Mat& map1, const Mat& map2, Mat& dstmap1, Mat& dstmap2,
 }
 
 
-void warpAffine( const Mat& src, Mat& dst, const Mat& M0, Size dsize,
-                 int flags, int borderType, const Scalar& borderValue )
+void cv::warpAffine( const InputArray& _src, OutputArray _dst,
+                     const InputArray& _M0, Size dsize,
+                     int flags, int borderType, const Scalar& borderValue )
 {
-    dst.create( dsize, src.type() );
+    Mat src = _src.getMat(), M0 = _M0.getMat();
+    _dst.create( dsize, src.type() );
+    Mat dst = _dst.getMat();
     CV_Assert( dst.data != src.data && src.cols > 0 && src.rows > 0 );
 
     const int BLOCK_SZ = 64;
@@ -2917,10 +2941,13 @@ void warpAffine( const Mat& src, Mat& dst, const Mat& M0, Size dsize,
 }
 
 
-void warpPerspective( const Mat& src, Mat& dst, const Mat& M0, Size dsize,
-                      int flags, int borderType, const Scalar& borderValue )
+void cv::warpPerspective( const InputArray& _src, OutputArray _dst, const InputArray& _M0,
+                          Size dsize, int flags, int borderType, const Scalar& borderValue )
 {
-    dst.create( dsize, src.type() );
+    Mat src = _src.getMat(), M0 = _M0.getMat();
+    _dst.create( dsize, src.type() );
+    Mat dst = _dst.getMat();
+    
     CV_Assert( dst.data != src.data && src.cols > 0 && src.rows > 0 );
 
     const int BLOCK_SZ = 32;
@@ -2999,7 +3026,7 @@ void warpPerspective( const Mat& src, Mat& dst, const Mat& M0, Size dsize,
 }
 
 
-Mat getRotationMatrix2D( Point2f center, double angle, double scale )
+cv::Mat cv::getRotationMatrix2D( Point2f center, double angle, double scale )
 {
     angle *= CV_PI/180;
     double alpha = cos(angle)*scale;
@@ -3042,7 +3069,7 @@ Mat getRotationMatrix2D( Point2f center, double angle, double scale )
  * where:
  *   cij - matrix coefficients, c22 = 1
  */
-Mat getPerspectiveTransform( const Point2f src[], const Point2f dst[] )
+cv::Mat cv::getPerspectiveTransform( const Point2f src[], const Point2f dst[] )
 {
     Mat M(3, 3, CV_64F), X(8, 1, CV_64F, M.data);
     double a[8][8], b[8];
@@ -3087,7 +3114,7 @@ Mat getPerspectiveTransform( const Point2f src[], const Point2f dst[] )
  * where:
  *   cij - matrix coefficients
  */
-Mat getAffineTransform( const Point2f src[], const Point2f dst[] )
+cv::Mat cv::getAffineTransform( const Point2f src[], const Point2f dst[] )
 {
     Mat M(2, 3, CV_64F), X(6, 1, CV_64F, M.data);
     double a[6*6], b[6];
@@ -3110,10 +3137,13 @@ Mat getAffineTransform( const Point2f src[], const Point2f dst[] )
     return M;
 }
     
-void invertAffineTransform(const Mat& matM, Mat& _iM)
+void cv::invertAffineTransform(const InputArray& _matM, OutputArray __iM)
 {
+    Mat matM = _matM.getMat();
     CV_Assert(matM.rows == 2 && matM.cols == 3);
-    _iM.create(2, 3, matM.type());
+    __iM.create(2, 3, matM.type());
+    Mat _iM = __iM.getMat();
+    
     if( matM.type() == CV_32F )
     {
         const float* M = (const float*)matM.data;
@@ -3148,8 +3178,6 @@ void invertAffineTransform(const Mat& matM, Mat& _iM)
         CV_Error( CV_StsUnsupportedFormat, "" );
 }    
 
-}
-
 CV_IMPL void
 cvResize( const CvArr* srcarr, CvArr* dstarr, int method )
 {
index 86fbbeb..0fb66c2 100644 (file)
@@ -807,10 +807,11 @@ cvInpaint( const CvArr* _input_img, const CvArr* _inpaint_mask, CvArr* _output_i
     }
 }
 
-void cv::inpaint( const Mat& src, const Mat& mask, Mat& dst,
+void cv::inpaint( const InputArray& _src, const InputArray& _mask, OutputArray _dst,
                   double inpaintRange, int flags )
 {
-    dst.create( src.size(), src.type() );
-    CvMat _src = src, _mask = mask, _dst = dst;
-    cvInpaint( &_src, &_mask, &_dst, inpaintRange, flags );
+    Mat src = _src.getMat();
+    _dst.create( src.size(), src.type() );
+    CvMat c_src = src, c_mask = _mask.getMat(), c_dst = _dst.getMat();
+    cvInpaint( &c_src, &c_mask, &c_dst, inpaintRange, flags );
 }
index fd0125c..3e6b4d3 100644 (file)
@@ -601,13 +601,14 @@ Moments::operator CvMoments() const
 
     return m;
 }
+    
 }
     
-cv::Moments cv::moments( const Mat& array, bool binaryImage )
+cv::Moments cv::moments( const InputArray& _array, bool binaryImage )
 {
     CvMoments om;
-    CvMat _array = array;
-    cvMoments(&_array, &om, binaryImage);
+    CvMat c_array = _array.getMat();
+    cvMoments(&c_array, &om, binaryImage);
     return om;
 }
 
index 901d6a0..5446842 100644 (file)
@@ -821,10 +821,12 @@ template<class Op, class VecOp> struct MorphFilter : BaseFilter
     vector<uchar*> ptrs;
     VecOp vecOp;
 };
+    
+}
 
 /////////////////////////////////// External Interface /////////////////////////////////////
 
-Ptr<BaseRowFilter> getMorphologyRowFilter(int op, int type, int ksize, int anchor)
+cv::Ptr<cv::BaseRowFilter> cv::getMorphologyRowFilter(int op, int type, int ksize, int anchor)
 {
     int depth = CV_MAT_DEPTH(type);
     if( anchor < 0 )
@@ -865,7 +867,7 @@ Ptr<BaseRowFilter> getMorphologyRowFilter(int op, int type, int ksize, int ancho
     return Ptr<BaseRowFilter>(0);
 }
 
-Ptr<BaseColumnFilter> getMorphologyColumnFilter(int op, int type, int ksize, int anchor)
+cv::Ptr<cv::BaseColumnFilter> cv::getMorphologyColumnFilter(int op, int type, int ksize, int anchor)
 {
     int depth = CV_MAT_DEPTH(type);
     if( anchor < 0 )
@@ -907,8 +909,9 @@ Ptr<BaseColumnFilter> getMorphologyColumnFilter(int op, int type, int ksize, int
 }
 
 
-Ptr<BaseFilter> getMorphologyFilter(int op, int type, const Mat& kernel, Point anchor)
+cv::Ptr<cv::BaseFilter> cv::getMorphologyFilter(int op, int type, const InputArray& _kernel, Point anchor)
 {
+    Mat kernel = _kernel.getMat();
     int depth = CV_MAT_DEPTH(type);
     anchor = normalizeAnchor(anchor, kernel.size());
     CV_Assert( op == MORPH_ERODE || op == MORPH_DILATE );
@@ -940,10 +943,11 @@ Ptr<BaseFilter> getMorphologyFilter(int op, int type, const Mat& kernel, Point a
 }
 
 
-Ptr<FilterEngine> createMorphologyFilter( int op, int type, const Mat& kernel,
+cv::Ptr<cv::FilterEngine> cv::createMorphologyFilter( int op, int type, const InputArray& _kernel,
          Point anchor, int _rowBorderType, int _columnBorderType,
          const Scalar& _borderValue )
 {
+    Mat kernel = _kernel.getMat();
     anchor = normalizeAnchor(anchor, kernel.size());
 
     Ptr<BaseRowFilter> rowFilter;
@@ -978,7 +982,7 @@ Ptr<FilterEngine> createMorphologyFilter( int op, int type, const Mat& kernel,
 }
 
 
-Mat getStructuringElement(int shape, Size ksize, Point anchor)
+cv::Mat cv::getStructuringElement(int shape, Size ksize, Point anchor)
 {
     int i, j;
     int r = 0, c = 0;
@@ -1031,31 +1035,36 @@ Mat getStructuringElement(int shape, Size ksize, Point anchor)
     return elem;
 }
 
-static void morphOp( int op, const Mat& src, Mat& dst, const Mat& _kernel,
+namespace cv
+{
+
+static void morphOp( int op, const InputArray& _src, OutputArray& _dst,
+                     const InputArray& _kernel,
                      Point anchor, int iterations,
                      int borderType, const Scalar& borderValue )
 {
-    Mat kernel;
-    Size ksize = _kernel.data ? _kernel.size() : Size(3,3);
+    Mat src = _src.getMat(), kernel = _kernel.getMat();
+    Size ksize = kernel.data ? kernel.size() : Size(3,3);
     anchor = normalizeAnchor(anchor, ksize);
 
     CV_Assert( anchor.inside(Rect(0, 0, ksize.width, ksize.height)) );
 
-    if( iterations == 0 || _kernel.rows*_kernel.cols == 1 )
+    _dst.create( src.size(), src.type() );
+    Mat dst = _dst.getMat();
+    
+    if( iterations == 0 || kernel.rows*kernel.cols == 1 )
     {
         src.copyTo(dst);
         return;
     }
 
-    dst.create( src.size(), src.type() );
-
-    if( !_kernel.data )
+    if( !kernel.data )
     {
         kernel = getStructuringElement(MORPH_RECT, Size(1+iterations*2,1+iterations*2));
         anchor = Point(iterations, iterations);
         iterations = 1;
     }
-    else if( iterations > 1 && countNonZero(_kernel) == _kernel.rows*_kernel.cols )
+    else if( iterations > 1 && countNonZero(kernel) == kernel.rows*kernel.cols )
     {
         anchor = Point(anchor.x*iterations, anchor.y*iterations);
         kernel = getStructuringElement(MORPH_RECT,
@@ -1064,8 +1073,6 @@ static void morphOp( int op, const Mat& src, Mat& dst, const Mat& _kernel,
                 anchor);
         iterations = 1;
     }
-    else
-        kernel = _kernel;
 
     Ptr<FilterEngine> f = createMorphologyFilter(op, src.type(),
         kernel, anchor, borderType, borderType, borderValue );
@@ -1074,29 +1081,36 @@ static void morphOp( int op, const Mat& src, Mat& dst, const Mat& _kernel,
     for( int i = 1; i < iterations; i++ )
         f->apply( dst, dst );
 }
+    
+template<> void Ptr<IplConvKernel>::delete_obj()
+{ cvReleaseStructuringElement(&obj); }
 
+}
 
-void erode( const Mat& src, Mat& dst, const Mat& kernel,
-            Point anchor, int iterations,
-            int borderType, const Scalar& borderValue )
+void cv::erode( const InputArray& src, OutputArray dst, const InputArray& kernel,
+                Point anchor, int iterations,
+                int borderType, const Scalar& borderValue )
 {
     morphOp( MORPH_ERODE, src, dst, kernel, anchor, iterations, borderType, borderValue );
 }
 
 
-void dilate( const Mat& src, Mat& dst, const Mat& kernel,
-             Point anchor, int iterations,
-             int borderType, const Scalar& borderValue )
+void cv::dilate( const InputArray& src, OutputArray dst, const InputArray& kernel,
+                 Point anchor, int iterations,
+                 int borderType, const Scalar& borderValue )
 {
     morphOp( MORPH_DILATE, src, dst, kernel, anchor, iterations, borderType, borderValue );
 }
 
 
-void morphologyEx( const Mat& src, Mat& dst, int op, const Mat& kernel,
-                   Point anchor, int iterations, int borderType,
-                   const Scalar& borderValue )
+void cv::morphologyEx( const InputArray& _src, OutputArray _dst, int op,
+                       const InputArray& kernel, Point anchor, int iterations,
+                       int borderType, const Scalar& borderValue )
 {
-    Mat temp;
+    Mat src = _src.getMat(), temp;
+    _dst.create(src.size(), src.type());
+    Mat dst = _dst.getMat();
+    
     switch( op )
     {
     case MORPH_ERODE:
@@ -1137,13 +1151,6 @@ void morphologyEx( const Mat& src, Mat& dst, int op, const Mat& kernel,
     }
 }
 
-    
-template<> void Ptr<IplConvKernel>::delete_obj()
-{ cvReleaseStructuringElement(&obj); }
-
-
-}
-
 CV_IMPL IplConvKernel *
 cvCreateStructuringElementEx( int cols, int rows,
                               int anchorX, int anchorY,
index 8e5cb82..83a75de 100644 (file)
@@ -399,11 +399,15 @@ pyrUp_( const Mat& _src, Mat& _dst )
 
 typedef void (*PyrFunc)(const Mat&, Mat&);
 
-void pyrDown( const Mat& _src, Mat& _dst, const Size& _dsz )
+}
+    
+void cv::pyrDown( const InputArray& _src, OutputArray _dst, const Size& _dsz )
 {
-    Size dsz = _dsz == Size() ? Size((_src.cols + 1)/2, (_src.rows + 1)/2) : _dsz;
-    _dst.create( dsz, _src.type() );
-    int depth = _src.depth();
+    Mat src = _src.getMat();
+    Size dsz = _dsz == Size() ? Size((src.cols + 1)/2, (src.rows + 1)/2) : _dsz;
+    _dst.create( dsz, src.type() );
+    Mat dst = _dst.getMat();
+    int depth = src.depth();
     PyrFunc func = 0;
     if( depth == CV_8U )
         func = pyrDown_<FixPtCast<uchar, 8>, PyrDownVec_32s8u>;
@@ -416,14 +420,16 @@ void pyrDown( const Mat& _src, Mat& _dst, const Size& _dsz )
     else
         CV_Error( CV_StsUnsupportedFormat, "" );
 
-    func( _src, _dst );
+    func( src, dst );
 }
 
-void pyrUp( const Mat& _src, Mat& _dst, const Size& _dsz )
+void cv::pyrUp( const InputArray& _src, OutputArray _dst, const Size& _dsz )
 {
-    Size dsz = _dsz == Size() ? Size(_src.cols*2, _src.rows*2) : _dsz;
-    _dst.create( dsz, _src.type() );
-    int depth = _src.depth();
+    Mat src = _src.getMat();
+    Size dsz = _dsz == Size() ? Size(src.cols*2, src.rows*2) : _dsz;
+    _dst.create( dsz, src.type() );
+    Mat dst = _dst.getMat();
+    int depth = src.depth();
     PyrFunc func = 0;
     if( depth == CV_8U )
         func = pyrUp_<FixPtCast<uchar, 6>, NoVec<int, uchar> >;
@@ -436,17 +442,16 @@ void pyrUp( const Mat& _src, Mat& _dst, const Size& _dsz )
     else
         CV_Error( CV_StsUnsupportedFormat, "" );
 
-    func( _src, _dst );
+    func( src, dst );
 }
 
-void buildPyramid( const Mat& _src, vector<Mat>& _dst, int maxlevel )
+void cv::buildPyramid( const InputArray& _src, OutputArrayOfArrays _dst, int maxlevel )
 {
-    _dst.resize( maxlevel + 1 );
-    _dst[0] = _src;
+    Mat src = _src.getMat();
+    _dst.create( maxlevel + 1, 1, 0 );
+    _dst.getMatRef(0) = src;
     for( int i = 1; i <= maxlevel; i++ )
-        pyrDown( _dst[i-1], _dst[i] );
-}
-
+        pyrDown( _dst.getMatRef(i-1), _dst.getMatRef(i) );
 }
 
 CV_IMPL void cvPyrDown( const void* srcarr, void* dstarr, int _filter )
index e21814c..24e8dee 100644 (file)
@@ -868,13 +868,15 @@ cvGetQuadrangleSubPix( const void* srcarr, void* dstarr, const CvMat* mat )
 }
 
 
-void cv::getRectSubPix( const Mat& image, Size patchSize, Point2f center,
-                        Mat& patch, int patchType )
+void cv::getRectSubPix( const InputArray& _image, Size patchSize, Point2f center,
+                        OutputArray _patch, int patchType )
 {
-    patch.create(patchSize, patchType < 0 ? image.type() :
+    Mat image = _image.getMat();
+    _patch.create(patchSize, patchType < 0 ? image.type() :
         CV_MAKETYPE(CV_MAT_DEPTH(patchType),image.channels()));
-    CvMat _image = image, _patch = patch;
-    cvGetRectSubPix(&_image, &_patch, center);
+    Mat patch = _patch.getMat();
+    CvMat _cimage = image, _cpatch = patch;
+    cvGetRectSubPix(&_cimage, &_cpatch, center);
 }
 
 /* End of file. */
index 11cbd30..f7bf822 100644 (file)
@@ -303,10 +303,10 @@ cvWatershed( const CvArr* srcarr, CvArr* dstarr )
 }
 
 
-void cv::watershed( const Mat& src, Mat& markers )
+void cv::watershed( const InputArray& src, InputOutputArray markers )
 {
-    CvMat _src = src, _markers = markers;
-    cvWatershed( &_src, &_markers );
+    CvMat c_src = src.getMat(), c_markers = markers.getMat();
+    cvWatershed( &c_src, &c_markers );
 }
 
 
@@ -523,14 +523,16 @@ cvPyrMeanShiftFiltering( const CvArr* srcarr, CvArr* dstarr,
     }
 }
 
-void cv::pyrMeanShiftFiltering( const Mat& src, Mat& dst,
+void cv::pyrMeanShiftFiltering( const InputArray& _src, OutputArray _dst,
                                 double sp, double sr, int maxLevel,
                                 TermCriteria termcrit )
 {
+    Mat src = _src.getMat();
+    
     if( src.empty() )
         return;
 
-    dst.create( src.size(), src.type() );
-    CvMat _src = src, _dst = dst;
-    cvPyrMeanShiftFiltering( &_src, &_dst, sp, sr, maxLevel, termcrit );
+    _dst.create( src.size(), src.type() );
+    CvMat c_src = src, c_dst = _dst.getMat();
+    cvPyrMeanShiftFiltering( &c_src, &c_dst, sp, sr, maxLevel, termcrit );
 }
index 273ccc5..b9f9326 100644 (file)
@@ -197,7 +197,9 @@ template<typename ST, typename T> struct ColumnSum : public BaseColumnFilter
 };
 
 
-Ptr<BaseRowFilter> getRowSumFilter(int srcType, int sumType, int ksize, int anchor)
+}
+    
+cv::Ptr<cv::BaseRowFilter> cv::getRowSumFilter(int srcType, int sumType, int ksize, int anchor)
 {
     int sdepth = CV_MAT_DEPTH(srcType), ddepth = CV_MAT_DEPTH(sumType);
     CV_Assert( CV_MAT_CN(sumType) == CV_MAT_CN(srcType) );
@@ -232,8 +234,8 @@ Ptr<BaseRowFilter> getRowSumFilter(int srcType, int sumType, int ksize, int anch
 }
 
 
-Ptr<BaseColumnFilter> getColumnSumFilter(int sumType, int dstType, int ksize,
-                                         int anchor, double scale)
+cv::Ptr<cv::BaseColumnFilter> cv::getColumnSumFilter(int sumType, int dstType, int ksize,
+                                                     int anchor, double scale)
 {
     int sdepth = CV_MAT_DEPTH(sumType), ddepth = CV_MAT_DEPTH(dstType);
     CV_Assert( CV_MAT_CN(sumType) == CV_MAT_CN(dstType) );
@@ -272,7 +274,7 @@ Ptr<BaseColumnFilter> getColumnSumFilter(int sumType, int dstType, int ksize,
 }
 
 
-Ptr<FilterEngine> createBoxFilter( int srcType, int dstType, Size ksize,
+cv::Ptr<cv::FilterEngine> cv::createBoxFilter( int srcType, int dstType, Size ksize,
                     Point anchor, bool normalize, int borderType )
 {
     int sdepth = CV_MAT_DEPTH(srcType);
@@ -292,14 +294,16 @@ Ptr<FilterEngine> createBoxFilter( int srcType, int dstType, Size ksize,
 }
 
 
-void boxFilter( const Mat& src, Mat& dst, int ddepth,
+void cv::boxFilter( const InputArray& _src, OutputArray _dst, int ddepth,
                 Size ksize, Point anchor,
                 bool normalize, int borderType )
 {
+    Mat src = _src.getMat();
     int sdepth = src.depth(), cn = src.channels();
     if( ddepth < 0 )
         ddepth = sdepth;
-    dst.create( src.size(), CV_MAKETYPE(ddepth, cn) );
+    _dst.create( src.size(), CV_MAKETYPE(ddepth, cn) );
+    Mat dst = _dst.getMat();
     if( borderType != BORDER_CONSTANT && normalize )
     {
         if( src.rows == 1 )
@@ -312,7 +316,7 @@ void boxFilter( const Mat& src, Mat& dst, int ddepth,
     f->apply( src, dst );
 }
 
-void blur( const Mat& src, CV_OUT Mat& dst,
+void cv::blur( const InputArray& src, OutputArray dst,
            Size ksize, Point anchor, int borderType )
 {
     boxFilter( src, dst, -1, ksize, anchor, true, borderType );
@@ -322,7 +326,7 @@ void blur( const Mat& src, CV_OUT Mat& dst,
                                      Gaussian Blur
 \****************************************************************************************/
 
-Mat getGaussianKernel( int n, double sigma, int ktype )
+cv::Mat cv::getGaussianKernel( int n, double sigma, int ktype )
 {
     const int SMALL_GAUSSIAN_SIZE = 7;
     static const float small_gaussian_tab[][SMALL_GAUSSIAN_SIZE] =
@@ -375,7 +379,7 @@ Mat getGaussianKernel( int n, double sigma, int ktype )
 }
 
 
-Ptr<FilterEngine> createGaussianFilter( int type, Size ksize,
+cv::Ptr<cv::FilterEngine> cv::createGaussianFilter( int type, Size ksize,
                                         double sigma1, double sigma2,
                                         int borderType )
 {
@@ -406,17 +410,20 @@ Ptr<FilterEngine> createGaussianFilter( int type, Size ksize,
 }
 
 
-void GaussianBlur( const Mat& src, Mat& dst, Size ksize,
+void cv::GaussianBlur( const InputArray& _src, OutputArray _dst, Size ksize,
                    double sigma1, double sigma2,
                    int borderType )
 {
+    Mat src = _src.getMat();
+    _dst.create( src.size(), src.type() );
+    Mat dst = _dst.getMat();
+    
     if( ksize.width == 1 && ksize.height == 1 )
     {
         src.copyTo(dst);
         return;
     }
 
-    dst.create( src.size(), src.type() );
     if( borderType != BORDER_CONSTANT )
     {
         if( src.rows == 1 )
@@ -433,6 +440,9 @@ void GaussianBlur( const Mat& src, Mat& dst, Size ksize,
                                       Median Filter
 \****************************************************************************************/
 
+namespace cv
+{
+
 #if _MSC_VER >= 1200
 #pragma warning( disable: 4244 )
 #endif
@@ -1207,9 +1217,14 @@ medianBlur_SortNet( const Mat& _src, Mat& _dst, int m )
     }
 }
 
-
-void medianBlur( const Mat& src0, Mat& dst, int ksize )
+}
+    
+void cv::medianBlur( const InputArray& _src0, OutputArray _dst, int ksize )
 {
+    Mat src0 = _src0.getMat();
+    _dst.create( src0.size(), src0.type() );
+    Mat dst = _dst.getMat();
+    
     if( ksize <= 1 )
     {
         src0.copyTo(dst);
@@ -1225,8 +1240,7 @@ void medianBlur( const Mat& src0, Mat& dst, int ksize )
             && src0.depth() > CV_8U
 #endif
         );
-
-    dst.create( src0.size(), src0.type() );
+    
     Mat src;
     if( useSortNet )
     {
@@ -1266,6 +1280,9 @@ void medianBlur( const Mat& src0, Mat& dst, int ksize )
                                    Bilateral Filtering
 \****************************************************************************************/
 
+namespace cv
+{
+
 static void
 bilateralFilter_8u( const Mat& src, Mat& dst, int d,
                     double sigma_color, double sigma_space,
@@ -1497,12 +1514,16 @@ bilateralFilter_32f( const Mat& src, Mat& dst, int d,
     }
 }
 
+}
 
-void bilateralFilter( const Mat& src, Mat& dst, int d,
+void cv::bilateralFilter( const InputArray& _src, OutputArray _dst, int d,
                       double sigmaColor, double sigmaSpace,
                       int borderType )
 {
-    dst.create( src.size(), src.type() );
+    Mat src = _src.getMat();
+    _dst.create( src.size(), src.type() );
+    Mat dst = _dst.getMat();
+    
     if( src.depth() == CV_8U )
         bilateralFilter_8u( src, dst, d, sigmaColor, sigmaSpace, borderType );
     else if( src.depth() == CV_32F )
@@ -1512,8 +1533,6 @@ void bilateralFilter( const Mat& src, Mat& dst, int d,
         "Bilateral filtering is only implemented for 8u and 32f images" );
 }
 
-}
-
 //////////////////////////////////////////////////////////////////////////////////////////
 
 CV_IMPL void
index 1c20120..0562f6a 100644 (file)
 namespace cv
 {
 
-template<typename QT> inline QT sqr(uchar a) { return a*a; }
-template<typename QT> inline QT sqr(float a) { return a*a; }
-template<typename QT> inline QT sqr(double a) { return a*a; }
-template<> inline double sqr(uchar a) { return CV_8TO32F_SQR(a); }
-
-
 template<typename T, typename ST, typename QT>
-void integral_( const Mat& _src, Mat& _sum, Mat& _sqsum, Mat& _tilted )
+void integral_( const T* src, size_t srcstep, ST* sum, size_t sumstep,
+                QT* sqsum, size_t sqsumstep, ST* tilted, size_t tiltedstep,
+                Size size, int cn )
 {
-    int cn = _src.channels();
-    Size size = _src.size();
     int x, y, k;
 
-    const T* src = (const T*)_src.data;
-    ST* sum = (ST*)_sum.data;
-    ST* tilted = (ST*)_tilted.data;
-    QT* sqsum = (QT*)_sqsum.data;
-
-    int srcstep = (int)(_src.step/sizeof(T));
-    int sumstep = (int)(_sum.step/sizeof(ST));
-    int tiltedstep = (int)(_tilted.step/sizeof(ST));
-    int sqsumstep = (int)(_sqsum.step/sizeof(QT));
+    srcstep /= sizeof(T);
+    sumstep /= sizeof(ST);
+    tiltedstep /= sizeof(ST);
+    sqsumstep /= sizeof(QT);
 
     size.width *= cn;
 
@@ -113,7 +102,7 @@ void integral_( const Mat& _src, Mat& _sum, Mat& _sqsum, Mat& _tilted )
                 {
                     T it = src[x];
                     s += it;
-                    sq += sqr<QT>(it);
+                    sq += (QT)it*it;
                     ST t = sum[x - sumstep] + s;
                     QT tq = sqsum[x - sqsumstep] + sq;
                     sum[x] = t;
@@ -128,45 +117,55 @@ void integral_( const Mat& _src, Mat& _sum, Mat& _sqsum, Mat& _tilted )
         ST* buf = _buf;
         ST s;
         QT sq;
-        for( k = 0; k < cn; k++, src++, sum++, tilted++, sqsum++, buf++ )
+        for( k = 0; k < cn; k++, src++, sum++, tilted++, buf++ )
         {
             sum[-cn] = tilted[-cn] = 0;
-            sqsum[-cn] = 0;
 
             for( x = 0, s = 0, sq = 0; x < size.width; x += cn )
             {
                 T it = src[x];
                 buf[x] = tilted[x] = it;
                 s += it;
-                sq += sqr<QT>(it);
+                sq += (QT)it*it;
                 sum[x] = s;
-                sqsum[x] = sq;
+                if( sqsum )
+                    sqsum[x] = sq;
             }
 
             if( size.width == cn )
                 buf[cn] = 0;
+            
+            if( sqsum )
+            {
+                sqsum[-cn] = 0;
+                sqsum++;
+            }
         }
 
         for( y = 1; y < size.height; y++ )
         {
             src += srcstep - cn;
             sum += sumstep - cn;
-            sqsum += sqsumstep - cn;
             tilted += tiltedstep - cn;
             buf += -cn;
+            
+            if( sqsum )
+                sqsum += sqsumstep - cn;
 
-            for( k = 0; k < cn; k++, src++, sum++, sqsum++, tilted++, buf++ )
+            for( k = 0; k < cn; k++, src++, sum++, tilted++, buf++ )
             {
                 T it = src[0];
                 ST t0 = s = it;
-                QT tq0 = sq = sqr<QT>(it);
+                QT tq0 = sq = (QT)it*it;
 
                 sum[-cn] = 0;
-                sqsum[-cn] = 0;
+                if( sqsum )
+                    sqsum[-cn] = 0;
                 tilted[-cn] = tilted[-tiltedstep];
 
                 sum[0] = sum[-sumstep] + t0;
-                sqsum[0] = sqsum[-sqsumstep] + tq0;
+                if( sqsum )
+                    sqsum[0] = sqsum[-sqsumstep] + tq0;
                 tilted[0] = tilted[-tiltedstep] + t0 + buf[cn];
 
                 for( x = cn; x < size.width - cn; x += cn )
@@ -174,11 +173,12 @@ void integral_( const Mat& _src, Mat& _sum, Mat& _sqsum, Mat& _tilted )
                     ST t1 = buf[x];
                     buf[x - cn] = t1 + t0;
                     t0 = it = src[x];
-                    tq0 = sqr<QT>(it);
+                    tq0 = (QT)it*it;
                     s += t0;
                     sq += tq0;
                     sum[x] = sum[x - sumstep] + s;
-                    sqsum[x] = sqsum[x - sqsumstep] + sq;
+                    if( sqsum )
+                        sqsum[x] = sqsum[x - sqsumstep] + sq;
                     t1 += buf[x + cn] + t0 + tilted[x - tiltedstep - cn];
                     tilted[x] = t1;
                 }
@@ -188,79 +188,96 @@ void integral_( const Mat& _src, Mat& _sum, Mat& _sqsum, Mat& _tilted )
                     ST t1 = buf[x];
                     buf[x - cn] = t1 + t0;
                     t0 = it = src[x];
-                    tq0 = sqr<QT>(it);
+                    tq0 = (QT)it*it;
                     s += t0;
                     sq += tq0;
                     sum[x] = sum[x - sumstep] + s;
-                    sqsum[x] = sqsum[x - sqsumstep] + sq;
+                    if( sqsum )
+                        sqsum[x] = sqsum[x - sqsumstep] + sq;
                     tilted[x] = t0 + t1 + tilted[x - tiltedstep - cn];
                     buf[x] = t0;
                 }
+                
+                if( sqsum )
+                    sqsum++;
             }
         }
     }
 }
 
-typedef void (*IntegralFunc)(const Mat& _src, Mat& _sum, Mat& _sqsum, Mat& _tilted );
+    
+#define DEF_INTEGRAL_FUNC(suffix, T, ST, QT) \
+void integral_##suffix( T* src, size_t srcstep, ST* sum, size_t sumstep, QT* sqsum, size_t sqsumstep, \
+                        ST* tilted, size_t tiltedstep, Size size, int cn ) \
+{ integral_(src, srcstep, sum, sumstep, sqsum, sqsumstep, tilted, tiltedstep, size, cn); }
+
+DEF_INTEGRAL_FUNC(8u32s, uchar, int, double)
+DEF_INTEGRAL_FUNC(8u32f, uchar, float, double)
+DEF_INTEGRAL_FUNC(8u64f, uchar, double, double)
+DEF_INTEGRAL_FUNC(32f, float, float, float)
+DEF_INTEGRAL_FUNC(32f64f, float, double, double)
+DEF_INTEGRAL_FUNC(64f, double, double, double)
+    
+typedef void (*IntegralFunc)(const uchar* src, size_t srcstep, uchar* sum, size_t sumstep,
+                             uchar* sqsum, size_t sqsumstep, uchar* tilted, size_t tstep,
+                             Size size, int cn );
+
+}
+
 
-static void
-integral( const Mat& src, Mat& sum, Mat* _sqsum, Mat* _tilted, int sdepth )
+void cv::integral( const InputArray& _src, OutputArray _sum, OutputArray _sqsum, OutputArray _tilted, int sdepth )
 {
+    Mat src = _src.getMat(), sum, sqsum, tilted;
     int depth = src.depth(), cn = src.channels();
     Size isize(src.cols + 1, src.rows+1);
-    Mat sqsum, tilted;
 
     if( sdepth <= 0 )
         sdepth = depth == CV_8U ? CV_32S : CV_64F;
     sdepth = CV_MAT_DEPTH(sdepth);
-    sum.create( isize, CV_MAKETYPE(sdepth, cn) );
+    _sum.create( isize, CV_MAKETYPE(sdepth, cn) );
+    sum = _sum.getMat();
     
-    if( _tilted )
-        _tilted->create( isize, CV_MAKETYPE(sdepth, cn) );
-    else
-        _tilted = &tilted;
+    if( _tilted.needed() )
+    {
+        _tilted.create( isize, CV_MAKETYPE(sdepth, cn) );
+        tilted = _tilted.getMat();
+    }
     
-    if( !_sqsum )
-        _sqsum = &sqsum;
+    if( _sqsum.needed() )
+    {
+        _sqsum.create( isize, CV_MAKETYPE(CV_64F, cn) );
+        sqsum = _sqsum.getMat();
+    }
     
-    if( _sqsum != &sqsum || _tilted->data )
-        _sqsum->create( isize, CV_MAKETYPE(CV_64F, cn) );
-
     IntegralFunc func = 0;
 
     if( depth == CV_8U && sdepth == CV_32S )
-        func = integral_<uchar, int, double>;
+        func = (IntegralFunc)integral_8u32s;
     else if( depth == CV_8U && sdepth == CV_32F )
-        func = integral_<uchar, float, double>;
+        func = (IntegralFunc)integral_8u32f;
     else if( depth == CV_8U && sdepth == CV_64F )
-        func = integral_<uchar, double, double>;
+        func = (IntegralFunc)integral_8u64f;
     else if( depth == CV_32F && sdepth == CV_32F )
-        func = integral_<float, float, double>;
+        func = (IntegralFunc)integral_32f;
     else if( depth == CV_32F && sdepth == CV_64F )
-        func = integral_<float, double, double>;
+        func = (IntegralFunc)integral_32f64f;
     else if( depth == CV_64F && sdepth == CV_64F )
-        func = integral_<double, double, double>;
+        func = (IntegralFunc)integral_64f;
     else
         CV_Error( CV_StsUnsupportedFormat, "" );
 
-    func( src, sum, *_sqsum, *_tilted );
-}
-
-void integral( const Mat& src, Mat& sum, int sdepth )
-{
-    integral( src, sum, 0, 0, sdepth );
+    func( src.data, src.step, sum.data, sum.step, sqsum.data, sqsum.step,
+          tilted.data, tilted.step, src.size(), cn );
 }
-
-void integral( const Mat& src, Mat& sum, Mat& sqsum, int sdepth )
+    
+void cv::integral( const InputArray& src, OutputArray sum, int sdepth )
 {
-    integral( src, sum, &sqsum, 0, sdepth );
+    integral( src, sum, OutputArray(), OutputArray(), sdepth );
 }
 
-void integral( const Mat& src, Mat& sum, Mat& sqsum, Mat& tilted, int sdepth )
+void cv::integral( const InputArray& src, OutputArray sum, OutputArray sqsum, int sdepth )
 {
-    integral( src, sum, &sqsum, &tilted, sdepth );
-}
-
+    integral( src, sum, sqsum, OutputArray(), sdepth );
 }
 
 
@@ -283,7 +300,8 @@ cvIntegral( const CvArr* image, CvArr* sumImage,
         tilted0 = tilted = cv::cvarrToMat(tiltedSumImage);
         ptilted = &tilted;
     }
-    cv::integral( src, sum, psqsum, ptilted, sum.depth() );
+    cv::integral( src, sum, psqsum ? cv::OutputArray(*psqsum) : cv::OutputArray(),
+                  ptilted ? cv::OutputArray(*ptilted) : cv::OutputArray(), sum.depth() );
 
     CV_Assert( sum.data == sum0.data && sqsum.data == sqsum0.data && tilted.data == tilted0.data );
 }
index 9c4188c..a82f348 100644 (file)
@@ -233,10 +233,11 @@ cv::crossCorr( const Mat& img, const Mat& templ, Mat& corr,
     icvCrossCorr( &_img, &_templ, &_corr, anchor, delta, borderType );
 }*/
 
+}
 
 /*****************************************************************************************/
 
-void matchTemplate( const Mat& _img, const Mat& _templ, Mat& result, int method )
+void cv::matchTemplate( const InputArray& _img, const InputArray& _templ, OutputArray _result, int method )
 {
     CV_Assert( CV_TM_SQDIFF <= method && method <= CV_TM_CCOEFF_NORMED );
     
@@ -246,17 +247,19 @@ void matchTemplate( const Mat& _img, const Mat& _templ, Mat& result, int method
                     method == CV_TM_SQDIFF_NORMED ||
                     method == CV_TM_CCOEFF_NORMED;
 
-    Mat img = _img, templ = _templ;
+    Mat img = _img.getMat(), templ = _templ.getMat();
     if( img.rows < templ.rows || img.cols < templ.cols )
         std::swap(img, templ);
     
     CV_Assert( (img.depth() == CV_8U || img.depth() == CV_32F) &&
                img.type() == templ.type() );
 
+    Size corrSize(img.cols - templ.cols + 1, img.rows - templ.rows + 1);
+    _result.create(corrSize, CV_32F);
+    Mat result = _result.getMat();
+    
     int cn = img.channels();
-    crossCorr( img, templ, result,
-               Size(img.cols - templ.cols + 1, img.rows - templ.rows + 1),
-               CV_32F, Point(0,0), 0, 0);
+    crossCorr( img, templ, result, result.size(), result.type(), Point(0,0), 0, 0);
 
     if( method == CV_TM_CCORR )
         return;
@@ -368,8 +371,6 @@ void matchTemplate( const Mat& _img, const Mat& _templ, Mat& result, int method
     }
 }
 
-}
-
 
 CV_IMPL void
 cvMatchTemplate( const CvArr* _img, const CvArr* _templ, CvArr* _result, int method )
index f041e43..2b0da32 100644 (file)
@@ -475,20 +475,24 @@ getThreshVal_Otsu_8u( const Mat& _src )
     return max_val;
 }
 
-
-double threshold( const Mat& _src, Mat& _dst, double thresh, double maxval, int type )
+}
+    
+double cv::threshold( const InputArray& _src, OutputArray _dst, double thresh, double maxval, int type )
 {
+    Mat src = _src.getMat();
     bool use_otsu = (type & THRESH_OTSU) != 0;
     type &= THRESH_MASK;
 
     if( use_otsu )
     {
-        CV_Assert( _src.type() == CV_8UC1 );
-        thresh = getThreshVal_Otsu_8u(_src);
+        CV_Assert( src.type() == CV_8UC1 );
+        thresh = getThreshVal_Otsu_8u(src);
     }
   
-    _dst.create( _src.size(), _src.type() );
-    if( _src.depth() == CV_8U )
+    _dst.create( src.size(), src.type() );
+    Mat dst = _dst.getMat();
+    
+    if( src.depth() == CV_8U )
     {
         int ithresh = cvFloor(thresh);
         thresh = ithresh;
@@ -506,16 +510,16 @@ double threshold( const Mat& _src, Mat& _dst, double thresh, double maxval, int
                 int v = type == THRESH_BINARY ? (ithresh >= 255 ? 0 : imaxval) :
                         type == THRESH_BINARY_INV ? (ithresh >= 255 ? imaxval : 0) :
                         type == THRESH_TRUNC ? imaxval : 0;
-                _dst = Scalar::all(v);
+                dst = Scalar::all(v);
             }
             else
-                _src.copyTo(_dst);
+                src.copyTo(dst);
         }
         else
-            thresh_8u( _src, _dst, (uchar)ithresh, (uchar)imaxval, type );
+            thresh_8u( src, dst, (uchar)ithresh, (uchar)imaxval, type );
     }
-    else if( _src.depth() == CV_32F )
-        thresh_32f( _src, _dst, (float)thresh, (float)maxval, type );
+    else if( src.depth() == CV_32F )
+        thresh_32f( src, dst, (float)thresh, (float)maxval, type );
     else
         CV_Error( CV_StsUnsupportedFormat, "" );
 
@@ -523,31 +527,33 @@ double threshold( const Mat& _src, Mat& _dst, double thresh, double maxval, int
 }
 
 
-void adaptiveThreshold( const Mat& _src, Mat& _dst, double maxValue,
-                        int method, int type, int blockSize, double delta )
+void cv::adaptiveThreshold( const InputArray& _src, OutputArray _dst, double maxValue,
+                            int method, int type, int blockSize, double delta )
 {
-    CV_Assert( _src.type() == CV_8UC1 );
+    Mat src = _src.getMat();
+    CV_Assert( src.type() == CV_8UC1 );
     CV_Assert( blockSize % 2 == 1 && blockSize > 1 );
-    Size size = _src.size();
+    Size size = src.size();
 
-    _dst.create( size, _src.type() );
+    _dst.create( size, src.type() );
+    Mat dst = _dst.getMat();
 
     if( maxValue < 0 )
     {
-        _dst = Scalar(0);
+        dst = Scalar(0);
         return;
     }
     
-    Mat _mean;
+    Mat mean;
 
-    if( _src.data != _dst.data )
-        _mean = _dst;
+    if( src.data != dst.data )
+        mean = dst;
 
     if( method == ADAPTIVE_THRESH_MEAN_C )
-        boxFilter( _src, _mean, _src.type(), Size(blockSize, blockSize),
+        boxFilter( src, mean, src.type(), Size(blockSize, blockSize),
                    Point(-1,-1), true, BORDER_REPLICATE );
     else if( method == ADAPTIVE_THRESH_GAUSSIAN_C )
-        GaussianBlur( _src, _mean, Size(blockSize, blockSize), 0, 0, BORDER_REPLICATE );
+        GaussianBlur( src, mean, Size(blockSize, blockSize), 0, 0, BORDER_REPLICATE );
     else
         CV_Error( CV_StsBadFlag, "Unknown/unsupported adaptive threshold method" );
 
@@ -565,7 +571,7 @@ void adaptiveThreshold( const Mat& _src, Mat& _dst, double maxValue,
     else
         CV_Error( CV_StsBadFlag, "Unknown/unsupported threshold type" );
 
-    if( _src.isContinuous() && _mean.isContinuous() && _dst.isContinuous() )
+    if( src.isContinuous() && mean.isContinuous() && dst.isContinuous() )
     {
         size.width *= size.height;
         size.height = 1;
@@ -573,17 +579,15 @@ void adaptiveThreshold( const Mat& _src, Mat& _dst, double maxValue,
 
     for( i = 0; i < size.height; i++ )
     {
-        const uchar* src = _src.data + _src.step*i;
-        const uchar* mean = _mean.data + _mean.step*i;
-        uchar* dst = _dst.data + _dst.step*i;
+        const uchar* sdata = src.data + src.step*i;
+        const uchar* mdata = mean.data + mean.step*i;
+        uchar* ddata = dst.data + dst.step*i;
 
         for( j = 0; j < size.width; j++ )
-            dst[j] = tab[src[j] - mean[j] + 255];
+            ddata[j] = tab[sdata[j] - mdata[j] + 255];
     }
 }
 
-}
-
 CV_IMPL double
 cvThreshold( const void* srcarr, void* dstarr, double thresh, double maxval, int type )
 {
index de328e5..8ef359e 100644 (file)
 
 #include "precomp.hpp"
 
-namespace cv
-{
-
-Mat getDefaultNewCameraMatrix( const Mat& cameraMatrix, Size imgsize,
+cv::Mat cv::getDefaultNewCameraMatrix( const InputArray& _cameraMatrix, Size imgsize,
                                bool centerPrincipalPoint )
 {
+    Mat cameraMatrix = _cameraMatrix.getMat();
     if( !centerPrincipalPoint && cameraMatrix.type() == CV_64F )
         return cameraMatrix;
     
@@ -61,35 +59,42 @@ Mat getDefaultNewCameraMatrix( const Mat& cameraMatrix, Size imgsize,
     return newCameraMatrix;
 }
 
-void initUndistortRectifyMap( const Mat& _cameraMatrix, const Mat& _distCoeffs,
-                              const Mat& matR, const Mat& _newCameraMatrix,
-                              Size size, int m1type, Mat& map1, Mat& map2 )
+void cv::initUndistortRectifyMap( const InputArray& _cameraMatrix, const InputArray& _distCoeffs,
+                              const InputArray& _matR, const InputArray& _newCameraMatrix,
+                              Size size, int m1type, OutputArray _map1, OutputArray _map2 )
 {
+    Mat cameraMatrix = _cameraMatrix.getMat(), distCoeffs = _distCoeffs.getMat();
+    Mat matR = _matR.getMat(), newCameraMatrix = _newCameraMatrix.getMat();
+    
     if( m1type <= 0 )
         m1type = CV_16SC2;
     CV_Assert( m1type == CV_16SC2 || m1type == CV_32FC1 || m1type == CV_32FC2 );
-    map1.create( size, m1type );
+    _map1.create( size, m1type );
+    Mat map1 = _map1.getMat(), map2;
     if( m1type != CV_32FC2 )
-        map2.create( size, m1type == CV_16SC2 ? CV_16UC1 : CV_32FC1 );
+    {
+        _map2.create( size, m1type == CV_16SC2 ? CV_16UC1 : CV_32FC1 );
+        map2 = _map2.getMat();
+    }
     else
-        map2.release();
+        _map2.release();
 
-    Mat_<double> R = Mat_<double>::eye(3, 3), distCoeffs;
-    Mat_<double> A = Mat_<double>(_cameraMatrix), Ar;
+    Mat_<double> R = Mat_<double>::eye(3, 3);
+    Mat_<double> A = Mat_<double>(cameraMatrix), Ar;
 
-    if( _newCameraMatrix.data )
-        Ar = Mat_<double>(_newCameraMatrix);
+    if( newCameraMatrix.data )
+        Ar = Mat_<double>(newCameraMatrix);
     else
         Ar = getDefaultNewCameraMatrix( A, size, true );
 
     if( matR.data )
         R = Mat_<double>(matR);
 
-    if( _distCoeffs.data )
-        distCoeffs = Mat_<double>(_distCoeffs);
+    if( distCoeffs.data )
+        distCoeffs = Mat_<double>(distCoeffs);
     else
     {
-        distCoeffs.create(8, 1);
+        distCoeffs.create(8, 1, CV_64F);
         distCoeffs = 0.;
     }
 
@@ -156,28 +161,33 @@ void initUndistortRectifyMap( const Mat& _cameraMatrix, const Mat& _distCoeffs,
 }
 
 
-void undistort( const Mat& src, Mat& dst, const Mat& _cameraMatrix,
-                const Mat& _distCoeffs, const Mat& _newCameraMatrix )
+void cv::undistort( const InputArray& _src, OutputArray _dst, const InputArray& _cameraMatrix,
+                    const InputArray& _distCoeffs, const InputArray& _newCameraMatrix )
 {
-    dst.create( src.size(), src.type() );
+    Mat src = _src.getMat(), cameraMatrix = _cameraMatrix.getMat();
+    Mat distCoeffs = _distCoeffs.getMat(), newCameraMatrix = _newCameraMatrix.getMat();
+    
+    _dst.create( src.size(), src.type() );
+    Mat dst = _dst.getMat();
+    
     CV_Assert( dst.data != src.data );
 
     int stripe_size0 = std::min(std::max(1, (1 << 12) / std::max(src.cols, 1)), src.rows);
     Mat map1(stripe_size0, src.cols, CV_16SC2), map2(stripe_size0, src.cols, CV_16UC1);
 
-    Mat_<double> A, distCoeffs, Ar, I = Mat_<double>::eye(3,3);
+    Mat_<double> A, Ar, I = Mat_<double>::eye(3,3);
 
-    _cameraMatrix.convertTo(A, CV_64F);
-    if( _distCoeffs.data )
-        distCoeffs = Mat_<double>(_distCoeffs);
+    cameraMatrix.convertTo(A, CV_64F);
+    if( distCoeffs.data )
+        distCoeffs = Mat_<double>(distCoeffs);
     else
     {
-        distCoeffs.create(5, 1);
+        distCoeffs.create(5, 1, CV_64F);
         distCoeffs = 0.;
     }
 
-    if( _newCameraMatrix.data )
-        _newCameraMatrix.convertTo(Ar, CV_64F);
+    if( newCameraMatrix.data )
+        newCameraMatrix.convertTo(Ar, CV_64F);
     else
         A.copyTo(Ar);
 
@@ -196,8 +206,6 @@ void undistort( const Mat& src, Mat& dst, const Mat& _cameraMatrix,
     }
 }
 
-}
-
 
 CV_IMPL void
 cvUndistort2( const CvArr* srcarr, CvArr* dstarr, const CvMat* Aarr, const CvMat* dist_coeffs, const CvMat* newAarr )
@@ -373,48 +381,34 @@ void cvUndistortPoints( const CvMat* _src, CvMat* _dst, const CvMat* _cameraMatr
 }
 
 
-namespace cv
+void cv::undistortPoints( const InputArray& _src, OutputArray _dst,
+                          const InputArray& _cameraMatrix,
+                          const InputArray& _distCoeffs,
+                          const InputArray& _Rmat,
+                          const InputArray& _Pmat )
 {
+    Mat src = _src.getMat(), cameraMatrix = _cameraMatrix.getMat();
+    Mat distCoeffs = _distCoeffs.getMat(), R = _Rmat.getMat(), P = _Pmat.getMat();
     
-void undistortPoints( const Mat& src, Mat& dst,
-                          const Mat& cameraMatrix, const Mat& distCoeffs,
-                          const Mat& R, const Mat& P )
-{
     CV_Assert( src.isContinuous() && (src.depth() == CV_32F || src.depth() == CV_64F) &&
               ((src.rows == 1 && src.channels() == 2) || src.cols*src.channels() == 2));
     
-    dst.create(src.size(), src.type());
-    CvMat _src = src, _dst = dst, _cameraMatrix = cameraMatrix;
-    CvMat matR, matP, _distCoeffs, *pR=0, *pP=0, *pD=0;
-    if( R.data )
-        pR = &(matR = R);
-    if( P.data )
-        pP = &(matP = P);
-    if( distCoeffs.data )
-        pD = &(_distCoeffs = distCoeffs);
-    cvUndistortPoints(&_src, &_dst, &_cameraMatrix, pD, pR, pP);
-}
-
-void undistortPoints( const Mat& src, std::vector<Point2f>& dst,
-                      const Mat& cameraMatrix, const Mat& distCoeffs,
-                      const Mat& R, const Mat& P )
-{
-    size_t sz = src.cols*src.rows*src.channels()/2;
-    CV_Assert( src.isContinuous() && src.depth() == CV_32F &&
-               ((src.rows == 1 && src.channels() == 2) || src.cols*src.channels() == 2));
+    _dst.create(src.size(), src.type(), -1, true);
+    Mat dst = _dst.getMat();
     
-    dst.resize(sz);
-    CvMat _src = src, _dst = Mat(dst), _cameraMatrix = cameraMatrix;
-    CvMat matR, matP, _distCoeffs, *pR=0, *pP=0, *pD=0;
+    CvMat _csrc = src, _cdst = dst, _ccameraMatrix = cameraMatrix;
+    CvMat matR, matP, _cdistCoeffs, *pR=0, *pP=0, *pD=0;
     if( R.data )
         pR = &(matR = R);
     if( P.data )
         pP = &(matP = P);
     if( distCoeffs.data )
-        pD = &(_distCoeffs = distCoeffs);
-    cvUndistortPoints(&_src, &_dst, &_cameraMatrix, pD, pR, pP);
+        pD = &(_cdistCoeffs = distCoeffs);
+    cvUndistortPoints(&_csrc, &_cdst, &_ccameraMatrix, pD, pR, pP);
 }
 
+namespace cv
+{
 
 static Point2f mapPointSpherical(const Point2f& p, float alpha, Vec4d* J, int projType)
 {
@@ -492,11 +486,13 @@ static Point2f invMapPointSpherical(Point2f _p, float alpha, int projType)
     return i < maxiter ? Point2f((float)q[0], (float)q[1]) : Point2f(-FLT_MAX, -FLT_MAX);
 }
 
+}
     
-float initWideAngleProjMap( const Mat& cameraMatrix0, const Mat& distCoeffs0,
+float cv::initWideAngleProjMap( const InputArray& _cameraMatrix0, const InputArray& _distCoeffs0,
                             Size imageSize, int destImageWidth, int m1type,
-                            Mat& map1, Mat& map2, int projType, double _alpha )
+                            OutputArray _map1, OutputArray _map2, int projType, double _alpha )
 {
+    Mat cameraMatrix0 = _cameraMatrix0.getMat(), distCoeffs0 = _distCoeffs0.getMat();
     double k[8] = {0,0,0,0,0,0,0,0}, M[9]={0,0,0,0,0,0,0,0,0};
     Mat distCoeffs(distCoeffs0.rows, distCoeffs0.cols, CV_MAKETYPE(CV_64F,distCoeffs0.channels()), k);
     Mat cameraMatrix(3,3,CV_64F,M);
@@ -562,15 +558,15 @@ float initWideAngleProjMap( const Mat& cameraMatrix0, const Mat& distCoeffs0,
     
     if(m1type == CV_32FC2)
     {
+        _map1.create(mapxy.size(), mapxy.type());
+        Mat map1 = _map1.getMat();
         mapxy.copyTo(map1);
-        map2.release();
+        _map2.release();
     }
     else
-        convertMaps(mapxy, Mat(), map1, map2, m1type, false);
+        convertMaps(mapxy, Mat(), _map1, _map2, m1type, false);
     
     return scale;
 }
 
-}
-
 /*  End of file  */
index 5609d6f..dd2ecbc 100644 (file)
@@ -195,13 +195,17 @@ static void copyMakeConstBorder_8u( const uchar* src, size_t srcstep, Size srcro
         memcpy(dst + (i + srcroi.height)*dststep, constBuf, dstroi.width);
 }
 
+}
     
-void copyMakeBorder( const Mat& src, Mat& dst, int top, int bottom,
-                    int left, int right, int borderType, const Scalar& value )
+void cv::copyMakeBorder( const InputArray& _src, OutputArray _dst, int top, int bottom,
+                         int left, int right, int borderType, const Scalar& value )
 {
+    Mat src = _src.getMat();
     CV_Assert( top >= 0 && bottom >= 0 && left >= 0 && right >= 0 );
     
-    dst.create( src.rows + top + bottom, src.cols + left + right, src.type() );
+    _dst.create( src.rows + top + bottom, src.cols + left + right, src.type() );
+    Mat dst = _dst.getMat();
+    
     if( borderType != BORDER_CONSTANT )
         copyMakeBorder_8u( src.data, src.step, src.size(),
                            dst.data, dst.step, dst.size(),
@@ -215,8 +219,6 @@ void copyMakeBorder( const Mat& src, Mat& dst, int top, int bottom,
                                 top, left, (int)src.elemSize(), (uchar*)buf );
     }
 }
-    
-}
 
 
 CV_IMPL void
index 6bd1b86..09e96aa 100644 (file)
@@ -524,7 +524,7 @@ int CV_WarpAffineTest::prepare_test_case( int test_case_idx )
     angle = cvtest::randReal(rng)*360;
     scale = ((double)dst.rows/src.rows + (double)dst.cols/src.cols)*0.5;
     getRotationMatrix2D(center, angle, scale).convertTo(mat, mat.depth());
-    rng.fill( tmp, CV_RAND_NORMAL, cvScalarAll(1.), cvScalarAll(0.01) );
+    rng.fill( tmp, CV_RAND_NORMAL, Scalar::all(1.), Scalar::all(0.01) );
     cv::max(tmp, 0.9, tmp);
     cv::min(tmp, 1.1, tmp);
     cv::multiply(tmp, mat, mat, 1.);
@@ -639,7 +639,7 @@ int CV_WarpPerspectiveTest::prepare_test_case( int test_case_idx )
     float buf[16];
     Mat tmp( 1, 16, CV_32FC1, buf );
 
-    rng.fill( tmp, CV_RAND_NORMAL, cvScalarAll(0.), cvScalarAll(0.1) );
+    rng.fill( tmp, CV_RAND_NORMAL, Scalar::all(0.), Scalar::all(0.1) );
 
     for( i = 0; i < 4; i++ )
     {
index b8851bd..6e412b6 100644 (file)
@@ -1228,7 +1228,7 @@ int CvANN_MLP::train_rprop( CvVectors x0, CvVectors u, const double* sw )
 
     __BEGIN__;
 
-    int i, ivcount, ovcount, l_count, total = 0, max_iter, buf_sz, dcount0, dcount=0;
+    int i, ivcount, ovcount, l_count, total = 0, max_iter, buf_sz, dcount0;
     double *buf_ptr;
     double prev_E = DBL_MAX*0.5, epsilon;
     double dw_plus, dw_minus, dw_min, dw_max;
@@ -1294,10 +1294,7 @@ int CvANN_MLP::train_rprop( CvVectors x0, CvVectors u, const double* sw )
     */
     for( iter = 0; iter < max_iter; iter++ )
     {
-        int n1, n2, si, j, k;
-        double* w;
-        CvMat _w, _dEdw, hdr1, hdr2, ghdr1, ghdr2, _df;
-        CvMat *x1, *x2, *grad1, *grad2, *temp;
+        int n1, n2, j, k;
         double E = 0;
 
         // first, iterate through all the samples and compute dEdw
index 4618932..1d7055c 100644 (file)
@@ -355,8 +355,6 @@ float CvKNearest::find_nearest( const CvMat* _samples, int k, CvMat* _results,
     float result = 0.f;
     const int max_blk_count = 128, max_buf_sz = 1 << 12;
 
-    int i, count, count_scale, blk_count0, blk_count = 0, buf_sz, k1;
-
     if( !samples )
         CV_Error( CV_StsError, "The search tree must be constructed first using train method" );
 
@@ -395,15 +393,15 @@ float CvKNearest::find_nearest( const CvMat* _samples, int k, CvMat* _results,
             "The distances from the neighbors (if present) must be floating-point matrix of <num_samples> x <k> size" );
     }
 
-    count = _samples->rows;
-    count_scale = k*2;
-    blk_count0 = MIN( count, max_blk_count );
-    buf_sz = MIN( blk_count0 * count_scale, max_buf_sz );
+    int count = _samples->rows;
+    int count_scale = k*2;
+    int blk_count0 = MIN( count, max_blk_count );
+    int buf_sz = MIN( blk_count0 * count_scale, max_buf_sz );
     blk_count0 = MAX( buf_sz/count_scale, 1 );
     blk_count0 += blk_count0 % 2;
     blk_count0 = MIN( blk_count0, count );
     buf_sz = blk_count0 * count_scale + k;
-    k1 = get_sample_count();
+    int k1 = get_sample_count();
     k1 = MIN( k1, k );
 
     cv::parallel_for(cv::BlockedRange(0, count), P1(this, buf_sz, k, _samples, _neighbors, k1,
index e1d4360..14f5f93 100644 (file)
@@ -203,7 +203,7 @@ void CV_KMeansTest::run( int /*start_from*/ )
     int code = cvtest::TS::OK;
     Mat bestLabels;
     // 1. flag==KMEANS_PP_CENTERS
-    kmeans( data, 3, bestLabels, TermCriteria( TermCriteria::COUNT, iters, 0.0), 0, KMEANS_PP_CENTERS, 0 );
+    kmeans( data, 3, bestLabels, TermCriteria( TermCriteria::COUNT, iters, 0.0), 0, KMEANS_PP_CENTERS, OutputArray() );
     if( calcErr( bestLabels, labels, sizes, false ) > 0.01f )
     {
         ts->printf( cvtest::TS::LOG, "bad accuracy if flag==KMEANS_PP_CENTERS" );
@@ -211,7 +211,7 @@ void CV_KMeansTest::run( int /*start_from*/ )
     }
 
     // 2. flag==KMEANS_RANDOM_CENTERS
-    kmeans( data, 3, bestLabels, TermCriteria( TermCriteria::COUNT, iters, 0.0), 0, KMEANS_RANDOM_CENTERS, 0 );
+    kmeans( data, 3, bestLabels, TermCriteria( TermCriteria::COUNT, iters, 0.0), 0, KMEANS_RANDOM_CENTERS, OutputArray() );
     if( calcErr( bestLabels, labels, sizes, false ) > 0.01f )
     {
         ts->printf( cvtest::TS::LOG, "bad accuracy if flag==KMEANS_PP_CENTERS" );
@@ -223,7 +223,7 @@ void CV_KMeansTest::run( int /*start_from*/ )
     RNG rng;
     for( int i = 0; i < 0.5f * pointsCount; i++ )
         bestLabels.at<int>( rng.next() % pointsCount, 0 ) = rng.next() % 3;
-    kmeans( data, 3, bestLabels, TermCriteria( TermCriteria::COUNT, iters, 0.0), 0, KMEANS_USE_INITIAL_LABELS, 0 );
+    kmeans( data, 3, bestLabels, TermCriteria( TermCriteria::COUNT, iters, 0.0), 0, KMEANS_USE_INITIAL_LABELS, OutputArray() );
     if( calcErr( bestLabels, labels, sizes, false ) > 0.01f )
     {
         ts->printf( cvtest::TS::LOG, "bad accuracy if flag==KMEANS_PP_CENTERS" );
index dbc7a4a..3c78531 100644 (file)
@@ -184,7 +184,7 @@ bool PlanarObjectDetector::operator()(const vector<Mat>& pyr, const vector<KeyPo
         return false;
 
     vector<uchar> mask;
-    matH = findHomography(Mat(fromPt), Mat(toPt), mask, RANSAC, 10);
+    matH = findHomography(fromPt, toPt, RANSAC, 10, mask);
     if( matH.data )
     {
         const Mat_<double>& H = matH;
index 96fbbde..3af8bf9 100644 (file)
@@ -24,20 +24,6 @@ using cv::Rect;
 
 class CV_EXPORTS TS;
     
-enum
-{
-    TYPE_MASK_8U = 1 << CV_8U,
-    TYPE_MASK_8S = 1 << CV_8S,
-    TYPE_MASK_16U = 1 << CV_16U,
-    TYPE_MASK_16S = 1 << CV_16S,
-    TYPE_MASK_32S = 1 << CV_32S,
-    TYPE_MASK_32F = 1 << CV_32F,
-    TYPE_MASK_64F = 1 << CV_64F,
-    TYPE_MASK_ALL = (TYPE_MASK_64F<<1)-1,
-    TYPE_MASK_ALL_BUT_8S = TYPE_MASK_ALL & ~TYPE_MASK_8S,
-    TYPE_MASK_FLT = TYPE_MASK_32F + TYPE_MASK_64F
-};
-
 CV_EXPORTS int64 readSeed(const char* str);
     
 CV_EXPORTS void randUni( RNG& rng, Mat& a, const Scalar& param1, const Scalar& param2 );
index 59d1163..80ad6d6 100644 (file)
@@ -71,7 +71,7 @@ int randomType(RNG& rng, int typeMask, int minChannels, int maxChannels)
 {
     int channels = rng.uniform(minChannels, maxChannels+1);
     int depth = 0;
-    CV_Assert((typeMask & TYPE_MASK_ALL) != 0);
+    CV_Assert((typeMask & DEPTH_MASK_ALL) != 0);
     for(;;)
     {
         depth = rng.uniform(CV_8U, CV_64F+1);
index c362bd1..fbc745d 100644 (file)
@@ -358,7 +358,7 @@ public:
     //! the virtual destructor
     virtual ~BackgroundSubtractor();
     //! the update operator that takes the next video frame and returns the current foreground mask as 8-bit binary image.
-    CV_WRAP_AS(apply) virtual void operator()(const Mat& image, CV_OUT Mat& fgmask,
+    CV_WRAP_AS(apply) virtual void operator()(const InputArray& image, OutputArray fgmask,
                                               double learningRate=0);
 };
 
@@ -383,7 +383,7 @@ public:
     //! the destructor
     virtual ~BackgroundSubtractorMOG();
     //! the update operator
-    virtual void operator()(const Mat& image, Mat& fgmask, double learningRate=0);
+    virtual void operator()(const InputArray& image, OutputArray fgmask, double learningRate=0);
     
     //! re-initiaization method
     virtual void initialize(Size frameSize, int frameType);
@@ -400,52 +400,73 @@ public:
 };     
 
 
-class CV_EXPORTS_W BackgroundSubtractorMOG2 : public BackgroundSubtractor
+class BackgroundSubtractorMOG2 : public BackgroundSubtractor
 {
 public:
     //! the default constructor
-    CV_WRAP BackgroundSubtractorMOG2();
+    BackgroundSubtractorMOG2();
     //! the full constructor that takes the length of the history, the number of gaussian mixtures, the background ratio parameter and the noise strength
-    CV_WRAP BackgroundSubtractorMOG2(double alphaT,
-                                     double sigma=15,
-                                     int nmixtures=5,
-                                     bool postFiltering=false,
-                                     double minArea=15,
-                                     bool detectShadows=true,
-                                     bool removeForeground=false,
-                                     
-                                     double Tb=16,
-                                     double Tg=9,
-                                     double TB=0.9,
-                                     double CT=0.05,
-                                     
-                                     int shadowOutputValue=127,
-                                     double tau=0.5);
-    
+    BackgroundSubtractorMOG2(int history,  float varThreshold, bool bShadowDetection=1);
     //! the destructor
     virtual ~BackgroundSubtractorMOG2();
     //! the update operator
-    virtual void operator()(const Mat& image, Mat& fgmask, double learningRate=0);
+    virtual void operator()(const InputArray& image, OutputArray fgmask, double learningRate=-1);
     
     //! re-initiaization method
-    virtual void initialize(Size frameSize,
-                            double alphaT,
-                            double sigma=15,
-                            int nmixtures=5,
-                            bool postFiltering=false,
-                            double minArea=15,
-                            bool detectShadows=true,
-                            bool removeForeground=false,
-                            
-                            double Tb=16,
-                            double Tg=9,
-                            double TB=0.9,
-                            double CT=0.05,
-                            
-                            int nShadowDetection=127,
-                            double tau=0.5);
+    virtual void initialize(Size frameSize, int frameType);
+    
+    Size frameSize;
+    int frameType;
+    Mat bgmodel;
+    Mat bgmodelUsedModes;//keep track of number of modes per pixel
+    int nframes;
+    int history;
+    int nmixtures;
+    //! here it is the maximum allowed number of mixture comonents.
+    //! Actual number is determined dynamically per pixel
+    float varThreshold;
+    // threshold on the squared Mahalan. dist. to decide if it is well described
+    //by the background model or not. Related to Cthr from the paper.
+    //This does not influence the update of the background. A typical value could be 4 sigma
+    //and that is varThreshold=4*4=16; Corresponds to Tb in the paper.
+    
+    /////////////////////////
+    //less important parameters - things you might change but be carefull
+    ////////////////////////
+    float backgroundRatio;
+    //corresponds to fTB=1-cf from the paper
+    //TB - threshold when the component becomes significant enough to be included into
+    //the background model. It is the TB=1-cf from the paper. So I use cf=0.1 => TB=0.
+    //For alpha=0.001 it means that the mode should exist for approximately 105 frames before
+    //it is considered foreground
+    //float noiseSigma;
+    float varThresholdGen;
+    //correspondts to Tg - threshold on the squared Mahalan. dist. to decide
+    //when a sample is close to the existing components. If it is not close
+    //to any a new component will be generated. I use 3 sigma => Tg=3*3=9.
+    //Smaller Tg leads to more generated components and higher Tg might make
+    //lead to small number of components but they can grow too large
+    float fVarInit;
+    float fVarMin;
+    float fVarMax;
+    //initial variance  for the newly generated components.
+    //It will will influence the speed of adaptation. A good guess should be made.
+    //A simple way is to estimate the typical standard deviation from the images.
+    //I used here 10 as a reasonable value
+    // min and max can be used to further control the variance
+    float fCT;//CT - complexity reduction prior
+    //this is related to the number of samples needed to accept that a component
+    //actually exists. We use CT=0.05 of all the samples. By setting CT=0 you get
+    //the standard Stauffer&Grimson algorithm (maybe not exact but very similar)
     
-    void* model;
+    //shadow detection parameters
+    bool bShadowDetection;//default 1 - do shadow detection
+    unsigned char nShadowDetection;//do shadow detection - insert this value as the detection result - 127 default value
+    float fTau;
+    // Tau - shadow threshold. The shadow is detected if the pixel is darker
+    //version of the background. Tau is a threshold on how much darker the shadow can be.
+    //Tau= 0.5 means that if pixel is more than 2 times darker then it is not shadow
+    //See: Prati,Mikic,Trivedi,Cucchiarra,"Detecting Moving Shadows...",IEEE PAMI,2003.
 };         
     
 }
index 5e5a051..35e7779 100644 (file)
@@ -244,30 +244,30 @@ namespace cv
 {
     
 //! updates motion history image using the current silhouette
-CV_EXPORTS_W void updateMotionHistory( const Mat& silhouette, Mat& mhi,
-                                     double timestamp, double duration );
+CV_EXPORTS_W void updateMotionHistory( const InputArray& silhouette, InputOutputArray mhi,
+                                       double timestamp, double duration );
 
 //! computes the motion gradient orientation image from the motion history image
-CV_EXPORTS_W void calcMotionGradient( const Mat& mhi, CV_OUT Mat& mask,
-                                      CV_OUT Mat& orientation,
+CV_EXPORTS_W void calcMotionGradient( const InputArray& mhi, OutputArray mask,
+                                      OutputArray orientation,
                                       double delta1, double delta2,
                                       int apertureSize=3 );
 
 //! computes the global orientation of the selected motion history image part
-CV_EXPORTS_W double calcGlobalOrientation( const Mat& orientation, const Mat& mask,
-                                           const Mat& mhi, double timestamp,
+CV_EXPORTS_W double calcGlobalOrientation( const InputArray& orientation, const InputArray& mask,
+                                           const InputArray& mhi, double timestamp,
                                            double duration );
 
-CV_EXPORTS_W void segmentMotion(const Mat& mhi, Mat& segmask,
+CV_EXPORTS_W void segmentMotion(const InputArray& mhi, OutputArray segmask,
                                 vector<Rect>& boundingRects,
                                 double timestamp, double segThresh);
 
 //! updates the object tracking window using CAMSHIFT algorithm
-CV_EXPORTS_W RotatedRect CamShift( const Mat& probImage, CV_IN_OUT Rect& window,
+CV_EXPORTS_W RotatedRect CamShift( const InputArray& probImage, CV_IN_OUT Rect& window,
                                    TermCriteria criteria );
 
 //! updates the object tracking window using meanshift algorithm
-CV_EXPORTS_W int meanShift( const Mat& probImage, CV_IN_OUT Rect& window,
+CV_EXPORTS_W int meanShift( const InputArray& probImage, CV_IN_OUT Rect& window,
                             TermCriteria criteria );
 
 /*!
@@ -315,9 +315,9 @@ public:
 enum { OPTFLOW_USE_INITIAL_FLOW=4, OPTFLOW_FARNEBACK_GAUSSIAN=256 };
 
 //! computes sparse optical flow using multi-scale Lucas-Kanade algorithm
-CV_EXPORTS_W void calcOpticalFlowPyrLK( const Mat& prevImg, const Mat& nextImg,
-                           const vector<Point2f>& prevPts, CV_OUT vector<Point2f>& nextPts,
-                           CV_OUT vector<uchar>& status, CV_OUT vector<float>& err,
+CV_EXPORTS_W void calcOpticalFlowPyrLK( const InputArray& prevImg, const InputArray& nextImg,
+                           const InputArray& prevPts, CV_OUT InputOutputArray nextPts,
+                           OutputArray status, OutputArray err,
                            Size winSize=Size(15,15), int maxLevel=3,
                            TermCriteria criteria=TermCriteria(
                             TermCriteria::COUNT+TermCriteria::EPS,
@@ -326,10 +326,15 @@ CV_EXPORTS_W void calcOpticalFlowPyrLK( const Mat& prevImg, const Mat& nextImg,
                            int flags=0 );
 
 //! computes dense optical flow using Farneback algorithm
-CV_EXPORTS_W void calcOpticalFlowFarneback( const Mat& prev, const Mat& next,
-                           CV_OUT Mat& flow, double pyr_scale, int levels, int winsize,
+CV_EXPORTS_W void calcOpticalFlowFarneback( const InputArray& prev, const InputArray& next,
+                           CV_OUT InputOutputArray flow, double pyr_scale, int levels, int winsize,
                            int iterations, int poly_n, double poly_sigma, int flags );
 
+//! estimates the best-fit Euqcidean, similarity, affine or perspective transformation
+// that maps one 2D point set to another or one image to another.
+CV_EXPORTS_W Mat estimateRigidTransform( const InputArray& src, const InputArray& dst,
+                                         bool fullAffine);
+    
 }
 
 #endif
index da4519b..14358de 100644 (file)
@@ -59,7 +59,7 @@ namespace cv
 {
     
 BackgroundSubtractor::~BackgroundSubtractor() {}
-void BackgroundSubtractor::operator()(const Mat&, Mat&, double)
+void BackgroundSubtractor::operator()(const InputArray&, OutputArray, double)
 {
 }
 
@@ -381,15 +381,17 @@ static void process8uC3( BackgroundSubtractorMOG& obj, const Mat& image, Mat& fg
     }
 }
 
-void BackgroundSubtractorMOG::operator()(const Mat& image, Mat& fgmask, double learningRate)
+void BackgroundSubtractorMOG::operator()(const InputArray& _image, OutputArray _fgmask, double learningRate)
 {
+    Mat image = _image.getMat();
     bool needToInitialize = nframes == 0 || learningRate >= 1 || image.size() != frameSize || image.type() != frameType;
     
     if( needToInitialize )
         initialize(image.size(), image.type());
     
     CV_Assert( image.depth() == CV_8U );
-    fgmask.create( image.size(), CV_8U );
+    _fgmask.create( image.size(), CV_8U );
+    Mat fgmask = _fgmask.getMat();
     
     ++nframes;
     learningRate = learningRate >= 0 && nframes > 1 ? learningRate : 1./min( nframes, history );
index e216a89..655db00 100644 (file)
 //http://www.zoranz.net/Publications/zivkovic2004PAMI.pdf
 //
 //
+//Example usage with as cpp class
+// BackgroundSubtractorMOG2 bg_model;
+//For each new image the model is updates using: 
+// bg_model(img, fgmask);
 //
-// Example usage as part of the CvBGStatModel:
+//Example usage as part of the CvBGStatModel:
 // CvBGStatModel* bg_model = cvCreateGaussianBGModel2( first_frame );
 //
 // //update for each frame
 // cvReleaseBGStatModel( &bg_model );
 //
 //Author: Z.Zivkovic, www.zoranz.net
-//Date: 27-April-2005, Version:0.9
+//Date: 7-April-2011, Version:1.0
 ///////////*/
 
 #include "precomp.hpp"
 
-#define CV_BG_MODEL_MOG2               3                       /* "Mixture of Gaussians 2".    */
+
+/*
+ Interface of Gaussian mixture algorithm from:
+ "Improved adaptive Gausian mixture model for background subtraction"
+ Z.Zivkovic
+ International Conference Pattern Recognition, UK, August, 2004
+ http://www.zoranz.net/Publications/zivkovic2004ICPR.pdf
+ Advantages:
+ -fast - number of Gausssian components is constantly adapted per pixel.
+ -performs also shadow detection (see bgfg_segm_test.cpp example)
+ */
+
+
+#define CV_BG_MODEL_MOG2            3                 /* "Mixture of Gaussians 2".  */
+
 
 /* default parameters of gaussian background detection algorithm */
 #define CV_BGFG_MOG2_STD_THRESHOLD            4.0f     /* lambda=2.5 is 99% */
 #define CV_BGFG_MOG2_BACKGROUND_THRESHOLD     0.9f     /* threshold sum of weights for background test */
 #define CV_BGFG_MOG2_STD_THRESHOLD_GENERATE   3.0f     /* lambda=2.5 is 99% */
 #define CV_BGFG_MOG2_NGAUSSIANS               5        /* = K = number of Gaussians in mixture */
-#define CV_BGFG_MOG2_SIGMA_INIT               15.0f
-#define CV_BGFG_MOG2_MINAREA                  15.0f
+#define CV_BGFG_MOG2_VAR_INIT                 15.0f    /* initial variance for new components*/
+#define CV_BGFG_MOG2_VAR_MIN                    4.0f
+#define CV_BGFG_MOG2_VAR_MAX                      5*CV_BGFG_MOG2_VAR_INIT
+#define CV_BGFG_MOG2_MINAREA                  15.0f    /* for postfiltering */
 
 /* additional parameters */
-#define CV_BGFG_MOG2_CT                                              0.05f     /* complexity reduction prior constant 0 - no reduction of number of components*/
+#define CV_BGFG_MOG2_CT                               0.05f     /* complexity reduction prior constant 0 - no reduction of number of components*/
 #define CV_BGFG_MOG2_SHADOW_VALUE             127       /* value to use in the segmentation mask for shadows, sot 0 not to do shadow detection*/
 #define CV_BGFG_MOG2_SHADOW_TAU               0.5f      /* Tau - shadow threshold, see the paper for explanation*/
 
-struct CvGaussBGStatModel2Params
-{  
-       bool bPostFiltering;//defult 1 - do postfiltering 
+typedef struct CvGaussBGStatModel2Params
+{
+    //image info
+    int nWidth;
+    int nHeight;
+    int nND;//number of data dimensions (image channels)
+    
+    bool bPostFiltering;//defult 1 - do postfiltering - will make shadow detection results also give value 255 
     double  minArea; // for postfiltering
     
-       bool bShadowDetection;//default 1 - do shadow detection 
-       bool bRemoveForeground;//default 0, set to 1 to remove foreground pixels from the image and return background image
-       bool bInit;//default 1, faster updates at start
+    bool bInit;//default 1, faster updates at start
     
-       /////////////////////////
-       //very important parameters - things you will change
-       ////////////////////////
-       float fAlphaT;
-       //alpha - speed of update - if the time interval you want to average over is T
-       //set alpha=1/T. It is also usefull at start to make T slowly increase
-       //from 1 until the desired T
-       float fTb;
-       //Tb - threshold on the squared Mahalan. dist. to decide if it is well described
-       //by the background model or not. Related to Cthr from the paper.
-       //This does not influence the update of the background. A typical value could be 4 sigma
-       //and that is Tb=4*4=16;
-       
-       /////////////////////////
-       //less important parameters - things you might change but be carefull
-       ////////////////////////
-       float fTg;
-       //Tg - threshold on the squared Mahalan. dist. to decide 
-       //when a sample is close to the existing components. If it is not close
-       //to any a new component will be generated. I use 3 sigma => Tg=3*3=9.
-       //Smaller Tg leads to more generated components and higher Tg might make
-       //lead to small number of components but they can grow too large
-       float fTB;//1-cf from the paper
-       //TB - threshold when the component becomes significant enough to be included into
-       //the background model. It is the TB=1-cf from the paper. So I use cf=0.1 => TB=0.
-       //For alpha=0.001 it means that the mode should exist for approximately 105 frames before
-       //it is considered foreground
-       float fSigma;
-       //initial standard deviation  for the newly generated components. 
-       //It will will influence the speed of adaptation. A good guess should be made. 
-       //A simple way is to estimate the typical standard deviation from the images.
-       //I used here 10 as a reasonable value
-       float fCT;//CT - complexity reduction prior
-       //this is related to the number of samples needed to accept that a component
-       //actually exists. We use CT=0.05 of all the samples. By setting CT=0 you get
-       //the standard Stauffer&Grimson algorithm (maybe not exact but very similar)
+    /////////////////////////
+    //very important parameters - things you will change
+    ////////////////////////
+    float fAlphaT;
+    //alpha - speed of update - if the time interval you want to average over is T
+    //set alpha=1/T. It is also usefull at start to make T slowly increase
+    //from 1 until the desired T
+    float fTb;
+    //Tb - threshold on the squared Mahalan. dist. to decide if it is well described
+    //by the background model or not. Related to Cthr from the paper.
+    //This does not influence the update of the background. A typical value could be 4 sigma
+    //and that is Tb=4*4=16;
+    
+    /////////////////////////
+    //less important parameters - things you might change but be carefull
+    ////////////////////////
+    float fTg;
+    //Tg - threshold on the squared Mahalan. dist. to decide
+    //when a sample is close to the existing components. If it is not close
+    //to any a new component will be generated. I use 3 sigma => Tg=3*3=9.
+    //Smaller Tg leads to more generated components and higher Tg might make
+    //lead to small number of components but they can grow too large
+    float fTB;//1-cf from the paper
+    //TB - threshold when the component becomes significant enough to be included into
+    //the background model. It is the TB=1-cf from the paper. So I use cf=0.1 => TB=0.
+    //For alpha=0.001 it means that the mode should exist for approximately 105 frames before
+    //it is considered foreground
+    float fVarInit;
+    float fVarMax;
+    float fVarMin;
+    //initial standard deviation  for the newly generated components.
+    //It will will influence the speed of adaptation. A good guess should be made.
+    //A simple way is to estimate the typical standard deviation from the images.
+    //I used here 10 as a reasonable value
+    float fCT;//CT - complexity reduction prior
+    //this is related to the number of samples needed to accept that a component
+    //actually exists. We use CT=0.05 of all the samples. By setting CT=0 you get
+    //the standard Stauffer&Grimson algorithm (maybe not exact but very similar)
     
-       //even less important parameters
-       int nM;//max number of modes - const - 4 is usually enough
+    //even less important parameters
+    int nM;//max number of modes - const - 4 is usually enough
     
-       //shadow detection parameters
-       unsigned char nShadowDetection;//do shadow detection - insert this value as the detection result
-       float fTau;
-       // Tau - shadow threshold. The shadow is detected if the pixel is darker
-       //version of the background. Tau is a threshold on how much darker the shadow can be.
-       //Tau= 0.5 means that if pixel is more than 2 times darker then it is not shadow
-       //See: Prati,Mikic,Trivedi,Cucchiarra,"Detecting Moving Shadows...",IEEE PAMI,2003.
-};
-
-struct CvPBGMMGaussian
+    //shadow detection parameters
+    bool bShadowDetection;//default 1 - do shadow detection
+    unsigned char nShadowDetection;//do shadow detection - insert this value as the detection result
+    float fTau;
+    // Tau - shadow threshold. The shadow is detected if the pixel is darker
+    //version of the background. Tau is a threshold on how much darker the shadow can be.
+    //Tau= 0.5 means that if pixel is more than 2 times darker then it is not shadow
+    //See: Prati,Mikic,Trivedi,Cucchiarra,"Detecting Moving Shadows...",IEEE PAMI,2003.
+} CvGaussBGStatModel2Params;
+
+#define CV_BGFG_MOG2_NDMAX 3
+
+typedef struct CvPBGMMGaussian
 {
-       float sigma;
-       float muR;
-       float muG;
-       float muB;
-       float weight;
-};
-
-struct CvGaussBGStatModel2Data
-{  
-       int nWidth,nHeight,nSize,nNBands;//image info
-       // dynamic array for the mixture of Gaussians
-    std::vector<CvPBGMMGaussian> rGMM;
-    std::vector<uchar> rnUsedModes;//number of Gaussian components per pixel
-};
+    float weight;
+    float mean[CV_BGFG_MOG2_NDMAX];
+    float variance;
+}CvPBGMMGaussian;
+
+typedef struct CvGaussBGStatModel2Data
+{ 
+    CvPBGMMGaussian* rGMM; //array for the mixture of Gaussians
+    unsigned char* rnUsedModes;//number of Gaussian components per pixel (maximum 255)
+} CvGaussBGStatModel2Data;
 
 //only foreground image is updated
 //no filtering included
-struct CvGaussBGModel2
+typedef struct CvGaussBGModel2
 {
+    CV_BG_STAT_MODEL_FIELDS();
     CvGaussBGStatModel2Params params;
-       CvGaussBGStatModel2Data   data;
-       int                       countFrames;
-};
+    CvGaussBGStatModel2Data   data;
+    int                       countFrames;
+}
+CvGaussBGModel2;
 
-static int _icvRemoveShadowGMM(long posPixel, 
-                                                               float red, float green, float blue, 
+CVAPI(CvBGStatModel*) cvCreateGaussianBGModel2( IplImage* first_frame,
+                                                CvGaussBGStatModel2Params* params CV_DEFAULT(NULL) );
+//shadow detection performed per pixel
+// should work for rgb data, could be usefull for gray scale and depth data as well
+//     See: Prati,Mikic,Trivedi,Cucchiarra,"Detecting Moving Shadows...",IEEE PAMI,2003.
+CV_INLINE int _icvRemoveShadowGMM(float* data, int nD,
                                                                unsigned char nModes, 
-                                                               CvPBGMMGaussian* m_aGaussians,
+                                                               CvPBGMMGaussian* pGMM,
                                                                float m_fTb,
                                                                float m_fTB,    
                                                                float m_fTau)
 {
-       //calculate distances to the modes (+ sort???)
-       //here we need to go in descending order!!!
-       long pos;
        float tWeight = 0;
        float numerator, denominator;
-       // check all the distributions, marked as background:
+       // check all the components  marked as background:
        for (int iModes=0;iModes<nModes;iModes++)
        {
-               pos=posPixel+iModes;
-               float var = m_aGaussians[pos].sigma;
-               float muR = m_aGaussians[pos].muR;
-               float muG = m_aGaussians[pos].muG;
-               float muB = m_aGaussians[pos].muB;
-               float weight = m_aGaussians[pos].weight;
-               tWeight += weight;
-               
-               numerator = red * muR + green * muG + blue * muB;
-               denominator = muR * muR + muG * muG + muB * muB;
+
+               CvPBGMMGaussian g=pGMM[iModes];
+
+               numerator = 0.0f;
+               denominator = 0.0f;
+               for (int iD=0;iD<nD;iD++)
+               {
+                               numerator   += data[iD]  * g.mean[iD];
+                               denominator += g.mean[iD]* g.mean[iD];
+               }
+
                // no division by zero allowed
                if (denominator == 0)
                {
-                               break;
+                               return 0;
                };
                float a = numerator / denominator;
 
                // if tau < a < 1 then also check the color distortion
-               if ((a <= 1) && (a >= m_fTau))//m_nBeta=1
-               {
-                       float dR=a * muR - red;
-                       float dG=a * muG - green;
-                       float dB=a * muB - blue;
-
-                       //square distance -slower and less accurate
-                       //float maxDistance = cvSqrt(m_fTb*var);
-                       //if ((fabs(dR) <= maxDistance) && (fabs(dG) <= maxDistance) && (fabs(dB) <= maxDistance))
-                       //circle
-                       float dist=(dR*dR+dG*dG+dB*dB);
-                       if (dist<m_fTb*var*a*a)
+               if ((a <= 1) && (a >= m_fTau))
+               {
+
+                       float dist2a=0.0f;
+                       
+                       for (int iD=0;iD<nD;iD++)
+                       {
+                               float dD= a*g.mean[iD] - data[iD];
+                               dist2a += (dD*dD);
+                       }
+
+                       if (dist2a<m_fTb*g.variance*a*a)
                        {
                                return 2;
                        }
                };
+
+               tWeight += g.weight;
                if (tWeight > m_fTB)
                {
-                               break;
+                               return 0;
                };
        };
        return 0;
 }
 
-static int _icvUpdatePixelBackgroundGMM(long posPixel, 
-                                                               float red, float green, float blue, 
+//update GMM - the base update function performed per pixel
+//
+//"Efficient Adaptive Density Estimapion per Image Pixel for the Task of Background Subtraction"
+//Z.Zivkovic, F. van der Heijden 
+//Pattern Recognition Letters, vol. 27, no. 7, pages 773-780, 2006.
+//
+//The algorithm similar to the standard Stauffer&Grimson algorithm with
+//additional selection of the number of the Gaussian components based on:
+//
+//"Recursive unsupervised learning of finite mixture models "
+//Z.Zivkovic, F.van der Heijden 
+//IEEE Trans. on Pattern Analysis and Machine Intelligence, vol.26, no.5, pages 651-656, 2004
+//http://www.zoranz.net/Publications/zivkovic2004PAMI.pdf
+
+CV_INLINE int _icvUpdateGMM(float* data, int nD,
                                                                unsigned char* pModesUsed, 
-                                                               CvPBGMMGaussian* m_aGaussians,
+                                                               CvPBGMMGaussian* pGMM,
                                                                int m_nM,
                                                                float m_fAlphaT,
                                                                float m_fTb,
                                                                float m_fTB,    
                                                                float m_fTg,
-                                                               float m_fSigma,
+                                                               float m_fVarInit,
+                                                               float m_fVarMax,
+                                                               float m_fVarMin,
                                                                float m_fPrune)
 {
-       //calculate distances to the modes (+ sort???)
-       //here we need to go in descending order!!!
-       
-       long pos;
-
-       
-       bool bFitsPDF=0;
-       bool bBackground=0;
+       //calculate distances to the modes (+ sort)
+       //here we need to go in descending order!!!     
+       bool bBackground=0;//return value -> true - the pixel classified as background
 
+       //internal:
+       bool bFitsPDF=0;//if it remains zero a new GMM mode will be added       
        float m_fOneMinAlpha=1-m_fAlphaT;
-
-       unsigned char nModes=*pModesUsed;
+       unsigned char nModes=*pModesUsed;//current number of modes in GMM
        float totalWeight=0.0f;
 
        //////
        //go through all modes
-       for (int iModes=0;iModes<nModes;iModes++)
+       int iMode=0;
+       CvPBGMMGaussian* pGauss=pGMM;
+       for (;iMode<nModes;iMode++,pGauss++)
        {
-               pos=posPixel+iModes;
-               float weight = m_aGaussians[pos].weight;
+               float weight = pGauss->weight;//need only weight if fit is found
+               weight=m_fOneMinAlpha*weight+m_fPrune;
 
                ////
                //fit not found yet
                if (!bFitsPDF)
                {
-                       //check if it belongs to some of the modes
-                       //calculate distance
-                       float var = m_aGaussians[pos].sigma;
-                       float muR = m_aGaussians[pos].muR;
-                       float muG = m_aGaussians[pos].muG;
-                       float muB = m_aGaussians[pos].muB;
-               
-                       float dR=muR - red;
-                       float dG=muG - green;
-                       float dB=muB - blue;
+                       //check if it belongs to some of the remaining modes
+                       float var=pGauss->variance;
 
-                       ///////
-                       //check if it fits the current mode (Factor * sigma)
-                       
-                       //square distance -slower and less accurate
-                       //float maxDistance = cvSqrt(m_fTg*var);
-                       //if ((fabs(dR) <= maxDistance) && (fabs(dG) <= maxDistance) && (fabs(dB) <= maxDistance))
-                       //circle
-                       float dist=(dR*dR+dG*dG+dB*dB);
-                       //background? - m_fTb
-                       if ((totalWeight<m_fTB)&&(dist<m_fTb*var))
+                       //calculate difference and distance
+                       float dist2=0.0f;
+#if (CV_BGFG_MOG2_NDMAX==1)
+                       float dData=pGauss->mean[0]-data[0];
+                       dist2=dData*dData;
+#else                  
+                       float dData[CV_BGFG_MOG2_NDMAX];
+
+                       for (int iD=0;iD<nD;iD++)
+                       {
+                               dData[iD]=pGauss->mean[iD]-data[iD];
+                               dist2+=dData[iD]*dData[iD];
+                       }
+#endif         
+                       //background? - m_fTb - usually larger than m_fTg
+                       if ((totalWeight<m_fTB)&&(dist2<m_fTb*var))
                                        bBackground=1;
+
                        //check fit
-                       if (dist<m_fTg*var)
+                       if (dist2<m_fTg*var)
                        {
                                /////
-                               //belongs to the mode
+                               //belongs to the mode - bFitsPDF becomes 1
                                bFitsPDF=1;
 
-                               //update distribution
-                               float k = m_fAlphaT/weight;
-                               weight=m_fOneMinAlpha*weight+m_fPrune;
+                               //update distribution                           
+                               
+                               //update weight
                                weight+=m_fAlphaT;
-                               m_aGaussians[pos].muR = muR - k*(dR);
-                               m_aGaussians[pos].muG = muG - k*(dG);
-                               m_aGaussians[pos].muB = muB - k*(dB);
-
-                               //limit update speed for cov matrice
-                               //not needed
-                               //k=k>20*m_fAlphaT?20*m_fAlphaT:k;
-                               //float sigmanew = var + k*((0.33*(dR*dR+dG*dG+dB*dB))-var);
-                               //float sigmanew = var + k*((dR*dR+dG*dG+dB*dB)-var);
-                               //float sigmanew = var + k*((0.33*dist)-var);
-                               float sigmanew = var + k*(dist-var);
-                               //limit the variance
-                               //m_aGaussians[pos].sigma = sigmanew>70?70:sigmanew;
-                               //m_aGaussians[pos].sigma = sigmanew>5*m_fSigma?5*m_fSigma:sigmanew;
-                               m_aGaussians[pos].sigma =sigmanew< 4 ? 4 : sigmanew>5*m_fSigma?5*m_fSigma:sigmanew;
-                               //m_aGaussians[pos].sigma =sigmanew< 4 ? 4 : sigmanew>3*m_fSigma?3*m_fSigma:sigmanew;
-                               //m_aGaussians[pos].sigma = m_fSigma;
+
+                               float k = m_fAlphaT/weight;
+
+                               //update mean
+#if (CV_BGFG_MOG2_NDMAX==1)
+                               pGauss->mean[0]-=k*dData;
+#else                          
+                               for (int iD=0;iD<nD;iD++)
+                               {
+                                       pGauss->mean[iD]-=k*dData[iD];
+                               }
+#endif
+
+                               //update variance
+                               float varnew = var + k*(dist2-var);
+                               //limit the variance                            
+                               pGauss->variance = MIN(m_fVarMax,MAX(varnew,m_fVarMin));
+
                                //sort
                                //all other weights are at the same place and 
-                               //only the matched (iModes) is higher -> just find the new place for it
-                               for (int iLocal = iModes;iLocal>0;iLocal--)
+                               //only the matched (iModes) is higher -> just find the new place for it                         
+                               for (int iLocal = iMode;iLocal>0;iLocal--)
                                {
-                                       long posLocal=posPixel + iLocal;
-                                       if (weight < (m_aGaussians[posLocal-1].weight))
+                                       //check one up
+                                       if (weight < (pGMM[iLocal-1].weight))
                                        {
                                                break;
                                        }
                                        else
                                        {
-                                               //swap
-                                               CvPBGMMGaussian temp = m_aGaussians[posLocal];
-                                               m_aGaussians[posLocal] = m_aGaussians[posLocal-1];
-                                               m_aGaussians[posLocal-1] = temp;
+                                               //swap one up
+                                               CvPBGMMGaussian temp = pGMM[iLocal];
+                                               pGMM[iLocal] = pGMM[iLocal-1];
+                                               pGMM[iLocal-1] = temp;
+                                               pGauss--;
                                        }
                                }
-
-                               //belongs to the mode
+                               //belongs to the mode - bFitsPDF becomes 1
                                /////
                        }
-                       else
+               }//!bFitsPDF)
+
+               //check prune
+               if (weight<-m_fPrune)
+               {
+                       weight=0.0;
+                       nModes--;
+               }
+
+               pGauss->weight=weight;//update weight by the calculated value
+               totalWeight+=weight;
+       }
+       //go through all modes
+       //////
+
+       //renormalize weights
+       for (iMode = 0; iMode < nModes; iMode++)
+       {
+               pGMM[iMode].weight = pGMM[iMode].weight/totalWeight;
+       }
+       
+       //make new mode if needed and exit
+       if (!bFitsPDF)
+       {
+               if (nModes==m_nM)
+               {
+           //replace the weakest
+                       pGauss=pGMM+m_nM-1;
+               }
+               else
+               {
+           //add a new one
+                       pGauss=pGMM+nModes;
+                       nModes++;
+               }
+
+       if (nModes==1)
+               {
+                       pGauss->weight=1;
+               }
+               else
+               {
+                       pGauss->weight=m_fAlphaT;
+
+                       //renormalize all weights
+                       for (iMode = 0; iMode < nModes-1; iMode++)
                        {
-                               weight=m_fOneMinAlpha*weight+m_fPrune;
-                               //check prune
-                               if (weight<-m_fPrune)
-                               {
-                                       weight=0.0;
-                                       nModes--;
-                               //      bPrune=1;
-                                       //break;//the components are sorted so we can skip the rest
-                               }
+                               pGMM[iMode].weight *=m_fOneMinAlpha;
                        }
-                       //check if it fits the current mode (2.5 sigma)
-                       ///////
                }
+
+               //init 
+               memcpy(pGauss->mean,data,nD*sizeof(float));
+               pGauss->variance=m_fVarInit;
+
+               //sort
+               //find the new place for it
+               for (int iLocal = nModes-1;iLocal>0;iLocal--)
+               {
+                                       //check one up
+                                       if (m_fAlphaT < (pGMM[iLocal-1].weight))
+                                       {
+                                               break;
+                                       }
+                                       else
+                                       {
+                                               //swap one up
+                                               CvPBGMMGaussian temp = pGMM[iLocal];
+                                               pGMM[iLocal] = pGMM[iLocal-1];
+                                               pGMM[iLocal-1] = temp;
+                                       }
+               }
+       }
+
+       //set the number of modes
+       *pModesUsed=nModes;
+
+    return bBackground;
+}
+
+// a bit more efficient implementation for common case of 3 channel (rgb) images
+CV_INLINE int _icvUpdateGMM_C3(float r,float g, float b,
+                                                               unsigned char* pModesUsed, 
+                                                               CvPBGMMGaussian* pGMM,
+                                                               int m_nM,
+                                                               float m_fAlphaT,
+                                                               float m_fTb,
+                                                               float m_fTB,    
+                                                               float m_fTg,
+                                                               float m_fVarInit,
+                                                               float m_fVarMax,
+                                                               float m_fVarMin,
+                                                               float m_fPrune)
+{
+       //calculate distances to the modes (+ sort)
+       //here we need to go in descending order!!!     
+       bool bBackground=0;//return value -> true - the pixel classified as background
+
+       //internal:
+       bool bFitsPDF=0;//if it remains zero a new GMM mode will be added       
+       float m_fOneMinAlpha=1-m_fAlphaT;
+       unsigned char nModes=*pModesUsed;//current number of modes in GMM
+       float totalWeight=0.0f;
+
+       //////
+       //go through all modes
+       int iMode=0;
+       CvPBGMMGaussian* pGauss=pGMM;
+       for (;iMode<nModes;iMode++,pGauss++)
+       {
+               float weight = pGauss->weight;//need only weight if fit is found
+               weight=m_fOneMinAlpha*weight+m_fPrune;
+
+               ////
                //fit not found yet
-               /////
-               else
+               if (!bFitsPDF)
                {
-                               weight=m_fOneMinAlpha*weight+m_fPrune;
-                               //check prune
-                               if (weight<-m_fPrune)
+                       //check if it belongs to some of the remaining modes
+                       float var=pGauss->variance;
+
+                       //calculate difference and distance
+                       float muR = pGauss->mean[0];
+                       float muG = pGauss->mean[1];
+                       float muB = pGauss->mean[2];
+               
+                       float dR=muR - r;
+                       float dG=muG - g;
+                       float dB=muB - b;
+
+                       float dist2=(dR*dR+dG*dG+dB*dB);                
+                       
+                       //background? - m_fTb - usually larger than m_fTg
+                       if ((totalWeight<m_fTB)&&(dist2<m_fTb*var))
+                                       bBackground=1;
+
+                       //check fit
+                       if (dist2<m_fTg*var)
+                       {
+                               /////
+                               //belongs to the mode - bFitsPDF becomes 1
+                               bFitsPDF=1;
+
+                               //update distribution                           
+                               
+                               //update weight
+                               weight+=m_fAlphaT;
+                               
+                               float k = m_fAlphaT/weight;
+
+                               //update mean
+                               pGauss->mean[0] = muR - k*(dR);
+                               pGauss->mean[1] = muG - k*(dG);
+                               pGauss->mean[2] = muB - k*(dB);
+
+                               //update variance
+                               float varnew = var + k*(dist2-var);
+                               //limit the variance                            
+                               pGauss->variance = MIN(m_fVarMax,MAX(varnew,m_fVarMin));
+
+                               //sort
+                               //all other weights are at the same place and 
+                               //only the matched (iModes) is higher -> just find the new place for it                         
+                               for (int iLocal = iMode;iLocal>0;iLocal--)
                                {
+                                       //check one up
+                                       if (weight < (pGMM[iLocal-1].weight))
+                                       {
+                                               break;
+                                       }
+                                       else
+                                       {
+                                               //swap one up
+                                               CvPBGMMGaussian temp = pGMM[iLocal];
+                                               pGMM[iLocal] = pGMM[iLocal-1];
+                                               pGMM[iLocal-1] = temp;
+                                               pGauss--;
+                                       }
+                               }
+                               //belongs to the mode - bFitsPDF becomes 1
+                               /////
+                       }       
+
+               }//!bFitsPDF)
+               
+               //check prunning
+               if (weight<-m_fPrune)
+               {
                                        weight=0.0;
                                        nModes--;
-                               }
                }
+
+               pGauss->weight=weight;
                totalWeight+=weight;
-               m_aGaussians[pos].weight=weight;
        }
        //go through all modes
        //////
 
        //renormalize weights
-       for (int iLocal = 0; iLocal < nModes; iLocal++)
+       for (iMode = 0; iMode < nModes; iMode++)
        {
-               m_aGaussians[posPixel+ iLocal].weight = m_aGaussians[posPixel+ iLocal].weight/totalWeight;
+               pGMM[iMode].weight = pGMM[iMode].weight/totalWeight;
        }
        
        //make new mode if needed and exit
@@ -390,47 +600,53 @@ static int _icvUpdatePixelBackgroundGMM(long posPixel,
                if (nModes==m_nM)
                {
            //replace the weakest
+                       pGauss=pGMM+m_nM-1;
                }
                else
                {
            //add a new one
+                       pGauss=pGMM+nModes;
                        nModes++;
                }
-               pos=posPixel+nModes-1;
 
        if (nModes==1)
-                       m_aGaussians[pos].weight=1;
+               {
+                       pGauss->weight=1;
+               }
                else
-                       m_aGaussians[pos].weight=m_fAlphaT;
-
-               //renormalize weights
-               int iLocal;
-               for (iLocal = 0; iLocal < nModes-1; iLocal++)
                {
-                       m_aGaussians[posPixel+ iLocal].weight *=m_fOneMinAlpha;
+                       pGauss->weight=m_fAlphaT;
+
+                       //renormalize all weights
+                       for (iMode = 0; iMode < nModes-1; iMode++)
+                       {
+                               pGMM[iMode].weight *=m_fOneMinAlpha;
+                       }
                }
 
-               m_aGaussians[pos].muR=red;
-               m_aGaussians[pos].muG=green;
-               m_aGaussians[pos].muB=blue;
-               m_aGaussians[pos].sigma=m_fSigma;
+               //init 
+               pGauss->mean[0]=r;
+               pGauss->mean[1]=g;
+               pGauss->mean[2]=b;
+
+               pGauss->variance=m_fVarInit;
 
                //sort
                //find the new place for it
-               for (iLocal = nModes-1;iLocal>0;iLocal--)
+               for (int iLocal = nModes-1;iLocal>0;iLocal--)
                {
-                       long posLocal=posPixel + iLocal;
-                       if (m_fAlphaT < (m_aGaussians[posLocal-1].weight))
-                       {
+                                       //check one up
+                                       if (m_fAlphaT < (pGMM[iLocal-1].weight))
+                                       {
                                                break;
-                       }
-                       else
-                       {
-                               //swap
-                               CvPBGMMGaussian temp = m_aGaussians[posLocal];
-                               m_aGaussians[posLocal] = m_aGaussians[posLocal-1];
-                               m_aGaussians[posLocal-1] = temp;
-                       }
+                                       }
+                                       else
+                                       {
+                                               //swap one up
+                                               CvPBGMMGaussian temp = pGMM[iLocal];
+                                               pGMM[iLocal] = pGMM[iLocal-1];
+                                               pGMM[iLocal-1] = temp;
+                                       }
                }
        }
 
@@ -440,238 +656,639 @@ static int _icvUpdatePixelBackgroundGMM(long posPixel,
     return bBackground;
 }
 
-static void _icvReplacePixelBackgroundGMM(long pos, 
-                                                               unsigned char* pData, 
-                                                               CvPBGMMGaussian* m_aGaussians)
+//the main function to update the background model
+void icvUpdatePixelBackgroundGMM2( const CvArr* srcarr, CvArr* dstarr ,
+                                                                                CvPBGMMGaussian *pGMM,
+                                                                                unsigned char *pUsedModes,
+                                                                                //CvGaussBGStatModel2Params* pGMMPar,
+                                                                                int nM,
+                                                                                float fTb, 
+                                                                                float fTB, 
+                                                                                float fTg, 
+                                                                                float fVarInit,
+                                                                                float fVarMax,
+                                                                                float fVarMin,
+                                                                                float fCT,
+                                                                                float fTau,
+                                                                                bool bShadowDetection,
+                                                                                unsigned char  nShadowDetection,
+                                                                                float alpha)
+{
+       CvMat sstub, *src = cvGetMat(srcarr, &sstub);
+    CvMat dstub, *dst = cvGetMat(dstarr, &dstub);
+    CvSize size = cvGetMatSize(src);
+       int nD=CV_MAT_CN(src->type);
+
+       //reshape if possible
+    if( CV_IS_MAT_CONT(src->type & dst->type) )
+    {
+        size.width *= size.height;
+        size.height = 1;
+    }
+
+    int x, y;
+       float data[CV_BGFG_MOG2_NDMAX];
+       float prune=-alpha*fCT;
+
+       //general nD
+
+       if (nD!=3)
+       {
+       switch (CV_MAT_DEPTH(src->type))
+       {
+       case CV_8U:
+               for( y = 0; y < size.height; y++ )
+               {
+                       uchar* sptr = src->data.ptr + src->step*y;
+                       uchar* pDataOutput = dst->data.ptr + dst->step*y;
+                       for( x = 0; x < size.width; x++,
+                               pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
+                       {
+                               //convert data
+                               for (int iD=0;iD<nD;iD++) data[iD]=float(sptr[iD]);
+                               //update GMM model
+                               int result = _icvUpdateGMM(data,nD,pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
+                               //detect shadows in the foreground
+                               if (bShadowDetection)
+                                       if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
+                               //generate output
+                               (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
+                       }
+               }
+               break;
+       case CV_16S:
+               for( y = 0; y < size.height; y++ )
+               {
+                       short* sptr = src->data.s + src->step*y;
+                       uchar* pDataOutput = dst->data.ptr + dst->step*y;
+                       for( x = 0; x < size.width; x++,
+                               pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
+                       {
+                               //convert data
+                               for (int iD=0;iD<nD;iD++) data[iD]=float(sptr[iD]);
+                               //update GMM model
+                               int result = _icvUpdateGMM(data,nD,pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
+                               //detect shadows in the foreground
+                               if (bShadowDetection)
+                                       if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
+                               //generate output
+                               (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
+                       }
+               }
+               break;
+       case CV_16U:
+               for( y = 0; y < size.height; y++ )
+               {
+                       unsigned short* sptr = (unsigned short*) (src->data.s + src->step*y);
+                       uchar* pDataOutput = dst->data.ptr + dst->step*y;
+                       for( x = 0; x < size.width; x++,
+                               pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
+                       {
+                               //convert data
+                               for (int iD=0;iD<nD;iD++) data[iD]=float(sptr[iD]);
+                               //update GMM model
+                               int result = _icvUpdateGMM(data,nD,pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
+                               //detect shadows in the foreground
+                               if (bShadowDetection)
+                                       if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
+                               //generate output
+                               (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
+                       }
+               }
+               break;
+       case CV_32S:
+               for( y = 0; y < size.height; y++ )
+               {
+                       int* sptr = src->data.i + src->step*y;
+                       uchar* pDataOutput = dst->data.ptr + dst->step*y;
+                       for( x = 0; x < size.width; x++,
+                               pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
+                       {
+                               //convert data
+                               for (int iD=0;iD<nD;iD++) data[iD]=float(sptr[iD]);
+                               //update GMM model
+                               int result = _icvUpdateGMM(data,nD,pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
+                               //detect shadows in the foreground
+                               if (bShadowDetection)
+                                       if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
+                               //generate output
+                               (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
+                       }
+               }
+               break;
+       case CV_32F:
+               for( y = 0; y < size.height; y++ )
+               {
+                       float* sptr = src->data.fl + src->step*y;
+                       uchar* pDataOutput = dst->data.ptr + dst->step*y;
+                       for( x = 0; x < size.width; x++,
+                               pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
+                       {
+                               //update GMM model
+                               int result = _icvUpdateGMM(sptr,nD,pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
+                               //detect shadows in the foreground
+                               if (bShadowDetection)
+                                       if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
+                               //generate output
+                               (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
+                       }
+               }
+               break;
+       case CV_64F:
+               for( y = 0; y < size.height; y++ )
+               {
+                       double* sptr = src->data.db + src->step*y;
+                       uchar* pDataOutput = dst->data.ptr + dst->step*y;
+                       for( x = 0; x < size.width; x++,
+                               pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
+                       {
+                               //convert data
+                               for (int iD=0;iD<nD;iD++) data[iD]=float(sptr[iD]);
+                               //update GMM model
+                               int result = _icvUpdateGMM(data,nD,pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
+                               //detect shadows in the foreground
+                               if (bShadowDetection)
+                                       if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
+                               //generate output
+                               (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
+                       }
+               }
+               break;
+       }
+       }else ///if (nD==3) - a bit faster
+       {
+       switch (CV_MAT_DEPTH(src->type))
+       {
+       case CV_8U:
+               for( y = 0; y < size.height; y++ )
+               {
+                       uchar* sptr = src->data.ptr + src->step*y;
+                       uchar* pDataOutput = dst->data.ptr + dst->step*y;
+                       for( x = 0; x < size.width; x++,
+                               pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
+                       {
+                               //convert data
+                               data[0]=float(sptr[0]),data[1]=float(sptr[1]),data[2]=float(sptr[2]);
+                               //update GMM model
+                               int result = _icvUpdateGMM_C3(data[0],data[1],data[2],pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
+                               //detect shadows in the foreground
+                               if (bShadowDetection)
+                                       if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
+                               //generate output
+                               (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
+                       }
+               }
+               break;
+       case CV_16S:
+               for( y = 0; y < size.height; y++ )
+               {
+                       short* sptr = src->data.s + src->step*y;
+                       uchar* pDataOutput = dst->data.ptr + dst->step*y;
+                       for( x = 0; x < size.width; x++,
+                               pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
+                       {
+                               //convert data
+                               data[0]=float(sptr[0]),data[1]=float(sptr[1]),data[2]=float(sptr[2]);
+                               //update GMM model
+                               int result = _icvUpdateGMM_C3(data[0],data[1],data[2],pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
+                               //detect shadows in the foreground
+                               if (bShadowDetection)
+                                       if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
+                               //generate output
+                               (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
+                       }
+               }
+               break;
+       case CV_16U:
+               for( y = 0; y < size.height; y++ )
+               {
+                       unsigned short* sptr = (unsigned short*) src->data.s + src->step*y;
+                       uchar* pDataOutput = dst->data.ptr + dst->step*y;
+                       for( x = 0; x < size.width; x++,
+                               pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
+                       {
+                               //convert data
+                               data[0]=float(sptr[0]),data[1]=float(sptr[1]),data[2]=float(sptr[2]);
+                               //update GMM model
+                               int result = _icvUpdateGMM_C3(data[0],data[1],data[2],pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
+                               //detect shadows in the foreground
+                               if (bShadowDetection)
+                                       if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
+                               //generate output
+                               (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
+                       }
+               }
+               break;
+       case CV_32S:
+               for( y = 0; y < size.height; y++ )
+               {
+                       int* sptr = src->data.i + src->step*y;
+                       uchar* pDataOutput = dst->data.ptr + dst->step*y;
+                       for( x = 0; x < size.width; x++,
+                               pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
+                       {
+                               //convert data
+                               data[0]=float(sptr[0]),data[1]=float(sptr[1]),data[2]=float(sptr[2]);
+                               //update GMM model
+                               int result = _icvUpdateGMM_C3(data[0],data[1],data[2],pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
+                               //detect shadows in the foreground
+                               if (bShadowDetection)
+                                       if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
+                               //generate output
+                               (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
+                       }
+               }
+               break;
+       case CV_32F:
+               for( y = 0; y < size.height; y++ )
+               {
+                       float* sptr = src->data.fl + src->step*y;
+                       uchar* pDataOutput = dst->data.ptr + dst->step*y;
+                       for( x = 0; x < size.width; x++,
+                               pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
+                       {
+                               //update GMM model
+                               int result = _icvUpdateGMM_C3(sptr[0],sptr[1],sptr[2],pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
+                               //detect shadows in the foreground
+                               if (bShadowDetection)
+                                       if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
+                               //generate output
+                               (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
+                       }
+               }
+               break;
+       case CV_64F:
+               for( y = 0; y < size.height; y++ )
+               {
+                       double* sptr = src->data.db + src->step*y;
+                       uchar* pDataOutput = dst->data.ptr + dst->step*y;
+                       for( x = 0; x < size.width; x++,
+                               pGMM+=nM,pUsedModes++,pDataOutput++,sptr+=nD)
+                       {
+                               //convert data
+                               data[0]=float(sptr[0]),data[1]=float(sptr[1]),data[2]=float(sptr[2]);
+                               //update GMM model
+                               int result = _icvUpdateGMM_C3(data[0],data[1],data[2],pUsedModes,pGMM,nM,alpha, fTb, fTB, fTg, fVarInit, fVarMax, fVarMin,prune);
+                               //detect shadows in the foreground
+                               if (bShadowDetection)
+                                       if (result==0) result= _icvRemoveShadowGMM(data,nD,(*pUsedModes),pGMM,fTb,fTB,fTau);
+                               //generate output
+                               (* pDataOutput)= (result==1) ? 0 : (result==2) ? (nShadowDetection) : 255; 
+                       }
+               }
+               break;
+       }
+       }//a bit faster for nD=3; 
+}
+
+
+
+//////////////////////////////////////////////
+//implementation as part of the CvBGStatModel
+static void CV_CDECL icvReleaseGaussianBGModel2( CvGaussBGModel2** bg_model );
+static int CV_CDECL icvUpdateGaussianBGModel2( IplImage* curr_frame, CvGaussBGModel2*  bg_model );
+
+
+CV_IMPL CvBGStatModel*
+cvCreateGaussianBGModel2( IplImage* first_frame, CvGaussBGStatModel2Params* parameters )
 {
-       pData[0]=(unsigned char) m_aGaussians[pos].muR;
-       pData[1]=(unsigned char) m_aGaussians[pos].muG;
-       pData[2]=(unsigned char) m_aGaussians[pos].muB;
+    CvGaussBGModel2* bg_model = 0;
+       int w,h;
+    
+    CV_FUNCNAME( "cvCreateGaussianBGModel2" );
+    
+    __BEGIN__;
+
+       CvGaussBGStatModel2Params params;
+    
+    if( !CV_IS_IMAGE(first_frame) )
+        CV_ERROR( CV_StsBadArg, "Invalid or NULL first_frame parameter" );
+
+       if( first_frame->nChannels>CV_BGFG_MOG2_NDMAX )
+        CV_ERROR( CV_StsBadArg, "Maxumum number of channels in the image is excedded (change CV_BGFG_MOG2_MAXBANDS constant)!" );
+
+
+       CV_CALL( bg_model = (CvGaussBGModel2*)cvAlloc( sizeof(*bg_model) ));
+    memset( bg_model, 0, sizeof(*bg_model) );
+    bg_model->type    = CV_BG_MODEL_MOG2;
+    bg_model->release = (CvReleaseBGStatModel) icvReleaseGaussianBGModel2;
+    bg_model->update  = (CvUpdateBGStatModel)  icvUpdateGaussianBGModel2;
+
+    //init parameters  
+    if( parameters == NULL )
+      {                        
+               /* These constants are defined in cvaux/include/cvaux.h: */
+               params.bShadowDetection = 1;
+               params.bPostFiltering=0;
+               params.minArea=CV_BGFG_MOG2_MINAREA;
+
+               //set parameters
+               // K - max number of Gaussians per pixel
+               params.nM = CV_BGFG_MOG2_NGAUSSIANS;//4;                        
+               // Tb - the threshold - n var
+               //pGMM->fTb = 4*4;
+               params.fTb = CV_BGFG_MOG2_STD_THRESHOLD*CV_BGFG_MOG2_STD_THRESHOLD;
+               // Tbf - the threshold
+               //pGMM->fTB = 0.9f;//1-cf from the paper 
+               params.fTB = CV_BGFG_MOG2_BACKGROUND_THRESHOLD;
+               // Tgenerate - the threshold
+               params.fTg = CV_BGFG_MOG2_STD_THRESHOLD_GENERATE*CV_BGFG_MOG2_STD_THRESHOLD_GENERATE;//update the mode or generate new
+               //pGMM->fSigma= 11.0f;//sigma for the new mode
+               params.fVarInit = CV_BGFG_MOG2_VAR_INIT;
+               params.fVarMax = CV_BGFG_MOG2_VAR_MAX;
+               params.fVarMin = CV_BGFG_MOG2_VAR_MIN;
+               // alpha - the learning factor
+               params.fAlphaT = 1.0f/CV_BGFG_MOG2_WINDOW_SIZE;//0.003f;
+               // complexity reduction prior constant
+               params.fCT = CV_BGFG_MOG2_CT;//0.05f;
+
+               //shadow
+               // Shadow detection
+               params.nShadowDetection = (unsigned char)CV_BGFG_MOG2_SHADOW_VALUE;//value 0 to turn off
+               params.fTau = CV_BGFG_MOG2_SHADOW_TAU;//0.5f;// Tau - shadow threshold
+    }
+    else
+    {
+        params = *parameters;
+    }
+
+       bg_model->params = params;
+
+       //image data 
+       w = first_frame->width;
+       h = first_frame->height;
+
+       bg_model->params.nWidth = w;
+       bg_model->params.nHeight = h;
+
+       bg_model->params.nND = first_frame->nChannels;
+
+
+       //allocate GMM data
+
+       //GMM for each pixel
+       bg_model->data.rGMM = (CvPBGMMGaussian*) malloc(w*h * params.nM * sizeof(CvPBGMMGaussian));
+       //used modes per pixel
+       bg_model->data.rnUsedModes = (unsigned char* ) malloc(w*h);
+       memset(bg_model->data.rnUsedModes,0,w*h);//no modes used
+  
+    //prepare storages    
+    CV_CALL( bg_model->background = cvCreateImage(cvSize(w,h), IPL_DEPTH_8U, first_frame->nChannels));
+    CV_CALL( bg_model->foreground = cvCreateImage(cvSize(w,h), IPL_DEPTH_8U, 1));
+    
+       //for eventual filtering
+    CV_CALL( bg_model->storage = cvCreateMemStorage());
+       
+       bg_model->countFrames = 0;
+
+    __END__;
+    
+    if( cvGetErrStatus() < 0 )
+    {
+        CvBGStatModel* base_ptr = (CvBGStatModel*)bg_model;
+        
+        if( bg_model && bg_model->release )
+            bg_model->release( &base_ptr );
+        else
+            cvFree( &bg_model );
+        bg_model = 0;
+    }
+    
+    return (CvBGStatModel*)bg_model;
 }
 
 
-static void icvUpdatePixelBackgroundGMM(CvGaussBGStatModel2Data* pGMMData,CvGaussBGStatModel2Params* pGMM, float m_fAlphaT, unsigned char* data,unsigned char* output)
+static void CV_CDECL
+icvReleaseGaussianBGModel2( CvGaussBGModel2** _bg_model )
 {
-       int size=pGMMData->nSize;
-       unsigned char* pDataCurrent=data;
-       unsigned char* pUsedModes=&pGMMData->rnUsedModes[0];
-       unsigned char* pDataOutput=output;
-       //some constants
-       int m_nM=pGMM->nM;
-       //float m_fAlphaT=pGMM->fAlphaT;
-
-       float m_fTb=pGMM->fTb;//Tb - threshold on the Mahalan. dist.
-       float m_fTB=pGMM->fTB;//1-TF from the paper
-       float m_fTg=pGMM->fTg;//Tg - when to generate a new component
-       float m_fSigma=pGMM->fSigma;//initial sigma
-       float m_fCT=pGMM->fCT;//CT - complexity reduction prior 
-       float m_fPrune=-m_fAlphaT*m_fCT;
-       float m_fTau=pGMM->fTau;
-       CvPBGMMGaussian* m_aGaussians=&pGMMData->rGMM[0];
-       long posPixel=0;
-       bool m_bShadowDetection=pGMM->bShadowDetection;
-       unsigned char m_nShadowDetection=pGMM->nShadowDetection;
-
-       //go through the image
-       for (int i=0;i<size;i++)
+    CV_FUNCNAME( "icvReleaseGaussianBGModel2" );
+
+    __BEGIN__;
+    
+    if( !_bg_model )
+        CV_ERROR( CV_StsNullPtr, "" );
+
+    if( *_bg_model )
+    {
+        CvGaussBGModel2* bg_model = *_bg_model;
+
+               free (bg_model->data.rGMM);
+               free (bg_model->data.rnUsedModes);
+
+        cvReleaseImage( &bg_model->background );
+        cvReleaseImage( &bg_model->foreground );
+        cvReleaseMemStorage(&bg_model->storage);
+        memset( bg_model, 0, sizeof(*bg_model) );
+        cvFree( _bg_model );
+    }
+
+    __END__;
+}
+
+
+static int CV_CDECL
+icvUpdateGaussianBGModel2( IplImage* curr_frame, CvGaussBGModel2*  bg_model )
+{ 
+       //checks        
+       if ((curr_frame->height!=bg_model->params.nHeight)||(curr_frame->width!=bg_model->params.nWidth)||(curr_frame->nChannels!=bg_model->params.nND))
+               CV_Error( CV_StsBadSize, "the image not the same size as the reserved GMM background model");
+
+       float alpha=bg_model->params.fAlphaT;
+       bg_model->countFrames++;
+       
+       //faster initial updates - increase value of alpha
+       if (bg_model->params.bInit){
+               float alphaInit=(1.0f/(2*bg_model->countFrames+1));
+               if (alphaInit>alpha)
+               {
+                       alpha = alphaInit;
+               }
+               else
+               {
+                       bg_model->params.bInit = 0;
+               }
+       }
+
+       //update background
+       //icvUpdatePixelBackgroundGMM2( curr_frame, bg_model->foreground, bg_model->data.rGMM,bg_model->data.rnUsedModes,&(bg_model->params),alpha);
+       icvUpdatePixelBackgroundGMM2( curr_frame, bg_model->foreground, bg_model->data.rGMM,bg_model->data.rnUsedModes,
+               bg_model->params.nM,
+               bg_model->params.fTb,
+               bg_model->params.fTB,
+               bg_model->params.fTg,
+               bg_model->params.fVarInit,
+               bg_model->params.fVarMax,
+               bg_model->params.fVarMin,
+               bg_model->params.fCT,
+               bg_model->params.fTau,
+               bg_model->params.bShadowDetection,
+               bg_model->params.nShadowDetection,
+               alpha);
+
+       //foreground filtering
+       if (bg_model->params.bPostFiltering==1)
        {
-               // retrieve the colors
-               float red = pDataCurrent[0];
-               float green = pDataCurrent[1];
-               float blue = pDataCurrent[2];
-               
-               //update model+ background subtract
-               int result = _icvUpdatePixelBackgroundGMM(posPixel, red, green, blue,pUsedModes,m_aGaussians,
-                       m_nM,m_fAlphaT, m_fTb, m_fTB, m_fTg, m_fSigma, m_fPrune);
-               unsigned char nMLocal=*pUsedModes;
-               
-               if (m_bShadowDetection)
-                               if (!result)
-                               {
-                                       result= _icvRemoveShadowGMM(posPixel, red, green, blue,nMLocal,m_aGaussians,
-                                                               m_fTb,
-                                                               m_fTB,  
-                                                               m_fTau);
-                               }
+               int region_count = 0;
+               CvSeq *first_seq = NULL, *prev_seq = NULL, *seq = NULL;
 
-               
-               switch (result)
+
+               //filter small regions
+               cvClearMemStorage(bg_model->storage);
+
+               cvMorphologyEx( bg_model->foreground, bg_model->foreground, 0, 0, CV_MOP_OPEN, 1 );
+               cvMorphologyEx( bg_model->foreground, bg_model->foreground, 0, 0, CV_MOP_CLOSE, 1 );
+
+               cvFindContours( bg_model->foreground, bg_model->storage, &first_seq, sizeof(CvContour), CV_RETR_LIST );
+               for( seq = first_seq; seq; seq = seq->h_next )
                {
-                       case 0:
-                               //foreground
-                               (* pDataOutput)=255;
-                               if (pGMM->bRemoveForeground) 
+                       CvContour* cnt = (CvContour*)seq;
+                       if( cnt->rect.width * cnt->rect.height < bg_model->params.minArea )
+                       {
+                               //delete small contour
+                               prev_seq = seq->h_prev;
+                               if( prev_seq )
                                {
-                                       _icvReplacePixelBackgroundGMM(posPixel,pDataCurrent,m_aGaussians);
+                                       prev_seq->h_next = seq->h_next;
+                                       if( seq->h_next ) seq->h_next->h_prev = prev_seq;
                                }
-                               break;
-                       case 1:
-                               //background
-                               (* pDataOutput)=0;
-                               break;
-                       case 2:
-                               //shadow
-                               (* pDataOutput)=m_nShadowDetection;
-                               if (pGMM->bRemoveForeground) 
+                               else
                                {
-                                       _icvReplacePixelBackgroundGMM(posPixel,pDataCurrent,m_aGaussians);
+                                       first_seq = seq->h_next;
+                                       if( seq->h_next ) seq->h_next->h_prev = NULL;
                                }
-
-                               break;
+                       }
+                       else
+                       {
+                               region_count++;
+                       }
                }
-               posPixel+=m_nM;
-               pDataCurrent+=3;
-               pDataOutput++;
-               pUsedModes++;
+               bg_model->foreground_regions = first_seq;
+               cvZero(bg_model->foreground);
+               cvDrawContours(bg_model->foreground, first_seq, CV_RGB(0, 0, 255), CV_RGB(0, 0, 255), 10, -1);
+
+               return region_count; 
        }
+
+       return 1;
 }
 
 
 namespace cv
 {
 
+static const int defaultHistory2 = CV_BGFG_MOG2_WINDOW_SIZE;
+static const float defaultVarThreshold2 = CV_BGFG_MOG2_STD_THRESHOLD*CV_BGFG_MOG2_STD_THRESHOLD;
+static const int defaultNMixtures2 = CV_BGFG_MOG2_NGAUSSIANS;
+static const float defaultBackgroundRatio2 = CV_BGFG_MOG2_BACKGROUND_THRESHOLD;
+static const float defaultVarThresholdGen2 = CV_BGFG_MOG2_STD_THRESHOLD_GENERATE*CV_BGFG_MOG2_STD_THRESHOLD_GENERATE;
+static const float defaultVarInit2 = CV_BGFG_MOG2_VAR_INIT;
+static const float defaultVarMax2 = CV_BGFG_MOG2_VAR_MAX;
+static const float defaultVarMin2 = CV_BGFG_MOG2_VAR_MIN;
+static const float defaultfCT2 = CV_BGFG_MOG2_CT;
+static const unsigned char defaultnShadowDetection2 = (unsigned char)CV_BGFG_MOG2_SHADOW_VALUE;
+static const float defaultfTau = CV_BGFG_MOG2_SHADOW_TAU;
+
+
 BackgroundSubtractorMOG2::BackgroundSubtractorMOG2()
 {
-    model = 0;
-    initialize(Size(), 0);
-}
+    frameSize = Size(0,0);
+    frameType = 0;
+    
+    nframes = 0;
+    history = defaultHistory2;
+       varThreshold = defaultVarThreshold2;
+       bShadowDetection = 1;
 
-BackgroundSubtractorMOG2::BackgroundSubtractorMOG2(double alphaT,
-    double sigma, int nmixtures, bool postFiltering, double minArea,
-    bool detectShadows, bool removeForeground, double Tb, double Tg,
-    double TB, double CT, int shadowValue, double tau)
-{
-    model = 0;
-    initialize(Size(), alphaT, sigma, nmixtures, postFiltering, minArea,
-               detectShadows, removeForeground, Tb, Tg, TB, CT, shadowValue, tau);
-}
+       nmixtures = defaultNMixtures2;   
+       backgroundRatio = defaultBackgroundRatio2;
+       fVarInit = defaultVarInit2;
+       fVarMax  = defaultVarMax2;
+       fVarMin = defaultVarMin2;
 
+       varThresholdGen = defaultVarThresholdGen2;
+       fCT = defaultfCT2;
+       nShadowDetection =  defaultnShadowDetection2;
+       fTau = defaultfTau;
+}
     
-void BackgroundSubtractorMOG2::initialize(Size frameSize, double alphaT,
-    double sigma, int nmixtures, bool postFiltering, double minArea,
-    bool detectShadows, bool removeForeground, double Tb, double Tg,
-    double TB, double CT, int shadowValue, double tau)
+BackgroundSubtractorMOG2::BackgroundSubtractorMOG2(int _history,  float _varThreshold, bool _bShadowDetection)
 {
-    if(!model)
-        model = new CvGaussBGModel2;
-    
-    CvGaussBGModel2* bg_model = (CvGaussBGModel2*)model;
-        
-    bg_model->params.bRemoveForeground=removeForeground;
-    bg_model->params.bShadowDetection = detectShadows;
-    bg_model->params.bPostFiltering = postFiltering;
-    bg_model->params.minArea = minArea;
-    bg_model->params.nM = nmixtures;
-    bg_model->params.fTb = Tb;
-    bg_model->params.fTB = TB;
-    bg_model->params.fTg = Tg;
-    bg_model->params.fSigma = sigma;
-    bg_model->params.fAlphaT = alphaT;
-    bg_model->params.fCT = CT;
-    bg_model->params.nShadowDetection = shadowValue;
-    bg_model->params.fTau = tau;
+    frameSize = Size(0,0);
+    frameType = 0;
     
-    int w = frameSize.width;
-    int h = frameSize.height;
-    int size = w*h;
-    
-    if( (bg_model->data.nWidth != w ||
-        bg_model->data.nHeight != h) &&
-        w > 0 && h > 0 )
-    {
-        bg_model->data.nWidth=w;
-        bg_model->data.nHeight=h;
-        bg_model->data.nNBands=3;
-        bg_model->data.nSize=size;
-        
-        //GMM for each pixel
-        bg_model->data.rGMM.resize(size * bg_model->params.nM);
-    }
-    //used modes per pixel
-    bg_model->data.rnUsedModes.resize(0);
-    bg_model->data.rnUsedModes.resize(size, (uchar)0);
-    bg_model->params.bInit = true;
-    bg_model->countFrames = 0;
-}
+    nframes = 0;
+    history = _history > 0 ? _history : defaultHistory2;
+       varThreshold = (_varThreshold>0)? _varThreshold : defaultVarThreshold2;
+       bShadowDetection = _bShadowDetection;
 
+       nmixtures = defaultNMixtures2;   
+       backgroundRatio = defaultBackgroundRatio2;
+       fVarInit = defaultVarInit2;
+       fVarMax  = defaultVarMax2;
+       fVarMin = defaultVarMin2;
+
+       varThresholdGen = defaultVarThresholdGen2;
+       fCT = defaultfCT2;
+       nShadowDetection =  defaultnShadowDetection2;
+       fTau = defaultfTau;
+}
     
 BackgroundSubtractorMOG2::~BackgroundSubtractorMOG2()
 {
-    delete (CvGaussBGModel2*)model;
 }
 
-void BackgroundSubtractorMOG2::operator()(const Mat& image0, Mat& fgmask0, double learningRate)
+
+void BackgroundSubtractorMOG2::initialize(Size _frameSize, int _frameType)
 {
-    CvGaussBGModel2* bg_model = (CvGaussBGModel2*)model;
+    frameSize = _frameSize;
+    frameType = _frameType;
+    nframes = 0;
     
-    CV_Assert(bg_model != 0);
-    Mat image = image0, fgmask = fgmask0;
-    CV_Assert( image.type() == CV_8UC1 || image.type() == CV_8UC3 );
-    
-    if( learningRate < 0 )
-        learningRate = bg_model->params.fAlphaT;
-    if( learningRate >= 1 )
-    {
-        learningRate = 1;
-        bg_model->params.bInit = true;
-    }
-    if( image.size() != Size(bg_model->data.nWidth, bg_model->data.nHeight) )
-        initialize(image.size(), learningRate, bg_model->params.fSigma,
-                   bg_model->params.nM, bg_model->params.bPostFiltering,
-                   bg_model->params.minArea, bg_model->params.bShadowDetection,
-                   bg_model->params.bRemoveForeground,
-                   bg_model->params.fTb, bg_model->params.fTg, bg_model->params.fTB,
-                   bg_model->params.fCT, bg_model->params.nShadowDetection, bg_model->params.fTau);
+    int nchannels = CV_MAT_CN(frameType);
+       CV_Assert( nchannels <= CV_BGFG_MOG2_NDMAX );
     
-    //int i, j, k, n;
-       float alpha = (float)bg_model->params.fAlphaT;
-       bg_model->countFrames++;
+    // for each gaussian mixture of each pixel bg model we store ...
+    // the mixture weight (w),
+    // the mean (nchannels values) and
+    // the covariance
+    bgmodel.create( 1, frameSize.height*frameSize.width*nmixtures*(2 + CV_BGFG_MOG2_NDMAX), CV_32F );
+       //make the array for keeping track of the used modes per pixel - all zeros at start
+       bgmodelUsedModes.create(frameSize,CV_8U);
+    bgmodelUsedModes = Scalar::all(0);
+}
+
+void BackgroundSubtractorMOG2::operator()(const InputArray& _image, OutputArray _fgmask, double learningRate)
+{
+    Mat image = _image.getMat();
+    bool needToInitialize = nframes == 0 || learningRate >= 1 || image.size() != frameSize || image.type() != frameType;
     
-       if (bg_model->params.bInit)
-    {
-               //faster initial updates
-               float alphaInit = 1.0f/(2*bg_model->countFrames+1);
-               if( alphaInit > alpha )
-                       alpha = alphaInit;
-               else
-                       bg_model->params.bInit = false;
-       }
+    if( needToInitialize )
+        initialize(image.size(), image.type());
     
-    if( !image.isContinuous() || image.channels() != 3 )
-    {
-        image.release();
-        image.create(image0.size(), CV_8UC3);
-        if( image0.type() == image.type() )
-            image0.copyTo(image);
-        else
-            cvtColor(image0, image, CV_GRAY2BGR);
-    }
-
-    if( !fgmask.isContinuous() )
-        fgmask.release();
-    fgmask.create(image.size(), CV_8UC1);
-                     
-    icvUpdatePixelBackgroundGMM(&bg_model->data,&bg_model->params,alpha,image.data,fgmask.data);
+    _fgmask.create( image.size(), CV_8U );
+    Mat fgmask = _fgmask.getMat();
     
-       if( bg_model->params.bPostFiltering )
-    {
-        //foreground filtering: filter out small regions    
-        morphologyEx(fgmask, fgmask, CV_MOP_OPEN, Mat());
-        morphologyEx(fgmask, fgmask, CV_MOP_CLOSE, Mat());
-        
-        vector<vector<Point> > contours;
-        findContours(fgmask, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
-        fgmask = Scalar::all(0);
-        
-        for( size_t i = 0; i < contours.size(); i++ )
-        {
-            if( boundingRect(Mat(contours[i])).area() < bg_model->params.minArea )
-                continue;
-            drawContours(fgmask, contours, (int)i, Scalar::all(255), -1, 8, vector<Vec4i>(), 1);
-        }
-    }
+    ++nframes;
+    learningRate = learningRate >= 0 && nframes > 1 ? learningRate : 1./min( 2*nframes, history );
+    CV_Assert(learningRate >= 0);
+    CvMat _cimage = image, _cfgmask = fgmask;
     
-    fgmask.copyTo(fgmask0);
+       if (learningRate > 0) 
+               icvUpdatePixelBackgroundGMM2( &_cimage, &_cfgmask, 
+               (CvPBGMMGaussian*) bgmodel.data,
+               bgmodelUsedModes.data,
+               nmixtures,//nM
+               varThreshold,//fTb
+               backgroundRatio,//fTB
+               varThresholdGen,//fTg,
+               fVarInit,
+               fVarMax,
+               fVarMin,
+               fCT,
+               fTau,
+               bShadowDetection,
+               nShadowDetection,
+               float(learningRate));
 }
 
 }
index 0c8bf11..0472ad8 100644 (file)
@@ -289,29 +289,25 @@ cvCamShift( const void* imgProb, CvRect windowIn,
     return itersUsed;
 }
 
-namespace cv
-{
 
-RotatedRect CamShift( const Mat& probImage, Rect& window,
+cv::RotatedRect cv::CamShift( const InputArray& _probImage, Rect& window,
                       TermCriteria criteria )
 {
     CvConnectedComp comp;
     CvBox2D box;
-    CvMat _probImage = probImage;
-    cvCamShift(&_probImage, window, (CvTermCriteria)criteria, &comp, &box);
+    CvMat c_probImage = _probImage.getMat();
+    cvCamShift(&c_probImage, window, (CvTermCriteria)criteria, &comp, &box);
     window = comp.rect;
     return RotatedRect(Point2f(box.center), Size2f(box.size), box.angle);
 }
 
-int meanShift( const Mat& probImage, Rect& window, TermCriteria criteria )
+int cv::meanShift( const InputArray& _probImage, Rect& window, TermCriteria criteria )
 {
     CvConnectedComp comp;
-    CvMat _probImage = probImage;
-    int iters = cvMeanShift(&_probImage, window, (CvTermCriteria)criteria, &comp );
+    CvMat c_probImage = _probImage.getMat();
+    int iters = cvMeanShift(&c_probImage, window, (CvTermCriteria)criteria, &comp );
     window = comp.rect;
     return iters;
 }
 
-}
-
 /* End of file. */
index 4870dee..bc3f993 100644 (file)
 #include <float.h>
 #include <stdio.h>
 
-namespace cv
-{
-
-void calcOpticalFlowPyrLK( const Mat& prevImg, const Mat& nextImg,
-                           const vector<Point2f>& prevPts,
-                           vector<Point2f>& nextPts,
-                           vector<uchar>& status, vector<float>& err,
+void cv::calcOpticalFlowPyrLK( const InputArray& _prevImg, const InputArray& _nextImg,
+                           const InputArray& _prevPts, InputOutputArray _nextPts,
+                           OutputArray _status, OutputArray _err,
                            Size winSize, int maxLevel,
                            TermCriteria criteria,
                            double derivLambda,
                            int flags )
 {
+    Mat prevImg = _prevImg.getMat(), nextImg = _nextImg.getMat(), prevPtsMat = _prevPts.getMat();
     derivLambda = std::min(std::max(derivLambda, 0.), 1.);
     double lambda1 = 1. - derivLambda, lambda2 = derivLambda;
     const int derivKernelSize = 3;
@@ -66,16 +63,34 @@ void calcOpticalFlowPyrLK( const Mat& prevImg, const Mat& nextImg,
     CV_Assert( prevImg.size() == nextImg.size() &&
         prevImg.type() == nextImg.type() );
 
-    size_t npoints = prevPts.size();
-    nextPts.resize(npoints);
-    status.resize(npoints);
-    for( size_t i = 0; i < npoints; i++ )
-        status[i] = true;
-    err.resize(npoints);
-
+    size_t npoints = prevPtsMat.total();
     if( npoints == 0 )
+    {
+        _nextPts.release();
+        _status.release();
+        _err.release();
         return;
+    }
+    
+    CV_Assert( prevPtsMat.isContinuous() );
+    const Point2f* prevPts = (const Point2f*)prevPtsMat.data;
+    
+    _nextPts.create((int)npoints, 1, prevPtsMat.type(), -1, true);
+    Mat nextPtsMat = _nextPts.getMat();
+    CV_Assert( nextPtsMat.isContinuous() );
+    Point2f* nextPts = (Point2f*)nextPtsMat.data;
     
+    _status.create((int)npoints, 1, CV_8U, -1, true);
+    Mat statusMat = _status.getMat();
+    CV_Assert( statusMat.isContinuous() );
+    uchar* status = statusMat.data;
+    for( size_t i = 0; i < npoints; i++ )
+        status[i] = true;
+    _err.create((int)npoints, 1, CV_32F, -1, true);
+    Mat errMat = _err.getMat();
+    CV_Assert( errMat.isContinuous() );
+    float* err = (float*)errMat.data;
+
     vector<Mat> prevPyr, nextPyr;
 
     int cn = prevImg.channels();
@@ -334,8 +349,6 @@ void calcOpticalFlowPyrLK( const Mat& prevImg, const Mat& nextImg,
     }
 }
 
-}
-
 static void
 intersect( CvPoint2D32f pt, CvSize win_size, CvSize imgSize,
            CvPoint* min_pt, CvPoint* max_pt )
@@ -1852,18 +1865,14 @@ cvEstimateRigidTransform( const CvArr* matA, const CvArr* matB, CvMat* matM, int
     return 1;
 }
 
-namespace cv
-{
-
-Mat estimateRigidTransform( const Mat& A,
-                            const Mat& B,
-                            bool fullAffine )
+cv::Mat cv::estimateRigidTransform( const InputArray& A,
+                                    const InputArray& B,
+                                    bool fullAffine )
 {
     Mat M(2, 3, CV_64F);
-    CvMat matA = A, matB = B, matM = M;
+    CvMat matA = A.getMat(), matB = B.getMat(), matM = M;
     cvEstimateRigidTransform(&matA, &matB, &matM, fullAffine);
     return M;
 }
-}
 
 /* End of file. */
index 1c94354..44eaa9d 100644 (file)
@@ -442,38 +442,40 @@ cvSegmentMotion( const CvArr* mhiimg, CvArr* segmask, CvMemStorage* storage,
 }
 
 
-void cv::updateMotionHistory( const Mat& silhouette, Mat& mhi,
+void cv::updateMotionHistory( const InputArray& _silhouette, InputOutputArray _mhi,
                               double timestamp, double duration )
 {
-    CvMat _silhouette = silhouette, _mhi = mhi;
-    cvUpdateMotionHistory( &_silhouette, &_mhi, timestamp, duration );
+    CvMat c_silhouette = _silhouette.getMat(), c_mhi = _mhi.getMat();
+    cvUpdateMotionHistory( &c_silhouette, &c_mhi, timestamp, duration );
 }
 
-void cv::calcMotionGradient( const Mat& mhi, Mat& mask,
-                             Mat& orientation,
+void cv::calcMotionGradient( const InputArray& _mhi, OutputArray _mask,
+                             OutputArray _orientation,
                              double delta1, double delta2,
                              int aperture_size )
 {
-    mask.create(mhi.size(), CV_8U);
-    orientation.create(mhi.size(), CV_32F);
-    CvMat _mhi = mhi, _mask = mask, _orientation = orientation;
-    cvCalcMotionGradient(&_mhi, &_mask, &_orientation, delta1, delta2, aperture_size);
+    Mat mhi = _mhi.getMat();
+    _mask.create(mhi.size(), CV_8U);
+    _orientation.create(mhi.size(), CV_32F);
+    CvMat c_mhi = mhi, c_mask = _mask.getMat(), c_orientation = _orientation.getMat();
+    cvCalcMotionGradient(&c_mhi, &c_mask, &c_orientation, delta1, delta2, aperture_size);
 }
 
-double cv::calcGlobalOrientation( const Mat& orientation, const Mat& mask,
-                                  const Mat& mhi, double timestamp,
+double cv::calcGlobalOrientation( const InputArray& _orientation, const InputArray& _mask,
+                                  const InputArray& _mhi, double timestamp,
                                   double duration )
 {
-    CvMat _orientation = orientation, _mask = mask, _mhi = mhi;
-    return cvCalcGlobalOrientation(&_orientation, &_mask, &_mhi, timestamp, duration);
+    CvMat c_orientation = _orientation.getMat(), c_mask = _mask.getMat(), c_mhi = _mhi.getMat();
+    return cvCalcGlobalOrientation(&c_orientation, &c_mask, &c_mhi, timestamp, duration);
 }
 
-void cv::segmentMotion(const Mat& mhi, Mat& segmask,
+void cv::segmentMotion(const InputArray& _mhi, OutputArray _segmask,
                        vector<Rect>& boundingRects,
                        double timestamp, double segThresh)
 {
-    segmask.create(mhi.size(), CV_32F);
-    CvMat c_mhi = mhi, c_segmask = segmask;
+    Mat mhi = _mhi.getMat();
+    _segmask.create(mhi.size(), CV_32F);
+    CvMat c_mhi = mhi, c_segmask = _segmask.getMat();
     Ptr<CvMemStorage> storage = cvCreateMemStorage();
     Seq<CvConnectedComp> comps = cvSegmentMotion(&c_mhi, &c_segmask, storage, timestamp, segThresh);
     Seq<CvConnectedComp>::const_iterator it(comps);
index 8d622e6..5b72af2 100644 (file)
@@ -561,22 +561,24 @@ FarnebackUpdateFlow_GaussianBlur( const Mat& _R0, const Mat& _R1,
     }
 }
 
+}
 
-void calcOpticalFlowFarneback( const Mat& prev0, const Mat& next0,
-                               Mat& flow0, double pyr_scale, int levels, int winsize,
+void cv::calcOpticalFlowFarneback( const InputArray& _prev0, const InputArray& _next0,
+                               OutputArray _flow0, double pyr_scale, int levels, int winsize,
                                int iterations, int poly_n, double poly_sigma, int flags )
 {
+    Mat prev0 = _prev0.getMat(), next0 = _next0.getMat();
     const int min_size = 32;
     const Mat* img[2] = { &prev0, &next0 };
-    Mat fimg;
 
     int i, k;
     double scale;
-    Mat prevFlow, flow;
+    Mat prevFlow, flow, fimg;
 
     CV_Assert( prev0.size() == next0.size() && prev0.channels() == next0.channels() &&
         prev0.channels() == 1 && pyr_scale < 1 );
-    flow0.create( prev0.size(), CV_32FC2 );
+    _flow0.create( prev0.size(), CV_32FC2 );
+    Mat flow0 = _flow0.getMat();
 
     for( k = 0, scale = 1; k < levels; k++ )
     {
@@ -643,7 +645,6 @@ void calcOpticalFlowFarneback( const Mat& prev0, const Mat& next0,
     }
 }
 
-}
 
 CV_IMPL void cvCalcOpticalFlowFarneback(
             const CvArr* _prev, const CvArr* _next,
index 452c73b..fe7425a 100644 (file)
@@ -169,12 +169,15 @@ double CV_UpdateMHITest::get_success_error_level( int /*test_case_idx*/, int /*i
 
 void CV_UpdateMHITest::run_func()
 {
-    cvUpdateMotionHistory( test_array[INPUT][0], test_array[INPUT_OUTPUT][0], timestamp, duration );
+    CvMat m = test_mat[INPUT_OUTPUT][0];
+    cv::updateMotionHistory( test_mat[INPUT][0], test_mat[INPUT_OUTPUT][0], timestamp, duration);
+    m = test_mat[INPUT_OUTPUT][0];
 }
 
 
 void CV_UpdateMHITest::prepare_to_validation( int /*test_case_idx*/ )
 {
+    CvMat m0 = test_mat[REF_INPUT_OUTPUT][0];
     test_updateMHI( test_mat[INPUT][0], test_mat[REF_INPUT_OUTPUT][0], timestamp, duration );
 }
 
@@ -290,8 +293,10 @@ double CV_MHIGradientTest::get_success_error_level( int /*test_case_idx*/, int /
 
 void CV_MHIGradientTest::run_func()
 {
-    cvCalcMotionGradient( test_array[INPUT][0], test_array[OUTPUT][0],
-                          test_array[OUTPUT][1], delta1, delta2, aperture_size );
+    cv::calcMotionGradient(test_mat[INPUT][0], test_mat[OUTPUT][0],
+                           test_mat[OUTPUT][1], delta1, delta2, aperture_size );
+    //cvCalcMotionGradient( test_array[INPUT][0], test_array[OUTPUT][0],
+    //                      test_array[OUTPUT][1], delta1, delta2, aperture_size );
 }
 
 
@@ -453,8 +458,10 @@ double CV_MHIGlobalOrientTest::get_success_error_level( int /*test_case_idx*/, i
 
 void CV_MHIGlobalOrientTest::run_func()
 {
-    angle = cvCalcGlobalOrientation( test_array[INPUT][2], test_array[INPUT][1],
-                                     test_array[INPUT][0], timestamp, duration );
+    //angle = cvCalcGlobalOrientation( test_array[INPUT][2], test_array[INPUT][1],
+    //                                 test_array[INPUT][0], timestamp, duration );
+    angle = cv::calcGlobalOrientation(test_mat[INPUT][2], test_mat[INPUT][1],
+                                      test_mat[INPUT][0], timestamp, duration );
 }