使用Opencv和Python从立体视觉生成点云时使用相同的3D坐标

使用Opencv和Python从立体视觉生成点云时使用相同的3D坐标,python,opencv,point-clouds,stereo-3d,3d-reconstruction,Python,Opencv,Point Clouds,Stereo 3d,3d Reconstruction,我对OpenCV和3D重建非常陌生。我试着从照相机拍摄的两张图像中生成点云。我用图书馆校准了照相机。这里我得到了相机的内在参数。我使用了ORB特征检测器和描述符。这些是主要的图像和我在特征检测后得到的图像 然后我得到了基本矩阵,并用它得到了基本矩阵。我用它来获取外部参数旋转和平移。但是我很抱歉,所有的三维坐标对于最后的所有点都是一样的。如果我使用不同的P1和P2硬编码,那么我会得到不同的3D坐标 这是密码 # Import library import numpy as np import

我对OpenCV和3D重建非常陌生。我试着从照相机拍摄的两张图像中生成点云。我用图书馆校准了照相机。这里我得到了相机的内在参数。我使用了ORB特征检测器和描述符。这些是主要的图像和我在特征检测后得到的图像

然后我得到了基本矩阵,并用它得到了基本矩阵。我用它来获取外部参数旋转和平移。但是我很抱歉,所有的三维坐标对于最后的所有点都是一样的。如果我使用不同的P1和P2硬编码,那么我会得到不同的3D坐标

这是密码

 # Import library

import numpy as np
import cv2
from matplotlib import pyplot as plt
import time


def degeneracyCheckPass(first_points, second_points, rot, trans):
    rot_inv = rot
    for first, second in zip(first_points, second_points):
        first_z = np.dot(rot[0, :] - second[0]*rot[2, :], trans) / np.dot(rot[0, :] - second[0]*rot[2, :], second)
        first_3d_point = np.array([first[0] * first_z, second[0] * first_z, first_z])
        second_3d_point = np.dot(rot.T, first_3d_point) - np.dot(rot.T, trans)

        if first_3d_point[2] < 0 or second_3d_point[2] < 0:
            return False

    return True

start = time.time();
# Load a pair of images
img1 = cv2.imread('1.jpg',1)          
img2 = cv2.imread('2.jpg',1) 

#camera_matrix:

#cmat is K
zero = np.float32([[0.0], [0.0], [0.0]])
cmat = np.float32([[2610.9791576918024, 0.0, 1035.3907882371566], [0.0, 2611.5091416583214, 479.1873404639389], [0.0, 0.0, 1.0]])
cmat_inv = np.linalg.inv(cmat)
#dist_coefs:
dist = np.matrix('0.10783691621695163 0.0979247249215728 -0.010931168141218273 0.009561950912198006 -1.745839718546563')


# Initiate ORB detector
orb = cv2.ORB_create()

# Find the keypoints and descriptors with ORB
kp1, des1 = orb.detectAndCompute(img1,None)
kp2, des2 = orb.detectAndCompute(img2,None)

# Create BFMatcher object
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)

# Match descriptors.
matches = bf.match(des1,des2)


#Ratio test as per Lowe's paper
good = []
pts1 = []
pts2 = []

dist = [m.distance for m in matches]
thres_dist = (sum(dist) / len(dist)) * 0.8
for m in matches:
    if m.distance < thres_dist:
        good.append(m)
        pts2.append(kp2[m.trainIdx].pt)
        pts1.append(kp1[m.queryIdx].pt)

# Draw  matches.
img3 = cv2.drawMatches(img1,kp1,img2,kp2,good, None, flags=2)
plt.imshow(img3),plt.show()

# Get the list of best matches from both the images
pts1 = np.int32(pts1)
pts2 = np.int32(pts2)

# Find fundamental Matrix
F, mask = cv2.findFundamentalMat(pts1, pts2, cv2.FM_LMEDS)

# Select inlier points
pts1 = pts1[mask.ravel()==1]
pts2 = pts2[mask.ravel()==1]

# Find essential matrix
#E = K'^T . F . K
E = cmat.T.dot(F).dot(cmat)


# Compute camera pose

U, S, Vt = np.linalg.svd(E)
W = np.array([0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]).reshape(3, 3)
first_inliers = []
second_inliers = []


for i in range(len(pts1)):
    first_inliers.append(cmat_inv.dot([pts1[i][0], pts1[i][1], 1.0]))
    second_inliers.append(cmat_inv.dot([pts2[i][0], pts2[i][1], 1.0]))


# First choice: R = U * W * Vt, T = u_3
R = U.dot(W).dot(Vt)
T = U[:, 2]

# Start degeneracy checks
if not degeneracyCheckPass(first_inliers, second_inliers, R, T):
    # Second choice: R = U * W * Vt, T = -u_3
    T = - U[:, 2]
    if not degeneracyCheckPass(first_inliers, second_inliers, R, T):
        # Third choice: R = U * Wt * Vt, T = u_3
        R = U.dot(W.T).dot(Vt)
        T = U[:, 2]
        if not degeneracyCheckPass(first_inliers, second_inliers, R, T):
            # Fourth choice: R = U * Wt * Vt, T = -u_3
            T = - U[:, 2]

T_r = T.reshape((T.shape[0],-1))

# Reconstruct 3D location of matched points
# Get camera projection matrix


P1 = np.hstack((cmat, zero))
P2 = np.dot(cmat, np.hstack((R,T_r))) 


pts1t = pts1.transpose()
pts2t = pts2.transpose()


floatpst1t = np.array([pts1t[0,:].astype(np.float) / 1944.0, pts1t[1,:].astype(np.float) / 2592.0])


floatpst2t = np.array([pts2t[0,:].astype(np.float) / 1944.0, pts2t[1,:].astype(np.float) / 2592.0])


#Demo projection matrix
#P1 = np.eye(4)
#P2 = np.array([[ 0.878, -0.01 ,  0.479, -1.995],
#            [ 0.01 ,  1.   ,  0.002, -0.226],
#            [-0.479,  0.002,  0.878,  0.615],
#            [ 0.   ,  0.   ,  0.   ,  1.   ]])
X = cv2.triangulatePoints(P1[:4], P2[:4], floatpst1t, floatpst2t)
print X
#here I will divide the first three parameters with the fourth one to get the 3d coordinate

finish = time.time();
print(finish - start)
这是X与我计算的P1和P2的结果

这是演示P1和P2


嘿,我注意到你的演示P1是一个4x4矩阵。你的零变量不是应该是np.float32[[0.0]、[0.0]、[0.0]、[1.0]]吗?因此np.hstackcmat的结果,零是4x4矩阵?这里P1和P2是3x4矩阵。在下一行中,4x4矩阵转换为3x4:X=cv2。三角点SP1[:3],P2[:3],floatpst1t,floatpst2t值变为-demo P1 P1[:3]=[[1.0.0.0.][0.1.0.0.][0.0.0.1.0.]]demo P2 P2[:3]=[0.878-0.01 0.479-1.995][0.01 1.0.002-0.226][-0.479 0.002-0.878 0.615]],如果我理解正确,P1矩阵的值与demoP1和P2的值相同,与demoP2的值相同。然而,当对点进行三角剖分时,会得到不同的结果?不,我的P1是摄影机矩阵,而demoP1类似于身份矩阵。两者具有相同的维度。