Processing Measurement Results#
정보
이 항목의 모든 정보는 모든 blaze 및 Smart blaze 카메라 모델에 적용됩니다. 간결함을 위해 모든 모델을 지칭할 때 "blaze"를 사용합니다.
개요#
Basler blaze 카메라는 각 센서 픽셀에 대해 빛이 이동한 거리를 측정합니다.
이 거리를 사용하여 카메라는 각 센서 픽셀에 대한 오른손잡이 좌표계의 x, y, z 좌표를 계산합니다. 좌표계의 원점은 카메라 하우징 내부에 위치한 카메라의 광학 중심에 있습니다. y축은 아래쪽을 향하고 z축은 카메라에서 멀어지는 방향을 향합니다.
카메라는 선택한 Pixel Format에 따라 뎁스 맵 또는 포인트 클라우드 형식으로 3D 정보를 제공합니다. 뎁스 맵에서 z 좌표는 16비트 회색조 값으로 인코딩됩니다. 아래 그림과 같이 모든 3D 좌표 값은 회색조 값에서 계산할 수 있습니다. 포인트 클라우드는 각 센서 픽셀의 x, y, z 3D 좌표를 부동 소수점 숫자로 포함합니다. 단위는 mm입니다.
센서 픽셀에 대한 유효한 깊이 정보가 없는 경우(예: 이상치 제거 또는 광량이 부족하여, 즉 빛이 통과하기에 충분히 강하지 않은 경우 신뢰 구간), 뎁스 맵 또는 포인트 클라우드의 해당 값은 Scan3dInvalidDataValue 매개변수(기본 설정은 0)에 의해 정의된 값으로 설정됩니다.
뎁스 맵 처리#
뎁스 맵은 16비트 회색조 값으로 구성됩니다. 각 센서 픽셀에 대해 카메라는 z 좌표 값을 회색조 값으로 변환하여 뎁스 맵에 저장합니다.
제공되는 카메라 캘리브레이션 데이터와 결합하여 Scan3dCoordinateScale, Scan3dPrincipalPointU, Scan3dPrincipalPointV및 Scan3dFocalLength 매개변수를 통해 뎁스 맵에서 완전한 3D 정보를 검색할 수 있습니다.
정보
The Scan3dCoordinateScale 매개변수 값은 선택한 Pixel Format에 따라 다릅니다. blaze Viewer에서 카메라로 작업할 때 Pixel Format은 항상 Coord3D_ABC32f Pixel Format으로 설정됩니다. 이 설정은 변경할 수 없습니다. blaze Viewer에서 제공하는 뎁스 맵은 포인트 클라우드를 기반으로 생성됩니다. 이 경우 Scan3dCoordinateScale 매개변수 값은 1입니다. pylon Viewer 외부에서 blaze 카메라로 작업하고 Pixel Format을 Coord3D_C16, Scan3dCoordinateScale 매개변수 값이 다릅니다. 서로 다른 Pixel Format에 대한 Scan3dCoordinateScale 매개변수 값은 다음 표에 나열되어 있습니다.
| Pixel Format | Scan3dCoordinateScale[C] 파라미터 값 |
|---|---|
| Coord3D_ABC32f | 1 |
| Coord3D_C16 | 0.152588 |
| Mono16 | 0.152588 |
카메라를 구성하여 뎁스 맵을 전송하는 방법과 뎁스 맵 데이터에 액세스하는 방법은 GrabDepthMap C++ 샘플을 참조하십시오.
2D 뎁스 맵에서 3D 좌표 계산하기#
뎁스 맵의 16비트 그레이 값을 mm 단위의 z 좌표로 변환하려면 다음 공식을 사용합니다.
z [mm] = gray2mm * g
여기서:
g = 뎁스 맵의 그레이 값
gray2mm = 다음의 값: Scan3dCoordinateScale 매개변수
x 및 y 좌표를 계산하려면 다음 공식을 사용합니다.
x [mm] = (u-cx) * z / f
y [mm] = (v-cy) * z / f
여기서:
(u,v) = 뎁스 맵의 열 및 행
f = 다음의 값: Scan3dFocalLength 파라미터, 즉 카메라 렌즈의 초점 거리
(cx,cy) = 다음의 값: Scan3dPrincipalPointU 및 Scan3dPrincipalPointV 파라미터, 즉 주점(principal point)
C++ 샘플 코드#
// Enable depth maps by enabling the Range component and setting the appropriate pixel format.
camera.ComponentSelector.SetValue(ComponentSelector_Range);
camera.ComponentEnable.SetValue(true);
camera.PixelFormat.SetValue(PixelFormat_Coord3D_C16);
// Query the conversion factor required to convert gray values to distances:
// Choose the z axis first...
camera.Scan3dCoordinateSelector.SetValue(Scan3dCoordinateSelector_CoordinateC);
// ... then retrieve the conversion factor.
const auto gray2mm = camera.Scan3dCoordinateScale.GetValue();
// Configure the gray value used for indicating missing depth data.
// Note: Before setting the value, the Scan3dCoordinateSelector parameter must be set to the axis the
// value is to be configured for, in this case the z axis. This means that Scan3dCoordianteSelector must be set
// to "CoordinateC". This has already been done a few lines above.
camera.Scan3dInvalidDataValue.SetValue((double)missingDepth);
// Retrieve calibration data from the camera.
const auto cx = camera.Scan3dPrincipalPointU.GetValue();
const auto cy = camera.Scan3dPrincipalPointV.GetValue();
const auto f = camera.Scan3dFocalLength.GetValue();
// ....
// Access the data.
const auto container = ptrGrabResult->GetDataContainer();
const auto rangeComponent = container.GetDataComponent(0);
const auto width = rangeComponent.GetWidth();
const auto height = rangeComponent.GetHeight();
// Calculate coordinates for pixel (u,v).
const uint16_t g = ((uint16_t*)rangeComponent.GetData())[u + v * width];
const double z = g * gray2mm;
const double x = (u - cx) * z / f;
const double y = (v - cy) * z / f;
저장된 뎁스 맵 다루기#
blaze Legacy SDK, pylon SDK 또는 blaze ROS 드라이버로 획득한 뎁스 맵의 경우 다음 공식을 사용해야 합니다.
측정된 거리 [mm] = Pixel_Value x Scan3dCoordinateScale[C]
blaze Viewer로 저장한 뎁스 맵의 경우 다음 공식을 사용하십시오.
측정된 거리 [mm] = DepthMin_parameter + (Pixel_Value x (DepthMax_Parameter - DepthMin_parameter)) / 65535
포인트 클라우드 처리#
포인트 클라우드는 카메라 좌표계 내의 x, y, z 좌표 삼원조(triple)로 구성되므로, 포인트 클라우드에서 3D 정보를 추출하기 위한 추가 처리가 필요하지 않습니다.
카메라를 구성하여 포인트 클라우드를 전송하는 방법과 데이터에 액세스하는 방법은 FirstSample C++ 샘플을 참조하십시오.
포인트 클라우드 외에 뎁스 맵이 필요한 경우, 포인트 클라우드에서 그레이스케일 및 RGB 뎁스 맵을 계산하는 방법을 보여주는 ConvertPointCloud2DepthMap C++ 샘플을 참조하십시오.
좌표계의 원점을 카메라 하우징 전면으로 이동#
카메라 좌표계의 원점은 카메라 하우징 내부에 있는 카메라 광학 중심에 위치합니다. 하우징 전면에 위치한 좌표계(즉, z축을 따라 이동된 좌표계)의 좌표를 선호하는 경우, 디바이스 고유의 상수 오프셋을 z 좌표에서 빼야 합니다. 필요한 오프셋은 다음 값을 가져와서 카메라에서 검색할 수 있습니다. ZOffsetOriginToCameraFront Parameter:
(x, y, z)가 카메라 좌표계 내 한 점의 좌표인 경우, 카메라 하우징 전면의 z축을 따라 이동한 좌표계에서의 해당 좌표 (x', y', z')는 다음 공식을 사용하여 결정할 수 있습니다.
x' = x
y' = y
z' = z - offset
거리 계산#
한 점의 좌표가 주어지면 (x,y,z) (단위: mm), 카메라 광학 중심에서 해당 점까지의 거리는 다음 공식을 사용하여 계산할 수 있습니다.
d = sqrt( xx + yy + z*z )
거리 d' 카메라 하우징 전면까지의 거리는 다음과 같이 계산할 수 있습니다.
z' = z - offset
d' = sqrt( xx + yy + z'*z')
깊이 정보를 RGB 이미지로 시각화하기#
무지개 색상 매핑을 위해 다음 방식을 사용하면 z 좌표 또는 거리 값에서 RGB 값을 계산할 수 있습니다. 이는 데이터 시각화를 개선하는 데 유용할 수 있습니다.
먼저, 다음의 깊이 값 [minDepth..maxDepth] 값 범위가 10비트 값으로 변환됩니다. 이 10비트 깊이 값은 각각 8비트 해상도를 가진 4개의 색상 범위로 매핑됩니다.
minDepth 및 maxDepth = 다음의 값: DepthMin 및 DepthMax parameter, 즉 카메라의 현재 Depth ROI
| Depth Value | 색상 범위로 매핑됨 |
|---|---|
| 0..255 | 빨강에서 노랑으로 (255,0,0) -> (255,255,0) |
| 256..511 | 노랑에서 초록으로 (255,255,0) -> (0, 255, 0) |
| 512..767 | 초록에서 아쿠아로 (0,255,0) -> (0,255,255) |
| 768..1023 | 아쿠아에서 파랑으로 (0,255,255) -> (0, 0, 255) |
다음 코드 스니펫에서, depth z 값 또는 mm 단위의 거리 값입니다.
const int minDepth = (int)m_camera.DepthMin.GetValue();
const int maxDepth = (int)m_camera.DepthMax.GetValue();
const double scale = 65536.0 / (maxDepth - minDepth);
for each pixel {
// Set depth either to the corresponding z value or
// a distance value calculated from the z value.
// Clip depth if required.
if (depth < minDepth)
depth = minDepth;
else if (depth > maxDepth)
depth = maxDepth;
// Compute RGB values.
const uint16_t g = (uint16_t)((depth - minDepth) * scale);
const uint16_t val = g >> 6 & 0xff;
const uint16_t sel = g >> 14;
uint32_t res = val << 8 | 0xff;
if (sel & 0x01)
{
res = (~res) >> 8 & 0xffff;
}
if (sel & 0x02)
{
res = res << 8;
}
const uint8_t r = res & 0xff;
res = res >> 8;
const uint8_t g = res & 0xff;
res = res >> 8;
const uint8_t b = res & 0xff;
}