40#include <pcl/range_image/range_image.h>
57 return std::atan2(y, x);
72 int x,
int y,
int offset_x,
int offset_y,
int pixel_radius)
const
76 range_image_->get1dPointAverage(x+offset_x, y+offset_y, offset_x, offset_y, pixel_radius, neighbor);
77 if (std::isinf(neighbor.
range))
79 if (neighbor.
range < 0.0f)
125 int delta_x=0, delta_y=0;
135 if (delta_x==0 && delta_y==0)
138 int x=border_description.
x, y=border_description.
y;
140 Eigen::Vector3f neighbor_point;
141 range_image_->calculate3DPoint(
static_cast<float> (x+delta_x),
static_cast<float> (y+delta_y), point.
range, neighbor_point);
144 if (local_surface!=
nullptr)
147 Eigen::Vector3f sensor_pos =
range_image_->getSensorPos(),
148 viewing_direction = neighbor_point-sensor_pos;
152 neighbor_point = lambda*viewing_direction + sensor_pos;
156 direction = neighbor_point-point.getVector3fMap();
157 direction.normalize();
166 border_direction =
nullptr;
171 border_direction =
new Eigen::Vector3f(0.0f, 0.0f, 0.0f);
174 delete border_direction;
175 border_direction =
nullptr;
181 float* border_scores_other_direction,
int& shadow_border_idx)
const
183 float& border_score = border_scores[y*
range_image_->width+x];
185 shadow_border_idx = -1;
186 if (border_score<
parameters_.minimum_border_probability)
189 if (border_score == 1.0f)
193 shadow_border_idx = (y+offset_y)*
range_image_->width + x+offset_x;
198 float best_shadow_border_score = 0.0f;
200 for (
int neighbor_distance=1; neighbor_distance<=
parameters_.pixel_radius_borders; ++neighbor_distance)
202 int neighbor_x=x+neighbor_distance*offset_x, neighbor_y=y+neighbor_distance*offset_y;
205 float neighbor_shadow_border_score = border_scores_other_direction[neighbor_y*
range_image_->width+neighbor_x];
207 if (neighbor_shadow_border_score < best_shadow_border_score)
209 shadow_border_idx = neighbor_y*
range_image_->width + neighbor_x;
210 best_shadow_border_score = neighbor_shadow_border_score;
213 if (shadow_border_idx >= 0)
217 border_score *= (std::max)(0.9f, 1-powf(1+best_shadow_border_score, 3));
218 if (border_score>=
parameters_.minimum_border_probability)
221 shadow_border_idx = -1;
228 float max_score_bonus = 0.5f;
230 float border_score = border_scores[y*
range_image_->width+x];
233 if (border_score + max_score_bonus*(1.0f-border_score) <
parameters_.minimum_border_probability)
236 float average_neighbor_score=0.0f, weight_sum=0.0f;
237 for (
int y2=y-1; y2<=y+1; ++y2)
239 for (
int x2=x-1; x2<=x+1; ++x2)
243 average_neighbor_score += border_scores[y2*
range_image_->width+x2];
247 average_neighbor_score /=weight_sum;
249 if (average_neighbor_score*border_score < 0.0f)
252 float new_border_score = border_score + max_score_bonus * average_neighbor_score * (1.0f-std::abs(border_score));
255 return new_border_score;
259 float* border_scores_other_direction,
int& shadow_border_idx)
const
261 float& border_score = border_scores[y*
range_image_->width+x];
262 if (border_score<
parameters_.minimum_border_probability)
265 shadow_border_idx = -1;
266 float best_shadow_border_score = -0.5f*
parameters_.minimum_border_probability;
268 for (
int neighbor_distance=1; neighbor_distance<=
parameters_.pixel_radius_borders; ++neighbor_distance)
270 int neighbor_x=x+neighbor_distance*offset_x, neighbor_y=y+neighbor_distance*offset_y;
273 float neighbor_shadow_border_score = border_scores_other_direction[neighbor_y*
range_image_->width+neighbor_x];
275 if (neighbor_shadow_border_score < best_shadow_border_score)
277 shadow_border_idx = neighbor_y*
range_image_->width + neighbor_x;
278 best_shadow_border_score = neighbor_shadow_border_score;
281 if (shadow_border_idx >= 0)
291 float border_score = border_scores[y*
range_image_->width+x];
292 int neighbor_x=x-offset_x, neighbor_y=y-offset_y;
293 if (
range_image_->isInImage(neighbor_x, neighbor_y) && border_scores[neighbor_y*
range_image_->width+neighbor_x] > border_score)
296 for (
int neighbor_distance=1; neighbor_distance<=
parameters_.pixel_radius_borders; ++neighbor_distance)
298 neighbor_x=x+neighbor_distance*offset_x; neighbor_y=y+neighbor_distance*offset_y;
301 int neighbor_index = neighbor_y*
range_image_->width + neighbor_x;
302 if (neighbor_index==shadow_border_idx)
305 float neighbor_border_score = border_scores[neighbor_index];
306 if (neighbor_border_score > border_score)
313 Eigen::Vector3f& main_direction)
const
318 if (local_surface==
nullptr)
327 for (
int step=1; step<=radius; ++step)
330 for (
int y2=y-step; y2<=y+step; y2+=step)
332 for (
int x2=x-step; x2<=x+step; x2+=step)
334 bool& beam_valid = beams_valid[beam_idx++];
337 beam_valid = (x2!=x || y2!=y);
349 const BorderTraits& border_traits = (*border_descriptions_)[index2].traits;
358 if (local_surface2==
nullptr)
363 vector_average.
add(normal2);
371 Eigen::Vector3f eigen_values, eigen_vector1, eigen_vector2;
372 vector_average.
doPCA(eigen_values, eigen_vector1, eigen_vector2, main_direction);
373 magnitude = std::sqrt (eigen_values[2]);
392 return std::isfinite(magnitude);
void add(const VectorType &sample, real weight=1.0)
Add a new sample.
void doPCA(VectorType &eigen_values, VectorType &eigen_vector1, VectorType &eigen_vector2, VectorType &eigen_vector3) const
Do Principal component analysis.
unsigned int getNoOfSamples()
Get the number of added vectors.
std::bitset< 32 > BorderTraits
Data type to store extended information about a transition from foreground to backgroundSpecification...
@ BORDER_TRAIT__OBSTACLE_BORDER_TOP
@ BORDER_TRAIT__OBSTACLE_BORDER_LEFT
@ BORDER_TRAIT__OBSTACLE_BORDER_RIGHT
@ BORDER_TRAIT__OBSTACLE_BORDER_BOTTOM
@ BORDER_TRAIT__OBSTACLE_BORDER
@ BORDER_TRAIT__SHADOW_BORDER
@ BORDER_TRAIT__VEIL_POINT
float squaredEuclideanDistance(const PointType1 &p1, const PointType2 &p2)
Calculate the squared euclidean distance between the two given points.
VectorAverage< float, 3 > VectorAverage3f
std::ostream & operator<<(std::ostream &os, const BivariatePolynomialT< real > &p)
A structure to store if a point in a range image lies on a border between an obstacle and the backgro...
A point structure representing Euclidean xyz coordinates, padded with an extra range float.