7

我一直在为 OpenCV 使用出色的 Emgu C# 包装器来从自制的立体设备中收集图像。两个网络摄像头用螺栓固定在一块木头上,相距 35 厘米,希望能让我生成 10-20 米范围内的深度图。我已将它们设置为尽可能平行(三角测量测试大约为 89.3 度)。

我正在尝试根据这些制作视差图,尽管该过程作为代码工作,但结果是非常随机的。我的意思是每次我尝试运行立体校正时,我都会得到非常不同的结果,而且图像经常严重扭曲,屏幕上几乎看不到任何东西。

据我了解,这样做的方法如下:


1) 打印出棋盘图案(例如 6 x 8 内角)- 粘在平坦的东西上。

2) 从相机 1 拍摄一组大约 10 张照片,将棋盘全视但位置不同。

3)使用 CameraCalibration.FindChessboardCorners 找到内角(6乘8)

4) 使用 img.FindCornerSubPix() 将这些角位置细化到亚像素级别

5) 使用 CameraCalibration.CalibrateCamera() 计算内在相机细节,并将其保存为 XML 文件

6) 对摄像机 2 重复上述操作。

7) 现在您有了内部相机失真信息,您可以拍摄立体照片对并使用 CameraCalibration.StereoCalibrate() 和先前计算的内在数据来计算外在信息(相机 1 和 2 之间的偏移和旋转)。

8) 使用 CvInvoke.cvStereoRectify() 和 CvInvoke.cvInitUndistortRectifyMap() 然后使用 CvInvoke.cvRemap() 构建一个输出图像,该图像应该在 Y 中排列,以便您可以运行立体对应测试之一。

我发现您需要使用 Emgu 2.1 版本 806 才能让 cvStereoRectify 正常工作而不会出现访问冲突错误。


我想我的问题是:

A) 我的流程正确吗?我一直在将相机固有校准作为一个单独的过程进行,因为由于相机相距 35 厘米,因此在办公室中将棋盘放在他们两个的视野中并移动它并不容易......因为它很快就会离开一边摄像机视图之一。我认为由于这些值是内在的,因此这些值与相机有关,因此应该可以转移到立体程序。这个对吗?

似乎内在价值在 cvStereoRectify 过程中发生了变化,并且变得非常不同。

例如。第一阶段的失真值 = 0.22,-1.2,0.01,-0.01,2.6 在 cvStereoRectify 之后值更改为 = 10,-489,-0.03,-0.09,13208

我不是专家,但第一组似乎更像我从其他人的评论中看到的,第二组似乎很出路!

B) 有什么方法可以阻止在 cvStereoRectify 期间更新的内在 + 失真值?

C)这是否适合内在价值(937,0,290,0,932,249,0,0,1)?

非常感谢您提供的任何提示...我已经坚持了一段时间...而且我真的不确定该过程的哪一部分引发了错误。任何提示或建议将非常受欢迎......

4

1 回答 1

0

我已经有几年没用过 EMGU 了,但我用它来校准相机和 Kinect。

我发现如果矩形是完全水平的,矩形角的顺序可能会有些混乱——我从来没有真正弄清楚为什么,这似乎对我有用。尝试将电路板设置为使矩形呈 45 度滚动(即从前面看,如果有任何意义,您会看到更多的菱形)。

我非常基本的理解是,这应该使两个摄像机都可以轻松确保它们选择与第一个角相同的角开始计数。

我不能保证这会解决您的问题 - 可能只是我的代码中存在严重错误,这就是为什么当棋盘平坦时它无法产生常规结果的原因。再说一次,它不会花你很长时间来测试,并且可能会起作用。

于 2014-03-24T11:07:18.160 回答