首页 > 解决方案 > 使用鱼眼(等距)立体校正重新映射后仅裁剪为有效像素?

问题描述

我有两个水平偏移的相机,并在针孔等距模型(失真系数)下使用 Kalibr 获取了它们的校准参数(相机矩阵和失真系数,以及它们之间的变换k1, k2, k3, k4)。

我想使用 openCVscv.fisheye.stereoRectify为我可以输入的每个相机创建新的投影矩阵,cv.fisheye.initUndistortRectifyMap然后输入cv.remap以校正和不扭曲每个图像。

不幸的是,即使将balancefisheye.stereoRectify 中的参数设置为 0,remaped 图像仍然有黑色像素向其中弯曲。我想裁剪每个图像,以便在任何一个未失真的相机图像中都不存在无效像素。

我看到标准cv.stereoRectify函数有一个alpha参数可以做到这一点。但是好像cv.fisheye.stereoRectify没有这个参数。因此,我想复制它的功能。

cv.stereoRectify似乎使用了 radtan 失真模型(失真参数k1, k2, p1, p2),所以我认为我不能轻松地交换该函数,因为我没有p1p2

我的管道中的片段如下:

R1, R2, P1, P2, Q = cv2.fisheye.stereoRectify(mtx_right, dist_right, 
                                              mtx_left, dist_left, 
                                              (960,1280), R, tvec, 
                                              flags=cv2.CALIB_ZERO_DISPARITY,
                                              balance= 0.0, fov_scale=1)

map1_right, map2_right = cv2.fisheye.initUndistortRectifyMap(mtx_right, dist_right, 
                                                             R1, P1[0:3, 0:3], 
                                                             (1280, 960), cv2.CV_16SC2)  

map1_left, map2_left = cv2.fisheye.initUndistortRectifyMap(mtx_left, dist_left,
                                                           R2, P2[0:3, 0:3],
                                                           (1280, 960), cv2.CV_16SC2)

undistorted_right = cv2.remap(img_rgb_right, map1_right, map2_right, 
                             interpolation=cv2.INTER_LINEAR,
                             borderMode=cv2.BORDER_CONSTANT)
undistorted_left = cv2.remap(img_rgb_left, map1_left, map2_left, 
                            interpolation=cv2.INTER_LINEAR,
                            borderMode=cv2.BORDER_CONSTANT)

alpha有没有一种简单的方法来获得与传统产品相同的功能cv.stereoRectifybalance=0看起来很接近,但并没有完全切断无效像素。

电流输出(balance=0.5缩小一点) 鱼眼立体校正

两个图像的目标是仅显示绿色框中的内容(如果不清楚,则两者的尺寸相同,以具有较小的有效像素矩形为准):

目标

标签: pythonopencv

解决方案


这是我在 Imagemagick 中使用 -trim 的方法。我注意到 -trim 可以跟踪修剪后左上角相对于修剪前的位置的偏移量(通过离开 +repage 来清除该几何信息)。所以我修剪每个图像并让它保持跟踪。然后我将修剪后的图像分别放在黑色背景中,然后并排附加两个结果,然后再次修剪黑色。

由于没有提供原件,我从提供的图像中剪掉了图像。

剩下:

在此处输入图像描述

对:

在此处输入图像描述

magick left.png -format "%wx%h" -write info: -fuzz 15% -trim \
-fuzz 5% -define trim:percent-background=0 \
-define trim:background-color=black -trim left_im_trim.png

magick right.png -format "%wx%h" -write info: -fuzz 15% -trim \
-fuzz 5% -define trim:percent-background=0 \
-define trim:background-color=black -trim right_im_trim.png


magick \
\( left_im_trim.png -set page "%wx+0+%Y" -background black -flatten \)  \
\( right_im_trim.png -set page "%wx+0+%Y" -background black -flatten \) \
-background black +append \
-define trim:percent-background=0 \
-define trim:background-color=black \
-trim +repage left_right_trim_append.png


左修剪:

在此处输入图像描述

右修剪:

在此处输入图像描述

再次附加和修剪:

在此处输入图像描述

我将上面的 3 个命令分开,以便可以看到结果。但它们都可以组合成 1 个长命令行。


推荐阅读