示例#1
0
        /// <summary>
        /// Add a pair of real space + image space points.
        /// Beware that calibration can fail if pattern is not rotated to fade forward, so that z is zero.
        /// Also ensure that the point order in the the two point sets are matching.
        /// </summary>
        /// <param name="patternRealModelSample">Must be measured in millimeters</param>
        /// <param name="patternImageSample"></param>
        public void AddSample(MatOfPoint3f patternRealModelSample, MatOfPoint2f patternImageSample)
        {
            //Debug.Log( "patternRealModelSample\n" + patternRealModelSample.dump() );
            //Debug.Log( "patternImageSample\n" + patternImageSample.dump() );

            _patternRealSamples.Add(patternRealModelSample.clone());
            _patternImageSamples.Add(patternImageSample.clone());
        }
示例#2
0
        // Update is called once per frame
        void Update()
        {
            if (webCamTextureToMatHelper.isPlaying() && webCamTextureToMatHelper.didUpdateThisFrame())
            {
                Mat rgbaMat = webCamTextureToMatHelper.GetMat();

                if (AppControl.control.calibrationComplete)
                {
                    Mat  rgbaMatUndistorted = rgbaMat.clone();
                    Size SizeCm             = AppControl.control.cameraMatrix.size();
                    Size SizeDc             = AppControl.control.distCoeffs.size();
                    Imgproc.undistort(rgbaMat, rgbaMatUndistorted, AppControl.control.cameraMatrix, AppControl.control.distCoeffs);
                    rgbaMat = rgbaMatUndistorted;
                }

                Imgproc.cvtColor(rgbaMat, hsvMat, Imgproc.COLOR_RGBA2RGB);
                Imgproc.cvtColor(hsvMat, hsvMat, Imgproc.COLOR_RGB2HSV);

                // IMAGE PROCESSING STARTS (rgbaMat is the captured image)

                // Convert the current rgba frame (rgbaMat) to a gray image (grayMat)
                Imgproc.cvtColor(rgbaMat, grayMat, Imgproc.COLOR_RGBA2GRAY);


                //CALIB_CB_FAST_CHECK saves a lot of time on images
                //that do not contain any chessboard corners
                bool patternfound = Calib3d.findChessboardCorners(grayMat, patternsize, pointbuf,
                                                                  Calib3d.CALIB_CB_ADAPTIVE_THRESH + Calib3d.CALIB_CB_NORMALIZE_IMAGE
                                                                  + Calib3d.CALIB_CB_FAST_CHECK);

                if (patternfound)
                {
                    Imgproc.cornerSubPix(grayMat, pointbuf, new Size(11, 11), new Size(-1, -1), new TermCriteria(TermCriteria.EPS + TermCriteria.MAX_ITER, 30, 0.1));

                    float timeNow = Time.realtimeSinceStartup;
                    if ((timeNow > lastInterval + updateInterval))
                    {
                        imagePoints.Add(pointbuf.clone());
                        calcChessboardCorners(patternsize, squaresize, objectpointbuf);
                        objectPoints.Add(objectpointbuf.clone());

                        ++numCalibImages;
                        lastInterval = timeNow;
                    }
                }


                if (numCalibImages > numCalibrationTakes && !calibrationComplete)
                {
                    // Do calibration

                    int flags = 0;
                    calibrationComplete = true;
                    Calib3d.calibrateCamera(objectPoints, imagePoints, imageSize, cameraMatrix, distCoeffs, rvecs, tvecs, flags);

                    // Calibration is complete
                    List <float> perViewErrors = new List <float>();
                    float        error;
                    error = computeReprojectionErrors(objectPoints, imagePoints, rvecs, tvecs, cameraMatrix, distCoeffs, perViewErrors);

                    // Debug statements
                    Debug.Log("Calibration complete!");
                    Debug.Log("Camera Matrix:");
                    Debug.Log(cameraMatrix.dump());
                    Debug.Log("Distortion Coefficients:");
                    Debug.Log(distCoeffs.dump());                      // Debug.Log("fx: " + cameraMatrix.get(0,0)[0]);
                    Debug.Log("Reprojection error average: " + error); // Error should be in units of pixels
                    Debug.Log(perViewErrors.ToString());

                    // Save the calibration variables in AppControl
                    AppControl.control.calibrationComplete = calibrationComplete;
                    AppControl.control.cameraMatrix        = cameraMatrix;
                    AppControl.control.distCoeffs          = distCoeffs;
                    AppControl.control.reprojectionError   = error;
                    AppControl.control.fx = (float)cameraMatrix.get(0, 0)[0];
                    AppControl.control.fy = (float)cameraMatrix.get(1, 1)[0];
                    AppControl.control.cx = (float)cameraMatrix.get(0, 2)[0];
                    AppControl.control.cy = (float)cameraMatrix.get(1, 2)[0];

                    // Store the calibration parameters in player preferences text file
                    PlayerPrefs.SetInt("Calibrated", 1);
                    PlayerPrefs.SetFloat("Error", error);
                    float k1 = (float)distCoeffs.get(0, 1)[0];
                    float k2 = (float)distCoeffs.get(0, 1)[0];
                    PlayerPrefs.SetFloat("k1", (float)distCoeffs.get(0, 0)[0]);
                    PlayerPrefs.SetFloat("k2", (float)distCoeffs.get(0, 1)[0]);
                    PlayerPrefs.SetFloat("p1", (float)distCoeffs.get(0, 2)[0]);
                    PlayerPrefs.SetFloat("p2", (float)distCoeffs.get(0, 3)[0]);
                    PlayerPrefs.SetFloat("k3", (float)distCoeffs.get(0, 4)[0]);
                    PlayerPrefs.SetFloat("fx", (float)cameraMatrix.get(0, 0)[0]);
                    PlayerPrefs.SetFloat("fy", (float)cameraMatrix.get(1, 1)[0]);
                    PlayerPrefs.SetFloat("cx", (float)cameraMatrix.get(0, 2)[0]);
                    PlayerPrefs.SetFloat("cy", (float)cameraMatrix.get(1, 2)[0]);
                }


                // SHOW IMAGE ON THE DISPLAY

                // Draw the chessboard corners so it's obvious that the app is working
                Calib3d.drawChessboardCorners(rgbaMat, patternsize, pointbuf, patternfound);

                // Notify the user when the calibration is finished
                if (!calibrationComplete)
                {
                    Core.putText(rgbaMat, "Number of images collected: " + numCalibImages, new Point(5, rgbaMat.rows() - 10), Core.FONT_HERSHEY_SIMPLEX, 1.0, new Scalar(255, 255, 255, 255), 2, Core.LINE_AA, false);
                }
                else
                {
                    // Mat rgbaMatUndistorted = new Mat();
                    Core.putText(rgbaMat, "Calibration complete", new Point(5, rgbaMat.rows() - 10), Core.FONT_HERSHEY_SIMPLEX, 1.0, new Scalar(255, 255, 255, 255), 2, Core.LINE_AA, false);
                }


                Utils.matToTexture2D(rgbaMat, texture); // Default display
                //  Utils.matToTexture2D (rgbaMat, texture, colors)
            }
        }
示例#3
0
 /// <summary>
 /// Add a pair of real space + image space points. Points must be undistorted.
 /// </summary>
 /// <param name="patternRealSample">Must be measured in millimeters</param>
 /// <param name="patternImageSample"></param>
 public void AddSample(MatOfPoint3f patternWorldSample, MatOfPoint2f cameraPatternImageSample, MatOfPoint2f projectorPatternImageSample)
 {
     _patternWorldSamples.Add(patternWorldSample.clone());
     _cameraPatternImageSamples.Add(cameraPatternImageSample.clone());
     _projectorPatternImageSamples.Add(projectorPatternImageSample.clone());
 }