首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >OpenCV + Python:计算立体重投影误差

OpenCV + Python:计算立体重投影误差
EN

Stack Overflow用户
提问于 2017-11-16 12:01:03
回答 1查看 3.6K关注 0票数 4

我想做一些类似于this question的事情,但是stereoCalibrate()而不是calibrateCamera()。也就是说,计算立体相机标定的重投影误差。

我的简化示例如下:

代码语言:javascript
运行
复制
import cv2
import numpy as np

def calibrate_stereo(w, h, objpoints, imgpoints_l, imgpoints_r):
    stereocalib_criteria = (cv2.TERM_CRITERIA_COUNT + cv2.TERM_CRITERIA_EPS , 1000, 1e-6)
    retval, A1, D1, A2, D2, R, T, E, F = cv2.stereoCalibrate(objpoints,imgpoints_l, imgpoints_r,None,None,None,None, (w,h), flags=0, criteria=stereocalib_criteria)

    return (retval, (A1,D1,A2,D2, R, T, E, F))

def calc_rms_stereo(objectpoints, imgpoints_l, imgpoints_r, A1, D1, A2, D2, R, T):
    tot_error = 0
    total_points = 0

    for i, objpoints in enumerate(objectpoints):
        # calculate world <-> cam1 transformation
        _, rvec_l, tvec_l,_ = cv2.solvePnPRansac(objpoints, imgpoints_l[i], A1, D1)

        # compute reprojection error for cam1
        rp_l, _ = cv2.projectPoints(objpoints, rvec_l, tvec_l, A1, D1)
        tot_error += np.sum(np.square(np.float64(imgpoints_l[i] - rp_l)))
        total_points += len(objpoints)

        # calculate world <-> cam2 transformation
        rvec_r, tvec_r  = cv2.composeRT(rvec_l,tvec_l,cv2.Rodrigues(R)[0],T)[:2]

        # compute reprojection error for cam2
        rp_r,_ = cv2.projectPoints(objpoints, rvec_r, tvec_r, A2, D2)
        tot_error += np.square(imgpoints_r[i] - rp_r).sum()
        total_points += len(objpoints)

    mean_error = np.sqrt(tot_error/total_points)

    return mean_error


if __name__ == "__main__":    
    # omitted: reading values for w,h, objectPoints, imgpoints_l, imgpoints_r from file (format as expected by the OpenCV functions)
    # [...]

    rms, (A1,D1,A2,D2,R,T,_,_) = calibrate_stereo(w, h, objectpoints, imgpoints_l, imgpoints_r)

    print("RMS (stereo calib): {}".format(rms))

    rms_2 = calc_rms_stereo(objectpoints, imgpoints_l, imgpoints_r, A1, D1, A2, D2, R, T)    
    print("RMS (custom calculation):", rms_2)

样本输出:

代码语言:javascript
运行
复制
RMS (stereo calib): 0.14342257926694932
RMS (custom calculation): 0.356273345751

据我所知,stereoCalibrate()源代码中的计算与我的非常相似。我遗漏了什么?

Ubuntu上的OpenCV 3.3.0

EN

Stack Overflow用户

回答已采纳

发布于 2018-01-23 12:00:32

在OpenCV实现的基础上实现了一个自定义立体标定算法,并对其进行了求解。

cv2.stereoCalibrate()内部计算的重投影误差与我的自定义计算之间的差异源于外部参数rvec_ltvec_l的不同值。这些矢量描述了左摄像机和每幅图像的校准模式之间的旋转和平移。cv2.solvePnpRansac()只根据左图像的重投影误差得到优化值,而在cv2.stereoCalibrate()中,这些值与RT一起根据每一对立体图像的重投影误差进行优化。

如果要准确复制cv2.stereoCalibrate()返回的均方根值,就必须修改cv::stereoCalibrate()的C/C++源代码,以返回优化的外部参数(cv::calibrateCamera()已经对单目校准做了此操作)。

票数 1
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47329154

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档