depth_registration_cpu.cpp
Go to the documentation of this file.
1 
18 #include "depth_registration_cpu.h"
19 
22 {
23 }
24 
26 {
27 }
28 
29 bool DepthRegistrationCPU::init(const int deviceId)
30 {
31  createLookup();
32 
33  proj(0, 0) = rotation.at<double>(0, 0);
34  proj(0, 1) = rotation.at<double>(0, 1);
35  proj(0, 2) = rotation.at<double>(0, 2);
36  proj(0, 3) = translation.at<double>(0, 0);
37  proj(1, 0) = rotation.at<double>(1, 0);
38  proj(1, 1) = rotation.at<double>(1, 1);
39  proj(1, 2) = rotation.at<double>(1, 2);
40  proj(1, 3) = translation.at<double>(1, 0);
41  proj(2, 0) = rotation.at<double>(2, 0);
42  proj(2, 1) = rotation.at<double>(2, 1);
43  proj(2, 2) = rotation.at<double>(2, 2);
44  proj(2, 3) = translation.at<double>(2, 0);
45  proj(3, 0) = 0;
46  proj(3, 1) = 0;
47  proj(3, 2) = 0;
48  proj(3, 3) = 1;
49 
50  fx = cameraMatrixRegistered.at<double>(0, 0);
51  fy = cameraMatrixRegistered.at<double>(1, 1);
52  cx = cameraMatrixRegistered.at<double>(0, 2) + 0.5;
53  cy = cameraMatrixRegistered.at<double>(1, 2) + 0.5;
54 
55  return true;
56 }
57 
58 inline uint16_t DepthRegistrationCPU::interpolate(const cv::Mat &in, const float &x, const float &y) const
59 {
60  const int xL = (int)floor(x);
61  const int xH = (int)ceil(x);
62  const int yL = (int)floor(y);
63  const int yH = (int)ceil(y);
64 
65  if(xL < 0 || yL < 0 || xH >= in.cols || yH >= in.rows)
66  {
67  return 0;
68  }
69 
70  const uint16_t pLT = in.at<uint16_t>(yL, xL);
71  const uint16_t pRT = in.at<uint16_t>(yL, xH);
72  const uint16_t pLB = in.at<uint16_t>(yH, xL);
73  const uint16_t pRB = in.at<uint16_t>(yH, xH);
74  int vLT = pLT > 0;
75  int vRT = pRT > 0;
76  int vLB = pLB > 0;
77  int vRB = pRB > 0;
78  int count = vLT + vRT + vLB + vRB;
79 
80  if(count < 3)
81  {
82  return 0;
83  }
84 
85  const uint16_t avg = (pLT + pRT + pLB + pRB) / count;
86  const uint16_t thres = 0.01 * avg;
87  vLT = abs(pLT - avg) < thres;
88  vRT = abs(pRT - avg) < thres;
89  vLB = abs(pLB - avg) < thres;
90  vRB = abs(pRB - avg) < thres;
91  count = vLT + vRT + vLB + vRB;
92 
93  if(count < 3)
94  {
95  return 0;
96  }
97 
98  double distXL = x - xL;
99  double distXH = 1.0 - distXL;
100  double distYL = y - yL;
101  double distYH = 1.0 - distYL;
102  distXL *= distXL;
103  distXH *= distXH;
104  distYL *= distYL;
105  distYH *= distYH;
106  const double tmp = sqrt(2.0);
107  const double fLT = vLT ? tmp - sqrt(distXL + distYL) : 0;
108  const double fRT = vRT ? tmp - sqrt(distXH + distYL) : 0;
109  const double fLB = vLB ? tmp - sqrt(distXL + distYH) : 0;
110  const double fRB = vRB ? tmp - sqrt(distXH + distYH) : 0;
111  const double sum = fLT + fRT + fLB + fRB;
112 
113  return ((pLT * fLT + pRT * fRT + pLB * fLB + pRB * fRB) / sum) + 0.5;
114 }
115 
116 void DepthRegistrationCPU::remapDepth(const cv::Mat &depth, cv::Mat &scaled) const
117 {
118  scaled.create(sizeRegistered, CV_16U);
119  #pragma omp parallel for
120  for(size_t r = 0; r < (size_t)sizeRegistered.height; ++r)
121  {
122  uint16_t *itO = scaled.ptr<uint16_t>(r);
123  const float *itX = mapX.ptr<float>(r);
124  const float *itY = mapY.ptr<float>(r);
125  for(size_t c = 0; c < (size_t)sizeRegistered.width; ++c, ++itO, ++itX, ++itY)
126  {
127  *itO = interpolate(depth, *itX, *itY);
128  }
129  }
130 }
131 
132 void DepthRegistrationCPU::projectDepth(const cv::Mat &scaled, cv::Mat &registered) const
133 {
134  registered = cv::Mat::zeros(sizeRegistered, CV_16U);
135 
136  #pragma omp parallel for
137  for(size_t r = 0; r < (size_t)sizeRegistered.height; ++r)
138  {
139  const uint16_t *itD = scaled.ptr<uint16_t>(r);
140  const double y = lookupY.at<double>(0, r);
141  const double *itX = lookupX.ptr<double>();
142 
143  for(size_t c = 0; c < (size_t)sizeRegistered.width; ++c, ++itD, ++itX)
144  {
145  const double depthValue = *itD / 1000.0;
146 
147  if(depthValue < zNear || depthValue > zFar)
148  {
149  continue;
150  }
151 
152  Eigen::Vector4d pointD(*itX * depthValue, y * depthValue, depthValue, 1);
153  Eigen::Vector4d pointP = proj * pointD;
154 
155  const double z = pointP[2];
156 
157  const double invZ = 1 / z;
158  const int xP = (fx * pointP[0]) * invZ + cx;
159  const int yP = (fy * pointP[1]) * invZ + cy;
160 
161  if(xP >= 0 && xP < sizeRegistered.width && yP >= 0 && yP < sizeRegistered.height)
162  {
163  const uint16_t z16 = z * 1000;
164  uint16_t &zReg = registered.at<uint16_t>(yP, xP);
165  if(zReg == 0 || z16 < zReg)
166  {
167  zReg = z16;
168  }
169  }
170  }
171  }
172 }
173 
174 bool DepthRegistrationCPU::registerDepth(const cv::Mat &depth, cv::Mat &registered)
175 {
176  cv::Mat scaled;
177  remapDepth(depth, scaled);
178  projectDepth(scaled, registered);
179  return true;
180 }
181 
183 {
184  const double fx = 1.0 / cameraMatrixRegistered.at<double>(0, 0);
185  const double fy = 1.0 / cameraMatrixRegistered.at<double>(1, 1);
186  const double cx = cameraMatrixRegistered.at<double>(0, 2);
187  const double cy = cameraMatrixRegistered.at<double>(1, 2);
188  double *it;
189 
190  lookupY = cv::Mat(1, sizeRegistered.height, CV_64F);
191  it = lookupY.ptr<double>();
192  for(size_t r = 0; r < (size_t)sizeRegistered.height; ++r, ++it)
193  {
194  *it = (r - cy) * fy;
195  }
196 
197  lookupX = cv::Mat(1, sizeRegistered.width, CV_64F);
198  it = lookupX.ptr<double>();
199  for(size_t c = 0; c < (size_t)sizeRegistered.width; ++c, ++it)
200  {
201  *it = (c - cx) * fx;
202  }
203 }
bool init(const int deviceId)
void projectDepth(const cv::Mat &scaled, cv::Mat &registered) const
bool registerDepth(const cv::Mat &depth, cv::Mat &registered)
void remapDepth(const cv::Mat &depth, cv::Mat &scaled) const
uint16_t interpolate(const cv::Mat &in, const float &x, const float &y) const


kinect2_registration
Author(s):
autogenerated on Wed Jan 3 2018 03:48:04