algorithms.cpp
Go to the documentation of this file.
1 /*
2 MIT License
3 
4 Copyright (c) 2021 Analog Devices, Inc.
5 
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12 
13 The above copyright notice and this permission notice shall be included in all
14 copies or substantial portions of the Software.
15 
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 SOFTWARE.
23 */
24 #include "algorithms.h"
25 #include "opencv_undistort.h"
26 
27 #include <cstring>
28 #include <math.h>
29 
31  const float **pp_x_table, const float **pp_y_table,
32  const float **pp_z_table, CameraIntrinsics *p_intr_data,
33  uint32_t n_sensor_rows, uint32_t n_sensor_cols, uint32_t n_out_rows,
34  uint32_t n_out_cols, uint32_t n_offset_rows, uint32_t n_offset_cols,
35  uint8_t row_bin_factor, uint8_t col_bin_factor, uint8_t iter) {
36  uint32_t n_cols = n_sensor_cols / col_bin_factor;
37  uint32_t n_rows = n_sensor_rows / row_bin_factor;
38 
39  float *p_xp = (float *)malloc(n_rows * n_cols * sizeof(float));
40  float *p_yp = (float *)malloc(n_rows * n_cols * sizeof(float));
41  float *p_z = (float *)malloc(n_rows * n_cols * sizeof(float));
42 
43  if ((p_xp == NULL) || (p_yp == NULL) || ((p_z == NULL))) {
44  if (p_xp)
45  free(p_xp);
46  if (p_yp)
47  free(p_yp);
48  if (p_z)
49  free(p_z);
50  return -1;
51  }
52 
53  // Adjust values based on optical center and focal length
54  float cx = p_intr_data->cx / row_bin_factor;
55  float cy = p_intr_data->cy / col_bin_factor;
56  // float codx = p_intr_data->codx;
57  //float cody = p_intr_data->cody;
58 
59  float r_min = sqrt((float)(n_rows * n_rows + n_cols * n_cols));
60 
61  // Generate the initial x,y tables using the positional
62  // index and crop the unused pixels from the maximum in
63  // each dimension
64  for (uint32_t i = 0; i < n_cols; i++) {
65  // Each value in a row increments by one
66  p_xp[i] = (float)i;
67  }
68  // Replicate the rows
69  for (uint32_t j = 0; j < n_rows; j++) {
70  memcpy(&p_xp[j * n_cols], p_xp, n_cols * sizeof(float));
71  }
72 
73  for (uint32_t j = 0; j < n_rows; j++) {
74  // Each row is one more than the last
75  float value = (float)j;
76  for (uint32_t i = 0; i < n_cols; i++) {
77  // Every value in a row is the same
78  p_yp[j * n_cols + i] = value;
79  }
80  }
81 
82  UndistortPoints(p_xp, p_yp, p_xp, p_yp, p_intr_data, iter, n_rows, n_cols,
83  row_bin_factor, col_bin_factor);
84 
85  for (uint32_t j = 0; j < n_rows; j++) {
86  for (uint32_t i = 0; i < n_cols; i++) {
87  int idx = j * n_cols + i;
88  float xp = p_xp[idx];
89  float yp = p_yp[idx];
90  p_z[idx] = sqrtf(xp * xp + yp * yp + 1);
91  //Check for invalid values
92  if (isnan(xp) || isnan(yp) || isnan(p_z[idx]) || p_z[idx] == 0) {
93  // Calculate the coordinates relative to the center pixel
94  float ix = (float)i - cx;
95  float iy = (float)j - cy;
96  float r = sqrt(ix * ix + iy * iy);
97  // Find the minimum radius with an invalid number
98  if (r < r_min) {
99  r_min = r;
100  }
101  }
102  }
103  }
104  //Add a 2 pixel buffer
105  r_min -= 2;
106 
107  //Filter for invalid pixels
108  for (uint32_t j = 0; j < n_rows; j++) {
109  for (uint32_t i = 0; i < n_cols; i++) {
110  int idx = j * n_cols + i;
111  float ix = (float)i - cx;
112  float iy = (float)j - cy;
113  float r = sqrt(ix * ix + iy * iy);
114  if (r >= r_min) {
115  // zero if the pixel is outside the valid radius
116  p_xp[idx] = 0;
117  p_yp[idx] = 0;
118  p_z[idx] = 0;
119  }
120  }
121  }
122 
123  // Add a 2 pixel buffer
124  r_min -= 2;
125 
126  float *p_xfull = p_xp;
127  float *p_yfull = p_yp;
128  float *p_zfull = p_z;
129 
130  p_xp = (float *)malloc(n_out_rows * n_out_cols * sizeof(float));
131  p_yp = (float *)malloc(n_out_rows * n_out_cols * sizeof(float));
132  p_z = (float *)malloc(n_out_rows * n_out_cols * sizeof(float));
133 
134  for (uint32_t j = 0; j < n_out_rows; j++) {
135  for (uint32_t i = 0; i < n_out_cols; i++) {
136  int idx = (j + n_offset_rows) * n_cols + i + n_offset_cols;
137  int crop_idx = j * n_out_cols + i;
138  float x = p_xfull[idx];
139  float y = p_yfull[idx];
140  float z = p_zfull[idx];
141  if (z != 0) {
142  p_xp[crop_idx] = x / z;
143  p_yp[crop_idx] = y / z;
144  p_z[crop_idx] = 1 / z;
145  }
146  }
147  }
148 
149  free(p_xfull);
150  free(p_yfull);
151  free(p_zfull);
152 
153  // Set the config pointers to the new buffers
154  *pp_x_table = p_xp;
155  *pp_y_table = p_yp;
156  *pp_z_table = p_z;
157 
158  return 0;
159 }
160 
161 uint32_t Algorithms::ComputeXYZ(const uint16_t *p_depth, XYZTable *p_xyz_data,
162  int16_t *p_xyz_image, uint32_t n_rows,
163  uint32_t n_cols) {
164 
165  for (int pixel_id = 0; pixel_id < n_rows * n_cols; pixel_id++) {
166  p_xyz_image[3 * pixel_id + 0] = (int16_t)(floorf(
167  p_xyz_data->p_x_table[pixel_id] * (float)p_depth[pixel_id] + 0.5f));
168 
169  p_xyz_image[3 * pixel_id + 1] = (int16_t)(floorf(
170  p_xyz_data->p_y_table[pixel_id] * (float)p_depth[pixel_id] + 0.5f));
171 
172  p_xyz_image[3 * pixel_id + 2] = (int16_t)((
173  p_xyz_data->p_z_table[pixel_id] * (float)p_depth[pixel_id] + 0.5f));
174  }
175 
176  return 0;
177 }
CameraIntrinsics::cx
float cx
Definition: tofi_camera_intrinsics.h:19
algorithms.h
NULL
NULL
Definition: test_security_zap.cpp:405
y
GLint y
Definition: glcorearb.h:2768
x
GLint GLenum GLint x
Definition: glcorearb.h:2834
UndistortPoints
void UndistortPoints(float *_srcx, float *_srcy, float *_dstx, float *_dsty, CameraIntrinsics *_cameraMatrix, int maxcount, int rows, int cols, uint8_t row_bin_factor, uint8_t col_bin_factor)
Definition: opencv_undistort.cpp:52
idx
static uint32_t idx(tarjan *t, const upb_refcounted *r)
Definition: ruby/ext/google/protobuf_c/upb.c:5925
i
int i
Definition: gmock-matchers_test.cc:764
z
GLdouble GLdouble GLdouble z
Definition: glcorearb.h:3117
Algorithms::GenerateXYZTables
static uint32_t GenerateXYZTables(const float **pp_x_table, const float **pp_y_table, const float **pp_z_table, CameraIntrinsics *p_intr_data, uint32_t n_sensor_rows, uint32_t n_sensor_cols, uint32_t n_out_rows, uint32_t n_out_cols, uint32_t n_offset_rows, uint32_t n_offset_cols, uint8_t row_bin_factor, uint8_t col_bin_factor, uint8_t iter)
Definition: algorithms.cpp:30
XYZTable::p_y_table
const float * p_y_table
Pointer to the radial correction Y Table.
Definition: tofi_config.h:36
Algorithms::ComputeXYZ
static uint32_t ComputeXYZ(const uint16_t *p_depth, XYZTable *p_xyz_data, int16_t *p_xyz_image, uint32_t n_rows, uint32_t n_cols)
Definition: algorithms.cpp:161
XYZTable
Definition: tofi_config.h:34
CameraIntrinsics
Definition: tofi_camera_intrinsics.h:16
r
GLboolean r
Definition: glcorearb.h:3228
XYZTable::p_x_table
const float * p_x_table
Pointer to the radial correction X Table.
Definition: tofi_config.h:35
value
GLsizei const GLfloat * value
Definition: glcorearb.h:3093
CameraIntrinsics::cy
float cy
Definition: tofi_camera_intrinsics.h:20
isnan
#define isnan(d)
Definition: cJSON.c:77
opencv_undistort.h
XYZTable::p_z_table
const float * p_z_table
Pointer to the radial correction Z Table.
Definition: tofi_config.h:37


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:47