跳转至

X2TestAccuracy

双目模式测试相机精度。以 Win 10 系统为例,操作步骤如下:

RVC 相机精度检测步骤

1. 搭建 Python 编译环境

此步骤可参考 Python SDK 配置步骤

① 安装 Python。适配版本:Python 3.7—Python 3.10,推荐版本:Python 3.7.9。

② 安装 RyRVC 模块。在命令窗口输入:

pip3 install PyRVC

③ 安装 NumPy。

pip3 install numpy

④ 安装 OpenCV-Python。

pip3 install opencv-python

⑤ 安装 Matplotlib。

pip3 install matplotlib

2. 选择合适的标定板

根据相机工作距离,确定合适的标定板大小,继而确定标定板圆心距与规格。

以 A6 标定板为例。A6:0.02 指的是圆心距 0.02 m,需根据标定板上标注的参数,选择下图所示的标定板。标定板详细规格及图示见 RVC 标定板尺寸图

标定板规格 A2 A3 A4 A5 A6 A7 A8 A9 A10
圆心距 (m) 0.08 0.056 0.04 0.028 0.02 0.014 0.01 0.007 0.0048

CaliboardA6

3. 调整拍摄参数

对标定板进行 2D、3D 拍摄,在 RVCManager 中调试拍摄参数,直至达到满意的效果,记录此时的拍摄参数。

进入 RVC 安装目录下的文件夹:/RVCSDK/examples/Python,找到双目模式精度测试例程 X2TestAccuracy.py,定位至下列代码,改成前面记录的拍摄参数。

# Set capture parameters
cap_opt = RVC.X2_CaptureOptions()
# Transform point map's coordinate to left/right(RVC.CameraID_Left/RVC.CameraID_Right) camera or reference
# plane(RVC.CameraID_NONE)
cap_opt.transform_to_camera = RVC.CameraID_Left
# Set 2d and 3d exposure time. Capture with white light, range [11, 100]ms, others [3, 100]ms.
cap_opt.exposure_time_2d = 20
cap_opt.exposure_time_3d = 20
# Set 2d and 3d gain. the default value is 0. The gain value of each series cameras is different, you can call function GetGainRange() to get specific range.
cap_opt.gain_2d = 0
cap_opt.gain_3d = 0
# Set 2d and 3d gamma. the default value is 1. The gamma value of each series cameras is different, you can call function GetGammaRange() to get specific range.
cap_opt.gamma_2d = 1
cap_opt.gamma_3d = 1
# range in [0, 10], default = 5. The contrast of point less than this value will be treat * as invalid point and be removed.
cap_opt.light_contrast_threshold = 2
# edge control after point matching, range in [0, 10], default = 2. The big the value, the more edge * noise to be
# removed.
cap_opt.edge_noise_reduction_threshold = 0
cap_opt.capture_mode = RVC.CaptureMode_Ultra

4. 热机

在 RVCManager 中,选择连续拍摄模式,循环拍摄 30 分钟进行热机。

5. 运行精度检测例程

执行命令:

python ./X2TestAccuracy.py 1 A6 10

此命令代表脚本名称为 X2TestAccuracy.py、Gamma 值为 1、标定板规格为 A6、精度测试次数为 10,可根据实际情况修改参数。请确保标定板规格准确,否则会导致测量误差。

6. 查看测试结果

精度检测结果将以折线图像显示,图像竖轴为精度偏差值,横轴为测试次数。若精度偏差值较大(如达到毫米级别),请联系技术支持。

示例代码

# Copyright (c) RVBUST, Inc - All rights reserved.
import PyRVC as RVC
import sys
import os
import numpy as np
import cv2

from Utils.CaliBoardUtils import *
from Utils.Tools import *


def App(gamma, pattern_type, capture_times):

    # Initialize RVC X system
    RVC.SystemInit()

    # Choose RVC X Camera type (USB, GigE or All)
    opt = RVC.SystemListDeviceTypeEnum.All

    # Scan all RVC X Camera devices
    ret, devices = RVC.SystemListDevices(opt)
    print("RVC X Camera devices number:", len(devices))

    # Find whether any RVC X Camera is connected or not
    if len(devices) == 0:
        print("Can not find any RVC X Camera!")
        RVC.SystemShutdown()
        exit(1)

    # Create a RVC X Camera
    x = RVC.X2.Create(devices[0])

    # Test RVC X Camera is valid or not
    if x.IsValid() == False:
        print("RVC X Camera is not valid!")
        RVC.X2.Destroy(x)
        RVC.SystemShutdown()
        exit(1)

    #PrintCaptureMode(devices[0])

    # Open RVC X Camera
    ret1 = x.Open()

    # Test RVC X Camera is opened or not
    if x.IsOpen() == False:
        print("RVC X Camera is not opened!")
        RVC.X2.Destroy(x)
        RVC.SystemShutdown()
        exit(1)

    # Print ExposureTime Range
    _, exp_range_min, exp_range_max = x.GetExposureTimeRange()
    print("ExposureTime Range:[{}, {}]".format(exp_range_min, exp_range_max))

    # Set capture parameters
    cap_opt = RVC.X2_CaptureOptions()
    # Transform point map's coordinate to left/right(RVC.CameraID_Left/RVC.CameraID_Right) camera or reference
    # plane(RVC.CameraID_NONE)
    cap_opt.transform_to_camera = RVC.CameraID_Left
    # Set 2d and 3d exposure time. Capture with white light, range [11, 100]ms, others [3, 100]ms.
    cap_opt.exposure_time_2d = 20
    cap_opt.exposure_time_3d = 20
    # Set 2d and 3d gain. the default value is 0. The gain value of each series cameras is different, you can call function GetGainRange() to get specific range.
    cap_opt.gain_2d = 0
    cap_opt.gain_3d = 0
    # Set 2d and 3d gamma. the default value is 1. The gamma value of each series cameras is different, you can call function GetGammaRange() to get specific range.
    cap_opt.gamma_2d = 1
    cap_opt.gamma_3d = 1
    # range in [0, 10], default = 5. The contrast of point less than this value will be treat * as invalid point and be removed.
    cap_opt.light_contrast_threshold = 2
    # edge control after point matching, range in [0, 10], default = 2. The big the value, the more edge * noise to be
    # removed.
    cap_opt.edge_noise_reduction_threshold = 0

    # Create saving address of image and point map.
    save_dir = "Data"
    if not os.path.exists(save_dir):
        os.makedirs(save_dir)

    valid_cnt = 0
    fail_cnt = 0
    err_list = []

    i = 0
    while valid_cnt < capture_times and fail_cnt < 5:
        # Capture a point map and a image.
        ret2 = x.Capture(cap_opt)
        if ret2 == True:
            # Get image data. choose left or right side. the point map is map to left image.
            img = x.GetImage(RVC.CameraID_Left)
            # Convert image to array and save it.
            img = np.array(img, copy=False)
            pm = np.array(x.GetPointMap(), copy=False).reshape(-1, 3)

            if 0 == i:
                # Save image and point map data, only save once to save time and space
                cv2.imwrite("{}/test.png".format(save_dir), img)
                print("Save image successed!")

                # Save point map (m) to file.
                if x.GetPointMap().Save("{}/test.ply".format(save_dir), RVC.PointMapUnitEnum.Meter):
                    print("Save point map successed!")
                else:
                    print("Save point map failed!")

            # Calculate accuracy by image and point cloud.
            ret3, error_mm = CalcAccuracy(img,
                                             pm,
                                             gamma=gamma,
                                             m_type=pattern_type)
            if ret3:
                valid_cnt += 1
                mean_err = np.mean(error_mm)
                err_list.append(mean_err)
                max_err = error_mm[np.argmax(np.abs(error_mm))]
                print(f"{valid_cnt} times accuracy test, mean error: {mean_err} mm, max_error: {max_err} mm")
            else:
                fail_cnt += 1

        else:
            print(RVC.GetLastErrorMessage())
            fail_cnt += 1
        i += 1

    if len(err_list) > 0:
        PlotError(err_list)
    else:
        print("no valid result, please adjust param as suggested!")

    # Close RVC X Camera
    x.Close()

    # Destroy RVC X Camera
    RVC.X2.Destroy(x)

    # Shut Down RVC X System
    RVC.SystemShutdown()


if __name__ == "__main__":
    """
        This demo shows how to get X2 accuracy.
        argv[1]: gamma (0~1), for adjust image brightness. gamma>1 will increse image brightness
                 and gamma<1 wille decrease image brightness
        argv[2]: pattern_type, type of cali board pattern used. You can choose A2, A3, ..., A10
                 Center distance of circles on cali borad (m):
                 A2:0.08
                 A3:0.056
                 A4:0.04
                 A5:0.028
                 A6:0.02
                 A7:0.014
                 A8:0.01
                 A9:0.007
                 A10:0.0048
        argv[3]: capture times, 10 - 100 recommended. Average error of N capture times will be returned
                 as result
        Please select a cali board pattern of appropriate size according to the working distance
        of 3D camera. For details, please consult technical support.
    """

    if len(sys.argv) != 4:
        sys.exit("Invalid arguments: Usage: python3 X2TestAccuracy.py 1 A4 10")

    gamma = sys.argv[1]
    pattern_type = sys.argv[2]
    capture_times = sys.argv[3]

    print("gamma: {}, pattern_type: {}, capture_times: {}".format(
        gamma, pattern_type, capture_times))

    gamma = float(gamma)
    capture_times = int(capture_times)
    App(gamma, pattern_type, capture_times)