opencv - 将一幅图像中的像素重新投影到另一幅图像中

标签 opencv computer-vision perspectivecamera image-stitching photogrammetry

我有许多已校准的相机拍摄平面场景的照片。为简单起见,我们假设有 3 个摄像头。这些相机正在进行一般运动,但主要是平移加上一些轻微的旋转。 Example positions of cameras

任务是将它们拼接在一起。我对 3D 坐标一无所知,只是一组用校准相机拍摄的图像。

我的工作:

我在 OpenCV 中使用 SURF/SIFT 实现检测特征,通过在每对图像 (1->2、2->3、1->3) 之间使用 findHomography 获得初始单应性。从这些单应性中,我得到了每个相机姿势的初步估计 (similiar procedure to this)

然后我尝试使用束调整技术来最小化每个匹配对的重投影误差。优化参数是三个平移值和三个旋转值(从 Rodrigues 的旋转公式获得),但我可以稍后添加内部参数(焦点、主点等)。

假设图像 #2 将是引用帧(通过与其他两个图像有最多的匹配),它的旋转和平移矩阵分别是单位矩阵和零矩阵。

我计算关键点(在图像 #2 和图像 #1 中都可见)从图像 #2 到图像 #1 的重投影(伪代码)

[x1_; y1_; z1_] = K1*R1*inv(K2)*[x2; y2; 1] + K1*T1/Z2;
x1 = x1_/z1_;
y1 = y1_/z1_;

x1 = ((f1/f2)*r11*x2 + (f1/f2)*r12*y2 + f1*r13 + f1*tx/Z2) / ((1/f2)*r31*x2 + (1/f2)*r32*y2 + r33 + tx/Z2)
y1 = ((f1/f2)*r21*x2 + (f1/f2)*r22*y2 + f1*r23 + f1*ty/Z2) / ((1/f2)*r31*x2 + (1/f2)*r32*y2 + r33 + ty/Z2)

其中 r__ 是 R1 矩阵的元素,两个内在矩阵的形式都是

[f 0 0]
[0 f 0]
[0 0 1]

我假设引用系的 Z2 坐标为 1。

下一阶段是使用获得的相机矩阵(K1、R1、T1、K3、R3、T3)将图像 #1 和 #3 扭曲到图像 #2 的公共(public)坐标系中。

问题是我不知道正确重投影到图像 #2 的引用帧所需的 Z1 和 Z3,因为图像 #1->#2 的反转重投影看起来像这样:

x2 = ((f2/f1)*R11*x1 + (f2/f1)*R12*y1 + f2*R13 - f0/Z1*(R11*tx + R12*ty + R13*tz)) / ((1/f1)*R31*x1 + (1/f1)*R32*y1 + R33 - 1/Z1*(R31*tx + R32*ty + R33*tz))
y2 = ((f2/f1)*R21*x1 + (f2/f1)*R22*y1 + f2*R23 - f0/Z1*(R21*tx + R22*ty + R23*tz)) / ((1/f1)*R31*x1 + (1/f1)*R32*y1 + R33 - 1/Z1*(R31*tx + R32*ty + R33*tz))

其中 R__ 是 inv(R1) 矩阵的元素。

是否有更好的方法来计算束平差 (2d->2d) 的重投影误差,然后将图像变形到公共(public)坐标系中?我注意到 OpenCV 在他们的拼接模块中有非常相似的框架,但它在纯旋转运动的假设下运行,而这里不是这种情况。

最佳答案

我在帖子 How to get points in stereo image from extrinsic parameters 中自动回答了这个问题

请注意,我使用的方法(经过测试和工作!)只有在 3D 坐标(真实世界!)中的对象是平面的并且它位于 Z=0(校准外部参数的点)时才有效相机)。在那种情况下,此方法与您的校准一样精确。注意:为了获得最佳校准检查 openCVs 圆校准,它具有 0.018 像素的重现误差(由在我大学工作的博士生测试)。

关于opencv - 将一幅图像中的像素重新投影到另一幅图像中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15220159/

相关文章:

c++ - OpenCV 序列——如何创建点对序列?

android - 没有找到 void org.tensorflow.demo.env.ImageUtils 的实现

c++ - 为什么 findHomography 返回错误结果?

matlab - 如何将输入安排为matlab的Extrinsics()函数的对象?

python - Ubuntu 17.04 上的 OpenCV VideoCapture() 无法正常工作

c++ - OpenCV 图像处理

python - 类型错误:使用 OpenCV 在 Python 中旋转图像时,参数 'mat' 需要 cv::UMat

opencv - Haar_Training_Cascade 连续运行很长时间没有任何反应

c++ - 基于学习内容的视频搜索的起点

c++ - gluLookAt() 使黑屏