经过多次校准后,固有摄像机参数矩阵并不总是相同

时间:2015-02-03 03:05:33

标签: c# emgucv camera-calibration

我在C#中使用emgu cv wiki教程制作了一个相机校准应用程序。 当我运行代码几次时,每次内在的相机参数矩阵与前一个不同。在这里,我没有改变相机的方向,也没有改变图像平面。相机设置已修复,如以下链接中的CameraSetup.jpg图像所示。 CameraSetup.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; 
        }
}
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:0)

我想这是自动对焦。校准相机时,请禁用自动对焦。另外,请确保您至少有20张图片。