|
29 | 29 | #define _USE_MATH_DEFINES |
30 | 30 | #include <math.h> |
31 | 31 | #include <libfreenect2/registration.h> |
| 32 | +#include <limits> |
32 | 33 |
|
33 | 34 | namespace libfreenect2 |
34 | 35 | { |
@@ -249,6 +250,99 @@ void Registration::apply(const Frame *rgb, const Frame *depth, Frame *undistorte |
249 | 250 | delete[] depth_to_c_off; |
250 | 251 | } |
251 | 252 |
|
| 253 | +#ifdef LIBFREENECT2_WITH_CX11_SUPPORT |
| 254 | +/** |
| 255 | + * Computes Euclidean coordinates of pixels and their color from already registered |
| 256 | + * depth and color frames. I.e. constructs a point cloud. |
| 257 | + * @param undistorted Undistorted depth frame from Registration::apply. |
| 258 | + * @param registered Registered color frame from Registration::apply. |
| 259 | + * @param[out] X x coordinates of points. |
| 260 | + * @param[out] Y y coordinates of points. |
| 261 | + * @param[out] Z z coordinates of points. |
| 262 | + * @param[out] RGB associated rgb color of points. |
| 263 | + * @note Available only when C++11 support is enabled. |
| 264 | + */ |
| 265 | +void Registration::computeCoordinatesAndColor (const Frame* undistorted, const Frame* registered, Array& X, Array& Y, Array& Z, Array& RGB) const |
| 266 | +{ |
| 267 | + const float bad_point = std::numeric_limits<float>::quiet_NaN(); |
| 268 | + const float cx(depth.cx), cy(depth.cy); |
| 269 | + const float fx(1/depth.fx), fy(1/depth.fy); |
| 270 | + float* undistorted_data = (float *)undistorted->data; |
| 271 | + float* registered_data = (float *)registered->data; |
| 272 | + size_t idx(0); |
| 273 | + for (size_t r=0; r<undistorted->height; ++r, ++idx) |
| 274 | + { |
| 275 | + for (size_t c=0; c<undistorted->width; ++c, ++idx) |
| 276 | + { |
| 277 | + const float depth_val = undistorted_data[idx]/1000.0f; //scaling factor, so that value of 1 is one meter. |
| 278 | + if (isnan(depth_val) || depth_val <= 0.001) |
| 279 | + { |
| 280 | + //depth value is not valid |
| 281 | + X.at(idx) = Y.at(idx) = Z.at(idx) = bad_point; |
| 282 | + RGB.at(idx) = 0; |
| 283 | + continue; |
| 284 | + } |
| 285 | + const float xu = (c + 0.5 - cx)*fx; |
| 286 | + const float yu = (r + 0.5 - cy)*fy; |
| 287 | + X.at(idx) = xu * depth_val; |
| 288 | + Y.at(idx) = yu * depth_val; |
| 289 | + Z.at(idx) = depth_val; |
| 290 | + RGB.at(idx) = registered_data[idx]; |
| 291 | + } |
| 292 | + } |
| 293 | +} |
| 294 | +#else |
| 295 | +/** |
| 296 | + * Computes Euclidean coordinates of pixels and their color from already registered |
| 297 | + * depth and color frames. I.e. constructs a point cloud. |
| 298 | + * @param undistorted Undistorted depth frame from Registration::apply. |
| 299 | + * @param registered Registered color frame from Registration::apply. |
| 300 | + * @param[out] X x coordinates of points. |
| 301 | + * @param[out] Y y coordinates of points. |
| 302 | + * @param[out] Z z coordinates of points. |
| 303 | + * @param[out] RGB associated rgb color of points. |
| 304 | + */ |
| 305 | +void Registration::computeCoordinatesAndColor (const Frame* undistorted, const Frame* registered, float* X, float* Y, float* Z, float* RGB) const |
| 306 | +{ |
| 307 | + const size_t wid = undistorted->width; |
| 308 | + const size_t hei = undistorted->height; |
| 309 | + if (X == 0) |
| 310 | + X = new float[wid*hei]; |
| 311 | + if (Y == 0) |
| 312 | + Y = new float[wid*hei]; |
| 313 | + if (Z == 0) |
| 314 | + Z = new float[wid*hei]; |
| 315 | + if (RGB == 0) |
| 316 | + RGB = new float[wid*hei]; |
| 317 | + const float bad_point = std::numeric_limits<float>::quiet_NaN(); |
| 318 | + const float cx(depth.cx), cy(depth.cy); |
| 319 | + const float fx(1/depth.fx), fy(1/depth.fy); |
| 320 | + float* undistorted_data = (float *)undistorted->data; |
| 321 | + float* registered_data = (float *)registered->data; |
| 322 | + size_t idx(0); |
| 323 | + for (size_t r=0; r<hei; ++r, ++idx) |
| 324 | + { |
| 325 | + for (size_t c=0; c<wid; ++c, ++idx) |
| 326 | + { |
| 327 | + const float depth_val = undistorted_data[idx]/1000.0f; //scaling factor, so that value of 1 is one meter. |
| 328 | + if (isnan(depth_val) || depth_val <= 0.001) |
| 329 | + { |
| 330 | + //depth value is not valid |
| 331 | + X[idx] = Y[idx] = Z[idx] = bad_point; |
| 332 | + RGB[idx] = 0; |
| 333 | + continue; |
| 334 | + } |
| 335 | + const float xu = (c + 0.5 - cx)*fx; |
| 336 | + const float yu = (r + 0.5 - cy)*fy; |
| 337 | + X[idx] = xu * depth_val; |
| 338 | + Y[idx] = yu * depth_val; |
| 339 | + Z[idx] = depth_val; |
| 340 | + RGB[idx] = registered_data[idx]; |
| 341 | + } |
| 342 | + } |
| 343 | +} |
| 344 | +#endif |
| 345 | + |
252 | 346 | Registration::Registration(Freenect2Device::IrCameraParams depth_p, Freenect2Device::ColorCameraParams rgb_p): |
253 | 347 | depth(depth_p), color(rgb_p), filter_width_half(2), filter_height_half(1), filter_tolerance(0.01f) |
254 | 348 | { |
|
0 commit comments