44 #include <pcl/2d/convolution.h>
45 #include <pcl/2d/edge.h>
46 #include <pcl/2d/keypoint.h>
52 template <
typename ImageType>
64 conv_2d.gaussianKernel(5, sigma_d, kernel_d);
65 conv_2d.gaussianKernel(5, sigma_i, kernel_i);
68 ImageType smoothed_image;
69 conv_2d.convolve(smoothed_image, kernel_d, input);
73 edge_detection.ComputeDerivativeXCentral(I_x, smoothed_image);
74 edge_detection.ComputeDerivativeYCentral(I_y, smoothed_image);
77 ImageType I_x2, I_y2, I_xI_y;
78 imageElementMultiply(I_x2, I_x, I_x);
79 imageElementMultiply(I_y2, I_y, I_y);
80 imageElementMultiply(I_xI_y, I_x, I_y);
83 ImageType M00, M10, M11;
84 conv_2d.convolve(M00, kernel_i, I_x2);
85 conv_2d.convolve(M10, kernel_i, I_xI_y);
86 conv_2d.convolve(M11, kernel_i, I_y2);
89 const std::size_t height = input.size();
90 const std::size_t width = input[0].size();
91 output.resize(height);
92 for (std::size_t i = 0; i < height; i++) {
93 output[i].resize(width);
94 for (std::size_t j = 0; j < width; j++) {
95 output[i][j] = M00[i][j] * M11[i][j] - (M10[i][j] * M10[i][j]) -
96 alpha * ((M00[i][j] + M11[i][j]) * (M00[i][j] + M11[i][j]));
98 if (output[i][j] < thresh)
107 for (std::size_t i = 1; i < height - 1; i++) {
108 for (std::size_t j = 1; j < width - 1; j++) {
109 if (output[i][j] > output[i - 1][j - 1] && output[i][j] > output[i - 1][j] &&
110 output[i][j] > output[i - 1][j + 1] && output[i][j] > output[i][j - 1] &&
111 output[i][j] > output[i][j + 1] && output[i][j] > output[i + 1][j - 1] &&
112 output[i][j] > output[i + 1][j] && output[i][j] > output[i + 1][j + 1])
120 template <
typename ImageType>
128 ImageType
kernel, cornerness;
132 ImageType smoothed_image;
133 conv_2d.convolve(smoothed_image,
kernel, input);
137 edge_detection.ComputeDerivativeXCentral(I_x, smoothed_image);
138 edge_detection.ComputeDerivativeYCentral(I_y, smoothed_image);
141 ImageType I_xx, I_yy, I_xy;
142 edge_detection.ComputeDerivativeXCentral(I_xx, I_x);
143 edge_detection.ComputeDerivativeYCentral(I_xy, I_x);
144 edge_detection.ComputeDerivativeYCentral(I_yy, I_y);
146 const std::size_t height = input.size();
147 const std::size_t width = input[0].size();
148 float min = std::numeric_limits<float>::max();
149 float max = std::numeric_limits<float>::min();
150 cornerness.resize(height);
151 for (std::size_t i = 0; i < height; i++) {
152 cornerness[i].resize(width);
153 for (std::size_t j = 0; j < width; j++) {
155 sigma * sigma * (I_xx[i][j] + I_yy[i][j] - I_xy[i][j] * I_xy[i][j]);
157 if (cornerness[i][j] < min)
158 min = cornerness[i][j];
159 if (cornerness[i][j] > max)
160 max = cornerness[i][j];
165 output.resize(height);
166 output[0].resize(width);
167 output[height - 1].resize(width);
168 for (std::size_t i = 1; i < height - 1; i++) {
169 output[i].resize(width);
170 for (std::size_t j = 1; j < width - 1; j++) {
172 output[i][j] = ((cornerness[i][j] - min) / (max - min));
174 output[i][j] = cornerness[i][j];
180 template <
typename ImageType>
184 const float start_scale,
185 const float scaling_factor,
186 const int num_scales)
188 const std::size_t height = input.size();
189 const std::size_t width = input[0].size();
190 const int local_search_radius = 1;
191 float scale = start_scale;
192 std::vector<ImageType> cornerness;
193 cornerness.resize(num_scales);
194 for (
int i = 0; i < num_scales; i++) {
195 hessianBlob(cornerness[i], input, scale,
false);
196 scale *= scaling_factor;
198 for (std::size_t i = 0; i < height; i++) {
199 for (std::size_t j = 0; j < width; j++) {
200 float scale_max = std::numeric_limits<float>::min();
203 for (
int k = 0; k < num_scales; k++) {
205 bool non_max_flag =
false;
206 const float local_max = cornerness[k][i][j];
207 for (
int n = -local_search_radius; n <= local_search_radius; n++) {
208 if (n + k < 0 || n + k >= num_scales)
210 for (
int l = -local_search_radius; l <= local_search_radius; l++) {
211 if (l + i < 0 || l + i >= height)
213 for (
int m = -local_search_radius; m <= local_search_radius; m++) {
214 if (m + j < 0 || m + j >= width)
216 if (cornerness[n + k][l + i][m + j] > local_max) {
230 if (cornerness[k][i][j] > scale_max) {
231 scale_max = cornerness[k][i][j];
234 output[i][j] = start_scale * pow(scaling_factor, k);
242 template <
typename ImageType>
248 const std::size_t height = input1.size();
249 const std::size_t width = input1[0].size();
250 output.resize(height);
251 for (std::size_t i = 0; i < height; i++) {
252 output[i].resize(width);
253 for (std::size_t j = 0; j < width; j++) {
254 output[i][j] = input1[i][j] * input2[i][j];
void imageElementMultiply(ImageType &output, ImageType &input1, ImageType &input2)
void hessianBlob(ImageType &output, ImageType &input, const float sigma, bool SCALE)
void harrisCorner(ImageType &output, ImageType &input, const float sigma_d, const float sigma_i, const float alpha, const float thresh)
void gaussianKernel(pcl::PointCloud< PointT > &kernel)