图像校正 - OpenCV - Python

Posted

技术标签:

【中文标题】图像校正 - OpenCV - Python【英文标题】:Image Rectification - OpenCV - Python 【发布时间】:2018-02-10 11:48:11 【问题描述】:

我正在尝试纠正来自RGB-D Dataset 7-Scenes 的图像对。由于该数据集提供了地面实况姿态数据,因此我没有尝试提取匹配点并计算 F。相反,我正在使用似乎正确的 https://math.stackexchange.com/a/709658 计算相对平移和旋转,并将两帧视为校准场景。

但是,整改的结果是垃圾。我尝试使用几个 alpha 值(-1、0、1 和 [0,1] 范围内的许多值),但没有得到好的结果。

相对的 R 和 t 看起来不错(近帧有小的旋转和平移)。

对于相机矩阵,我使用the dataset 中给出的值(主点(320,240),焦距(585,585))

import cv2
import numpy as np
from matplotlib import pyplot as plt

frame1 = 100
frame2 = 160

img_1_path = './chess/seq-01/frame-000.color.png'.format(frame1)
img_2_path = './chess/seq-01/frame-000.color.png'.format(frame2)

pose_1_path = './chess/seq-01/frame-000.pose.txt'.format(frame1)
pose_2_path = './chess/seq-01/frame-000.pose.txt'.format(frame2)

img_1 = cv2.imread(img_1_path)
img_2 = cv2.imread(img_2_path)

pose1 = np.loadtxt(pose_1_path)
pose2 = np.loadtxt(pose_2_path)

R1 = pose1[0:3, 0:3]
t1 = pose1[0:3, 3]

R2 = pose2[0:3, 0:3]
t2 = pose2[0:3, 3]

# https://math.stackexchange.com/questions/709622/relative-camera-matrix-pose-from-global-camera-matrixes
R = np.matmul(np.linalg.inv(R2), R1)
T = np.matmul(np.linalg.inv(R2), (t1 - t2))


# https://www.microsoft.com/en-us/research/project/rgb-d-dataset-7-scenes/
px = 320.0
py = 240.0
fx = 585.0
fy = 585.0

cameraMatrix1 = np.array(
    [
        [fx, 0, px],
        [0, fy, py],
        [0, 0, 1.0]
    ]
)

cameraMatrix2 = cameraMatrix1

distCoeff = np.zeros(4)

R1, R2, P1, P2, Q, roi1, roi2 = cv2.stereoRectify(
    cameraMatrix1=cameraMatrix1,
    distCoeffs1=distCoeff,
    cameraMatrix2=cameraMatrix2,
    distCoeffs2=distCoeff,
    imageSize=(640, 480),
    R=R,
    T=T,
    flags=cv2.CALIB_ZERO_DISPARITY,
    alpha=1)

map1x, map1y = cv2.initUndistortRectifyMap(
    cameraMatrix=cameraMatrix1,
    distCoeffs=distCoeff,
    R=R1,
    newCameraMatrix=P1,
    size=(640, 480),
    m1type=cv2.CV_32FC1)

map2x, map2y = cv2.initUndistortRectifyMap(
    cameraMatrix=cameraMatrix2,
    distCoeffs=distCoeff,
    R=R2,
    newCameraMatrix=P2,
    size=(640, 480),
    m1type=cv2.CV_32FC1)


img1_rect = cv2.remap(img_1, map1x, map1y, cv2.INTER_LINEAR)
img2_rect = cv2.remap(img_2, map2x, map2y, cv2.INTER_LINEAR)

fig, ax = plt.subplots(nrows=2, ncols=2)

plt.subplot(2, 2, 1)
plt.imshow(img_1)

plt.subplot(2, 2, 2)
plt.imshow(img_2)

plt.subplot(2, 2, 3)
plt.imshow(img1_rect)

plt.subplot(2, 2, 4)
plt.imshow(img2_rect)

plt.show(block=False)
plt.pause(10)
plt.close()

知道我错过了什么吗?我应该不相信地面实况姿势数据还是我的管道存在缺陷?

谢谢。

【问题讨论】:

你能画出两幅图中的极线吗?看起来极点位于图像内部。完全纠正这种情况是不可能的(因为极点映射到无穷大),我对您的纠正算法失败并不感到惊讶。 你是对的:imgur.com/a/CvyRU,看起来图像中至少有一个极点。有什么办法可以克服吗? 正如我所说,纠正完整的图像是不可能的。因此,要么只纠正其中的一部分(你必须自己实现),要么根本不纠正。 【参考方案1】:

当图中极点在:http://homes.esat.kuleuven.be/~konijn/publications/1999/MPOL-simple.pdf

【讨论】:

以上是关于图像校正 - OpenCV - Python的主要内容,如果未能解决你的问题,请参考以下文章

图像校正 - OpenCV - Python

使用 opencv 进行立体图像校正不起作用

opencv图像倾斜校正和切边

正确校正 GPU 的立体图像(opencv)

OpenCV 校正,图像 C++ 上有太多黑色区域

如何使用opencv在鱼眼校正图像中绘制内接矩形?