本文主要介绍基于EmguCV(3.4.3)的相机标定简单函数使用。
首先感谢这两位博主对我思路的指引,十分感谢!
https://blog.csdn.net/Kano365/article/details/90721424
https://blog.csdn.net/sinat_33442459/article/details/79861762
**注意:**自EmguCV3.0之后,Emgu.CV的DLL引用就换成了—Emgu.CV.World。
在相机标定中,存在两个关键矩阵:相机内参矩阵、相机畸变参数矩阵。这两个矩阵的参数决定了相机校准的质量。(可以参考以上二位的博文)。
现实校准应用中我们不可能每次都计算求解校准矩阵以及参数,所以通常的做法是把校准参数以文件的形式保存下来,每次校准的时候读取校准文件即可。但我在接触EmguCV的函数后发现,它仅仅包括了将Mat数据输出保存的函数,并未包括读取相关文件并对Mat矩阵赋值的便捷函数。
保存与读取函数:
以下是Mat数据的保存函数,可以保存成txt、xml等多种形式,自己选择。
FileStorage storage_came = new FileStorage(@matrix_path + "//" + "cameraMatrix.txt", FileStorage.Mode.Write);//路径不能出现中文名字。。。。。
storage_came.Write(cameraMatrix);
storage_came.ReleaseAndGetString();
-------------------------------------------------------------
以下是读取Mat矩阵文件函数,以及对数据的分割处理。
FileStream filereader = new FileStream((@matrix_path + "//" + "cameraMatrix.txt"), FileMode.Open, FileAccess.Read);
StreamReader streamReader = new StreamReader(filereader);
CamerMatrix_value = streamReader.ReadToEnd();
CamerMatrix_start_index = CamerMatrix_value.IndexOf("[");
CamerMatrix_end_index = CamerMatrix_value.IndexOf("]");
CamerMatrix_value = CamerMatrix_value.Substring(CamerMatrix_start_index + 1, CamerMatrix_end_index - CamerMatrix_start_index - 1);
CamerMatrix_value = CamerMatrix_value.Replace("\r\n", "");
------------------------------------------------------
以下是Mat矩阵参数的配置和写入。
Mat cameraMatrix_T = new Mat(3, 3, DepthType.Cv64F, 1);//相机内参矩阵
Mat distCoeffs_T = new Mat(1, 5, DepthType.Cv64F, 1);//相机5个畸变参数
string[] A = new string[9];
string[] B = new string[15];
char[] separator = { ',' };需要空空格代替回车换行
A = CamerMatrix_value.Split(separator);
B = distCoeffs_value.Split(separator);
for (int i = 0; i < 3; i++)
{
for (int y = 0; y < 3; y++)
{
MatExtension.SetValue(cameraMatrix_T, i, y, Convert.ToDouble(A[k]));
k++;
}
}
注意:以上代码中的MatExtension类函数,需要自己进行编写。具体的方法可以参考文章末尾的博文连接,在此感谢该博主!
程序的初始界面:
程序运行的界面:
关于校准文件的读取函数,大家可以参考这位博主的博文,写的很好,可惜我都没仔细的看。
https://blog.csdn.net/Zythonista/article/details/103889756
整个程序的校准功能只是原理性的验证了,实际的效果如何还没有测试,所以,请忽略界面上两张图的对比!
补充一张定标后的测试图片,效果还不错!