如何在 OpenCV 中校正裁剪后的立体图像?

问题描述 投票:0回答:2

我有一对水平对齐的立体相机,它们是使用图像的全尺寸进行校准的。

我通过调用 cv2.initUn DistreifyMap 来获取每个相机的地图来进行纠正,然后调用 cv2.remap

使用全尺寸图像时,看起来像:

map1, map2 = cv2.initUndistortRectifyMap(camera_matrix_1, dist_coeffs_1, R1, P1, (w, h), cv2.CV_16SC2)
map3, map4 = cv2.initUndistortRectifyMap(camera_matrix_2, dist_coeffs_2, R2, P2, (w, h), cv2.CV_16SC2)
rectified1 = cv2.remap(img1, map1, map2, cv2.INTER_LINEAR)
rectified2 = cv2.remap(img2, map3, map4, cv2.INTER_LINEAR)

其中

cv2.initUndistortRectifyMap
的参数是
cv2.stereoCalibrate
cv2.stereoRectify

的输出

但是,为了提高处理速度,图像在处理时将被裁剪(并可能被合并),然后才能进行校正。这意味着校正过程无法使用图像的完整尺寸。

在完成校正之前,需要更改哪些内容才能使代码能够用于图像的裁剪(和合并)?

python opencv image-processing computer-vision camera-calibration
2个回答
2
投票

如果您想对原始

img1
img2
进行裁剪和调整大小(缩放)并在校准后使用它,那么您需要更改
camera_matrix_1
camera_matrix_2
。裁剪改变了一个主点,比例改变了焦距。但
rectified1
rectified2
的结果(输出)不会改变它的大小:
w, h
。如果您想要更小的输出图像,您需要更改
P1
P2

z 0 sx
0 z sy * camera_matrix  ->  camera_matrix'
0 0 1 

分别是

z
- 比例因子,
s
- 裁剪图像中心的移动。
camera_matrix
P
的比例和移位可能不同。 不要忘记使用
map1
和新参数重新创建
map2
initUndistortRectifyMap
...。


0
投票

要消除黑色区域,请使用以下代码根据有效的 ROI 裁剪校正图像。

R1, R2, P1, P2, Q, validRoi1, validRoi2 = cv2.stereoRectify(Kl, Dl, Kr, Dr, image_size, R, T, flags=cv2.CALIB_ZERO_DISPARITY, alpha=1)
xl, yl, wl, hl = validRoi1
xr, yr, wr, hr = validRoi2

x = max(xl, xr)
w = min(wl, wr)

y = max(yl, yr)
h_ind = np.argmin([yl+hl, yr+hr])

if h_ind == 0:
    h = hl
else:
    h = hr - y

xmap1, ymap1 = cv2.initUndistortRectifyMap(Kl, Dl, R1, P1, image_size, cv2.CV_32FC1)
xmap2, ymap2 = cv2.initUndistortRectifyMap(Kr, Dr, R2, P2, image_size, cv2.CV_32FC1)

left_img_rectifiedt = cv2.remap(left_img, xmap1, ymap1, cv2.INTER_LINEAR)
right_img_rectifiedt = cv2.remap(right_img, xmap2, ymap2, cv2.INTER_LINEAR)

left_img_rectified = cv2.remap(left_img, xmap1, ymap1, cv2.INTER_LINEAR)[y:y+h, xl:xl+w]
right_img_rectified = cv2.remap(right_img, xmap2, ymap2, cv2.INTER_LINEAR)[y:y+h, xr:xr+w]
© www.soinside.com 2019 - 2024. All rights reserved.