在多次校准相机后,固有相机参数矩阵并不总是相同的

  • 本文关键字:相机 参数 c# emgucv camera-calibration
  • 更新时间 :
  • 英文 :


我按照 C# 中的 emgu cv wiki 教程制作了一个相机校准应用程序。当我多次运行代码时,每次内部相机参数矩阵都与以前的不同。在这里,我没有改变相机方向,也没有改变图像平面。相机设置已修复,如以下链接中的图像相机设置.jpg所示。相机设置.jpg

我的代码如下。我不知道如何继续前进。问候!

namespace CameraCallibration
{
    public partial class Form1 : Form
    {
        #region variables
        Capture capture = new Capture(1);
        int bufferIndex;
        const int width = 9;//9 //width of chessboard no. squares in width - 1
        const int height = 6;//6 // heght of chess board no. squares in heigth - 1
        Size patternSize = new Size(width, height); //size of chess board to be detected
        Bgr[] line_colour_array = new Bgr[width * height]; // just for displaying coloured lines of detected chessboard
        static Image<Gray, Byte>[] Frame_array_buffer = new Image<Gray, byte>[100];
        MCvPoint3D32f[][] corners_object_list = new MCvPoint3D32f[Frame_array_buffer.Length][];
        PointF[][] corners_points_list = new PointF[Frame_array_buffer.Length][];
        IntrinsicCameraParameters IC = new IntrinsicCameraParameters();
        ExtrinsicCameraParameters[] EX_Param;
        enum mode
        {
            SavingFrames,
            Caluculating_Intrinsics,
            Calibrated
        };
        mode currentMode = new mode();
        #endregion
        public Form1()
        {
            InitializeComponent();
            timer1.Interval = 10;
            currentMode = mode.SavingFrames;
            bufferIndex = 0;
        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            Image<Bgr, Byte> BgrFrame = capture.QueryFrame();
            imageBox1.Image = BgrFrame.Resize(320, 240, Emgu.CV.CvEnum.INTER.CV_INTER_NN);
            Image<Gray, Byte> GrayFrame = BgrFrame.Convert<Gray, Byte>();
            imageBox2.Image = GrayFrame.Resize(320, 240, Emgu.CV.CvEnum.INTER.CV_INTER_NN);
            if(currentMode == mode.SavingFrames)
            {
                Frame_array_buffer[bufferIndex] = GrayFrame.Copy();
                bufferIndex++;
                if(bufferIndex == Frame_array_buffer.Length)
                {
                    currentMode = mode.Caluculating_Intrinsics;
                    textBox1.Text = "Frames Saved";
                    timer1.Enabled = false;
                }
            }
            if(currentMode == mode.Caluculating_Intrinsics)
            {
                for(int i = 0; i < Frame_array_buffer.Length ; i++)
                {
                    corners_points_list[i] = CameraCalibration.FindChessboardCorners(GrayFrame, patternSize, Emgu.CV.CvEnum.CALIB_CB_TYPE.ADAPTIVE_THRESH);
                    List<MCvPoint3D32f> object_list = new List<MCvPoint3D32f>();
                   
                    for(int j = 0; j < height; j++)
                    {
                        for(int k = 0; k < width; k++)
                        {
                            object_list.Add(new MCvPoint3D32f(k * 20.0F, j * 20.0F, 0.0F));
                        }
                    }
                    corners_object_list[i] = object_list.ToArray();
                }
                double difError =  CameraCalibration.CalibrateCamera(corners_object_list, corners_points_list, GrayFrame.Size, IC, Emgu.CV.CvEnum.CALIB_TYPE.CV_CALIB_RATIONAL_MODEL,out EX_Param);
                currentMode = mode.Calibrated;
                textBox1.Clear();
                textBox1.Text = "Calculated";
            }
            if(currentMode == mode.Calibrated)
            {
                //calculate the camera intrinsics
                Matrix<Single> Map1, Map2;
                IC.InitUndistortMap(BgrFrame.Width,BgrFrame.Height,out Map1,out Map2);
                //remap the image to the particular intrinsics
                //In the current version of EMGU any pixel that is not corrected is set to transparent allowing the original image to be displayed if the same
                //image is mapped backed, in the future this should be controllable through the flag '0'
                Image<Bgr, Byte> temp = BgrFrame.CopyBlank();
                CvInvoke.cvRemap(BgrFrame, temp, Map1, Map2,0,new MCvScalar(0) );
                imageBox3.Image = temp.Resize(320,240,Emgu.CV.CvEnum.INTER.CV_INTER_NN);
                textBox1.Clear();
                textBox1.Text = "Calibrated";
                Matrix<double> IntrParaMat = IC.IntrinsicMatrix;
                for(int i =0 ; i < IntrParaMat.Rows ; i++)
                {
                    for(int j =0 ; j < IntrParaMat.Cols; j++)
                    {
                        textBox2.Text += Convert.ToString( IntrParaMat[i, j]) + "  ";
                    }
                    textBox2.Text += Environment.NewLine;
                }
            }
        }
        private void button1_Click(object sender, EventArgs e)
        {
                timer1.Enabled = true;
                button1.Enabled = false; 
        }
}

我猜是自动对焦。 校准相机时禁用自动对焦。还要确保您至少有 20 张图像。

相关内容

  • 没有找到相关文章

最新更新