Overview #
An interactive measurement tool that computes the real-world 3D distance between two user-selected points based on depth camera data.
Expected Output #

Prerequisite #
Tutorial #
C++
error: 'clamp' is not a member of 'std'- This sample uses std::clamp, which was introduced in C++17.
- If the project is compiled with C++14 or earlier, the compiler will report an error
C++
static inline Point mapColorToDepth(const Point& pColor)
{
if (g_regAligned && g_colorSize == g_depthSize)
return pColor;
int dx = cvRound((double)pColor.x * g_depthSize.width / g_colorSize.width);
int dy = cvRound((double)pColor.y * g_depthSize.height / g_colorSize.height);
dx = std::clamp(dx, 0, g_depthSize.width - 1);
dy = std::clamp(dy, 0, g_depthSize.height - 1);
return Point(dx, dy);
}- Translates a pixel from color image space to depth image space.
- Uses perfect mapping when Depth→Color registration is enabled; otherwise uses a simple proportional mapping as a best-effort approximation.
C++
bool depthPixelToWorldM(int dx, int dy, uint16_t depth_mm,
float& X, float& Y, float& Z)
{
if (!g_depthStream) return false;
if (depth_mm == 0) return false; // Invalid depth
CoordinateConverter::convertDepthToWorld(*g_depthStream,
static_cast<float>(dx), static_cast<float>(dy), static_cast<float>(depth_mm),
&X, &Y, &Z);
// Convert from mm to m
X *= 0.001f; Y *= 0.001f; Z *= 0.001f;
return true;
}- Converts a depth pixel (x,y) with depth (mm) into 3D coordinates (meters).
- Uses OpenNI’s intrinsic model; assumes return units are mm, then scales to meters.
C++
static void onMouse(int event, int x, int y, int, void*)
{
if (event == EVENT_LBUTTONDOWN)
{
if (g_lastDepth16.empty()) return;
if (g_p1.x < 0) {
g_p1 = Point(x, y);
g_p2 = Point(-1, -1);
g_lastDistM = -1.0;
}
else if (g_p2.x < 0) {
g_p2 = Point(x, y);
// Both points selected, compute distance
Point d1 = mapColorToDepth(g_p1);
Point d2 = mapColorToDepth(g_p2);
uint16_t z1 = g_lastDepth16.at<uint16_t>(d1.y, d1.x);
uint16_t z2 = g_lastDepth16.at<uint16_t>(d2.y, d2.x);
float X1, Y1, Z1, X2, Y2, Z2;
bool ok1 = depthPixelToWorldM(d1.x, d1.y, z1, X1, Y1, Z1);
bool ok2 = depthPixelToWorldM(d2.x, d2.y, z2, X2, Y2, Z2);
if (ok1 && ok2) {
g_lastDistM = std::sqrt((X1 - X2) * (X1 - X2) +
(Y1 - Y2) * (Y1 - Y2) +
(Z1 - Z2) * (Z1 - Z2));
cout << "Distance between points: " << g_lastDistM << " m" << endl;
}
else {
g_lastDistM = -1.0;
cout << "Invalid depth, unable to measure distance!" << endl;
}
}
else {
// Already had two points, start over when clicked again
g_p1 = Point(x, y);
g_p2 = Point(-1, -1);
g_lastDistM = -1.0;
}
}
else if (event == EVENT_RBUTTONDOWN)
{
// Right click: reset
g_p1 = g_p2 = Point(-1, -1);
g_lastDistM = -1.0;
}
}- Handles user interaction: two left-clicks to measure 3D distance between points; right-click to reset.
