38 #ifndef PCL_FILTER_IMPL_FIELD_VAL_CONDITION_H_
39 #define PCL_FILTER_IMPL_FIELD_VAL_CONDITION_H_
41 #include <pcl/common/io.h>
42 #include <pcl/common/copy_point.h>
43 #include <pcl/filters/conditional_removal.h>
48 template <
typename Po
intT>
52 , compare_val_ (compare_val), point_data_ (nullptr)
58 const auto point_fields = pcl::getFields<PointT> ();
61 if (point_fields.empty ())
63 PCL_WARN (
"[pcl::FieldComparison::FieldComparison] no fields found!\n");
70 for (d = 0; d < point_fields.size (); ++d)
72 if (point_fields[d].name == field_name)
76 if (d == point_fields.size ())
78 PCL_WARN (
"[pcl::FieldComparison::FieldComparison] field not found!\n");
82 std::uint8_t datatype = point_fields[d].datatype;
83 std::uint32_t offset = point_fields[d].offset;
90 template <
typename Po
intT>
97 template <
typename Po
intT>
bool
102 PCL_WARN (
"[pcl::FieldComparison::evaluate] invalid comparison!\n");
109 int compare_result = point_data_->compare (point, compare_val_);
114 return (compare_result > 0);
116 return (compare_result >= 0);
118 return (compare_result < 0);
120 return (compare_result <= 0);
122 return (compare_result == 0);
124 PCL_WARN (
"[pcl::FieldComparison::evaluate] unrecognized op_!\n");
132 template <
typename Po
intT>
135 component_name_ (component_name), component_offset_ (), compare_val_ (compare_val)
138 const auto point_fields = pcl::getFields<PointT> ();
142 for (d = 0; d < point_fields.size (); ++d)
144 if (point_fields[d].name ==
"rgb" || point_fields[d].name ==
"rgba")
147 if (d == point_fields.size ())
149 PCL_WARN (
"[pcl::PackedRGBComparison::PackedRGBComparison] rgb field not found!\n");
155 std::uint8_t datatype = point_fields[d].datatype;
160 PCL_WARN (
"[pcl::PackedRGBComparison::PackedRGBComparison] has unusable type!\n");
166 if (component_name ==
"r")
170 else if (component_name ==
"g")
174 else if (component_name ==
"b")
180 PCL_WARN (
"[pcl::PackedRGBComparison::PackedRGBComparison] unrecognized component name!\n");
192 template <
typename Po
intT>
bool
196 const auto* pt_data =
reinterpret_cast<const std::uint8_t*
> (&point);
197 std::uint8_t my_val = *(pt_data + component_offset_);
203 return (my_val > this->compare_val_);
205 return (my_val >= this->compare_val_);
207 return (my_val < this->compare_val_);
209 return (my_val <= this->compare_val_);
211 return (my_val == this->compare_val_);
213 PCL_WARN (
"[pcl::PackedRGBComparison::evaluate] unrecognized op_!\n");
221 template <
typename Po
intT>
224 component_name_ (component_name), component_id_ (), compare_val_ (compare_val), rgb_offset_ ()
227 const auto point_fields = pcl::getFields<PointT> ();
231 for (d = 0; d < point_fields.size (); ++d)
232 if (point_fields[d].name ==
"rgb" || point_fields[d].name ==
"rgba")
234 if (d == point_fields.size ())
236 PCL_WARN (
"[pcl::PackedHSIComparison::PackedHSIComparison] rgb field not found!\n");
242 std::uint8_t datatype = point_fields[d].datatype;
247 PCL_WARN (
"[pcl::PackedHSIComparison::PackedHSIComparison] has unusable type!\n");
253 std::uint32_t offset = point_fields[d].offset;
256 PCL_WARN (
"[pcl::PackedHSIComparison::PackedHSIComparison] rgb field is not 32 bit aligned!\n");
263 if (component_name ==
"h" )
267 else if (component_name ==
"s")
271 else if (component_name ==
"i")
277 PCL_WARN (
"[pcl::PackedHSIComparison::PackedHSIComparison] unrecognized component name!\n");
288 template <
typename Po
intT>
bool
292 static std::uint32_t rgb_val_ = 0;
293 static std::uint8_t r_ = 0;
294 static std::uint8_t g_ = 0;
295 static std::uint8_t b_ = 0;
296 static std::int8_t h_ = 0;
297 static std::uint8_t s_ = 0;
298 static std::uint8_t i_ = 0;
301 const auto* pt_data =
reinterpret_cast<const std::uint8_t*
> (&point);
302 const auto* rgb_data =
reinterpret_cast<const std::uint32_t*
> (pt_data + rgb_offset_);
303 std::uint32_t new_rgb_val = *rgb_data;
305 if (rgb_val_ != new_rgb_val)
307 rgb_val_ = new_rgb_val;
309 r_ =
static_cast <std::uint8_t
> (rgb_val_ >> 16);
310 g_ =
static_cast <std::uint8_t
> (rgb_val_ >> 8);
311 b_ =
static_cast <std::uint8_t
> (rgb_val_);
314 float hx = (2.0f * r_ - g_ - b_) / 4.0f;
315 float hy =
static_cast<float> (g_ - b_) * 111.0f / 255.0f;
316 h_ =
static_cast<std::int8_t
> (std::atan2(hy, hx) * 128.0f /
M_PI);
318 std::int32_t i = (r_+g_+b_)/3;
319 i_ =
static_cast<std::uint8_t
> (i);
322 m = (r_ < g_) ? r_ : g_;
323 m = (m < b_) ? m : b_;
325 s_ =
static_cast<std::uint8_t
> ((i == 0) ? 0 : 255 - (m * 255) / i);
330 switch (component_id_)
333 my_val =
static_cast <float> (h_);
336 my_val =
static_cast <float> (s_);
339 my_val =
static_cast <float> (i_);
349 return (my_val > this->compare_val_);
351 return (my_val >= this->compare_val_);
353 return (my_val < this->compare_val_);
355 return (my_val <= this->compare_val_);
357 return (my_val == this->compare_val_);
359 PCL_WARN (
"[pcl::PackedHSIComparison::evaluate] unrecognized op_!\n");
368 template<
typename Po
intT>
373 const auto point_fields = pcl::getFields<PointT> ();
377 for (dX = 0; dX < point_fields.size (); ++dX)
379 if (point_fields[dX].name ==
"x")
382 if (dX == point_fields.size ())
384 PCL_WARN (
"[pcl::TfQuadraticXYZComparison::TfQuadraticXYZComparison] x field not found!\n");
391 for (dY = 0; dY < point_fields.size (); ++dY)
393 if (point_fields[dY].name ==
"y")
396 if (dY == point_fields.size ())
398 PCL_WARN (
"[pcl::TfQuadraticXYZComparison::TfQuadraticXYZComparison] y field not found!\n");
405 for (dZ = 0; dZ < point_fields.size (); ++dZ)
407 if (point_fields[dZ].name ==
"z")
410 if (dZ == point_fields.size ())
412 PCL_WARN (
"[pcl::TfQuadraticXYZComparison::TfQuadraticXYZComparison] z field not found!\n");
417 comp_matr_ << 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0;
426 template<
typename Po
intT>
428 const Eigen::Matrix3f &comparison_matrix,
429 const Eigen::Vector3f &comparison_vector,
430 const float &comparison_scalar,
431 const Eigen::Affine3f &comparison_transform) :
432 comp_scalar_ (comparison_scalar)
435 const auto point_fields = pcl::getFields<PointT> ();
439 for (dX = 0; dX < point_fields.size (); ++dX)
441 if (point_fields[dX].name ==
"x")
444 if (dX == point_fields.size ())
446 PCL_WARN (
"[pcl::TfQuadraticXYZComparison::TfQuadraticXYZComparison] x field not found!\n");
453 for (dY = 0; dY < point_fields.size (); ++dY)
455 if (point_fields[dY].name ==
"y")
458 if (dY == point_fields.size ())
460 PCL_WARN (
"[pcl::TfQuadraticXYZComparison::TfQuadraticXYZComparison] y field not found!\n");
467 for (dZ = 0; dZ < point_fields.size (); ++dZ)
469 if (point_fields[dZ].name ==
"z")
472 if (dZ == point_fields.size ())
474 PCL_WARN (
"[pcl::TfQuadraticXYZComparison::TfQuadraticXYZComparison] z field not found!\n");
483 if (!comparison_transform.matrix ().isIdentity ())
488 template<
typename Po
intT>
492 Eigen::Vector4f pointAffine;
493 pointAffine << point.x, point.y, point.z, 1;
495 float myVal =
static_cast<float>(2.0f * tf_comp_vect_.transpose () * pointAffine) +
static_cast<float>(pointAffine.transpose () * tf_comp_matr_ * pointAffine) + comp_scalar_ - 3.0f;
511 PCL_WARN (
"[pcl::TfQuadraticXYZComparison::evaluate] unrecognized op_!\n");
519 template <
typename Po
intT>
int
526 const auto* pt_data =
reinterpret_cast<const std::uint8_t*
> (&p);
528 #define SAFE_COMPARE(CASE_LABEL) \
530 pcl::traits::asType_t<CASE_LABEL> pt_val; \
531 memcpy(&pt_val, pt_data + this->offset_, sizeof(pt_val)); \
532 return (pt_val > static_cast<pcl::traits::asType_t<(CASE_LABEL)>>(val)) - \
533 (pt_val < static_cast<pcl::traits::asType_t<(CASE_LABEL)>>(val)); \
551 PCL_WARN (
"[pcl::PointDataAtOffset::compare] unknown data_type!\n");
560 template <
typename Po
intT>
void
563 if (!comparison->isCapable ())
565 comparisons_.push_back (comparison);
569 template <
typename Po
intT>
void
572 if (!condition->isCapable ())
574 conditions_.push_back (condition);
580 template <
typename Po
intT>
bool
583 for (std::size_t i = 0; i < comparisons_.size (); ++i)
584 if (!comparisons_[i]->evaluate (point))
587 for (std::size_t i = 0; i < conditions_.size (); ++i)
588 if (!conditions_[i]->evaluate (point))
597 template <
typename Po
intT>
bool
600 if (comparisons_.empty () && conditions_.empty ())
602 for (std::size_t i = 0; i < comparisons_.size (); ++i)
603 if (comparisons_[i]->evaluate(point))
606 for (std::size_t i = 0; i < conditions_.size (); ++i)
607 if (conditions_[i]->evaluate (point))
616 template <
typename Po
intT>
void
619 condition_ = condition;
620 capable_ = condition_->isCapable ();
624 template <
typename Po
intT>
void
629 PCL_WARN (
"[pcl::%s::applyFilter] not capable!\n", getClassName ().c_str ());
635 PCL_WARN (
"[pcl::%s::applyFilter] No input dataset given!\n", getClassName ().c_str ());
639 if (condition_.get () ==
nullptr)
641 PCL_WARN (
"[pcl::%s::applyFilter] No filtering condition given!\n", getClassName ().c_str ());
646 output.
header = input_->header;
647 if (!keep_organized_)
654 output.
height = this->input_->height;
655 output.
width = this->input_->width;
656 output.
is_dense = this->input_->is_dense;
658 output.
resize (input_->size ());
659 removed_indices_->resize (input_->size ());
661 int nr_removed_p = 0;
663 if (!keep_organized_)
669 const PointT& point = (*input_)[index];
671 if (!std::isfinite (point.x)
672 || !std::isfinite (point.y)
673 || !std::isfinite (point.z))
675 if (extract_removed_indices_)
677 (*removed_indices_)[nr_removed_p] = index;
683 if (condition_->evaluate (point))
690 if (extract_removed_indices_)
692 (*removed_indices_)[nr_removed_p] = index;
704 std::sort (indices.begin (), indices.end ());
705 bool removed_p =
false;
707 for (std::size_t cp = 0; cp < input_->size (); ++cp)
709 if (cp ==
static_cast<std::size_t
> (indices[ci]))
711 if (ci < indices.size () - 1)
714 if (cp ==
static_cast<std::size_t
> (indices[ci]))
721 if (!condition_->evaluate ((*input_)[cp]))
723 output[cp].getVector4fMap ().setConstant (user_filter_value_);
726 if (extract_removed_indices_)
728 (*removed_indices_)[nr_removed_p] =
static_cast<int> (cp);
735 output[cp].getVector4fMap ().setConstant (user_filter_value_);
741 if (removed_p && !std::isfinite (user_filter_value_))
744 removed_indices_->resize (nr_removed_p);
747 #define PCL_INSTANTIATE_PointDataAtOffset(T) template class PCL_EXPORTS pcl::PointDataAtOffset<T>;
748 #define PCL_INSTANTIATE_ComparisonBase(T) template class PCL_EXPORTS pcl::ComparisonBase<T>;
749 #define PCL_INSTANTIATE_FieldComparison(T) template class PCL_EXPORTS pcl::FieldComparison<T>;
750 #define PCL_INSTANTIATE_PackedRGBComparison(T) template class PCL_EXPORTS pcl::PackedRGBComparison<T>;
751 #define PCL_INSTANTIATE_PackedHSIComparison(T) template class PCL_EXPORTS pcl::PackedHSIComparison<T>;
752 #define PCL_INSTANTIATE_TfQuadraticXYZComparison(T) template class PCL_EXPORTS pcl::TfQuadraticXYZComparison<T>;
753 #define PCL_INSTANTIATE_ConditionBase(T) template class PCL_EXPORTS pcl::ConditionBase<T>;
754 #define PCL_INSTANTIATE_ConditionAnd(T) template class PCL_EXPORTS pcl::ConditionAnd<T>;
755 #define PCL_INSTANTIATE_ConditionOr(T) template class PCL_EXPORTS pcl::ConditionOr<T>;
756 #define PCL_INSTANTIATE_ConditionalRemoval(T) template class PCL_EXPORTS pcl::ConditionalRemoval<T>;
The (abstract) base class for the comparison object.
ComparisonOps::CompareOp op_
The comparison operator type.
bool capable_
True if capable.
std::string field_name_
Field name to compare data on.
bool evaluate(const PointT &point) const override
Determine if a point meets this condition.
void addCondition(Ptr condition)
Add a nested condition to this condition.
typename ComparisonBase::ConstPtr ComparisonBaseConstPtr
void addComparison(ComparisonBaseConstPtr comparison)
Add a new comparison.
shared_ptr< ConditionBase< PointT > > Ptr
bool evaluate(const PointT &point) const override
Determine if a point meets this condition.
void applyFilter(PointCloud &output) override
Filter a Point Cloud.
void setCondition(ConditionBasePtr condition)
Set the condition that the filter will use.
typename ConditionBase::Ptr ConditionBasePtr
The field-based specialization of the comparison object.
~FieldComparison() override
Destructor.
PointDataAtOffset< PointT > * point_data_
The point data to compare.
bool evaluate(const PointT &point) const override
Determine the result of this comparison.
Filter represents the base filter class.
A packed HSI specialization of the comparison object.
std::uint32_t rgb_offset_
The offset of the component.
bool evaluate(const PointT &point) const override
Determine the result of this comparison.
ComponentId component_id_
The ID of the component.
A packed rgb specialization of the comparison object.
bool evaluate(const PointT &point) const override
Determine the result of this comparison.
std::uint32_t component_offset_
The offset of the component.
PointCloud represents the base class in PCL for storing collections of 3D points.
bool is_dense
True if no points are invalid (e.g., have NaN or Inf values in any of their floating point fields).
void resize(std::size_t count)
Resizes the container to contain count elements.
std::uint32_t width
The point cloud width (if organized as an image-structure).
pcl::PCLHeader header
The point cloud header.
std::uint32_t height
The point cloud height (if organized as an image-structure).
A datatype that enables type-correct comparisons.
int compare(const PointT &p, const double &val)
Compare function.
TfQuadraticXYZComparison()
Constructor.
void setComparisonVector(const Eigen::Vector3f &vector)
set the vector "v" of the comparison "p'Ap + 2v'p + c [OP] 0".
Eigen::Matrix4f comp_matr_
void transformComparison(const Eigen::Matrix4f &transform)
transform the coordinate system of the comparison.
Eigen::Vector4f comp_vect_
void setComparisonMatrix(const Eigen::Matrix3f &matrix)
set the matrix "A" of the comparison "p'Ap + 2v'p + c [OP] 0".
bool evaluate(const PointT &point) const override
Determine the result of this comparison.
void copyPoint(const PointInT &point_in, PointOutT &point_out)
Copy the fields of a source point into a target point.
CompareOp
The kind of comparison operations that are possible within a comparison object.
IndicesAllocator<> Indices
Type used for indices in PCL.
A point structure representing Euclidean xyz coordinates, and the RGB color.