运行现场标定
在相机上运行现场标定有两种选择:使用CLI工具或通过SDK实现。
CLI功能概述
DESCRIPTION
Tool for verifying, computing and updating in-field correction parameters on a Zivid camera
SYNOPSIS
ZividExperimentalInfieldCorrection.exe (verify|correct|read|reset) [-h]
OPTIONS
verify verify camera correction quality based on a single capture
correct calculate in-field correction based on a series of captures at different distances and positions
read get information about the correction currently on the connected camera
reset reset correction on connected camera to factory settings
verify :此功能使用单次捕获来确定放置的Zivid标定板点云的局部尺寸真实度。
correct :此功能通过拍摄Zivid标定板来确定必要的参数,以提高点云的精度。该功能还将返回校正后的误差,即在拍摄图像的工作距离上的1σ(标准差)统计确定性。
reset : 使用重置功能将删除之前正确应用的现场标定的结果。 在进行新的现场标定之前不需要进行重置。
read :读取功能将返回上一次将现场标定结果写入相机的时间。
如果在安装期间将Zivid安装到自定义路径,则CLI工具也位于该路径下,否则,CLI工具位于 C:\Program Files\Zivid\bin
下。
CLI工具位于主路径中。
Verify(验证)
将标定板放置需要验证的位置。
CLI
使用命令行运行验证功能: ZividExperimentalInfieldCorrection verify
。
SDK
如果想要通过SDK验证相机的局部尺寸真实度,请先连接到相机。
std::cout << "Connecting to camera" << std::endl;
auto camera = zivid.connectCamera();
print("Connecting to camera")
camera = app.connect_camera()
然后,通过捕获Zivid标定板来收集数据。
std::cout << "Capturing calibration board" << std::endl;
const auto detectionResult = Zivid::Experimental::Calibration::detectFeaturePoints(camera);
print("Capturing calibration board")
detection_result = calibration.detect_feature_points(camera)
之后,准备数据并检查它是否适合现场验证。
const auto input = Zivid::Experimental::Calibration::InfieldCorrectionInput{ detectionResult };
if(!input.valid())
{
throw std::runtime_error(
"Capture not valid for in-field verification! Feedback: " + input.statusDescription());
}
infield_input = calibration.InfieldCorrectionInput(detection_result)
if not infield_input.valid():
raise RuntimeError(
f"Capture not valid for in-field verification! Feedback: {infield_input.status_description()}"
)
最后显示验证结果。
std::cout << "Successful measurement at " << detectionResult.centroid() << std::endl;
const auto verification = Zivid::Experimental::Calibration::verifyCamera(input);
std::cout << "Estimated dimension trueness at measured position: " << std::setprecision(2) << std::fixed
<< verification.localDimensionTrueness() * 100.0F << "%" << std::endl;
print(f"Successful measurement at {detection_result.centroid()}")
camera_verification = calibration.verify_camera(infield_input)
print(
f"Estimated dimension trueness at measured position: {camera_verification.local_dimension_trueness()*100:.3f}%"
)
Correct(校正)
首次将标定板对齐以进行校正时,请使用Zivid studio中的实时模式,将棋盘格对齐到要进行现场标定拍照的最近点。 使标定板与相机的坐标系尽可能平行,并确保整个标定板在相机视野中可见。
CLI
通过在计算机上的终端输入指令 ZividExperimentalInfieldCorrection correct
调用现场标定工具(不要忘记从Zivid Studio中断开与相机的连接)。
SDK
如果想要通过SDK在相机上执行现场校正,请先连接到相机。
std::cout << "Connecting to camera" << std::endl;
auto camera = zivid.connectCamera();
print("Connecting to camera")
camera = app.connect_camera()
然后,将相机对准Zivid标定板并收集数据以进行现场校正。
std::vector<Zivid::Experimental::Calibration::InfieldCorrectionInput> dataset;
std::cout << "Please point the camera at a Zivid in-field calibration board. " << std::endl;
const std::string printLine = "------------------------------------------------------------------------";
while(true)
{
std::cout << printLine << std::endl;
if(yesNoPrompt("Capture (y) or finish (n)?"))
{
std::cout << "Capturing calibration board" << std::endl;
const auto detectionResult = Zivid::Experimental::Calibration::detectFeaturePoints(camera);
const auto input = Zivid::Experimental::Calibration::InfieldCorrectionInput{ detectionResult };
if(input.valid())
{
dataset.emplace_back(input);
std::cout << "Valid measurement at: " << input.detectionResult().centroid() << std::endl;
}
else
{
std::cout << "****INVALID****" << std::endl;
std::cout << "Feedback: " << input.statusDescription() << std::endl;
}
std::cout << printLine << std::endl;
}
else
{
std::cout << "End of capturing stage." << std::endl;
std::cout << printLine << std::endl;
break;
}
std::cout << "You have collected " << dataset.size() << " valid measurements so far." << std::endl;
}
dataset = []
print("Please point the camera at a Zivid in-field calibration board. ")
print_line = "------------------------------------------------------------------------"
while True:
print(print_line)
if _yes_no_prompt("Capture (y) or finish (n)? "):
print("Capturing calibration board")
detection_result = calibration.detect_feature_points(camera)
infield_input = calibration.InfieldCorrectionInput(detection_result)
if infield_input.valid():
dataset.append(infield_input)
else:
print("****INVALID****")
print(f"Feedback: {infield_input.status_description()}")
print(print_line)
else:
print("End of capturing stage.")
print(print_line)
break
print(f"You have collected {len(dataset)} valid measurements so far.")
如果标定板偏离方向太远或捕获质量太差导致无法提供足够的数据,您将被告知存在潜在的设置问题:
标定板在X,Y或Z平面中倾斜角度过大。
并非所有特征点都是可检测的。
基准标记不可见。
标定板的图像质量太差,无法提供足够的数据。
通过在不同距离和FOV中的不同位置捕获标定板图像来继续收集数据,具体可参考 进行现场标定的准则。在完成现场校正所需要的捕获后,即可使用这些数据生成校正参数。
std::cout << "Computing new camera correction..." << std::endl;
const auto correction = Zivid::Experimental::Calibration::computeCameraCorrection(dataset);
print("Computing new camera correction...")
correction = calibration.compute_camera_correction(dataset)
在应用新的标定数据之前,请先估计新校正的预期尺寸精度。
const auto accuracyEstimate = correction.accuracyEstimate();
std::cout
<< "If written to the camera, this correction can be expected to yield a dimension accuracy of "
<< std::fixed << std::setprecision(2) << 100.0F * accuracyEstimate.dimensionAccuracy()
<< "% or better in the range of z=[" << static_cast<int>(std::round(accuracyEstimate.zMin())) << ","
<< static_cast<int>(std::round(accuracyEstimate.zMax()))
<< "] across the full FOV. Accuracy close to where the correction data was collected is likely better."
<< std::endl;
accuracy_estimate = correction.accuracy_estimate()
print(
"If written to the camera, this correction can be expected to yield a dimension accuracy of ",
f"{accuracy_estimate.dimension_accuracy()*100:.3f} or better in the range of z=[{accuracy_estimate.z_min():.3f}, {accuracy_estimate.z_max():.3f}] across the full FOV.",
"Accuracy close to where the correction data was collected is likely better.",
)
完成此过程返回的信息包括:
最新计算出的FOV大部分区域的最大尺寸真实度误差。
该误差的范围取决于拍摄校正图像的距离。
如果对校正的结果满意,请选择将校正参数应用于相机。
最后,在相机上应用现场校正的结果。
std::cout << "Writing camera correction..." << std::endl;
Zivid::Experimental::Calibration::writeCameraCorrection(camera, correction);
print("Writing correction to camera")
calibration.write_camera_correction(camera, correction)
Read(读取)
可使用读取功能查看上次校正是什么时间写入相机的。 这将返回上一次将标定参数写入相机的日期和时间。
CLI
ZividExperimentalInfieldCorrection read
SDK
if(Zivid::Experimental::Calibration::hasCameraCorrection(camera))
{
const auto timestamp = Zivid::Experimental::Calibration::cameraCorrectionTimestamp(camera);
const auto time = std::chrono::system_clock::to_time_t(timestamp);
std::cout << "Timestamp of current camera correction: " << std::put_time(std::gmtime(&time), "%FT%TZ")
<< std::endl;
}
else
{
std::cout << "This camera has no in-field correction written to it." << std::endl;
}
if calibration.has_camera_correction(camera):
timestamp = calibration.camera_correction_timestamp(camera)
print(f"Timestamp of current camera correction: {timestamp.strftime(r'%Y-%m-%d %H:%M:%S')}")
else:
print("This camera has no in-field correction written to it.")
Reset(重置)
使用重置功能可删除已应用到相机的标定结果。 这会将相机的标定参数重置为Zivid的出厂标定参数。 在测试和应用新标定参数之前,不需要删除已有的标定参数。
CLI
ZividExperimentalInfieldCorrection reset
SDK
std::cout << "Reset in-field correction on the camera" << std::endl;
Zivid::Experimental::Calibration::resetCameraCorrection(camera);
print("Reset in-field correction on the camera")
calibration.reset_camera_correction(camera)