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.

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();

Then, gather data by capturing the Zivid calibration board.

std::cout << "Capturing calibration board" << std::endl;
const auto detectionResult = Zivid::Experimental::Calibration::detectFeaturePoints(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());
}

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;

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();

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;
}

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:

  1. Board is too tilted in X, Y, or Z plane.

  2. Not all of the feature points are detectable.

  3. The fiducial marker is not visible.

  4. 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);

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;

The information returned from completing this process includes:

  1. Estimated new maximum dimension trueness error for the majority of the FOV.

  2. 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);

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;
}

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);