@@ -84,80 +84,149 @@ void Registration::apply( int dx, int dy, float dz, float& cx, float &cy) const
8484 cx = rx * color.fx + color.cx ;
8585}
8686
87- void Registration::apply (const Frame *rgb, const Frame *depth, Frame *undistorted, Frame *registered) const
87+ void Registration::apply (const Frame *rgb, const Frame *depth, Frame *undistorted, Frame *registered, const bool enable_filter ) const
8888{
8989 // Check if all frames are valid and have the correct size
9090 if (!undistorted || !rgb || !registered ||
91- rgb->width != 1920 || rgb->height != 1080 || rgb->bytes_per_pixel != 3 ||
91+ rgb->width != 1920 || rgb->height != 1080 || rgb->bytes_per_pixel != 4 ||
9292 depth->width != 512 || depth->height != 424 || depth->bytes_per_pixel != 4 ||
9393 undistorted->width != 512 || undistorted->height != 424 || undistorted->bytes_per_pixel != 4 ||
94- registered->width != 512 || registered->height != 424 || registered->bytes_per_pixel != 3 )
94+ registered->width != 512 || registered->height != 424 || registered->bytes_per_pixel != 4 )
9595 return ;
9696
9797 const float *depth_data = (float *)depth->data ;
98+ const unsigned int *rgb_data = (unsigned int *)rgb->data ;
9899 float *undistorted_data = (float *)undistorted->data ;
99- unsigned char *registered_data = registered->data ;
100+ unsigned int *registered_data = ( unsigned int *) registered->data ;
100101 const int *map_dist = distort_map;
101102 const float *map_x = depth_to_color_map_x;
102103 const int *map_yi = depth_to_color_map_yi;
104+
103105 const int size_depth = 512 * 424 ;
104- const int size_color = 1920 * 1080 * 3 ;
106+ const int size_color = 1920 * 1080 ;
105107 const float color_cx = color.cx + 0 .5f ; // 0.5f added for later rounding
106108
109+ // size of filter map with a border of filter_height_half on top and bottom so that no check for borders is needed.
110+ // since the color image is wide angle no border to the sides is needed.
111+ const int size_filter_map = size_color + 1920 * filter_height_half * 2 ;
112+ // offset to the important data
113+ const int offset_filter_map = 1920 * filter_height_half;
114+
115+ // map for storing the min z values used for each color pixel
116+ float *filter_map = NULL ;
117+ // pointer to the beginning of the important data
118+ float *p_filter_map = NULL ;
119+
120+ // map for storing the color offest for each depth pixel
121+ int *depth_to_c_off = new int [size_depth];
122+ int *map_c_off = depth_to_c_off;
123+
124+ // initializing the depth_map with values outside of the Kinect2 range
125+ if (enable_filter){
126+ filter_map = new float [size_filter_map];
127+ p_filter_map = filter_map + offset_filter_map;
128+
129+ for (float *it = filter_map, *end = filter_map + size_filter_map; it != end; ++it){
130+ *it = 65536 .0f ;
131+ }
132+ }
133+
107134 // 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) {
135+ // the four maps have the same structure as the images, so their pointers are increased each iteration as well
136+ for (int i = 0 ; i < size_depth; ++i, ++undistorted_data, ++map_dist, ++map_x, ++map_yi, ++map_c_off) {
110137 // getting index of distorted depth pixel
111138 const int index = *map_dist;
112139
113140 // check if distorted depth pixel is outside of the depth image
114141 if (index < 0 ){
142+ *map_c_off = -1 ;
115143 *undistorted_data = 0 ;
116- *registered_data = 0 ;
117- *++registered_data = 0 ;
118- *++registered_data = 0 ;
119144 continue ;
120145 }
121146
122147 // getting depth value for current pixel
123- const float z_raw = depth_data[index];
124- *undistorted_data = z_raw ;
148+ const float z = depth_data[index];
149+ *undistorted_data = z ;
125150
126151 // checking for invalid depth value
127- if (z_raw <= 0 .0f ) {
128- *registered_data = 0 ;
129- *++registered_data = 0 ;
130- *++registered_data = 0 ;
152+ if (z <= 0 .0f ){
153+ *map_c_off = -1 ;
131154 continue ;
132155 }
133156
134157 // 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;
158+ const float rx = (*map_x + (color.shift_m / z )) * color.fx + color_cx;
136159 const int cx = rx; // same as round for positive numbers (0.5f was already added to color_cx)
137160 // getting y offset for depth image
138161 const int cy = *map_yi;
139162 // combining offsets
140- const int c_off = cx * 3 + cy;
163+ const int c_off = cx + cy * 1920 ;
141164
142165 // check if c_off is outside of rgb image
143166 // 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) {
145- *registered_data = 0 ;
146- *++registered_data = 0 ;
147- *++registered_data = 0 ;
167+ if (c_off < 0 || c_off >= size_color){
168+ *map_c_off = -1 ;
148169 continue ;
149170 }
150171
151- // Setting RGB or registered image
152- const unsigned char *rgb_data = rgb->data + c_off;
153- *registered_data = *rgb_data;
154- *++registered_data = *++rgb_data;
155- *++registered_data = *++rgb_data;
172+ // saving the offset for later
173+ *map_c_off = c_off;
174+
175+ if (enable_filter){
176+ // setting a window around the filter map pixel corresponding to the color pixel with the current z value
177+ int yi = (cy - filter_height_half) * 1920 + cx - filter_width_half; // index of first pixel to set
178+ for (int r = -filter_height_half; r <= filter_height_half; ++r, yi += 1920 ) // index increased by a full row each iteration
179+ {
180+ float *it = p_filter_map + yi;
181+ for (int c = -filter_width_half; c <= filter_width_half; ++c, ++it)
182+ {
183+ // only set if the current z is smaller
184+ if (z < *it)
185+ *it = z;
186+ }
187+ }
188+ }
189+ }
190+
191+ // reseting the pointers to the beginning
192+ map_c_off = depth_to_c_off;
193+ undistorted_data = (float *)undistorted->data ;
194+
195+ if (enable_filter){
196+ // run through all registered color pixels and set them based on filter results
197+ for (int i = 0 ; i < size_depth; ++i, ++map_c_off, ++undistorted_data, ++registered_data){
198+ const int c_off = *map_c_off;
199+
200+ // check if offset is out of image
201+ if (c_off < 0 ){
202+ *registered_data = 0 ;
203+ continue ;
204+ }
205+
206+ const float min_z = p_filter_map[c_off];
207+ const float z = *undistorted_data;
208+
209+ // check for allowed depth noise
210+ *registered_data = (z - min_z) / z > filter_tolerance ? 0 : *(rgb_data + c_off);
211+ }
212+
213+ delete[] filter_map;
214+ }
215+ else
216+ {
217+ // run through all registered color pixels and set them based on c_off
218+ for (int i = 0 ; i < size_depth; ++i, ++map_c_off, ++registered_data){
219+ const int c_off = *map_c_off;
220+
221+ // check if offset is out of image
222+ *registered_data = c_off < 0 ? 0 : *(rgb_data + c_off);
223+ }
156224 }
225+ delete[] depth_to_c_off;
157226}
158227
159228Registration::Registration (Freenect2Device::IrCameraParams depth_p, Freenect2Device::ColorCameraParams rgb_p):
160- depth (depth_p), color(rgb_p)
229+ depth (depth_p), color(rgb_p), filter_width_half( 2 ), filter_height_half( 1 ), filter_tolerance( 0 . 01f )
161230{
162231 float mx, my;
163232 int ix, iy, index;
@@ -186,7 +255,7 @@ Registration::Registration(Freenect2Device::IrCameraParams depth_p, Freenect2Dev
186255 *map_x++ = rx;
187256 *map_y++ = ry;
188257 // compute the y offset to minimize later computations
189- *map_yi++ = roundf (ry) * 1920 * 3 ;
258+ *map_yi++ = roundf (ry);
190259 }
191260 }
192261}
0 commit comments