Skip to content

Commit 87ba084

Browse files
Thiemo Wiedemeyerfloe
authored andcommitted
Apply will also undistort the depth image.
Improved speed, there was still a double conversion in one if statement.
1 parent 10c012c commit 87ba084

File tree

3 files changed

+69
-51
lines changed

3 files changed

+69
-51
lines changed

examples/protonect/Protonect.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ int main(int argc, char *argv[])
124124

125125
libfreenect2::SyncMultiFrameListener listener(libfreenect2::Frame::Color | libfreenect2::Frame::Ir | libfreenect2::Frame::Depth);
126126
libfreenect2::FrameMap frames;
127-
libfreenect2::Frame registered(512, 424, 3);
127+
libfreenect2::Frame undistorted(512, 424, 4), registered(512, 424, 3);
128128

129129
dev->setColorFrameListener(&listener);
130130
dev->setIrAndDepthFrameListener(&listener);
@@ -146,7 +146,9 @@ int main(int argc, char *argv[])
146146
cv::imshow("ir", cv::Mat(ir->height, ir->width, CV_32FC1, ir->data) / 20000.0f);
147147
cv::imshow("depth", cv::Mat(depth->height, depth->width, CV_32FC1, depth->data) / 4500.0f);
148148

149-
registration->apply(rgb,depth,&registered);
149+
registration->apply(rgb,depth,&undistorted,&registered);
150+
151+
cv::imshow("undistorted", cv::Mat(undistorted.height, undistorted.width, CV_32FC1, undistorted.data) / 4500.0f);
150152
cv::imshow("registered", cv::Mat(registered.height, registered.width, CV_8UC3, registered.data));
151153

152154
int key = cv::waitKey(1);

examples/protonect/include/libfreenect2/registration.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,19 +44,19 @@ class LIBFREENECT2_API Registration
4444
void apply(int dx, int dy, float dz, float& cx, float &cy) const;
4545

4646
// undistort/register a whole image
47-
void apply(const Frame* rgb, const Frame* depth, Frame* registered) const;
47+
void apply(const Frame* rgb, const Frame* depth, Frame* undistorted, Frame* registered) const;
4848

4949
private:
50-
void undistort_depth(int dx, int dy, float& mx, float& my);
51-
void depth_to_color(float mx, float my, float& rx, float& ry);
50+
void distort(int mx, int my, float& dx, float& dy) const;
51+
void depth_to_color(float mx, float my, float& rx, float& ry) const;
5252

5353
Freenect2Device::IrCameraParams depth;
5454
Freenect2Device::ColorCameraParams color;
5555

56-
float undistort_map[512 * 424 * 2];
56+
int distort_map[512 * 424];
5757
float depth_to_color_map_x[512 * 424];
5858
float depth_to_color_map_y[512 * 424];
59-
int depth_to_color_map_i[512 * 424];
59+
int depth_to_color_map_yi[512 * 424];
6060
};
6161

6262
} /* namespace libfreenect2 */

examples/protonect/src/registration.cpp

Lines changed: 60 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -39,26 +39,23 @@ namespace libfreenect2
3939
static const float depth_q = 0.01;
4040
static const float color_q = 0.002199;
4141

42-
void Registration::undistort_depth(int x, int y, float& mx, float& my)
42+
void Registration::distort(int mx, int my, float& x, float& y) const
4343
{
44-
float dx = ((float)x - depth.cx) / depth.fx;
45-
float dy = ((float)y - depth.cy) / depth.fy;
46-
47-
float ps = (dx * dx) + (dy * dy);
48-
float qs = ((ps * depth.k3 + depth.k2) * ps + depth.k1) * ps + 1.0;
49-
for (int i = 0; i < 9; i++) {
50-
float qd = ps / (qs * qs);
51-
qs = ((qd * depth.k3 + depth.k2) * qd + depth.k1) * qd + 1.0;
52-
}
53-
54-
mx = dx / qs;
55-
my = dy / qs;
44+
float dx = ((float)mx - depth.cx) / depth.fx;
45+
float dy = ((float)my - depth.cy) / depth.fy;
46+
float dx2 = dx * dx;
47+
float dy2 = dy * dy;
48+
float r2 = dx2 + dy2;
49+
float dxdy2 = 2 * dx * dy;
50+
float kr = 1 + ((depth.k3 * r2 + depth.k2) * r2 + depth.k1) * r2;
51+
x = depth.fx * (dx * kr + depth.p2 * (r2 + 2 * dx2) + depth.p1 * dxdy2) + depth.cx;
52+
y = depth.fy * (dy * kr + depth.p1 * (r2 + 2 * dy2) + depth.p2 * dxdy2) + depth.cy;
5653
}
5754

58-
void Registration::depth_to_color(float mx, float my, float& rx, float& ry)
55+
void Registration::depth_to_color(float mx, float my, float& rx, float& ry) const
5956
{
60-
mx *= depth.fx * depth_q;
61-
my *= depth.fy * depth_q;
57+
mx = (mx - depth.cx) * depth_q;
58+
my = (my - depth.cy) * depth_q;
6259

6360
float wx =
6461
(mx * mx * mx * color.mx_x3y0) + (my * my * my * color.mx_x0y3) +
@@ -86,71 +83,90 @@ void Registration::apply( int dx, int dy, float dz, float& cx, float &cy) const
8683
cx = rx * color.fx + color.cx;
8784
}
8885

89-
void Registration::apply(const Frame* rgb, const Frame* depth, Frame* registered) const
86+
void Registration::apply(const Frame *rgb, const Frame *depth, Frame *undistorted, Frame *registered) const
9087
{
91-
if (!depth || !rgb || !registered ||
92-
depth->width != 512 || depth->height != 424 || depth->bytes_per_pixel != 4 ||
88+
if (!undistorted || !rgb || !registered ||
9389
rgb->width != 1920 || rgb->height != 1080 || rgb->bytes_per_pixel != 3 ||
90+
depth->width != 512 || depth->height != 424 || depth->bytes_per_pixel != 4 ||
91+
undistorted->width != 512 || undistorted->height != 424 || undistorted->bytes_per_pixel != 4 ||
9492
registered->width != 512 || registered->height != 424 || registered->bytes_per_pixel != 3)
9593
return;
9694

97-
const float *depth_raw = (float*)depth->data;
95+
const float *depth_data = (float*)depth->data;
96+
float *undistorted_data = (float*)undistorted->data;
97+
unsigned char *registered_data = registered->data;
98+
const int *map_dist = distort_map;
9899
const float *map_x = depth_to_color_map_x;
99-
const int *map_i = depth_to_color_map_i;
100-
unsigned char *registered_raw = registered->data;
100+
const int *map_yi = depth_to_color_map_yi;
101101
const int size_depth = 512 * 424;
102102
const int size_color = 1920 * 1080 * 3;
103103

104-
for (int i = 0; i < size_depth; ++i, ++registered_raw, ++map_x, ++map_i, ++depth_raw) {
105-
const float z_raw = *depth_raw;
104+
for (int i = 0; i < size_depth; ++i, ++registered_data, ++undistorted_data, ++map_dist, ++map_x, ++map_yi) {
105+
const int index = *map_dist;
106+
107+
if(index < 0){
108+
*undistorted_data = 0;
109+
*registered_data = 0;
110+
*++registered_data = 0;
111+
*++registered_data = 0;
112+
continue;
113+
}
114+
115+
const float z_raw = depth_data[index];
116+
*undistorted_data = z_raw;
106117

107-
if (z_raw == 0.0) {
108-
*registered_raw = 0;
109-
*++registered_raw = 0;
110-
*++registered_raw = 0;
118+
if (z_raw <= 0.0f) {
119+
*registered_data = 0;
120+
*++registered_data = 0;
121+
*++registered_data = 0;
111122
continue;
112123
}
113124

114125
const float rx = (*map_x + (color.shift_m / z_raw)) * color.fx + color.cx;
115126
const int cx = rx + 0.5f; // same as round for positive numbers
116-
const int cy = *map_i;
127+
const int cy = *map_yi;
117128
const int c_off = cx * 3 + cy;
118129

119130
if (c_off < 0 || c_off > size_color || rx < -0.5f) {
120-
*registered_raw = 0;
121-
*++registered_raw = 0;
122-
*++registered_raw = 0;
131+
*registered_data = 0;
132+
*++registered_data = 0;
133+
*++registered_data = 0;
123134
continue;
124135
}
125136

126137
const unsigned char *rgb_data = rgb->data + c_off;
127-
*registered_raw = *rgb_data;
128-
*++registered_raw = *++rgb_data;
129-
*++registered_raw = *++rgb_data;
138+
*registered_data = *rgb_data;
139+
*++registered_data = *++rgb_data;
140+
*++registered_data = *++rgb_data;
130141
}
131142
}
132143

133144
Registration::Registration(Freenect2Device::IrCameraParams depth_p, Freenect2Device::ColorCameraParams rgb_p):
134145
depth(depth_p), color(rgb_p)
135146
{
136147
float mx, my;
148+
int ix, iy, index;
137149
float rx, ry;
138-
float *it_undist = undistort_map;
150+
int *map_dist = distort_map;
139151
float *map_x = depth_to_color_map_x;
140152
float *map_y = depth_to_color_map_y;
141-
int *map_i = depth_to_color_map_i;
153+
int *map_yi = depth_to_color_map_yi;
142154

143155
for (int y = 0; y < 424; y++) {
144156
for (int x = 0; x < 512; x++) {
145-
146-
undistort_depth(x,y,mx,my);
147-
*it_undist++ = mx;
148-
*it_undist++ = my;
149-
150-
depth_to_color(mx,my,rx,ry);
157+
distort(x,y,mx,my);
158+
ix = roundf(mx);
159+
iy = roundf(my);
160+
if(ix < 0 || ix >= 512 || iy < 0 || iy >= 424)
161+
index = -1;
162+
else
163+
index = iy * 512 + ix;
164+
*map_dist++ = index;
165+
166+
depth_to_color(x,y,rx,ry);
151167
*map_x++ = rx;
152168
*map_y++ = ry;
153-
*map_i++ = round(ry) * 1920 * 3;
169+
*map_yi++ = roundf(ry) * 1920 * 3;
154170
}
155171
}
156172
}

0 commit comments

Comments
 (0)