我已经放在一起的立体摄像机,并且无法使用它产生良好的视差图。这里的两位纠正图像的例子,视差映射我与他们产生:在OpenCV中使用StereoBM的差视差图
正如你所看到的,结果是非常糟糕的。改变StereoBM的设置并没有太大的改变。
的设置
- 这两款相机是相同的模型,并用USB连接到电脑。
- 它们固定在刚性木板上,使其不会移动。我尽可能地将它们对齐,但当然这并不完美。他们无法移动,所以他们在校准期间和校准后的位置都是一样的。
- 我使用OpenCV校准了立体对,并使用OpenCV的
StereoBM
类生成视差图。 - 这可能不是那么相关,但我使用Python进行编码。
问题我能想象
我这样做的第一次,所以我远不是一个专家,但我猜问题是在校准或立体声整流,而不是视差图的计算。我试过StereoBM
的所有设置排列,尽管我得到了不同的结果,但它们都像上面显示的视差图:黑色和白色的补丁。
这个想法得到了进一步支持,据我所知,立体声校正应该对齐每张照片上的所有点,以便它们通过直线(在我的情况下是水平)连接。如果我检查两幅相邻的纠正图片,很明显情况并非如此。右图中的相应点比左边高得多。不过,我不确定校准或校正是否是问题。
代码
实际的代码在物体包裹起来 - 如果你有兴趣看到它的全部,它的可用on GitHub。下面是什么(在真正的代码,我当然校准使用不止2张)实际上是运行一个简单的例子:
import cv2
import numpy as np
## Load test images
# TEST_IMAGES is a list of paths to test images
input_l, input_r = [cv2.imread(image, cv2.CV_LOAD_IMAGE_GRAYSCALE)
for image in TEST_IMAGES]
image_size = input_l.shape[:2]
## Retrieve chessboard corners
# CHESSBOARD_ROWS and CHESSBOARD_COLUMNS are the number of inside rows and
# columns in the chessboard used for calibration
pattern_size = CHESSBOARD_ROWS, CHESSBOARD_COLUMNS
object_points = np.zeros((np.prod(pattern_size), 3), np.float32)
object_points[:, :2] = np.indices(pattern_size).T.reshape(-1, 2)
# SQUARE_SIZE is the size of the chessboard squares in cm
object_points *= SQUARE_SIZE
image_points = {}
ret, corners_l = cv2.findChessboardCorners(input_l, pattern_size, True)
cv2.cornerSubPix(input_l, corners_l,
(11, 11), (-1, -1),
(cv2.TERM_CRITERIA_MAX_ITER + cv2.TERM_CRITERIA_EPS,
30, 0.01))
image_points["left"] = corners_l.reshape(-1, 2)
ret, corners_r = cv2.findChessboardCorners(input_r, pattern_size, True)
cv2.cornerSubPix(input_r, corners_r,
(11, 11), (-1, -1),
(cv2.TERM_CRITERIA_MAX_ITER + cv2.TERM_CRITERIA_EPS,
30, 0.01))
image_points["right"] = corners_r.reshape(-1, 2)
## Calibrate cameras
(cam_mats, dist_coefs, rect_trans, proj_mats, valid_boxes,
undistortion_maps, rectification_maps) = {}, {}, {}, {}, {}, {}, {}
criteria = (cv2.TERM_CRITERIA_MAX_ITER + cv2.TERM_CRITERIA_EPS,
100, 1e-5)
flags = (cv2.CALIB_FIX_ASPECT_RATIO + cv2.CALIB_ZERO_TANGENT_DIST +
cv2.CALIB_SAME_FOCAL_LENGTH)
(ret, cam_mats["left"], dist_coefs["left"], cam_mats["right"],
dist_coefs["right"], rot_mat, trans_vec, e_mat,
f_mat) = cv2.stereoCalibrate(object_points,
image_points["left"], image_points["right"],
image_size, criteria=criteria, flags=flags)
(rect_trans["left"], rect_trans["right"],
proj_mats["left"], proj_mats["right"],
disp_to_depth_mat, valid_boxes["left"],
valid_boxes["right"]) = cv2.stereoRectify(cam_mats["left"],
dist_coefs["left"],
cam_mats["right"],
dist_coefs["right"],
image_size,
rot_mat, trans_vec, flags=0)
for side in ("left", "right"):
(undistortion_maps[side],
rectification_maps[side]) = cv2.initUndistortRectifyMap(cam_mats[side],
dist_coefs[side],
rect_trans[side],
proj_mats[side],
image_size,
cv2.CV_32FC1)
## Produce disparity map
rectified_l = cv2.remap(input_l, undistortion_maps["left"],
rectification_maps["left"],
cv2.INTER_NEAREST)
rectified_r = cv2.remap(input_r, undistortion_maps["right"],
rectification_maps["right"],
cv2.INTER_NEAREST)
cv2.imshow("left", rectified_l)
cv2.imshow("right", rectified_r)
block_matcher = cv2.StereoBM(cv2.STEREO_BM_BASIC_PRESET, 0, 5)
disp = block_matcher.compute(rectified_l, rectified_r, disptype=cv2.CV_32F)
cv2.imshow("disparity", disp)
什么错吗?