public virtual void Draw(Mat src, Mat dst) { var points = new MatOfPoint2f(); var patternSize = new Size((int)SizeX, (int)SizeY); var found = false; switch (boardType) { case BoardType.ChessBoard: found = Calib3d.findChessboardCorners(src, patternSize, points, Calib3d.CALIB_CB_ADAPTIVE_THRESH | Calib3d.CALIB_CB_FAST_CHECK | Calib3d.CALIB_CB_NORMALIZE_IMAGE); break; case BoardType.CirclesGrid: found = Calib3d.findCirclesGrid(src, patternSize, points, Calib3d.CALIB_CB_SYMMETRIC_GRID); break; case BoardType.AsymmetricCirclesGrid: found = Calib3d.findCirclesGrid(src, patternSize, points, Calib3d.CALIB_CB_ASYMMETRIC_GRID); break; } if (found) { if (boardType == BoardType.ChessBoard) { Imgproc.cornerSubPix(src, points, new Size(5, 5), new Size(-1, -1), new TermCriteria(TermCriteria.EPS + TermCriteria.COUNT, 30, 0.1)); } Calib3d.drawChessboardCorners(dst, patternSize, points, found); } }
public static bool FindAsymmetricCirclesGrid(Mat grayTexMat, Vector2Int patternSize, ref MatOfPoint2f centerPoints) { Vector2IntToSize(patternSize, ref _tempSize); if (centerPoints == null) { centerPoints = new MatOfPoint2f(); } return(Calib3d.findCirclesGrid(grayTexMat, _tempSize, centerPoints, Calib3d.CALIB_CB_ASYMMETRIC_GRID)); }
private double CaptureFrame(Mat frameMat) { double repErr = -1; switch (markerType) { default: case MarkerType.ChArUcoBoard: List <Mat> corners = new List <Mat>(); Mat ids = new Mat(); Aruco.detectMarkers(frameMat, dictionary, corners, ids, detectorParams, rejectedCorners, camMatrix, distCoeffs); if (refineMarkerDetection) { Aruco.refineDetectedMarkers(frameMat, charucoBoard, corners, ids, rejectedCorners, camMatrix, distCoeffs, 10f, 3f, true, recoveredIdxs, detectorParams); } if (ids.total() > 0) { Debug.Log("Frame captured."); allCorners.Add(corners); allIds.Add(ids); allImgs.Add(frameMat); } else { Debug.Log("Invalid frame."); frameMat.Dispose(); if (ids != null) { ids.Dispose(); } foreach (var item in corners) { item.Dispose(); } corners.Clear(); return(-1); } // calibrate camera using aruco markers //double arucoRepErr = CalibrateCameraAruco (allCorners, allIds, charucoBoard, frameMat.size(), camMatrix, distCoeffs, rvecs, tvecs, calibrationFlags); //Debug.Log ("arucoRepErr: " + arucoRepErr); // calibrate camera using charuco repErr = CalibrateCameraCharuco(allCorners, allIds, charucoBoard, frameMat.size(), camMatrix, distCoeffs, rvecs, tvecs, calibrationFlags, calibrationFlags); break; case MarkerType.ChessBoard: case MarkerType.CirclesGlid: case MarkerType.AsymmetricCirclesGlid: MatOfPoint2f points = new MatOfPoint2f(); Size patternSize = new Size((int)squaresX, (int)squaresY); bool found = false; switch (markerType) { default: case MarkerType.ChessBoard: found = Calib3d.findChessboardCorners(frameMat, patternSize, points, Calib3d.CALIB_CB_ADAPTIVE_THRESH | Calib3d.CALIB_CB_FAST_CHECK | Calib3d.CALIB_CB_NORMALIZE_IMAGE); break; case MarkerType.CirclesGlid: found = Calib3d.findCirclesGrid(frameMat, patternSize, points, Calib3d.CALIB_CB_SYMMETRIC_GRID); break; case MarkerType.AsymmetricCirclesGlid: found = Calib3d.findCirclesGrid(frameMat, patternSize, points, Calib3d.CALIB_CB_ASYMMETRIC_GRID); break; } if (found) { Debug.Log("Frame captured."); if (markerType == MarkerType.ChessBoard) { Imgproc.cornerSubPix(frameMat, points, new Size(5, 5), new Size(-1, -1), new TermCriteria(TermCriteria.EPS + TermCriteria.COUNT, 30, 0.1)); } imagePoints.Add(points); allImgs.Add(frameMat); } else { Debug.Log("Invalid frame."); frameMat.Dispose(); if (points != null) { points.Dispose(); } return(-1); } if (imagePoints.Count < 1) { Debug.Log("Not enough points for calibration."); repErr = -1; } else { MatOfPoint3f objectPoint = new MatOfPoint3f(new Mat(imagePoints[0].rows(), 1, CvType.CV_32FC3)); CalcChessboardCorners(patternSize, squareSize, objectPoint, markerType); List <Mat> objectPoints = new List <Mat>(); for (int i = 0; i < imagePoints.Count; ++i) { objectPoints.Add(objectPoint); } repErr = Calib3d.calibrateCamera(objectPoints, imagePoints, frameMat.size(), camMatrix, distCoeffs, rvecs, tvecs, calibrationFlags); objectPoint.Dispose(); } break; } Debug.Log("repErr: " + repErr); Debug.Log("camMatrix: " + camMatrix.dump()); Debug.Log("distCoeffs: " + distCoeffs.dump()); return(repErr); }
private void DrawFrame(Mat grayMat, Mat bgrMat) { Imgproc.cvtColor(grayMat, bgrMat, Imgproc.COLOR_GRAY2BGR); switch (markerType) { default: case MarkerType.ChArUcoBoard: // detect markers. Aruco.detectMarkers(grayMat, dictionary, corners, ids, detectorParams, rejectedCorners, camMatrix, distCoeffs); // refine marker detection. if (refineMarkerDetection) { Aruco.refineDetectedMarkers(grayMat, charucoBoard, corners, ids, rejectedCorners, camMatrix, distCoeffs, 10f, 3f, true, recoveredIdxs, detectorParams); } // if at least one marker detected if (ids.total() > 0) { Aruco.interpolateCornersCharuco(corners, ids, grayMat, charucoBoard, charucoCorners, charucoIds, camMatrix, distCoeffs, charucoMinMarkers); // draw markers. Aruco.drawDetectedMarkers(bgrMat, corners, ids, new Scalar(0, 255, 0, 255)); // if at least one charuco corner detected if (charucoIds.total() > 0) { Aruco.drawDetectedCornersCharuco(bgrMat, charucoCorners, charucoIds, new Scalar(0, 0, 255, 255)); } } break; case MarkerType.ChessBoard: case MarkerType.CirclesGlid: case MarkerType.AsymmetricCirclesGlid: // detect markers. MatOfPoint2f points = new MatOfPoint2f(); bool found = false; switch (markerType) { default: case MarkerType.ChessBoard: found = Calib3d.findChessboardCorners(grayMat, new Size((int)squaresX, (int)squaresY), points, Calib3d.CALIB_CB_ADAPTIVE_THRESH | Calib3d.CALIB_CB_FAST_CHECK | Calib3d.CALIB_CB_NORMALIZE_IMAGE); break; case MarkerType.CirclesGlid: found = Calib3d.findCirclesGrid(grayMat, new Size((int)squaresX, (int)squaresY), points, Calib3d.CALIB_CB_SYMMETRIC_GRID); break; case MarkerType.AsymmetricCirclesGlid: found = Calib3d.findCirclesGrid(grayMat, new Size((int)squaresX, (int)squaresY), points, Calib3d.CALIB_CB_ASYMMETRIC_GRID); break; } if (found) { if (markerType == MarkerType.ChessBoard) { Imgproc.cornerSubPix(grayMat, points, new Size(5, 5), new Size(-1, -1), new TermCriteria(TermCriteria.EPS + TermCriteria.COUNT, 30, 0.1)); } // draw markers. Calib3d.drawChessboardCorners(bgrMat, new Size((int)squaresX, (int)squaresY), points, found); } break; } double[] camMatrixArr = new double[(int)camMatrix.total()]; camMatrix.get(0, 0, camMatrixArr); double[] distCoeffsArr = new double[(int)distCoeffs.total()]; distCoeffs.get(0, 0, distCoeffsArr); int ff = Imgproc.FONT_HERSHEY_SIMPLEX; double fs = 0.4; Scalar c = new Scalar(255, 255, 255, 255); int t = 0; int lt = Imgproc.LINE_AA; bool blo = false; int frameCount = (markerType == MarkerType.ChArUcoBoard) ? allCorners.Count : imagePoints.Count; Imgproc.putText(bgrMat, frameCount + " FRAME CAPTURED", new Point(bgrMat.cols() - 300, 20), ff, fs, c, t, lt, blo); Imgproc.putText(bgrMat, "IMAGE_WIDTH: " + bgrMat.width(), new Point(bgrMat.cols() - 300, 40), ff, fs, c, t, lt, blo); Imgproc.putText(bgrMat, "IMAGE_HEIGHT: " + bgrMat.height(), new Point(bgrMat.cols() - 300, 60), ff, fs, c, t, lt, blo); Imgproc.putText(bgrMat, "CALIBRATION_FLAGS: " + calibrationFlags, new Point(bgrMat.cols() - 300, 80), ff, fs, c, t, lt, blo); Imgproc.putText(bgrMat, "CAMERA_MATRIX: ", new Point(bgrMat.cols() - 300, 100), ff, fs, c, t, lt, blo); for (int i = 0; i < camMatrixArr.Length; i = i + 3) { Imgproc.putText(bgrMat, " " + camMatrixArr[i] + ", " + camMatrixArr[i + 1] + ", " + camMatrixArr[i + 2] + ",", new Point(bgrMat.cols() - 300, 120 + 20 * i / 3), ff, fs, c, t, lt, blo); } Imgproc.putText(bgrMat, "DISTORTION_COEFFICIENTS: ", new Point(bgrMat.cols() - 300, 180), ff, fs, c, t, lt, blo); for (int i = 0; i < distCoeffsArr.Length; ++i) { Imgproc.putText(bgrMat, " " + distCoeffsArr[i] + ",", new Point(bgrMat.cols() - 300, 200 + 20 * i), ff, fs, c, t, lt, blo); } Imgproc.putText(bgrMat, "AVG_REPROJECTION_ERROR: " + repErr, new Point(bgrMat.cols() - 300, 300), ff, fs, c, t, lt, blo); if (frameCount == 0) { Imgproc.putText(bgrMat, "To calibration start, please press the calibration button or do air tap gesture!", new Point(5, bgrMat.rows() - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar(255, 255, 255, 255), 1, Imgproc.LINE_AA, false); } }
public virtual double Calibrate(Mat mat) { var repError = -1.0; var points = new MatOfPoint2f(); var patternSize = new Size((int)SizeX, (int)SizeY); var found = false; switch (boardType) { case BoardType.ChessBoard: found = Calib3d.findChessboardCorners(mat, patternSize, points, Calib3d.CALIB_CB_ADAPTIVE_THRESH | Calib3d.CALIB_CB_FAST_CHECK | Calib3d.CALIB_CB_NORMALIZE_IMAGE); break; case BoardType.CirclesGrid: found = Calib3d.findCirclesGrid(mat, patternSize, points, Calib3d.CALIB_CB_SYMMETRIC_GRID); break; case BoardType.AsymmetricCirclesGrid: found = Calib3d.findCirclesGrid(mat, patternSize, points, Calib3d.CALIB_CB_ASYMMETRIC_GRID); break; } if (found) { if (boardType == BoardType.ChessBoard) { Imgproc.cornerSubPix(mat, points, new Size(5, 5), new Size(-1, -1), new TermCriteria(TermCriteria.EPS + TermCriteria.COUNT, 30, 0.1)); } imagePoints.Add(points); } else { Debug.Log("Invalid frame."); if (points != null) { points.Dispose(); } ErrorEvent?.Invoke("Invalid frame."); return(repError); } if (imagePoints.Count < 1) { Debug.Log("Not enough points for calibration."); ErrorEvent?.Invoke("Not enough points for calibration."); return(repError); } else { var objectPoint = new MatOfPoint3f(new Mat(imagePoints[0].rows(), 1, CvType.CV_32FC3)); CalcCorners(patternSize, squareSize, objectPoint); var objectPoints = new List <Mat>(); for (int i = 0; i < imagePoints.Count; ++i) { objectPoints.Add(objectPoint); } repError = Calib3d.calibrateCamera(objectPoints, imagePoints, mat.size(), cameraMatrix, distCoeffs, rvecs, tvecs); CalibrationEvent?.Invoke(repError); objectPoint.Dispose(); } Debug.Log("-----calibrate-----"); Debug.Log("repErr: " + repError); Debug.Log("camMatrix: " + cameraMatrix.dump()); Debug.Log("distCoeffs: " + distCoeffs.dump()); return(repError); }