39 #ifndef PCL_TRAJKOVIC_KEYPOINT_2D_IMPL_H_
40 #define PCL_TRAJKOVIC_KEYPOINT_2D_IMPL_H_
46 template <
typename Po
intInT,
typename Po
intOutT,
typename IntensityT>
bool
53 keypoints_indices_->indices.reserve (input_->size ());
55 if (!input_->isOrganized ())
57 PCL_ERROR (
"[pcl::%s::initCompute] %s doesn't support non organized clouds!\n", name_.c_str ());
61 if (indices_->size () != input_->size ())
63 PCL_ERROR (
"[pcl::%s::initCompute] %s doesn't support setting indices!\n", name_.c_str ());
67 if ((window_size_%2) == 0)
69 PCL_ERROR (
"[pcl::%s::initCompute] Window size must be odd!\n", name_.c_str ());
75 PCL_ERROR (
"[pcl::%s::initCompute] Window size must be >= 3x3!\n", name_.c_str ());
79 half_window_size_ = window_size_ / 2;
85 template <
typename Po
intInT,
typename Po
intOutT,
typename IntensityT>
void
89 const int w =
static_cast<int> (input_->width) - half_window_size_;
90 const int h =
static_cast<int> (input_->height) - half_window_size_;
94 #if OPENMP_LEGACY_CONST_DATA_SHARING_RULE
95 #pragma omp parallel for \
99 #pragma omp parallel for \
102 num_threads(threads_)
104 for(
int j = half_window_size_; j < h; ++j)
106 for(
int i = half_window_size_; i < w; ++i)
108 float center = intensity_ ((*input_) (i,j));
109 float up = intensity_ ((*input_) (i, j-half_window_size_));
110 float down = intensity_ ((*input_) (i, j+half_window_size_));
111 float left = intensity_ ((*input_) (i-half_window_size_, j));
112 float right = intensity_ ((*input_) (i+half_window_size_, j));
114 float up_center = up - center;
115 float r1 = up_center * up_center;
116 float down_center = down - center;
117 r1+= down_center * down_center;
119 float right_center = right - center;
120 float r2 = right_center * right_center;
121 float left_center = left - center;
122 r2+= left_center * left_center;
124 float d = std::min (r1, r2);
126 if (d < first_threshold_)
129 float b1 = (right - up) * up_center;
130 b1+= (left - down) * down_center;
131 float b2 = (right - down) * down_center;
132 b2+= (left - up) * up_center;
133 float B = std::min (b1, b2);
134 float A = r2 - r1 - 2*
B;
136 (*response_) (i,j) = ((
B < 0) && ((
B + A) > 0)) ? r1 - ((
B*
B)/A) : d;
142 #if OPENMP_LEGACY_CONST_DATA_SHARING_RULE
143 #pragma omp parallel for \
145 num_threads(threads_)
147 #pragma omp parallel for \
150 num_threads(threads_)
152 for(
int j = half_window_size_; j < h; ++j)
154 for(
int i = half_window_size_; i < w; ++i)
156 float center = intensity_ ((*input_) (i,j));
157 float up = intensity_ ((*input_) (i, j-half_window_size_));
158 float down = intensity_ ((*input_) (i, j+half_window_size_));
159 float left = intensity_ ((*input_) (i-half_window_size_, j));
160 float right = intensity_ ((*input_) (i+half_window_size_, j));
161 float upleft = intensity_ ((*input_) (i-half_window_size_, j-half_window_size_));
162 float upright = intensity_ ((*input_) (i+half_window_size_, j-half_window_size_));
163 float downleft = intensity_ ((*input_) (i-half_window_size_, j+half_window_size_));
164 float downright = intensity_ ((*input_) (i+half_window_size_, j+half_window_size_));
165 std::vector<float> r (4,0);
167 float up_center = up - center;
168 r[0] = up_center * up_center;
169 float down_center = down - center;
170 r[0]+= down_center * down_center;
172 float upright_center = upright - center;
173 r[1] = upright_center * upright_center;
174 float downleft_center = downleft - center;
175 r[1]+= downleft_center * downleft_center;
177 float right_center = right - center;
178 r[2] = right_center * right_center;
179 float left_center = left - center;
180 r[2]+= left_center * left_center;
182 float downright_center = downright - center;
183 r[3] = downright_center * downright_center;
184 float upleft_center = upleft - center;
185 r[3]+= upleft_center * upleft_center;
187 float d = *(std::min_element (r.begin (), r.end ()));
189 if (d < first_threshold_)
192 std::vector<float>
B (4,0);
193 std::vector<float> A (4,0);
194 std::vector<float> sumAB (4,0);
195 B[0] = (upright - up) * up_center;
196 B[0]+= (downleft - down) * down_center;
197 B[1] = (right - upright) * upright_center;
198 B[1]+= (left - downleft) * downleft_center;
199 B[2] = (downright - right) * downright_center;
200 B[2]+= (upleft - left) * upleft_center;
201 B[3] = (down - downright) * downright_center;
202 B[3]+= (up - upleft) * upleft_center;
203 A[0] = r[1] - r[0] -
B[0] -
B[0];
204 A[1] = r[2] - r[1] -
B[1] -
B[1];
205 A[2] = r[3] - r[2] -
B[2] -
B[2];
206 A[3] = r[0] - r[3] -
B[3] -
B[3];
207 sumAB[0] = A[0] +
B[0];
208 sumAB[1] = A[1] +
B[1];
209 sumAB[2] = A[2] +
B[2];
210 sumAB[3] = A[3] +
B[3];
211 if ((*std::max_element (
B.begin (),
B.end ()) < 0) &&
212 (*std::min_element (sumAB.begin (), sumAB.end ()) > 0))
214 std::vector<float> D (4,0);
215 D[0] =
B[0] *
B[0] / A[0];
216 D[1] =
B[1] *
B[1] / A[1];
217 D[2] =
B[2] *
B[2] / A[2];
218 D[3] =
B[3] *
B[3] / A[3];
219 (*response_) (i,j) = *(std::min (D.begin (), D.end ()));
222 (*response_) (i,j) = d;
229 std::sort (indices.begin (), indices.end (), [
this] (
int p1,
int p2) { return greaterCornernessAtIndices (p1, p2); });
232 output.reserve (input_->size ());
234 std::vector<bool> occupency_map (indices.size (),
false);
235 const int width (input_->width);
236 const int height (input_->height);
238 #if OPENMP_LEGACY_CONST_DATA_SHARING_RULE
239 #pragma omp parallel for \
241 shared(indices, occupency_map, output) \
242 num_threads(threads_)
244 #pragma omp parallel for \
246 shared(height, indices, occupency_map, output, width) \
247 num_threads(threads_)
251 for (std::ptrdiff_t i = 0; i < static_cast<std::ptrdiff_t> (indices.size ()); ++i)
253 int idx = indices[i];
254 if (((*response_)[idx] < second_threshold_) || occupency_map[idx])
258 p.getVector3fMap () = (*input_)[idx].getVector3fMap ();
259 p.intensity = response_->points [idx];
263 output.push_back (p);
264 keypoints_indices_->indices.push_back (idx);
267 const int x = idx % width;
268 const int y = idx / width;
269 const int u_end = std::min (width, x + half_window_size_);
270 const int v_end = std::min (height, y + half_window_size_);
271 for(
int v = std::max (0, y - half_window_size_); v < v_end; ++v)
272 for(
int u = std::max (0, x - half_window_size_); u < u_end; ++u)
273 occupency_map[v*width + u] =
true;
277 output.width = output.size();
279 output.is_dense = input_->is_dense;
284 #define PCL_INSTANTIATE_TrajkovicKeypoint2D(T,U,I) template class PCL_EXPORTS pcl::TrajkovicKeypoint2D<T,U,I>;
TrajkovicKeypoint2D implements Trajkovic and Hedley corner detector on organized point cloud using in...
typename Keypoint< PointInT, PointOutT >::PointCloudOut PointCloudOut
void detectKeypoints(PointCloudOut &output) override
bool initCompute() override
IndicesAllocator<> Indices
Type used for indices in PCL.