You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

三维重建姿态出现旋转偏移的原因排查与解决咨询

三维姿态重建的旋转与偏移问题

我有足球比赛的两个不同视角视频,先在两个视角上用2D姿态估计器提取2D人体姿态点,再手动匹配两个相机下的2D姿态点建立对应关系。目前三维重建出的姿态形态看起来合理,但整体在空间中存在旋转和偏移,找不到原因。

我的三角化姿态结果如图所示。

相机标定实现

为标定相机,我手动标记了场地中的已知点(如场地角点、点球点等平面点,也用到球门横梁交点这类非平面点)。尝试多种方法后,最佳结果是通过平面点调用cameraCalibrate函数估计内参矩阵,核心实现函数如下:

def new_guess(self, image_points, real_worlds):
        planar_img, planar_3d = Homo_est.get_planar_points(image_points, real_worlds)
        mat, ds = self.create_camera_guess(planar_img, planar_3d)
        real_worlds = np.array([list(tup) for tup in real_worlds])
        image_points =[list(tup) for tup in image_points]
        objPts = []
        imgPts = []
        
        objPts.append(real_worlds)
        imgPts.append(image_points)
        objPts = np.float32(objPts)
        imgPts = np.float32(imgPts)
        dist_coeffs = np.zeros((4,1)) 
        gray = cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY)
        #mat = self.second_camera_guess() # bästa so far
        criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30000, 0.0001) # att ha 
        ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objPts, imgPts, gray.shape[::-1], mat, ds, flags=cv2.CALIB_USE_INTRINSIC_GUESS, criteria=criteria)
        return mtx, dist

P矩阵计算(基于solvePNP)

将上述得到的内参矩阵传入solvePNP函数计算投影矩阵P,并用cv2.projectPoints()验证结果,投影误差最多10像素(多数情况更小),这个精度我认为是合格的。核心实现函数如下:

def calibrate_solvePNP(self, image_points, real_worlds):
        planar_img, planar_3d = Homo_est.get_planar_points(image_points, real_worlds)    
        mat, dist = self.new_guess(image_points, real_worlds)
        real_worlds = np.array([list(tup) for tup in real_worlds])
        image_points =[list(tup) for tup in image_points]
        objPts = []
        imgPts = []        
        objPts.append(real_worlds)
        imgPts.append(image_points)
        objPts = np.float32(objPts)
        imgPts = np.float32(imgPts)
        dist_coeffs = np.zeros((4,1)) 
        gray = cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY)
        (succsess, rvec, t) = cv2.solvePnP(objPts, imgPts, mat, dist_coeffs)
        res, jac = cv2.projectPoints(real_worlds, rvec, t, mat, dist_coeffs)

        R, jac = cv2.Rodrigues(rvec)
        Rt = np.concatenate([R,t], axis=-1) # [R|t]
        P = np.matmul(mat, Rt)
        return P 

三角化实现

完成相机参数计算后,对匹配的姿态点进行三角化,核心实现如下:

def triangulate_pts(self):
        P1_points = Homo_est.player_view1() # pose coordinates view 1
        P2_points = Homo_est.player_view2() # pose coordinates view 2
        homo = Homo_est()
        P1, P2, K1, K2, d1, d2 = homo.generate_cameras() # essentially calls my calibrate_solvePNP and new_guess to create these values
        dist_coeffs = np.zeros((4,1)) 
        P1_new = np.matmul(np.linalg.inv(K1), P1) # unsure if this is good or bad
        P2_new = np.matmul(np.linalg.inv(K2), P2)

        # doesn't seem to make a difference using d1 or d2
        P1_undist = cv2.undistortPoints(P1_points, cameraMatrix=K1, distCoeffs=dist_coeffs)
        
        P2_undist = cv2.undistortPoints(P2_points, 
                                   cameraMatrix=K2,
                                   distCoeffs=dist_coeffs)
        
        triangulation = cv2.triangulatePoints(P1_new, P2_new, P1_undist, P2_undist)

        homog_points = triangulation.transpose()
        
        euclid_points = cv2.convertPointsFromHomogeneous(homog_points)

euclid_points就是我用于绘制三维姿态的点集。

已尝试的解决方案

  • 调整畸变系数的各种参数,对结果影响不大;
  • 尝试将其中一个相机归一化为[I 0]并转换另一个相机的参数,但操作后未解决问题(可能操作有误);
  • 遵循标准三角化流程进行实现。

求助问题

我几乎尝试了所有能想到的方法,直觉上认为肯定存在消除这种旋转和偏移的方式——毕竟重建出的姿态形态是正确的。最坏情况下,只要能消除旋转即可(因为我已经有场地平面点的准确单应性)。请问导致这种旋转和偏移的可能原因是什么?

内容的提问来源于stack exchange,提问作者emil holmberg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 04:37:06