Running Infield Correction
There are two options to run in-field correction on a camera: using the CLI tool or using SDK functions.
CLI function overview
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: this function uses a single capture to determine the local dimension trueness of the point cloud where the Zivid calibration board is placed.
correct: this function is used to determine the necessary parameters for improving the accuracy of the point cloud using captures of the Zivid calibration board. This will return a post-correction error as 1σ statistical certainty over the working distance the images were captured.
reset: using reset will remove any infield correction that has been applied in previous correct instances. It is not required to do a reset before doing a new infield correction.
read: the read function will return the last time an infield correction was written to the camera.
The CLI tool is in PATH if Zivid was added to PATH during installation, otherwise, the CLI tool is found under C:\Program Files\Zivid\bin
.
The CLI tool is in the main PATH.
Verify
Place the board in the desired location.
CLI
Run the verify function using the command line: ZividExperimentalInfieldCorrection verify
.
SDK
To verify the local dimension trueness of a camera from the SDK, first connect to the camera.
std::cout << "Connecting to camera" << std::endl;
auto camera = zivid.connectCamera();
print("Connecting to camera")
camera = app.connect_camera()
Then, gather data by capturing the Zivid calibration board.
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)
After that, prepare data and check that it is appropriate for in-field verification.
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()}"
)
Finally, show verification results.
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
In order to align the board correctly it is recommended to use Zivid Studio and capture with the camera in live mode. The first time aligning the board for the infield correction, align the checkerboard at the closest point you want to capture for infield correction. Try to have the board as parallel as possible to the coordinate system in the camera and make sure the entire board is visible in the camera frame.
CLI
Call the infield correction tool using the terminal on the computer as ZividExperimentalInfieldCorrection correct
(don’t forget to disconnect from the camera in Zivid Studio).
SDK
To perform In-field correction on a camera from the SDK, first connect to the camera.
std::cout << "Connecting to camera" << std::endl;
auto camera = zivid.connectCamera();
print("Connecting to camera")
camera = app.connect_camera()
Then, point the camera at a Zivid calibration board and gather data for In-field correction.
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.")
If the board is too far out of the orientation or the capture is of poor quality to provide sufficient data, you will be informed of the potential setup issue:
Board is too tilted in X, Y, or Z plane.
Not all of the feature points are detectable.
The fiducial marker is not visible.
The image of the board is of too poor quality to provide sufficient data.
Continue gathering data by capturing the board at different distances and at different locations in the FOV, as described in Guidelines for Performing Infield Correction. When finished taking the captures for infield correction, use the data to generate correction parameters.
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)
Before applying it, estimate the expected dimension accuracy for the new correction.
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.",
)
The information returned from completing this process includes:
Estimated new maximum dimension trueness error for the majority of the FOV.
The range at which this error is expected dependent on the distances at which the correction images were taken.
If satisfied with the correction output, then choose to apply the correction parameters to the camera.
Finally, apply the In-field correction on the camera.
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
Use the read function to check when the last correction was written to the camera. This will return the date and time of the last correction applied to the camera.
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
Use the reset function to remove the correction that has been applied to the camera. This will reset the camera to only having the Zivid factory calibration. It is not necessary to remove a correction before testing and applying a new one.
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)