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

Posted

技术标签:

【中文标题】使用 Open CV Python 使用带有对角视差的 StereoBM 创建视差图【英文标题】:Use Open CV Python to create dispairty map with StereoBM with diagonal parallax 【发布时间】:2014-06-20 18:47:44 【问题描述】:

我有一个立体对,想创建一个视差图。然而,这两个图像之间的移动不仅仅是从左到右或上下,而是两者的某种组合。我曾尝试在 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)

感谢到目前为止的回答!

【问题讨论】:

您在使用 StereoBM 之前是否进行了图像立体校正(使用stereoRectify (doc) 或stereoRectifyUncalibrated (doc))? 您好,我尝试使用 stereoRectifyUncalibrated 方法。我无法使用棋盘图案校准它们。我使用 SURF 生成的特征点创建了基本矩阵,并与 FLANN 匹配器匹配。但是,当我尝试运行 stereoRectifyUncalibrated 函数时,我收到一个长错误,开头是这样的: (-215) CV_IS_MAT(_points1) && CV_IS_MAT(_points2) && (_points1->rows == 1 || _points1->cols = = 1) &&.... 我读到这可能是函数不接受基本矩阵的错误,但我找不到解决方案。 此错误似乎与您提供给函数的点数组有关,而不是与基本矩阵有关。它显示了应该为真但被发现为假的断言。您能否编辑您的问题并展示您如何拨打stereoRectifyUncalibrated 【参考方案1】:

看来这个函数 stereoRectifyUncalibrated 需要一个行或列向量,而不是一个 n x 2 矩阵 输出似乎也有 3 个元素

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)

【讨论】:

以上是关于使用 Open CV Python 使用带有对角视差的 StereoBM 创建视差图的主要内容,如果未能解决你的问题,请参考以下文章

Python使用 Open CV 进行口罩检测

使用树莓派、pi 相机、python 和 Open Cv 进行人脸识别

Python - 如何使用Open-cv或PIL将24位PNG图像转换为32位

使用 Open CV python 对两幅图像进行边缘检测和直方图匹配。

如何使用 Open CV 3 python 3 用鼠标从大图像中裁剪 ROI

在open cv2 python中使用Tensor flow 2.0对象的方法是啥,为啥这么迂回?