40 #ifndef POINT_CLOUD_COMMON_ORGANIZED_NEIGHBOR2_IMPL_H_
41 #define POINT_CLOUD_COMMON_ORGANIZED_NEIGHBOR2_IMPL_H_
43 #include <pcl/search/organized.h>
44 #include <pcl/common/eigen.h>
45 #include <pcl/common/time.h>
46 #include <Eigen/Eigenvalues>
54 template <
typename Po
intT>
56 std::vector<int>& k_indices,
57 std::vector<float>& k_sqr_distances,
58 unsigned int max_nn)
const {
60 assert(isFinite(query) &&
"Invalid (NaN, Inf) point coordinates given to nearestKSearch!");
63 unsigned left, right, top, bottom;
65 float squared_distance;
66 double squared_radius;
69 k_sqr_distances.clear();
71 squared_radius = radius * radius;
73 this->getProjectedRadiusSearchBox(query,
static_cast<float>(squared_radius), left, right, top, bottom);
76 if (max_nn == 0 || max_nn >=
static_cast<unsigned int>(input_->points.size()))
77 max_nn =
static_cast<unsigned int>(input_->points.size());
79 k_indices.reserve(max_nn);
80 k_sqr_distances.reserve(max_nn);
82 unsigned yEnd = (bottom + 1) * input_->width + right + 1;
83 register unsigned idx = top * input_->width + left;
84 unsigned skip = input_->width - right + left - 1;
85 unsigned xEnd = idx - left + right + 1;
87 for (; xEnd != yEnd; idx += skip, xEnd += input_->width) {
88 for (; idx < xEnd; ++idx) {
89 if (!mask_[idx] || !isFinite(input_->points[idx]))
continue;
91 float dist_x = input_->points[idx].x - query.x;
92 float dist_y = input_->points[idx].y - query.y;
93 float dist_z = input_->points[idx].z - query.z;
94 squared_distance = dist_x * dist_x + dist_y * dist_y + dist_z * dist_z;
96 if (squared_distance <= squared_radius) {
97 k_indices.push_back(idx);
98 k_sqr_distances.push_back(squared_distance);
100 if (k_indices.size() == max_nn) {
101 if (sorted_results_) this->sortResults(k_indices, k_sqr_distances);
107 if (sorted_results_) this->sortResults(k_indices, k_sqr_distances);
108 return (
static_cast<int>(k_indices.size()));
112 template <
typename Po
intT>
114 std::vector<float>& k_sqr_distances)
const {
115 assert(isFinite(query) &&
"Invalid (NaN, Inf) point coordinates given to nearestKSearch!");
118 k_sqr_distances.clear();
122 const Eigen::Vector3f queryvec(query.x, query.y, query.z);
124 const Eigen::Vector2f q = projectPoint(queryvec);
125 int xBegin =
static_cast<int>(q[0] + 0.5f);
126 int yBegin =
static_cast<int>(q[1] + 0.5f);
127 int xEnd = xBegin + 1;
128 int yEnd = yBegin + 1;
132 unsigned right = input_->width - 1;
134 unsigned bottom = input_->height - 1;
136 std::priority_queue<Entry> results;
140 if (xBegin >= 0 && xBegin <
static_cast<int>(input_->width) && yBegin >= 0 &&
141 yBegin < static_cast<int>(input_->height)) {
142 testPoint(query, k, results, yBegin * input_->width + xBegin);
146 int dist = std::numeric_limits<int>::max();
150 else if (xBegin >=
static_cast<int>(input_->width))
151 dist = xBegin -
static_cast<int>(input_->width);
154 dist = std::min(dist, -yBegin);
155 else if (yBegin >=
static_cast<int>(input_->height))
156 dist = std::min(dist, yBegin -
static_cast<int>(input_->height));
177 clipRange(xFrom, xTo, 0, input_->width);
182 if (yBegin >= 0 && yBegin <
static_cast<int>(input_->height)) {
183 int idx = yBegin * input_->width + xFrom;
184 int idxTo = idx + xTo - xFrom;
185 for (; idx < idxTo; ++idx) stop = testPoint(query, k, results, idx) || stop;
190 if (yEnd > 0 && yEnd <=
static_cast<int>(input_->height)) {
191 int idx = (yEnd - 1) * input_->width + xFrom;
192 int idxTo = idx + xTo - xFrom;
194 for (; idx < idxTo; ++idx) stop = testPoint(query, k, results, idx) || stop;
198 int yFrom = yBegin + 1;
200 clipRange(yFrom, yTo, 0, input_->height);
204 if (xBegin >= 0 && xBegin <
static_cast<int>(input_->width)) {
205 int idx = yFrom * input_->width + xBegin;
206 int idxTo = yTo * input_->width + xBegin;
208 for (; idx < idxTo; idx += input_->width) stop = testPoint(query, k, results, idx) || stop;
211 if (xEnd > 0 && xEnd <=
static_cast<int>(input_->width)) {
212 int idx = yFrom * input_->width + xEnd - 1;
213 int idxTo = yTo * input_->width + xEnd - 1;
215 for (; idx < idxTo; idx += input_->width) stop = testPoint(query, k, results, idx) || stop;
219 if (stop) getProjectedRadiusSearchBox(query, results.top().distance, left, right, top, bottom);
222 stop = (
static_cast<int>(left) >= xBegin &&
static_cast<int>(left) < xEnd &&
static_cast<int>(right) >= xBegin &&
223 static_cast<int>(right) < xEnd &&
static_cast<int>(top) >= yBegin &&
static_cast<int>(top) < yEnd &&
224 static_cast<int>(bottom) >= yBegin &&
static_cast<int>(bottom) < yEnd);
227 k_indices.resize(results.size());
228 k_sqr_distances.resize(results.size());
229 size_t idx = results.size() - 1;
230 while (!results.empty()) {
231 k_indices[idx] = results.top().index;
232 k_sqr_distances[idx] = results.top().distance;
237 return (
static_cast<int>(k_indices.size()));
241 template <
typename Po
intT>
243 unsigned& minX,
unsigned& maxX,
244 unsigned& minY,
unsigned& maxY)
const {
245 const Eigen::Vector3f queryvec(point.x, point.y, point.z);
246 const Eigen::Vector2f q = projectPoint(queryvec);
248 float a = squared_radius * KR_KRT_.coeff(8) - q[2] * q[2];
249 float b = squared_radius * KR_KRT_.coeff(7) - q[1] * q[2];
250 float c = squared_radius * KR_KRT_.coeff(4) - q[1] * q[1];
253 float det = b * b - a * c;
256 maxY = input_->height - 1;
258 float y1 =
static_cast<float>((b - sqrt(det)) / a);
259 float y2 =
static_cast<float>((b + sqrt(det)) / a);
261 min = std::min(
static_cast<int>(floor(y1)),
static_cast<int>(floor(y2)));
262 max = std::max(
static_cast<int>(ceil(y1)),
static_cast<int>(ceil(y2)));
263 minY =
static_cast<unsigned>(std::min(
static_cast<int>(input_->height) - 1, std::max(0, min)));
264 maxY =
static_cast<unsigned>(std::max(std::min(
static_cast<int>(input_->height) - 1, max), 0));
267 b = squared_radius * KR_KRT_.coeff(6) - q[0] * q[2];
268 c = squared_radius * KR_KRT_.coeff(0) - q[0] * q[0];
273 maxX = input_->width - 1;
275 float x1 =
static_cast<float>((b - sqrt(det)) / a);
276 float x2 =
static_cast<float>((b + sqrt(det)) / a);
278 min = std::min(
static_cast<int>(floor(x1)),
static_cast<int>(floor(x2)));
279 max = std::max(
static_cast<int>(ceil(x1)),
static_cast<int>(ceil(x2)));
280 minX =
static_cast<unsigned>(std::min(
static_cast<int>(input_->width) - 1, std::max(0, min)));
281 maxX =
static_cast<unsigned>(std::max(std::min(
static_cast<int>(input_->width) - 1, max), 0));
286 template <
typename Po
intT>
288 Eigen::Vector3f projected = intrinsics_matrix_ * point;
290 q.x() = projected[0] / projected[2];
291 q.y() = projected[1] / projected[2];
294 #define PCL_INSTANTIATE_OrganizedNeighbor2(T) template class PCL_EXPORTS pcl::search::OrganizedNeighbor2<T>;
296 #endif // POINT_CLOUD_COMMON_ORGANIZED_NEIGHBOR2_IMPL_H_