使用Open CV Python创建具有对角视差的StereoBM视差图

0 投票
1 回答
2677 浏览
提问于 2025-04-18 10:33

我有一对立体图像,想要创建一个视差图。不过,这两张图像之间的偏移并不是简单的左右或上下,而是两者的组合。我尝试使用Open CV Python中的StereoBM函数,但结果图像上出现了对角线的黑白条纹。我的问题是,是否可以使用两张视差在对角方向的图像来计算视差图,还是说必须先旋转图像才能让这个函数正常工作?

补充:在阅读了下面的回答并进行了一些研究后,我决定尝试使用stereoRectifyUncalibrated函数。我首先用SURF在第一张图像中找到关键点,然后在第二张图像中重复这个过程。接着,我使用基于FLANN的匹配器来匹配这些点,并去掉一些异常值。然后,我用findFundamentalMat函数找到基础矩阵,接着调用stereoRectifyUncalibrated。然而,我遇到了一个错误,错误信息开头是这样的:(-215) CV_IS_MAT(_points1) && CV_IS_MAT(_points2) && (_points1->rows == 1 || _points1->cols == 1) &&...

我确保所有数据类型都是一样的,并且每个点的数组尺寸也相同。下面是我使用stereoRectifyUncalibrated的代码部分。

#Detect feature points with SURF
detector = cv2.SURF()
kp1, desc1 = detector.detectAndCompute(img1, None)
kp2, desc2 = detector.detectAndCompute(img2, None)

#Match Points
FLANN_INDEX_KDTREE = 1  # bug: flann enums are missing
flann_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
matcher = cv2.FlannBasedMatcher(flann_params, {})
matches = matcher.knnMatch(desc1, trainDescriptors = desc2, k=2)
mkp1, mkp2 = [], []
ratio = 0.75
for m in matches:
    if len(m) == 2 and m[0].distance < m[1].distance * ratio:
        m = m[0]
        mkp1.append( kp1[m.queryIdx] )
        mkp2.append( kp2[m.trainIdx] )
np.float32([kp.pt for kp in mkp1])
p1 = np.float32([kp.pt for kp in mkp1])
p2 = np.float32([kp.pt for kp in mkp2])
kp_pairs = zip(mkp1, mkp2)
H, status = cv2.findHomography(p1, p2, cv2.RANSAC, 5.0)
print '%d / %d  inliers/matched' % (np.sum(status), len(status))
statusmat = np.zeros((max(status.shape),2),dtype = np.float64)
statusmat[:,0] = status[:,0]
statusmat[:,1] = status[:,0]
status = np.array(status, dtype=bool)
p1f=p1[status.view(np.ndarray).ravel()==1,:] #Remove Outliers
p2f=p2[status.view(np.ndarray).ravel()==1,:] #Remove Outliers

#Attempt to rectify using stereoRectifyUncalibrated
fundmat, mask = cv2.findFundamentalMat(p1f,p2f,cv2.RANSAC,3,0.99,)
rectmat1, rectmat2 = cv2.stereoRectifyUncalibrated(p1f,p2f,fundmat,imgsize)

感谢大家到目前为止的回答!

1 个回答

2

看起来这个函数 stereoRectifyUncalibrated 接受的是一维的行向量或列向量,而不是一个 n x 2 的矩阵。此外,输出结果似乎有三个元素。

p1fNew = p1f.reshape((p1f.shape[0] * 2, 1))
p2fNew = p2f.reshape((p2f.shape[0] * 2, 1))

retBool ,rectmat1, rectmat2 = cv2.stereoRectifyUncalibrated(p1fNew,p2fNew,fundmat,imgsize)

撰写回答