【问题标题】:Emgu.CV Fisheye.Calibrate methodEmgu.CV Fisheye.Calibrate 方法
【发布时间】:2019-05-07 23:46:33
【问题描述】:

我目前正在尝试使用 Emgu.CV 库中的 Fisheye.Calibrate 方法和 Fisheye.UndistorImage 方法。据我了解,Calibrate 方法用于计算相机矩阵 (K) 和失真向量 (D),它们将用于使用 UndistorImage 方法对鱼眼图像进行不失真处理。但是,当我使用这两种方法时,结果并不令人信服。这是我正在测试的输入图像:fisheye input image,这是结果:fisheye output image

当我试图通过查看对象的数据变量来查看 K 和 D 的值时,它对 K 和 D 都表示“null”。因此我不确定我是否使用 Calibrate( ) 方法正确。我的代码如下:

private void EmguCVUndistortFisheye()
    {
        string[] fileNames = Directory.GetFiles(@"C:\Users\Test\Desktop\Jakob\ImageAnalysis\Images\Calibration", "*.png");
        Size patternSize = new Size(6, 8);
        VectorOfVectorOfPoint3D32F objPoints = new VectorOfVectorOfPoint3D32F();
        VectorOfVectorOfPointF imagePoints = new VectorOfVectorOfPointF();
        foreach (string file in fileNames)
        {
            Mat img = CvInvoke.Imread(file, ImreadModes.Grayscale);
            CvInvoke.Imshow("input", img);
            VectorOfPointF corners = new VectorOfPointF(patternSize.Width * patternSize.Height);
            bool find = CvInvoke.FindChessboardCorners(img, patternSize, corners);
            if (find)
            {
                MCvPoint3D32f[] points = new MCvPoint3D32f[patternSize.Width * patternSize.Height];
                int loopIndex = 0;
                for (int i = 0; i < patternSize.Height; i++)
                {
                    for (int j = 0; j < patternSize.Width; j++)
                        points[loopIndex++] = new MCvPoint3D32f(j, i, 0);
                }
                objPoints.Push(new VectorOfPoint3D32F(points));
                imagePoints.Push(corners);
            }
        }
        Size imageSize = new Size(1280, 1024);
        Mat K = new Mat();
        Mat D = new Mat();
        Mat rotation = new Mat();
        Mat translation = new Mat();
        Fisheye.Calibrate(
            objPoints,
            imagePoints,
            imageSize,
            K,
            D,
            rotation,
            translation,
            Fisheye.CalibrationFlag.CheckCond,
            new MCvTermCriteria(30, 0.1)
        );

        foreach (string file in fileNames)
        {
            Mat img = CvInvoke.Imread(file, ImreadModes.Grayscale);
            Mat output = img.Clone();
            Fisheye.UndistorImage(img, output, K, D);
            CvInvoke.Imshow("output", output);
        }
    }

我的奇怪结果的原因是校准方法的参数错误,还是仅仅是没有使用足够的输入图像?

【问题讨论】:

    标签: c# emgucv camera-calibration fisheye


    【解决方案1】:

    这看起来与我最近在需要Matrix 时尝试将Mat 传递给校准函数时遇到的问题相似,并且您发现它只是在不报告任何错误的情况下无法工作。我认为您将需要以下内容:

    var K = new Matrix<double>(3, 3);
    var D = new Matrix<double>(4, 1);
    

    另请注意,如果您想检索旋转和平移向量,传入 Mat 很好,但如果您想对它们执行计算,您可能需要转换回 Matrix。我只是使用普通的相机校准而不是鱼眼校准,但以下工作代码片段可能对了解这个想法很有用:

    var cameraMatrix = new Matrix<double>(3, 3);
    var distortionCoeffs = new Matrix<double>(4, 1);
    var termCriteria = new MCvTermCriteria(30, 0.1);
    System.Drawing.PointF[][] imagePoints = imagePointsList.Select(p => p.ToArray()).ToArray();
    MCvPoint3D32f[][] worldPoints = worldPointsList.Select(p => p.ToArray()).ToArray();
    double error = CvInvoke.CalibrateCamera(worldPoints, imagePoints, imageSize, cameraMatrix, distortionCoeffs, CalibType.RationalModel, termCriteria, out Mat[] rotationVectors, out Mat[] translationVectors);
    var rotation = new Matrix<double>(rotationVectors[0].Rows, rotationVectors[0].Cols, rotationVectors[0].DataPointer);
    var translation = new Matrix<double>(translationVectors[0].Rows, translationVectors[0].Cols, translationVectors[0].DataPointer);
    

    【讨论】:

      猜你喜欢
      • 2020-05-20
      • 2018-06-16
      • 1970-01-01
      • 2021-06-25
      • 1970-01-01
      • 2020-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多