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>
48template <
typename Po
intT>
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;
90template <
typename Po
intT>
97template <
typename Po
intT>
bool
102 PCL_WARN (
"[pcl::FieldComparison::evaluate] invalid comparison!\n");
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");
132template <
typename Po
intT>
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");
192template <
typename Po
intT>
bool
196 const auto* pt_data =
reinterpret_cast<const std::uint8_t*
> (&point);
211 return (my_val == this->compare_val_);
213 PCL_WARN (
"[pcl::PackedRGBComparison::evaluate] unrecognized op_!\n");
221template <
typename Po
intT>
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");
288template <
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);
333 my_val =
static_cast <float> (h_);
336 my_val =
static_cast <float> (s_);
339 my_val =
static_cast <float> (i_);
357 return (my_val == this->compare_val_);
359 PCL_WARN (
"[pcl::PackedHSIComparison::evaluate] unrecognized op_!\n");
368template<
typename Po
intT>
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;
426template<
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) :
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 ())
488template<
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");
519template <
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");
560template <
typename Po
intT>
void
563 if (!comparison->isCapable ())
569template <
typename Po
intT>
void
572 if (!condition->isCapable ())
580template <
typename Po
intT>
bool
587 for (std::size_t i = 0; i <
conditions_.size (); ++i)
597template <
typename Po
intT>
bool
606 for (std::size_t i = 0; i <
conditions_.size (); ++i)
616template <
typename Po
intT>
void
624template <
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 ());
641 PCL_WARN (
"[pcl::%s::applyFilter] No filtering condition given!\n",
getClassName ().c_str ());
646 output.header =
input_->header;
650 output.is_dense =
true;
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 ());
661 int nr_removed_p = 0;
669 const PointT& point = (*input_)[index];
671 if (!std::isfinite (point.x)
672 || !std::isfinite (point.y)
673 || !std::isfinite (point.z))
677 (*removed_indices_)[nr_removed_p] = index;
692 (*removed_indices_)[nr_removed_p] = index;
699 output.resize (nr_p);
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]))
728 (*removed_indices_)[nr_removed_p] =
static_cast<int> (cp);
742 output.is_dense =
false;
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>;
ComparisonBase()=default
Constructor.
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.
bool capable_
True if capable.
void addCondition(Ptr condition)
Add a nested condition to this condition.
typename ComparisonBase::ConstPtr ComparisonBaseConstPtr
std::vector< ComparisonBaseConstPtr > comparisons_
The collection of all comparisons that need to be verified.
std::vector< Ptr > conditions_
The collection of all conditions that need to be verified.
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.
bool keep_organized_
Keep the structure of the data organized, by setting the filtered points to the a user given value (N...
ConditionBasePtr condition_
The condition to use for filtering.
typename ConditionBase::Ptr ConditionBasePtr
bool capable_
True if capable.
float user_filter_value_
User given value to be set to any filtered point.
~FieldComparison() override
Destructor.
double compare_val_
All types (that we care about) can be represented as a double.
PointDataAtOffset< PointT > * point_data_
The point data to compare.
FieldComparison(const std::string &field_name, ComparisonOps::CompareOp op, double compare_val)
Construct a FieldComparison.
bool evaluate(const PointT &point) const override
Determine the result of this comparison.
bool extract_removed_indices_
Set to true if we want to return the indices of the removed points.
const std::string & getClassName() const
Get a string representation of the name of this class.
IndicesPtr removed_indices_
Indices of the points that are removed.
PointCloudConstPtr input_
The input point cloud dataset.
IndicesPtr indices_
A pointer to the vector of point indices to use.
std::uint32_t rgb_offset_
The offset of the component.
bool evaluate(const PointT &point) const override
Determine the result of this comparison.
std::string component_name_
The name of the component.
PackedHSIComparison(const std::string &component_name, ComparisonOps::CompareOp op, double compare_val)
Construct a PackedHSIComparison.
ComponentId component_id_
The ID of the component.
double compare_val_
All types (that we care about) can be represented as a double.
bool evaluate(const PointT &point) const override
Determine the result of this comparison.
PackedRGBComparison(const std::string &component_name, ComparisonOps::CompareOp op, double compare_val)
Construct a PackedRGBComparison.
std::uint32_t component_offset_
The offset of the component.
double compare_val_
All types (that we care about) can be represented as a double.
std::string component_name_
The name of the component.
A datatype that enables type-correct comparisons.
int compare(const PointT &p, const double &val)
Compare function.
std::uint8_t datatype_
The type of data.
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.
std::vector< pcl::PCLPointField > getFields()
Get the list of available fields (i.e., dimension/channel)
CompareOp
The kind of comparison operations that are possible within a comparison object.
IndicesAllocator<> Indices
Type used for indices in PCL.