Skip to content

Commit d3d3477

Browse files
author
Thiemo Wiedemeyer
committed
implemented filtering of shadowed regions.
1 parent 15b7f08 commit d3d3477

File tree

2 files changed

+85
-18
lines changed

2 files changed

+85
-18
lines changed

examples/protonect/include/libfreenect2/registration.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ class LIBFREENECT2_API Registration
5757
float depth_to_color_map_x[512 * 424];
5858
float depth_to_color_map_y[512 * 424];
5959
int depth_to_color_map_yi[512 * 424];
60+
61+
const int filter_width_half;
62+
const int filter_height_half;
63+
const float filter_tolerance;
6064
};
6165

6266
} /* namespace libfreenect2 */

examples/protonect/src/registration.cpp

Lines changed: 81 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -100,64 +100,127 @@ void Registration::apply(const Frame *rgb, const Frame *depth, Frame *undistorte
100100
const int *map_dist = distort_map;
101101
const float *map_x = depth_to_color_map_x;
102102
const int *map_yi = depth_to_color_map_yi;
103+
103104
const int size_depth = 512 * 424;
104-
const int size_color = 1920 * 1080 * 3;
105+
const int size_color = 1920 * 1080;
105106
const float color_cx = color.cx + 0.5f; // 0.5f added for later rounding
106107

108+
// size of filter map with a border of filter_height_half on top and bottom so that no check for borders is needed.
109+
// since the color image is wide angle no border to the sides is needed.
110+
const int size_filter_map = size_color + 1920 * filter_height_half * 2;
111+
// offset to the important data
112+
const int offset_filter_map = 1920 * filter_height_half;
113+
114+
// map for storing the min z values used for each color pixel
115+
float *filter_map = new float[size_filter_map];
116+
// pointer to the beginning of the important data
117+
float *p_filter_map = filter_map + offset_filter_map;
118+
119+
// map for storing the color offest for each depth pixel
120+
int *depth_to_c_off = new int[size_depth];
121+
int *map_c_off = depth_to_c_off;
122+
123+
// initializing the depth_map with values outside of the Kinect2 range
124+
for(float *it = filter_map, *end = filter_map + size_filter_map; it != end; ++it){
125+
*it = 65536.0f;
126+
}
127+
107128
// iterating over all pixels from undistorted depth and registered color image
108-
// the three maps have the same structure as the images, so their pointers are increased each iteration as well
109-
for (int i = 0; i < size_depth; ++i, ++registered_data, ++undistorted_data, ++map_dist, ++map_x, ++map_yi) {
129+
// the four maps have the same structure as the images, so their pointers are increased each iteration as well
130+
for(int i = 0; i < size_depth; ++i, ++undistorted_data, ++map_dist, ++map_x, ++map_yi, ++map_c_off){
110131
// getting index of distorted depth pixel
111132
const int index = *map_dist;
112133

113134
// check if distorted depth pixel is outside of the depth image
114135
if(index < 0){
136+
*map_c_off = -1;
115137
*undistorted_data = 0;
116-
*registered_data = 0;
117-
*++registered_data = 0;
118-
*++registered_data = 0;
119138
continue;
120139
}
121140

122141
// getting depth value for current pixel
123-
const float z_raw = depth_data[index];
124-
*undistorted_data = z_raw;
142+
const float z = depth_data[index];
143+
*undistorted_data = z;
125144

126145
// checking for invalid depth value
127-
if (z_raw <= 0.0f) {
128-
*registered_data = 0;
129-
*++registered_data = 0;
130-
*++registered_data = 0;
146+
if(z <= 0.0f){
147+
*map_c_off = -1;
131148
continue;
132149
}
133150

134151
// calculating x offset for rgb image based on depth value
135-
const float rx = (*map_x + (color.shift_m / z_raw)) * color.fx + color_cx;
152+
const float rx = (*map_x + (color.shift_m / z)) * color.fx + color_cx;
136153
const int cx = rx; // same as round for positive numbers (0.5f was already added to color_cx)
137154
// getting y offset for depth image
138155
const int cy = *map_yi;
139156
// combining offsets
140-
const int c_off = cx * 3 + cy;
157+
const int c_off = cx + cy * 1920;
141158

142159
// check if c_off is outside of rgb image
143160
// checking rx/cx is not needed because the color image is much wider then the depth image
144-
if (c_off < 0 || c_off >= size_color) {
161+
if(c_off < 0 || c_off >= size_color){
162+
*map_c_off = -1;
163+
continue;
164+
}
165+
166+
// setting a window around the filter map pixel corresponding to the color pixel with the current z value
167+
int yi = (cy - filter_height_half) * 1920 + cx - filter_width_half; // index of first pixel to set
168+
for(int r = -filter_height_half; r <= filter_height_half; ++r, yi += 1920) // index increased by a full row each iteration
169+
{
170+
float *it = p_filter_map + yi;
171+
for(int c = -filter_width_half; c <= filter_width_half; ++c, ++it)
172+
{
173+
// only set if the current z is smaller
174+
if(z < *it)
175+
*it = z;
176+
}
177+
}
178+
179+
// saving the offset for later
180+
*map_c_off = c_off;
181+
}
182+
183+
// reseting the pointers to the beginning
184+
undistorted_data = (float*)undistorted->data;
185+
map_c_off = depth_to_c_off;
186+
187+
// run through all registered color pixels and set them based on filter results
188+
for(int i = 0; i < size_depth; ++i, ++registered_data, ++map_c_off, ++undistorted_data){
189+
const int c_off = *map_c_off;
190+
191+
// check if offset is out of image
192+
if(c_off < 0){
193+
*registered_data = 0;
194+
*++registered_data = 0;
195+
*++registered_data = 0;
196+
continue;
197+
}
198+
199+
const float min_z = p_filter_map[c_off];
200+
const float z = *undistorted_data;
201+
202+
// check for allowed depth noise
203+
if((z - min_z) / z > filter_tolerance) {
145204
*registered_data = 0;
146205
*++registered_data = 0;
147206
*++registered_data = 0;
148207
continue;
149208
}
150209

151210
// Setting RGB or registered image
152-
const unsigned char *rgb_data = rgb->data + c_off;
211+
const unsigned char *rgb_data = rgb->data + c_off * 3;
153212
*registered_data = *rgb_data;
154213
*++registered_data = *++rgb_data;
155214
*++registered_data = *++rgb_data;
156215
}
216+
217+
// delete the temporary maps
218+
delete[] filter_map;
219+
delete[] depth_to_c_off;
157220
}
158221

159222
Registration::Registration(Freenect2Device::IrCameraParams depth_p, Freenect2Device::ColorCameraParams rgb_p):
160-
depth(depth_p), color(rgb_p)
223+
depth(depth_p), color(rgb_p), filter_width_half(2), filter_height_half(1), filter_tolerance(0.01f)
161224
{
162225
float mx, my;
163226
int ix, iy, index;
@@ -186,7 +249,7 @@ Registration::Registration(Freenect2Device::IrCameraParams depth_p, Freenect2Dev
186249
*map_x++ = rx;
187250
*map_y++ = ry;
188251
// compute the y offset to minimize later computations
189-
*map_yi++ = roundf(ry) * 1920 * 3;
252+
*map_yi++ = roundf(ry);
190253
}
191254
}
192255
}

0 commit comments

Comments
 (0)