in opencv-kinfu-samples/main.cpp [199:278]
static void create_undistortion_lut(const k4a_calibration_t* calibration,
const k4a_calibration_type_t camera,
const pinhole_t* pinhole,
k4a_image_t lut,
interpolation_t type)
{
coordinate_t* lut_data = (coordinate_t*)(void*)k4a_image_get_buffer(lut);
k4a_float3_t ray;
ray.xyz.z = 1.f;
int src_width = calibration->depth_camera_calibration.resolution_width;
int src_height = calibration->depth_camera_calibration.resolution_height;
if (camera == K4A_CALIBRATION_TYPE_COLOR)
{
src_width = calibration->color_camera_calibration.resolution_width;
src_height = calibration->color_camera_calibration.resolution_height;
}
for (int y = 0, idx = 0; y < pinhole->height; y++)
{
ray.xyz.y = ((float)y - pinhole->py) / pinhole->fy;
for (int x = 0; x < pinhole->width; x++, idx++)
{
ray.xyz.x = ((float)x - pinhole->px) / pinhole->fx;
k4a_float2_t distorted;
int valid;
k4a_calibration_3d_to_2d(calibration, &ray, camera, camera, &distorted, &valid);
coordinate_t src;
if (type == INTERPOLATION_NEARESTNEIGHBOR)
{
// Remapping via nearest neighbor interpolation
src.x = (int)floorf(distorted.xy.x + 0.5f);
src.y = (int)floorf(distorted.xy.y + 0.5f);
}
else if (type == INTERPOLATION_BILINEAR || type == INTERPOLATION_BILINEAR_DEPTH)
{
// Remapping via bilinear interpolation
src.x = (int)floorf(distorted.xy.x);
src.y = (int)floorf(distorted.xy.y);
}
else
{
printf("Unexpected interpolation type!\n");
exit(-1);
}
if (valid && src.x >= 0 && src.x < src_width && src.y >= 0 && src.y < src_height)
{
lut_data[idx] = src;
if (type == INTERPOLATION_BILINEAR || type == INTERPOLATION_BILINEAR_DEPTH)
{
// Compute the floating point weights, using the distance from projected point src to the
// image coordinate of the upper left neighbor
float w_x = distorted.xy.x - src.x;
float w_y = distorted.xy.y - src.y;
float w0 = (1.f - w_x) * (1.f - w_y);
float w1 = w_x * (1.f - w_y);
float w2 = (1.f - w_x) * w_y;
float w3 = w_x * w_y;
// Fill into lut
lut_data[idx].weight[0] = w0;
lut_data[idx].weight[1] = w1;
lut_data[idx].weight[2] = w2;
lut_data[idx].weight[3] = w3;
}
}
else
{
lut_data[idx].x = INVALID;
lut_data[idx].y = INVALID;
}
}
}
}