Emgu (OpenCV for C#) - 使用 cvStereoRectify 构建视差图
Posted
技术标签:
【中文标题】Emgu (OpenCV for C#) - 使用 cvStereoRectify 构建视差图【英文标题】:Emgu (OpenCV for C#) - building a disparity map using cvStereoRectify 【发布时间】:2011-04-18 12:34:02 【问题描述】:我一直在为 OpenCV 使用出色的 Emgu C# 包装器来从自制的立体设备中收集图像。两个网络摄像头用螺栓固定在一块木头上,相距 35 厘米,希望能让我生成 10-20 米范围内的深度图。我已将它们设置为尽可能平行(三角测量测试大约为 89.3 度)。
我正在尝试根据这些制作视差图,尽管该过程作为代码工作,但结果非常随机。我的意思是每次我尝试运行立体校正时,我都会得到非常不同的结果,而且图像经常严重扭曲,屏幕上几乎看不到任何东西。
据我了解,这样做的方法如下:
1) 打印出棋盘图案(例如 6 x 8 内角)- 粘在平坦的东西上。
2) 从相机 1 拍摄一组大约 10 张照片,将棋盘全视但位置不同。
3) 使用 CameraCalibration.FindChessboardCorners 查找内角(6 x 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
我不是专家,但第一组似乎更像我从其他人的 cmets 中看到的,第二组似乎很出路!
B) 有什么方法可以阻止在 cvStereoRectify 期间更新的内在 + 失真值?
C) 这是否适合内在价值 (937,0,290,0,932,249,0,0,1)?
非常感谢您提供的任何提示...我已经坚持了一段时间...而且我真的不确定该过程的哪个部分引发了错误。任何提示或建议都将非常受欢迎......
【问题讨论】:
我刚刚发现,如果您同时从 L 和 R 相机收集图像集,然后解决所有对象模型点(即棋盘角坐标),一切似乎都会更好以及两组图像角坐标(即左右相机子像素坐标)。 此外,当棋盘离相机相当近时,它似乎做得更好......我的问题是,这并没有给我太多的工作空间,因为我的相机相距甚远。因此,我刚刚制作了一个更大的棋盘(200%)并将其保持在更远的地方......给了我角落匹配的准确性以及更多移动它的空间。似乎有帮助...仍在努力! @timemirror:你有没有检查过 Matlab 校准工具箱(www.vision.caltech.edu/bouguetj/calib_doc/)或 Danail Stoyonov 的相机校准工具(ubimon.doc.ic.ac.uk/dvs/m581.html)都是出色的校准工具.顺便问一下,您对 emguCV 库有什么发现,您是否得到了满意的结果? 您可以使用这些工具从 emguCV 库中验证您的发现,您还可以在此链接vision.caltech.edu/bouguetj/calib_doc/htmls/links.html找到许多其他校准工具箱的链接 @Kevin Boyd - 感谢您的链接和 cmets。不幸的是,我无法访问 Matlab。我发现 Emgu 非常好。我发现我的相机校准有两个主要问题.. a) 我必须同时校准立体设备中的两个相机 b) 设备使用两个便宜的网络摄像头手动对焦,其中一个对焦环略微松动,因此当相机在校准后移动时,焦点会发生轻微变化,但足以完成我之前的校准。最后我改用了更高质量的摄像机,Emgu 完美地工作了。 【参考方案1】:我已经有几年没用过 EMGU,但我用它来校准相机和 Kinect。
我发现如果矩形完全水平,矩形角的顺序可能会有些混乱 - 我从来没有真正了解原因,这似乎对我有用。尝试将电路板设置为使矩形呈 45 度角(即从正面看,您会看到更多的菱形,如果这有意义的话)。
我非常基本的理解是,这应该可以让两个摄像机轻松确保它们选择与第一个角相同的角开始计数。
我不能保证这会解决您的问题 - 可能只是我的代码中存在严重错误,这就是为什么当棋盘是平的时它无法产生常规结果的原因。再说一次,它不会花你很长时间来测试,并且可能会起作用。
【讨论】:
以上是关于Emgu (OpenCV for C#) - 使用 cvStereoRectify 构建视差图的主要内容,如果未能解决你的问题,请参考以下文章
c# emgu/opencv 使用抛出异常 - 试图读取或写入受保护的内存
在Emgu中使用Erode和Dilate(OpenCV for C#)
如何使用 C# 中的 Emgu CV 库在图像上绘制矩形。举个例子