diff --git a/modules/python/cv.cpp b/modules/python/cv.cpp
index b19cfde8e..8243d535f 100644
--- a/modules/python/cv.cpp
+++ b/modules/python/cv.cpp
@@ -3847,10 +3847,21 @@ static int zero = 0;
 
 #include "generated0.i"
 
+#include "opencv2x.h"
+
 static PyMethodDef methods[] = {
 
 #if PYTHON_USE_NUMPY
-  {"fromarray", (PyCFunction)pycvfromarray, METH_KEYWORDS, "fromarray(array) -> cvmatnd"},
+    {"fromarray", (PyCFunction)pycvfromarray, METH_KEYWORDS, "fromarray(array) -> cvmatnd"},
+  
+    {"absdiff", (PyCFunction)cv::pyopencv_absdiff, METH_KEYWORDS, "absdiff(src1,src2,dst=None) -> dst"},    
+    {"add", (PyCFunction)cv::pyopencv_add, METH_KEYWORDS, "add(src1,src2,dst=None,mask=None) -> dst"},
+    {"bitwise_and", (PyCFunction)cv::pyopencv_and, METH_KEYWORDS, "bitwise_and(src1,src2,dst=None,mask=None) -> dst"},
+    {"bitwise_or", (PyCFunction)cv::pyopencv_or, METH_KEYWORDS, "bitwise_or(src1,src2,dst=None,mask=None) -> dst"},
+    {"bitwise_xor", (PyCFunction)cv::pyopencv_xor, METH_KEYWORDS, "bitwise_xor(src1,src2,dst=None,mask=None) -> dst"},
+    {"max", (PyCFunction)cv::pyopencv_max, METH_KEYWORDS, "max(src1,src2,dst=None) -> dst"},
+    {"min", (PyCFunction)cv::pyopencv_min, METH_KEYWORDS, "min(src1,src2,dst=None) -> dst"},
+    {"subtract", (PyCFunction)cv::pyopencv_subtract, METH_KEYWORDS, "subtract(src1,src2,dst=None,mask=None) -> dst"},
 #endif
 
   //{"CalcOpticalFlowFarneback", (PyCFunction)pycvCalcOpticalFlowFarneback, METH_KEYWORDS, "CalcOpticalFlowFarneback(prev, next, flow, pyr_scale=0.5, levels=3, win_size=15, iterations=3, poly_n=7, poly_sigma=1.5, flags=0) -> None"},
@@ -3887,6 +3898,10 @@ __declspec(dllexport)
 
 void initcv()
 {
+#if PYTHON_USE_NUMPY
+    import_array();
+#endif
+    
   PyObject *m, *d;
 
   cvSetErrMode(CV_ErrModeParent);
diff --git a/modules/python/opencv_api_extra.hpp b/modules/python/opencv_api_extra.hpp
new file mode 100644
index 000000000..781cd2df8
--- /dev/null
+++ b/modules/python/opencv_api_extra.hpp
@@ -0,0 +1,525 @@
+#ifndef _OPENCV_API_EXTRA_HPP_
+#define _OPENCV_API_EXTRA_HPP_
+
+#include "opencv2/core/core.hpp"
+#include "opencv2/imgproc/imgproc.hpp"
+#include "opencv2/calib3d/calib3d.hpp"
+
+namespace cv
+{
+
+template<typename _Tp>
+static inline void mv2vv(const vector<Mat>& src, vector<vector<_Tp> >& dst)
+{
+    size_t i, n = src.size();
+    dst.resize(src.size());
+    for( i = 0; i < n; i++ )
+        src[i].copyTo(dst[i]);
+}
+
+///////////////////////////// core /////////////////////////////
+
+CV_WRAP_AS(getTickCount) static inline double getTickCount_()
+{
+    return (double)getTickCount();
+}
+
+CV_WRAP_AS(getCPUTickCount) static inline double getCPUTickCount_()
+{
+    return (double)getCPUTickCount();
+}
+
+CV_WRAP static inline void SVDecomp(const Mat& src, CV_OUT Mat& w, CV_OUT Mat& u, CV_OUT Mat& vt, int flags=0 )
+{
+    SVD::compute(src, w, u, vt, flags);
+}
+
+CV_WRAP static inline void SVDBackSubst( const Mat& w, const Mat& u, const Mat& vt,
+                                         const Mat& rhs, CV_OUT Mat& dst )
+{
+    SVD::backSubst(w, u, vt, rhs, dst);
+}
+
+CV_WRAP static inline void mixChannels(const vector<Mat>& src, vector<Mat>& dst,
+                                       const vector<int>& fromTo)
+{
+    if(fromTo.empty())
+        return;
+    CV_Assert(fromTo.size()%2 == 0);
+    mixChannels(&src[0], (int)src.size(), &dst[0], (int)dst.size(), &fromTo[0], (int)(fromTo.size()/2));
+}
+
+CV_WRAP static inline bool eigen(const Mat& src, bool computeEigenvectors,
+                                 CV_OUT Mat& eigenvalues, CV_OUT Mat& eigenvectors,
+                                 int lowindex=-1, int highindex=-1)
+{
+    if(computeEigenvectors)
+        eigen(src, eigenvalues, eigenvectors, lowindex, highindex);
+    else
+        eigen(src, eigenvalues, lowindex, highindex);
+}
+
+CV_WRAP static inline void fillConvexPoly(Mat& img, const Mat& points,
+                               const Scalar& color, int lineType=8,
+                               int shift=0)
+{
+    CV_Assert(points.checkVector(2, CV_32S) >= 0);
+    fillConvexPoly(img, (const Point*)points.data, points.rows*points.cols*points.channels()/2, color, lineType, shift);
+}
+
+CV_WRAP static inline void fillPoly(Mat& img, const vector<Mat>& pts,
+                                   const Scalar& color, int lineType=8, int shift=0,
+                                   Point offset=Point() )
+{
+    if( pts.empty() )
+        return;
+    AutoBuffer<Point*> _ptsptr(pts.size());
+    AutoBuffer<int> _npts(pts.size());
+    Point** ptsptr = _ptsptr;
+    int* npts = _npts;
+    
+    for( size_t i = 0; i < pts.size(); i++ )
+    {
+        const Mat& p = pts[i];
+        CV_Assert(p.checkVector(2, CV_32S) >= 0);
+        ptsptr[i] = (const Point*)p.data;
+        npts[i] = p.rows*p.cols*p.channels()/2;
+    }
+    fillPoly(img, ptsptr, npts, (int)pts.size(), color, lineType, shift, offset);
+}
+
+CV_WRAP static inline void polylines(Mat& img, const vector<Mat>& pts,
+                          bool isClosed, const Scalar& color,
+                          int thickness=1, int lineType=8, int shift=0 )
+{
+    if( pts.empty() )
+        return;
+    AutoBuffer<Point*> _ptsptr(pts.size());
+    AutoBuffer<int> _npts(pts.size());
+    Point** ptsptr = _ptsptr;
+    int* npts = _npts;
+    
+    for( size_t i = 0; i < pts.size(); i++ )
+    {
+        const Mat& p = pts[i];
+        CV_Assert(p.checkVector(2, CV_32S) >= 0);
+        ptsptr[i] = (const Point*)p.data;
+        npts[i] = p.rows*p.cols*p.channels()/2;
+    }
+    polylines(img, ptsptr, npts, (int)pts.size(), isClosed, color, thickness, lineType, shift);
+}
+
+/////////////////////////// imgproc /////////////////////////////////
+
+CV_WRAP static inline void HuMoments(const Moments& m, CV_OUT vector<double>& hu)
+{
+    hu.resize(7);
+    HuMoments(m, &hu[0]);
+}
+
+CV_WRAP static inline Mat getPerspectiveTransform(const vector<Point2f>& src, const vector<Point2f>& dst)
+{
+    CV_Assert(src.size() == 4 && dst.size() == 4);
+    return getPerspectiveTransform(&src[0], &dst[0]);
+}
+
+CV_WRAP static inline Mat getAffineTransform(const vector<Point2f>& src, const vector<Point2f>& dst)
+{
+    CV_Assert(src.size() == 3 && dst.size() == 3);
+    return getAffineTransform(&src[0], &dst[0]);
+}
+
+CV_WRAP static inline void calcHist( const vector<Mat>& images, const vector<int>& channels,
+                                     const Mat& mask, CV_OUT Mat& hist,
+                                     const vector<int>& histSize,
+                                     const vector<float>& ranges,
+                                     bool accumulate=false)
+{
+    int i, dims = (int)histSize.size(), rsz = (int)ranges.size(), csz = (int)channels.size();
+    CV_Assert(images.size() > 0 && dims > 0);
+    CV_Assert(rsz == dims*2 || (rsz == 0 && images[0].depth() == CV_8U));
+    CV_Assert(csz == 0 || csz == dims);
+    float* _ranges[CV_MAX_DIM];
+    if( rsz > 0 )
+    {
+        _all_ranges = _ranges;
+        for( int i = 0; i < rsz/2; i++ )
+            _ranges[i] = &ranges[i*2];
+    }
+    calcHist(&images[0], (int)images.size(), csz ? &channels[0] : 0,
+            mask, hist, dims, &histSize[0], rsz ? (const float**)_ranges : 0,
+            true, accumulate);
+}
+
+                                     
+CV_WRAP void calcBackProject( const vector<Mat>& images, const vector<int>& channels,
+                              const Mat& hist, CV_OUT Mat& dst,
+                              const vector<float>& ranges,
+                              double scale=1 )
+{
+    int i, dims = hist.dims, rsz = (int)ranges.size(), csz = (int)channels.size();
+    CV_Assert(images.size() > 0);
+    CV_Assert(rsz == dims*2 || (rsz == 0 && images[0].depth() == CV_8U));
+    CV_Assert(csz == 0 || csz == dims);
+    float* _ranges[CV_MAX_DIM];
+    if( rsz > 0 )
+    {
+        _all_ranges = _ranges;
+        for( int i = 0; i < rsz/2; i++ )
+            _ranges[i] = &ranges[i*2];
+    }
+    calcHist(&images[0], (int)images.size(), csz ? &channels[0] : 0,
+        hist, dst, rsz ? (const float**)_ranges : 0, scale, true);
+}
+
+
+static void addChildContour(const vector<Mat>& contours,
+                            const Mat& hierarchy,
+                            int i, vector<CvSeq>& seq,
+                            vector<CvSeqBlock>& block)
+{
+    size_t count = contours.size();
+    for( ; i >= 0; i = ((const Vec4i*)hierarchy.data)[i][0] )
+    {
+        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] );
+        const Vec4i h_i = ((const Vec4i*)hierarchy.data)[i];
+        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;
+        seq[i].v_prev = (size_t)v_prev < count ? &seq[v_prev] : 0;
+        
+        if( v_next >= 0 )
+            addChildContour(contours, hierarchy, v_next, seq, block);
+    }
+}
+
+//! draws contours in the image
+CV_WRAP static inline void drawContours( Mat& image, const vector<Mat>& contours,
+                                int contourIdx, const Scalar& color,
+                                int thickness=1, int lineType=8,
+                                const Mat& hierarchy=Mat(),
+                                int maxLevel=INT_MAX, Point offset=Point() )
+{
+    CvMat _image = image;
+
+    size_t i = 0, first = 0, last = contours.size();
+    vector<CvSeq> seq;
+    vector<CvSeqBlock> block;
+
+    if( !last )
+        return;
+
+    seq.resize(last);
+    block.resize(last);
+
+    for( i = first; i < last; i++ )
+        seq[i].first = 0;
+
+    if( contourIdx >= 0 )
+    {
+        CV_Assert( 0 <= contourIdx && contourIdx < (int)last );
+        first = contourIdx;
+        last = contourIdx + 1;
+    }
+
+    for( i = first; i < last; i++ )
+    {
+        const Mat& ci = contours[i];
+        int ci_size = ci.checkVector(2, CV_32S);
+        CV_Assert( ci_size >= 0 );
+        cvMakeSeqHeaderForArray(CV_SEQ_POLYGON, sizeof(CvSeq), sizeof(Point),
+                                ci_size > 0 ? ci.data : 0, ci_size, &seq[i], &block[i] );
+    }
+
+    if( hierarchy.empty() || maxLevel == 0 )
+        for( i = first; i < last; i++ )
+        {
+            seq[i].h_next = i < last-1 ? &seq[i+1] : 0;
+            seq[i].h_prev = i > first ? &seq[i-1] : 0;
+        }
+    else
+    {
+        int hsz = hierarchy.checkVector(4, CV_32S);
+        size_t count = last - first;
+        CV_Assert((size_t)hsz == contours.size());
+        if( count == contours.size() )
+        {
+            for( i = first; i < last; i++ )
+            {
+                const Vec4i& h_i = ((const Vec4i*)hierarchy.data)[i];
+                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;
+                seq[i].v_prev = (size_t)v_prev < count ? &seq[v_prev] : 0;
+            }
+        }
+        else
+        {
+            int child = ((const Vec4i*)hierarchy.data)[first][2];
+            if( child >= 0 )
+            {
+                addChildContour(contours, hierarchy, child, seq, block);
+                seq[first].v_next = &seq[child];
+            }
+        }
+    }
+
+    cvDrawContours( &_image, &seq[first], color, color, contourIdx >= 0 ?
+                   -maxLevel : maxLevel, thickness, lineType, offset );
+}
+
+
+CV_WRAP static inline void approxPolyDP( const Mat& curve,
+                              CV_OUT Mat& approxCurve,
+                              double epsilon, bool closed )
+{
+    if( curve.depth() == CV_32S )
+    {
+        vector<Point> result;
+        approxyPolyDP(curve, result, epsilon, closed);
+        Mat(result).copyTo(approxCurve);
+    }
+    else if( curve.depth() == CV_32F )
+    {
+        vector<Point2f> result;
+        approxyPolyDP(curve, result, epsilon, closed);
+        Mat(result).copyTo(approxCurve);
+    }
+    else
+        CV_Error(CV_StsUnsupportedFormat, "")
+}
+
+
+CV_WRAP static inline void convexHull( const Mat& points, CV_OUT Mat& hull, bool returnPoints=true, bool clockwise=false )
+{
+    if( !returnPoints )
+    {
+        vector<int> h;
+        convexHull(points, h, clockwise);
+        Mat(h).copyTo(hull);
+    }
+    else if( points.depth() == CV_32S )
+    {
+        vector<Point> h;
+        convexHull(points, h, clockwise);
+        Mat(h).copyTo(hull);
+    }
+    else if( points.depth() == CV_32F )
+    {
+        vector<Point2f> h;
+        convexHull(points, h, clockwise);
+        Mat(h).copyTo(hull);
+    }
+}
+
+CV_WRAP static inline void fitLine( const Mat& points, CV_OUT CV_CUSTOM_CARRAY(points) float* line,
+                      int distType, double param, double reps, double aeps )
+{
+    if(points.channels() == 2 || points.cols == 2)
+        fitLine(points, *(Vec4f*)line, distType, param, reps, aeps);
+    else
+        fitLine(points, *(Vec6f*)line, distType, param, reps, aeps);
+}
+
+CV_WRAP static inline int estimateAffine3D( const Mat& from, const Mat& to,
+                              CV_OUT Mat& dst, CV_OUT Mat& outliers,
+                              double param1 = 3.0, double param2 = 0.99 )
+{
+    vector<int> outliers_vec;
+    int res = estimateAffine3D(from, to, dst, outliers_vec, param1, param2);
+    outliers_vec.copyTo(outliers);
+    return res;
+}
+
+
+CV_WRAP static inline void cornerSubPix( const Mat& image, Mat& corners,
+                                         Size winSize, Size zeroZone,
+                                         TermCriteria criteria )
+{
+    int n = corners.checkVector(2, CV_32F);
+    CV_Assert(n >= 0);
+    
+    if( n == 0 )
+        return;
+        
+    CvMat _image = image;
+    cvCornerSubPix(&_image, (CvPoint2D32f*)corners.data, n, winSize, zeroZone, criteria);
+}
+
+CV_WRAP static inline void goodFeaturesToTrack( const Mat& image, CV_OUT Mat& corners,
+                                     int maxCorners, double qualityLevel, double minDistance,
+                                     const Mat& mask=Mat(), int blockSize=3,
+                                     bool useHarrisDetector=false, double k=0.04 )
+{
+    vector<Point2f> corners_vec;
+    goodFeaturesToTrack(image, corners_vec, maxCorners, qualityLevel,
+                        minDistance, mask, blockSize, useHarrisDetector, k);
+    Mat(corners_vec).copyTo(corners);
+}
+
+CV_WRAP static inline void HoughLines( const Mat& image, CV_OUT Mat& lines,
+                                       double rho, double theta, int threshold,
+                                       double srn=0, double stn=0 )
+{
+    vector<Vec2f>& lines_vec;
+    HoughLines(image, lines_vec, rho, theta, threshold, srn, stn);
+    Mat(lines_vec).copyTo(lines);
+}
+
+CV_WRAP static inline void HoughLinesP( Mat& image, CV_OUT Mat& lines,
+                                        double rho, double theta, int threshold,
+                                        double minLineLength=0, double maxLineGap=0 )
+{
+    vector<Vec4i>& lines_vec;
+    HoughLinesP(image, lines_vec, rho, theta, threshold, minLineLength, maxLineGap);
+    Mat(lines_vec).copyTo(lines);
+}
+
+CV_WRAP static inline 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 )
+{
+    vector<Vec3f>& circles_vec;
+    HoughCircles(image, circles_vec, method, dp, minDist, param1, param2, minRadius, maxRadius);
+    Mat(circles_vec).copyTo(circles);
+}
+
+
+/////////////////////////////// calib3d ///////////////////////////////////////////
+
+CV_WRAP static inline bool findChessboardCorners( const Mat& image, Size patternSize,
+                                       CV_OUT Mat& corners,
+                                       int flags=CALIB_CB_ADAPTIVE_THRESH+
+                                              CALIB_CB_NORMALIZE_IMAGE )
+{
+    vector<Point2f> corners_vec;
+    bool res = findChessboardCorners(image, patternSize, corners_vec, flags);
+    corners_vec.copyTo(corners);
+    return res;
+}
+
+
+CV_WRAP static inline void projectPoints( const Mat& objectPoints,
+                               const Mat& rvec, const Mat& tvec,
+                               const Mat& cameraMatrix,
+                               const Mat& distCoeffs,
+                               CV_OUT Mat& imagePoints )
+{
+    vector<Point2f> imgpt;
+    projectPoints(objectPoints, rvec, tvec, cameraMatrix, distCoeffs, imgpt);
+    Mat(imgpt).copyTo(imagePoints);
+}
+
+CV_WRAP static inline void projectPointsJ( const Mat& objectPoints,
+                               const Mat& rvec, const Mat& tvec,
+                               const Mat& cameraMatrix,
+                               const Mat& distCoeffs,
+                               CV_OUT Mat& imagePoints,
+                               CV_OUT Mat& dpdrot, CV_OUT Mat& dpdt, CV_OUT Mat& dpdf,
+                               CV_OUT Mat& dpdc, CV_OUT Mat& dpddist,
+                               double aspectRatio=0 )
+{
+    vector<Point2f> imgpt;
+    projectPoints(objectPoints, rvec, tvec, cameraMatri, distCoeffs, imgpt,
+        dpdrot, dpdt, dpdf, dpdc, dpddist, aspectRatio);
+    Mat(imgpt).copyTo(imagePoints);
+}
+
+CV_WRAP static inline void convertPointsHomogeneous( const Mat& src, CV_OUT Mat& dst )
+{
+    int n;
+    if( (n = src.checkVector(2)) >= 0 )
+        dst.create(n, 2, src.depth());
+    else if( (n = src.checkVector(3)) >= 0 )
+        dst.create(n, 3, src.depth());
+    else
+        CV_Assert(CV_StsBadSize, "");
+    CvMat _src = src, _dst = dst;
+    cvConvertHomogeneous(&_src, &_dst);
+}
+
+
+//! initializes camera matrix from a few 3D points and the corresponding projections.
+CV_WRAP static inline Mat initCameraMatrix2D( const vector<Mat>& objectPoints,
+                                   const vector<Mat>& imagePoints,
+                                   Size imageSize, double aspectRatio=1. )
+{
+    vector<vector<Point3f> > _objectPoints;
+    vector<vector<Point2f> > _imagePoints;
+    mv2vv(objectPoints, _objectPoints);
+    mv2vv(imagePoints, _imagePoints);
+    return initCameraMatrix2D(_objectPoints, _imagePoints, imageSize, aspectRatio);
+}
+
+
+CV_WRAP static inline double calibrateCamera( const vector<Mat>& objectPoints,
+                                  const vector<Mat>& imagePoints,
+                                  Size imageSize,
+                                  CV_IN_OUT Mat& cameraMatrix,
+                                  CV_IN_OUT Mat& distCoeffs,
+                                  vector<Mat>& rvecs, vector<Mat>& tvecs,
+                                  int flags=0 )
+{
+    vector<vector<Point3f> > _objectPoints;
+    vector<vector<Point2f> > _imagePoints;
+    mv2vv(objectPoints, _objectPoints);
+    mv2vv(imagePoints, _imagePoints);
+    return calibrateCamera(_objectPoints, _imagePoints, imageSize, cameraMatrix, distCoeffs, rvec, tvecs, flags);
+}
+
+
+CV_WRAP static inline double stereoCalibrate( const vector<Mat>& objectPoints,
+                                  const vector<Mat>& imagePoints1,
+                                  const vector<Mat>& 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,
+                                  TermCriteria criteria = TermCriteria(TermCriteria::COUNT+
+                                                                       TermCriteria::EPS, 30, 1e-6),
+                                  int flags=CALIB_FIX_INTRINSIC )
+{
+    vector<vector<Point3f> > _objectPoints;
+    vector<vector<Point2f> > _imagePoints1;
+    vector<vector<Point2f> > _imagePoints2;
+    mv2vv(objectPoints, _objectPoints);
+    mv2vv(imagePoints1, _imagePoints1);
+    mv2vv(imagePoints2, _imagePoints2);
+    return stereoCalibrate(_objectPoints, _imagePoints1, _imagePoints2, cameraMatrix1, cameraMatrix2,
+                            imageSize, R, T, E, F, criteria, flags);
+}
+    
+
+CV_WRAP static float rectify3Collinear( const Mat& cameraMatrix1, const Mat& distCoeffs1,
+                     const Mat& cameraMatrix2, const Mat& distCoeffs2,
+                     const Mat& cameraMatrix3, const Mat& distCoeffs3,
+                     const vector<Mat>& imgpt1, const vector<Mat>& 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_OUT Rect* roi1, CV_OUT Rect* roi2, int flags )
+{
+    vector<vector<Point2f> > _imagePoints1;
+    vector<vector<Point2f> > _imagePoints3;
+    mv2vv(imgpt1, _imagePoints1);
+    mv2vv(imgpt3, _imagePoints3);
+    return rectify3Collinear(cameraMatrix1, distCoeffs1,
+                            cameraMatrix2, distCoeffs2,
+                            cameraMatrix3, distCoeffs3,
+                            _imagePoints1, _imagePoints3, imageSize,
+                            R12, T12, R13, T13, R1, R2, R3, P1, P2, P3,
+                            Q, alpha, newImgSize, roi1, roi2, flags);
+}
+
+
+}
\ No newline at end of file