ROI Box via Checkerboard

이 튜토리얼에서는 Zivid calibration board 를 사용하여 ROI 상자 파라미터를 찾는 방법과 이를 사용하여 빈의 내용물을 필터링하는 방법을 설명합니다. 여기서는 캘리브레이션 보드가 빈의 오른쪽 하단에 배치되어 있다고 가정합니다. 빈 크기도 이미 알고 있는 것으로 가정하고 ROI 상자의 크기를 설정하는 데 사용합니다. 이렇게 하면 카메라 프레임에서 ROI 파라미터를 자동으로 찾을 수 있습니다.

참고

이 튜토리얼에서는 데모를 위해 아래 이미지의 장면에 파일 카메라를 사용합니다.

ROI box filtering reduces capture time.

카메라 파일은 Sample Data 에서 다운로드할 수 있습니다.

먼저 체커보드의 포인트 클라우드를 캡처합니다.

소스로 이동

소스

const auto fileCamera = std::string(ZIVID_SAMPLE_DATA_DIR) + "/BinWithCalibrationBoard.zfc";

std::cout << "Creating virtual camera using file: " << fileCamera << std::endl;
auto camera = zivid.createFileCamera(fileCamera);

auto settings = Zivid::Settings{ Zivid::Settings::Acquisitions{ Zivid::Settings::Acquisition{} } };

const auto originalFrame = camera.capture(settings);
auto pointCloud = originalFrame.pointCloud();
소스로 이동

source

string fileCamera = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "/Zivid/BinWithCalibrationBoard.zfc";

Console.WriteLine("Creating virtual camera using file: " + fileCamera);
var camera = zivid.CreateFileCamera(fileCamera);

var settings = new Zivid.NET.Settings
{
    Acquisitions = { new Zivid.NET.Settings.Acquisition { } }
};

var originalFrame = camera.Capture(settings);
var pointCloud = originalFrame.PointCloud;
소스로 이동

source

file_camera = get_sample_data_path() / "BinWithCalibrationBoard.zfc"

print(f"Creating virtual camera using file: {file_camera}")
camera = app.create_file_camera(file_camera)

settings = zivid.Settings([zivid.Settings.Acquisition()])

original_frame = camera.capture(settings)
point_cloud = original_frame.point_cloud()

체커보드 프레임은 보드의 왼쪽 상단 모서리에 있는 4개의 체커 사이의 교차점에 원점이 있습니다.

체커보드 프레임에 상대적인 ROI 상자 크기 및 오른쪽 하단 모서리.

체커보드 프레임과 ROI 상자 크기를 기준으로 ROI 상자의 오른쪽 하단 모서리 위치를 정의합니다. 그런 다음 길이와 너비에서 빈 가장자리의 너비를 빼서 빈 벽을 제거합니다.

소스로 이동

소스

// Coordinates are relative to the checkerboard origin which lies in the intersection between the four checkers
// in the top-left corner of the checkerboard: Positive x-axis is "East", y-axis is "South" and z-axis is "Down"
const Zivid::PointXYZ roiBoxLowerRightCornerInCheckerboardFrame{ 240.F, 260.F, 5.F };
const Zivid::PointXYZ roiBoxUpperRightCornerInCheckerboardFrame{ roiBoxLowerRightCornerInCheckerboardFrame.x,
                                                                 roiBoxLowerRightCornerInCheckerboardFrame.y
                                                                     - roiBoxWidth,
                                                                 roiBoxLowerRightCornerInCheckerboardFrame.z };
const Zivid::PointXYZ roiBoxLowerLeftCornerInCheckerboardFrame{ roiBoxLowerRightCornerInCheckerboardFrame.x
                                                                    - roiBoxLength,
                                                                roiBoxLowerRightCornerInCheckerboardFrame.y,
                                                                roiBoxLowerRightCornerInCheckerboardFrame.z };
const float roiBoxLength = 545.F;
const float roiBoxWidth = 345.F;
const float roiBoxHeight = 150.F;
소스로 이동

source

// Coordinates are relative to the checkerboard origin which lies in the intersection between the four checkers
// in the top-left corner of the checkerboard: Positive x-axis is "East", y-axis is "South" and z-axis is "Down"
var roiBoxLowerRightCornerInCheckerboardFrame = new Zivid.NET.PointXYZ
{
    x = 240F,
    y = 260F,
    z = 5F
};
var roiBoxUpperRightCornerInCheckerboardFrame = new Zivid.NET.PointXYZ
{
    x = roiBoxLowerRightCornerInCheckerboardFrame.x,
    y = roiBoxLowerRightCornerInCheckerboardFrame.y - roiBoxWidth,
    z = roiBoxLowerRightCornerInCheckerboardFrame.z
};
var roiBoxLowerLeftCornerInCheckerboardFrame = new Zivid.NET.PointXYZ
{
    x = roiBoxLowerRightCornerInCheckerboardFrame.x - roiBoxLength,
    y = roiBoxLowerRightCornerInCheckerboardFrame.y,
    z = roiBoxLowerRightCornerInCheckerboardFrame.z

};
float roiBoxLength = 545F;
float roiBoxWidth = 345F;
float roiBoxHeight = 150F;
소스로 이동

source

roi_box_lower_right_corner = np.array([240, 260, 0.5])
roi_box_upper_right_corner = np.array(
    [
        roi_box_lower_right_corner[0],
        roi_box_lower_right_corner[1] - roi_box_width,
        roi_box_lower_right_corner[2],
    ]
)
roi_box_lower_left_corner = np.array(
    [
        roi_box_lower_right_corner[0] - roi_box_length,
        roi_box_lower_right_corner[1],
        roi_box_lower_right_corner[2],
    ]
)
roi_box_length = 545
roi_box_width = 345
roi_box_height = 150

그런 다음 ROI 상자의 기본 프레임을 정의하는 세 지점을 설정할 수 있습니다.

소스로 이동

소스

const Zivid::PointXYZ pointOInCheckerboardFrame = roiBoxLowerRightCornerInCheckerboardFrame;
const Zivid::PointXYZ pointAInCheckerboardFrame = roiBoxUpperRightCornerInCheckerboardFrame;
const Zivid::PointXYZ pointBInCheckerboardFrame = roiBoxLowerLeftCornerInCheckerboardFrame;
소스로 이동

source

var pointOInCheckerboardFrame = roiBoxLowerRightCornerInCheckerboardFrame;
var pointAInCheckerboardFrame = roiBoxUpperRightCornerInCheckerboardFrame;
var pointBInCheckerboardFrame = roiBoxLowerLeftCornerInCheckerboardFrame;
소스로 이동

source

point_o_in_checkerboard_frame = roi_box_lower_right_corner
point_a_in_checkerboard_frame = roi_box_upper_right_corner
point_b_in_checkerboard_frame = roi_box_lower_left_corner

그런 다음 체커보드의 포즈를 추정하여 세 지점을 카메라 기준 프레임으로 변환합니다.

소스로 이동

소스

std::cout << "Detecting and estimating pose of the Zivid checkerboard in the camera frame" << std::endl;
const auto detectionResult = Zivid::Calibration::detectCalibrationBoard(originalFrame);
const auto transformCameraToCheckerboard = detectionResult.pose().toMatrix();

std::cout << "Transforming the ROI base frame points to the camera frame" << std::endl;
const auto roiPointsInCameraFrame = transformPoints(
    std::vector<Zivid::PointXYZ>{
        pointOInCheckerboardFrame, pointAInCheckerboardFrame, pointBInCheckerboardFrame },
    transformCameraToCheckerboard);
소스로 이동

source

Console.WriteLine("Detecting and estimating pose of the Zivid checkerboard in the camera frame");
var detectionResult = Detector.DetectCalibrationBoard(originalFrame);
var cameraToCheckerboardTransform = new Zivid.NET.Matrix4x4(detectionResult.Pose().ToMatrix());

Console.WriteLine("Transforming the ROI base frame points to the camera frame");
var roiPointsInCameraFrame = TransformPoints(
    new List<Zivid.NET.PointXYZ> { pointOInCheckerboardFrame, pointAInCheckerboardFrame, pointBInCheckerboardFrame },
    cameraToCheckerboardTransform);
소스로 이동

source

print("Detecting and estimating pose of the Zivid checkerboard in the camera frame")
detection_result = zivid.calibration.detect_feature_points(original_frame)
camera_to_checkerboard_transform = detection_result.pose().to_matrix()

print("Transforming the ROI base frame points to the camera frame")
roi_points_in_camera_frame = _transform_points(
    [point_o_in_checkerboard_frame, point_a_in_checkerboard_frame, point_b_in_checkerboard_frame],
    camera_to_checkerboard_transform,
)

힌트

작동 방식이 궁금하다면 Position, Orientation and Coordinate Transformations 에 대해 자세히 알아보세요.

이제 ROI 상자의 크기와 위치를 기반으로 포인트 클라우드를 필터링할 수 있습니다. 첫 번째 범위는 바닥을 포함하도록 작은 음수 값으로 설정되고 두 번째 범위는 상자의 원하는 높이로 설정됩니다.

소스로 이동

소스

settings.set(Zivid::Settings::RegionOfInterest{
    Zivid::Settings::RegionOfInterest::Box::Enabled::yes,
    Zivid::Settings::RegionOfInterest::Box::PointO{ roiPointsInCameraFrame[0] },
    Zivid::Settings::RegionOfInterest::Box::PointA{ roiPointsInCameraFrame[1] },
    Zivid::Settings::RegionOfInterest::Box::PointB{ roiPointsInCameraFrame[2] },
    Zivid::Settings::RegionOfInterest::Box::Extents{ -10, roiBoxHeight } });
소스로 이동

source

settings.RegionOfInterest.Box.Enabled = true;
settings.RegionOfInterest.Box.PointO = roiPointsInCameraFrame[0];
settings.RegionOfInterest.Box.PointA = roiPointsInCameraFrame[1];
settings.RegionOfInterest.Box.PointB = roiPointsInCameraFrame[2];
settings.RegionOfInterest.Box.Extents = new Zivid.NET.Range<double>(-10, roiBoxHeight);
소스로 이동

source

settings.region_of_interest.box.enabled = True
settings.region_of_interest.box.point_o = roi_points_in_camera_frame[0]
settings.region_of_interest.box.point_a = roi_points_in_camera_frame[1]
settings.region_of_interest.box.point_b = roi_points_in_camera_frame[2]
settings.region_of_interest.box.extents = (-10, roi_box_height)

마지막으로 새로운 캡처를 수행하고 필터링된 포인트 클라우드를 시각화합니다.

소스로 이동

소스

const auto roiFrame = camera.capture(settings);

std::cout << "Displaying the ROI-filtered point cloud" << std::endl;
visualizeZividPointCloud(roiFrame);
소스로 이동

source

var roiFrame = camera.Capture(settings);

Console.WriteLine("Displaying the ROI-filtered point cloud");
VisualizeZividPointCloud(roiFrame);
소스로 이동

source

roi_point_cloud = camera.capture(settings).point_cloud()

print("Displaying the ROI-filtered point cloud")
display_pointcloud(roi_point_cloud.copy_data("xyz"), roi_point_cloud.copy_data("rgba")[:, :, :3])

체커 보드를 사용하여 빈의 ROI 필터링 및 변환된 포인트 클라우드

ROI 상자를 기반으로 포인트 클라우드를 필터링하려면 다음 코드 샘플을 실행합니다.

Sample: ROIBoxViaCheckerboard.cpp

./ROIBoxViaCheckerboard

Sample: ROIBoxViaCheckerboard.cs

./ROIBoxViaCheckerboard

Sample: roi_box_via_checkerboard.py

python roi_box_via_checkerboard.py

자신의 설정에서 이것을 사용하려면 코드 샘플을 수정하십시오.

  1. 파일 카메라를 실제 카메라 및 설정으로 교체하십시오.

  2. 빈의 오른쪽 하단 모서리에 체커보드를 놓습니다.

  3. ROI 상자 크기를 실제 사용하는 빈의 크기로 수정합니다.

  4. 샘플 실행합니다!

이제 ROI 매개변수로 캡처 설정을 저장하고 칼리브레이션 보드를 제거하고 전체 빈의 설정을 사용할 수 있습니다.