private void Calibrate(IEnumerable<Image<Gray, byte>> images, int nx, int ny, int useUncalibrated, float _squareSize /* Chessboard square size in cm */)
        {
            int displayCorners = 1;
            int showUndistorted = 1;
            bool isVerticalStereo = false;//OpenCV can handle left-right
                                      //or up-down camera arrangements
            const int maxScale = 1;

            //FILE* f = fopen(imageList, "rt");
            int i, j, lr, nframes, n = nx*ny, N = 0;

               List<MCvPoint3D32f> objectPoints;

               var points = new List<MCvPoint2D64f>[2];

               List<int> npoints;
               List<char>[] active = new List<char>[2];

               var temp = new PointF[n];

            var imageSize = new System.Drawing.Size(0,0);

            // ARRAY AND VECTOR STORAGE:
            Matrix<double> _M1 = new Matrix<double>(3, 3);
            Matrix<double> _M2 = new Matrix<double>(3, 3);
            Matrix<double> _D1 = new Matrix<double>(1, 5);
            Matrix<double> _D2 = new Matrix<double>(1, 5);
            Matrix<double> _R =  new Matrix<double>(3, 3);
            Matrix<double> _T =  new Matrix<double>(3, 1);
            Matrix<double> _E =  new Matrix<double>(3, 3);
            Matrix<double> _F =  new Matrix<double>(3, 3);
            Matrix<double> _Q =  new Matrix<double>(4, 4);

            double [,] M1 = _M1.Data;
            double [,] M2 = _M2.Data;
            double [,] D1 = _D1.Data;
            double [,] D2 = _D2.Data;

            double [,] R = _R.Data;
            double [,] T = _T.Data;
            double [,] E = _E.Data;
            double [,] F = _F.Data;

            double [,] Q = _Q.Data;

            for(i=0;i<images.Count();i++)
            {
            int count = 0, result=0;

            lr = i % 2;

            List<MCvPoint2D64f> pts = points[lr];

            var img = images.ElementAt(i);

            imageSize = img.Size;

            //FIND CHESSBOARDS AND CORNERS THEREIN:
            for( int s = 1; s <= maxScale; s++ )
            {
            var timg = img;

            if( s > 1 )
            {
                timg=new Image<Gray,byte>(img.Width * s, img.Height * s);

                img.Resize(timg.Width, timg.Height, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC);
            }

            temp = Emgu.CV.CameraCalibration.FindChessboardCorners(timg, new Size(nx, ny),
                Emgu.CV.CvEnum.CALIB_CB_TYPE.ADAPTIVE_THRESH | Emgu.CV.CvEnum.CALIB_CB_TYPE.NORMALIZE_IMAGE);

            Emgu.CV.CameraCalibration.

            result = temp.Count();

            if( timg != img )
                timg.Dispose();

            if( result == 0 || s == maxScale)
                for( j = 0; j < count; j++ )
                {
                    temp[j].X /= s;
                    temp[j].Y /= s;
                }
            if( result )
                break;
            }
            if( displayCorners )
            {
            printf("%s\n", buf);
            IplImage* cimg = cvCreateImage( imageSize, 8, 3 );
            cvCvtColor( img, cimg, CV_GRAY2BGR );
            cvDrawChessboardCorners( cimg, cvSize(nx, ny), &temp[0],
                count, result );
            cvShowImage( "corners", cimg );
            cvReleaseImage( &cimg );
            if( cvWaitKey(0) == 27 ) //Allow ESC to quit
                exit(-1);
            }
            else
            putchar('.');
            N = pts.size();
            pts.resize(N + n, cvPoint2D32f(0,0));
            active[lr].push_back((uchar)result);
            //assert( result != 0 );
            if( result )
            {
             //Calibration will suffer without subpixel interpolation
            cvFindCornerSubPix( img, &temp[0], count,
                cvSize(11, 11), cvSize(-1,-1),
                cvTermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,
                30, 0.01) );
            copy( temp.begin(), temp.end(), pts.begin() + N );
            }
            cvReleaseImage( &img );
            }
            fclose(f);
            printf("\n");
            // HARVEST CHESSBOARD 3D OBJECT POINT LIST:
            nframes = active[0].size();//Number of good chessboads found
            objectPoints.resize(nframes*n);
            for( i = 0; i < ny; i++ )
            for( j = 0; j < nx; j++ )
            objectPoints[i*nx + j] = cvPoint3D32f(i*squareSize, j*squareSize, 0);
            for( i = 1; i < nframes; i++ )
            copy( objectPoints.begin(), objectPoints.begin() + n,
            objectPoints.begin() + i*n );
            npoints.resize(nframes,n);
            N = nframes*n;
            CvMat _objectPoints = cvMat(1, N, CV_32FC3, &objectPoints[0] );
            CvMat _imagePoints1 = cvMat(1, N, CV_32FC2, &points[0][0] );
            CvMat _imagePoints2 = cvMat(1, N, CV_32FC2, &points[1][0] );
            CvMat _npoints = cvMat(1, npoints.size(), CV_32S, &npoints[0] );
            cvSetIdentity(&_M1);
            cvSetIdentity(&_M2);
            cvZero(&_D1);
            cvZero(&_D2);

            // CALIBRATE THE STEREO CAMERAS
            printf("Running stereo calibration ...");
            fflush(stdout);
            cvStereoCalibrate( &_objectPoints, &_imagePoints1,
            &_imagePoints2, &_npoints,
            &_M1, &_D1, &_M2, &_D2,
            imageSize, &_R, &_T, &_E, &_F,
            cvTermCriteria(CV_TERMCRIT_ITER+
            CV_TERMCRIT_EPS, 100, 1e-5),
            CV_CALIB_FIX_ASPECT_RATIO +
            CV_CALIB_ZERO_TANGENT_DIST +
            CV_CALIB_SAME_FOCAL_LENGTH );
            printf(" done\n");
            // CALIBRATION QUALITY CHECK
            // because the output fundamental matrix implicitly
            // includes all the output information,
            // we can check the quality of calibration using the
            // epipolar geometry constraint: m2^t*F*m1=0
            vector<CvPoint3D32f> lines[2];
            points[0].resize(N);
            points[1].resize(N);
            _imagePoints1 = cvMat(1, N, CV_32FC2, &points[0][0] );
            _imagePoints2 = cvMat(1, N, CV_32FC2, &points[1][0] );
            lines[0].resize(N);
            lines[1].resize(N);
            CvMat _L1 = cvMat(1, N, CV_32FC3, &lines[0][0]);
            CvMat _L2 = cvMat(1, N, CV_32FC3, &lines[1][0]);
            //Always work in undistorted space
            cvUndistortPoints( &_imagePoints1, &_imagePoints1,
            &_M1, &_D1, 0, &_M1 );
            cvUndistortPoints( &_imagePoints2, &_imagePoints2,
            &_M2, &_D2, 0, &_M2 );
            cvComputeCorrespondEpilines( &_imagePoints1, 1, &_F, &_L1 );
            cvComputeCorrespondEpilines( &_imagePoints2, 2, &_F, &_L2 );
            double avgErr = 0;
            for( i = 0; i < N; i++ )
            {
            double err = fabs(points[0][i].x*lines[1][i].x +
            points[0][i].y*lines[1][i].y + lines[1][i].z)
            + fabs(points[1][i].x*lines[0][i].x +
            points[1][i].y*lines[0][i].y + lines[0][i].z);
            avgErr += err;
            }
            printf( "avg err = %g\n", avgErr/(nframes*n) );
            //COMPUTE AND DISPLAY RECTIFICATION
            if( showUndistorted )
            {
            CvMat* mx1 = cvCreateMat( imageSize.height,
            imageSize.width, CV_32F );
            CvMat* my1 = cvCreateMat( imageSize.height,
            imageSize.width, CV_32F );
            CvMat* mx2 = cvCreateMat( imageSize.height,

            imageSize.width, CV_32F );
            CvMat* my2 = cvCreateMat( imageSize.height,
            imageSize.width, CV_32F );
            CvMat* img1r = cvCreateMat( imageSize.height,
            imageSize.width, CV_8U );
            CvMat* img2r = cvCreateMat( imageSize.height,
            imageSize.width, CV_8U );
            CvMat* disp = cvCreateMat( imageSize.height,
            imageSize.width, CV_16S );
            CvMat* vdisp = cvCreateMat( imageSize.height,
            imageSize.width, CV_8U );
            CvMat* pair;
            double R1[3][3], R2[3][3], P1[3][4], P2[3][4];