public void Process(List <Point3f> worldPoints, List <Point2f> imagePoints, Size size) { mDistCoefs = new double[5]; mCameraMatrixArray = new double[3, 3]; Size screenSize = size; Vec3d[] rotVecs = new Vec3d[1]; Vec3d[] trVecs = new Vec3d[1]; double errorValue = Cv2.CalibrateCamera(new List <List <Point3f> >() { worldPoints }, new List <List <Point2f> >() { imagePoints }, screenSize, mCameraMatrixArray, mDistCoefs, out rotVecs, out trVecs, CalibrationFlags.ZeroTangentDist | CalibrationFlags.FixK1 | CalibrationFlags.FixK2 | CalibrationFlags.FixK3); mRotVectorArray = new double[3] { rotVecs[0].Item0, rotVecs[0].Item1, rotVecs[0].Item2 }; mTrVectorArray = new double[3] { trVecs[0].Item0, trVecs[0].Item1, trVecs[0].Item2 }; }
public void CalibrateCameraByMat() { var patternSize = new Size(10, 7); using (var image = Image("calibration/00.jpg")) using (var corners = new MatOfPoint2f()) { Cv2.FindChessboardCorners(image, patternSize, corners); var objectPointsArray = Create3DChessboardCorners(patternSize, 1.0f).ToArray(); var imagePointsArray = corners.ToArray(); using (var objectPoints = MatOfPoint3f.FromArray(objectPointsArray)) using (var imagePoints = MatOfPoint2f.FromArray(imagePointsArray)) using (var cameraMatrix = new MatOfDouble(Mat.Eye(3, 3, MatType.CV_64FC1))) using (var distCoeffs = new MatOfDouble()) { var rms = Cv2.CalibrateCamera(new[] { objectPoints }, new[] { imagePoints }, image.Size(), cameraMatrix, distCoeffs, out var rotationVectors, out var translationVectors, CalibrationFlags.UseIntrinsicGuess | CalibrationFlags.FixK5); var distCoeffValues = distCoeffs.ToArray(); Assert.Equal(6.16, rms, 2); Assert.Contains(distCoeffValues, d => Math.Abs(d) > 1e-20); } } }
/// <summary> /// Outputs error margin, intrinsics, extrinsics and the amount of images where the pattern was detected in a camera calibration process /// using a rectangular chessboard pattern /// </summary> /// <param name="images">A spread of Mat representing the images to be used as input during the camera calibration operation</param> /// <param name="rows">Amount of rows in the chessboard pattern</param> /// <param name="cols">Amount of columns in the chessboard pattern</param> /// <param name="intrinsics">Output intrinsics value, also called cameraMatrix</param> /// <param name="extrinsics">Output extrinsics value, also called distortion coefficients</param> /// <param name="foundPatternCount">Integer representing the amount of images where the chessboard patter was found</param> /// <returns></returns> public static double CalibrateCamera(Spread <Mat> images, int rows, int cols, out Mat intrinsics, out Mat extrinsics, out int foundPatternCount) { int imageCount = images.Count; int patternSizeInt = rows * cols; Size patternSize = new Size(cols, rows); float rectangleSize = 24.0f; //initialization of the base objectPoint IEnumerable var objectPoint = new List <Point3f>(); for (int i = 0; i < patternSize.Height; i++) { for (int j = 0; j < patternSize.Width; j++) { objectPoint.Add(new Point3f(j * rectangleSize, i * rectangleSize, 0.0F)); } } Mat[] objectPoints = new Mat[imageCount]; Mat[] imagePoints = new Mat[imageCount]; foundPatternCount = 0; for (int i = 0; i < imageCount; i++) { Point2f[] corners; bool found = Cv2.FindChessboardCorners(images[i], patternSize, out corners, ChessboardFlags.AdaptiveThresh | ChessboardFlags.NormalizeImage); if (found) { //add object to objectPoints objectPoints[i] = new Mat(1, patternSizeInt, OpenCvSharp.MatType.CV_32FC3, objectPoint.ToArray()); //add corners to allCorners imagePoints[i] = new Mat(1, patternSizeInt, OpenCvSharp.MatType.CV_32FC2, corners); foundPatternCount++; } } Mat cameraMatrix = new Mat(3, 3, OpenCvSharp.MatType.CV_64FC1); Mat distortion = new Mat(1, 4, OpenCvSharp.MatType.CV_64FC1); Mat[] rotations = new Mat[imageCount]; Mat[] translations = new Mat[imageCount]; double error = Cv2.CalibrateCamera(objectPoints, imagePoints, images[0].Size(), cameraMatrix, distortion, out rotations, out translations); /*Mat newMatrix = new Mat(); * for (int i = 0; i < imageCount; i++) * { * Rect ROI = new Rect(); * Cv2.GetOptimalNewCameraMatrix(cameraMatrix, distortion, images[i].Size(), 1, images[i].Size(), out ROI); * * Mat dest = new Mat(images[i], ROI); * Cv2.Undistort(images[i], dest, cameraMatrix, distortion); * }*/ intrinsics = cameraMatrix; extrinsics = distortion; return(error); }
void CamUpdate() { CvUtil.GetWebCamMat(webCamTexture, ref mat); Cv2.CvtColor(mat, gray, ColorConversionCodes.RGBA2GRAY); Point2f[] corners; bool ret = Cv2.FindChessboardCorners(gray, size, out corners); if (ret) { TermCriteria criteria = TermCriteria.Both(30, 0.001f); Point2f[] corners2 = Cv2.CornerSubPix(gray, corners, size, new Size(-1, -1), criteria); Cv2.DrawChessboardCorners(mat, size, corners2, ret); List <Point3f> lObjectPoints = new List <Point3f>(); for (int i = 0; i < size.Width; i++) { for (int j = 0; j < size.Height; j++) { lObjectPoints.Add(new Point3f(i, j, 0) * cellSize); } } var objectPoints = new List <IEnumerable <Point3f> > { lObjectPoints }; var imagePoints = new List <IEnumerable <Point2f> > { corners2 }; double[,] cameraMatrix = new double[3, 3]; double[] distCoefficients = new double[5]; Vec3d[] rvecs, tvecs; Cv2.CalibrateCamera(objectPoints, imagePoints, mat.Size(), cameraMatrix, distCoefficients, out rvecs, out tvecs); print( cameraMatrix[0, 0] + ", " + cameraMatrix[0, 1] + ", " + cameraMatrix[0, 2] + "\n" + cameraMatrix[1, 0] + ", " + cameraMatrix[1, 1] + ", " + cameraMatrix[1, 2] + "\n" + cameraMatrix[2, 0] + ", " + cameraMatrix[2, 1] + ", " + cameraMatrix[2, 2] ); print(tvecs[0].Item0 + ", " + tvecs[0].Item1 + ", " + tvecs[0].Item2); } CvConvert.MatToTexture2D(mat, ref tex); rawImage.texture = tex; }
public void CalibrateFromImages(List <Mat> images, ChessBoard chessBoard) { List <Mat> objectPointsOfFrames = new List <Mat> (images.Count); List <Mat> imagePointsOfFrames = new List <Mat> (images.Count); foreach (Mat image in images) { imagePointsOfFrames.Add(chessBoard.FindFromImage(image)); objectPointsOfFrames.Add(chessBoard.GetObjectMat( )); } Cv2.CalibrateCamera(objectPointsOfFrames, imagePointsOfFrames, FrameSize, CameraMatrix, DistortionCoefficients, out Mat [] _, out Mat [] _);
public void CalibrateCameraByArray() { var patternSize = new Size(10, 7); using var image = Image("calibration/00.jpg"); using var corners = new Mat <Point2f>(); Cv2.FindChessboardCorners(image, patternSize, corners); var objectPoints = Create3DChessboardCorners(patternSize, 1.0f); var imagePoints = corners.ToArray(); var cameraMatrix = new double[, ] { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } }; var distCoeffs = new double[5]; var rms = Cv2.CalibrateCamera(new [] { objectPoints }, new[] { imagePoints }, image.Size(), cameraMatrix, distCoeffs, out var rotationVectors, out var translationVectors, CalibrationFlags.UseIntrinsicGuess | CalibrationFlags.FixK5); Assert.Equal(6.16, rms, 2); Assert.Contains(distCoeffs, d => Math.Abs(d) > 1e-20); }
private void ComputeCameraMatrix(out Mat cameraMatrix, out Mat distCoeffs, Size size) { cameraMatrix = new Mat(Mat.Eye(3, 3, MatType.CV_64FC1)); distCoeffs = new Mat <double>(); var objectPoints = new List <Mat>(); var imagePoints = new List <Mat>(); var cornerPositions = CalcBoardCornerPositions(); var corners = _chessboardCorners.ToArray(); for (int i = 0; i < _chessboardCorners.Count; i++) { objectPoints.Add(Mat.FromArray(cornerPositions)); imagePoints.Add(Mat.FromArray(corners[i])); } double error = Cv2.CalibrateCamera(objectPoints, imagePoints, size, cameraMatrix, distCoeffs, out var rotationVectors, out var translationVectors, CalibrationFlags.FixK4 | CalibrationFlags.FixK5); _logger.LogInformation($"Calculated camera matrix with reprojection error: {error}"); }
private static void CameraCalibration(Mat _img_crop, Size board_sz, Point2f[] cornerSubPix) { float cellSize = 0.001f; // in metres List <Point3f> chessboard_coords = new List <Point3f>(); for (int i = 0; i < board_sz.Height; i++) { for (int j = 0; j < board_sz.Width; j++) { chessboard_coords.Add(new Point3f(j, i, 0) * cellSize); } } var objectPoints = new List <IEnumerable <Point3f> > { chessboard_coords }; var imagePoints = new List <IEnumerable <Point2f> > { cornerSubPix }; double[,] cameraMatrix = new double[3, 3]; double[] distCoefficients = new double[5]; Cv2.CalibrateCamera(objectPoints, imagePoints, _img_crop.Size(), cameraMatrix, distCoefficients, out Vec3d[] rvecs, out Vec3d[] tvecs);
private void btnCalibrate_Click(object sender, EventArgs e) { WriteMessage("开始摄像机标定!"); OpenCvSharp.Size SquareSize = new OpenCvSharp.Size(90, 60); double[,] cameraMatrix = new double[3, 3]; double[] distCoeffs = new double[5]; Vec3d[] rvecs = new Vec3d[100]; Vec3d[] tvecs = new Vec3d[100]; for (int t = 0; t < ImageCount; t++) { Point3f[] GList = new Point3f[BoardSize.Width * BoardSize.Height]; for (int i = 0; i < BoardSize.Height; i++) { for (int j = 0; j < BoardSize.Width; j++) { Point3f realPoint = new Point3f(); realPoint.X = i * SquareSize.Width; //行 realPoint.Y = j * SquareSize.Height; //列 realPoint.Z = 0; GList[BoardSize.Height * i + j] = realPoint; } } GPointList[t] = GList; } Cv2.CalibrateCamera(GPointList, CPointList, BoardSize, cameraMatrix, distCoeffs, out rvecs, out tvecs, CalibrationFlags.None, new TermCriteria(CriteriaType.MaxIter, 10, 0.1)); WriteMessage("定标完成!"); WriteMessage("标定结果显示"); WriteMessage("相机内参:intrinsic_matrix"); for (int h = 0; h < 3; h++) { WriteMessage("intrinsic_matrix:X:" + cameraMatrix[h, 0] + ",Y:" + cameraMatrix[h, 1] + ",Z:" + cameraMatrix[h, 2]); } WriteMessage("畸变系数:distortion_coeffs"); for (int ndis = 0; ndis < 4; ndis++) { WriteMessage("畸变系数:" + ndis + ":" + distCoeffs[ndis].ToString()); } WriteMessage("rotation_vectors"); for (int i = 0; i < rvecs.Length; i++) { WriteMessage("X:" + rvecs[i].Item0 + ",Y:" + rvecs[i].Item1 + ",Z:" + rvecs[i].Item2); } WriteMessage("translation_vectors"); for (int i = 0; i < tvecs.Length; i++) { WriteMessage("X:" + tvecs[i].Item0 + ",Y:" + tvecs[i].Item1 + ",Z:" + tvecs[i].Item2); } WriteMessage("开始评价定标结果………………"); double total_err = 0.0; double err = 0.0; //Matrix<double> image_points2(1,point_counts(0,0,0),2); //int temp_num = point_counts(0,0,0); //cout<<"\t每幅图像的定标误差:\n"; //fout<<"每幅图像的定标误差:\n"; for (int i = 0; i < ImageCount; i++) { Point2f[] imagePoints = new Point2f[100]; double[,] jacobian = new double[1, 1]; //Cv2.ProjectPoints(GPointList[i], rvecs.ToArray(), tvecs.ToArray(), cameraMatrix, distCoeffs, out imagePoints, out jacobian, 0); //Cv2.ProjectPoints(GPointList.g.get_cols(i * point_counts(0, 0, 0), (i + 1) * point_counts(0, 0, 0) - 1).cvmat, // rotation_vectors.get_col(i).cvmat, // translation_vectors.get_col(i).cvmat, // intrinsic_matrix.cvmat, // distortion_coeffs.cvmat, // image_points2.cvmat, // 0, 0, 0, 0); //err = cvNorm(image_points.get_cols(i*point_counts(0,0,0),(i+1)*point_counts(0,0,0)-1).cvmat, // image_points2.cvmat, // CV_L1); //total_err += err/=point_counts(0,0,0); //cout<<"******************************************************************\n"; //cout<<"\t\t第"<<i+1<<"幅图像的平均误差:"<<err<<"像素"<<'\n'; //fout<<"\t第"<<i+1<<"幅图像的平均误差:"<<err<<"像素"<<'\n'; //cout<<"显示image_point2\n"; //for(int ih=0;ih<7;ih++) //{ // cout<<"X:"<<image_points2(0,ih,0)<<"\tY:"<<image_points2(0,ih,1)<<"\n"; //} //cout<<"显示object_Points\n"; //for(int iw=0;iw<7;iw++) //{ // cout<<"X:"<<image_points.get_cols(i*point_counts(0,0,0),(i+1)*point_counts(0,0,0)-1)(0,iw,0) // <<"\tY:"<<image_points.get_cols(i*point_counts(0,0,0),(i+1)*point_counts(0,0,0)-1)(0,iw,1)<<"\n"; //} } }
private async void DoCalibrationButton_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e) { var objList = new List <Point3f>(); var objPoints = new List <Point3f[]>(); var imgPoints = new List <Point2f[]>(); var chessboardSize = new Size(7, 5); var terminationCriteria = new TermCriteria(CriteriaType.Eps | CriteriaType.MaxIter, 30, 0.001); for (int y = 0; y < chessboardSize.Height; y++) { for (int x = 0; x < chessboardSize.Width; x++) { var point = new Point3f { X = x, Y = y, Z = 0 }; objList.Add(point); } } foreach (var ci in calibrateImages) { var img = new Mat(ci.Height, ci.Width, MatType.CV_8UC4, ci.Buffer); Mat grayImg = new Mat(); Point2f[] corners; Cv2.CvtColor(img, grayImg, ColorConversionCodes.RGBA2GRAY); var result = Cv2.FindChessboardCorners(grayImg, chessboardSize, out corners, ChessboardFlags.None); if (result) { var winSize = new Size(11, 11); var zeroZone = new Size(-1, -1); var refinedCorners = Cv2.CornerSubPix(grayImg, corners, winSize, zeroZone, terminationCriteria); objPoints.Add(objList.ToArray()); imgPoints.Add(corners); Cv2.DrawChessboardCorners(img, chessboardSize, refinedCorners, result); Cv2.ImShow("img", img); Cv2.WaitKey(500); } } if (objPoints.Count > 0) { var cameraMat = new double[3, 3]; var distCoeffVec = new double[14]; var rVecs = new Vec3d[0]; var tVecs = new Vec3d[0]; var calResult = Cv2.CalibrateCamera(objPoints, imgPoints, new Size(frameWidth, frameHeight), cameraMat, distCoeffVec, out rVecs, out tVecs); } calibrateImages.Clear(); await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { ImageCount.Text = "Calibration Image Count: " + calibrateImages.Count; }); }
private void Calibrate() { Debug.Log("Calibrating Async....."); // calibrationMutex.WaitOne(); if (OnCalibrationStarted != null) { CalibrateCamera.OnCalibrationStarted(); } //prepare the data which the calibration process will fill up int maxSize = (int)Mathf.Max(imageWidth, imageHeight); double fx = maxSize; double fy = maxSize; double cx = (double)imageWidth / 2; double cy = (double)imageHeight / 2; double[,] k = new double[3, 3] { { fx, 0d, cx }, { 0d, fy, cy }, { 0d, 0d, 1d } }; double[] d = new double[5]; double projectionError = -1; Vec3d[] rvec = new Vec3d[boardWidth * boardHeight]; Vec3d[] tvec = new Vec3d[boardWidth * boardHeight]; Size boardSize = new Size(boardWidth, boardHeight); try { // calibrate the camera projectionError = Cv2.CalibrateCamera(objPoints, CornerPoints, new Size(imageWidth, imageHeight), k, d, out rvec, out tvec, calibrationFlags, TermCriteria.Both(30, 0.1)); Debug.Log("Error: " + projectionError); } catch (Exception e) { ResetCalibrationImmediate(); Debug.Log("restarting..."); } //register the data and save them calibrationData.RegisterMatrix(k); calibrationData.RegisterDistortionCoefficients(d); calibrationData.projectionError = projectionError; string s = ""; for (int i = 0; i < d.Length; i++) { s += d[i] + " "; } Debug.Log(s); Debug.Log("Finished!!"); if (OnCalibrationFinished != null) { OnCalibrationFinished(calibrationData); } //calibrationMutex.ReleaseMutex(); }