<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * Author : <NAME>
 * Email  : <EMAIL>
 *
 */

#ifndef PCL_ROPS_ESTIMATION_HPP_
#define PCL_ROPS_ESTIMATION_HPP_

#include <pcl/features/rops_estimation.h>

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT>
pcl::ROPSEstimation <PointInT, PointOutT>::ROPSEstimation () :
  number_of_bins_ (5),
  number_of_rotations_ (3),
  support_radius_ (1.0f),
  sqr_support_radius_ (1.0f),
  step_ (30.0f),
  triangles_ (0),
  triangles_of_the_point_ (0)
{
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT>
pcl::ROPSEstimation <PointInT, PointOutT>::~ROPSEstimation ()
{
  triangles_.clear ();
  triangles_of_the_point_.clear ();
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> void
pcl::ROPSEstimation <PointInT, PointOutT>::setNumberOfPartitionBins (unsigned int number_of_bins)
{
  if (number_of_bins != 0)
    number_of_bins_ = number_of_bins;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> unsigned int
pcl::ROPSEstimation <PointInT, PointOutT>::getNumberOfPartitionBins () const
{
  return (number_of_bins_);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> void
pcl::ROPSEstimation <PointInT, PointOutT>::setNumberOfRotations (unsigned int number_of_rotations)
{
  if (number_of_rotations != 0)
  {
    number_of_rotations_ = number_of_rotations;
    step_ = 90.0f / static_cast <float> (number_of_rotations_ + 1);
  }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> unsigned int
pcl::ROPSEstimation <PointInT, PointOutT>::getNumberOfRotations () const
{
  return (number_of_rotations_);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> void
pcl::ROPSEstimation <PointInT, PointOutT>::setSupportRadius (float support_radius)
{
  if (support_radius > 0.0f)
  {
    support_radius_ = support_radius;
    sqr_support_radius_ = support_radius * support_radius;
  }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> float
pcl::ROPSEstimation <PointInT, PointOutT>::getSupportRadius () const
{
  return (support_radius_);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> void
pcl::ROPSEstimation <PointInT, PointOutT>::setTriangles (const std::vector <pcl::Vertices>& triangles)
{
  triangles_ = triangles;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> void
pcl::ROPSEstimation <PointInT, PointOutT>::getTriangles (std::vector <pcl::Vertices>& triangles) const
{
  triangles = triangles_;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> void
pcl::ROPSEstimation <PointInT, PointOutT>::computeFeature (PointCloudOut &output)
{
  if (triangles_.size () == 0)
  {
    output.points.clear ();
    return;
  }

  buildListOfPointsTriangles ();

  //feature size = number_of_rotations * number_of_axis_to_rotate_around * number_of_projections * number_of_central_moments
  unsigned int feature_size = number_of_rotations_ * 3 * 3 * 5;
  unsigned int number_of_points = static_cast <unsigned int> (indices_->size ());
  output.points.resize (number_of_points, PointOutT ());

  for (unsigned int i_point = 0; i_point < number_of_points; i_point++)
  {
    std::set <unsigned int> local_triangles;
    std::vector <int> local_points;
    getLocalSurface (input_->points[(*indices_)[i_point]], local_triangles, local_points);

    Eigen::Matrix3f lrf_matrix;
    computeLRF (input_->points[(*indices_)[i_point]], local_triangles, lrf_matrix);

    PointCloudIn transformed_cloud;
    transformCloud (input_->points[(*indices_)[i_point]], lrf_matrix, local_points, transformed_cloud);

    PointInT axis[3];
    axis[0].x = 1.0f; axis[0].y = 0.0f; axis[0].z = 0.0f;
    axis[1].x = 0.0f; axis[1].y = 1.0f; axis[1].z = 0.0f;
    axis[2].x = 0.0f; axis[2].y = 0.0f; axis[2].z = 1.0f;
    std::vector <float> feature;
    for (unsigned int i_axis = 0; i_axis < 3; i_axis++)
    {
      float theta = step_;
      do
      {
        //rotate local surface and get bounding box
        PointCloudIn rotated_cloud;
        Eigen::Vector3f min, max;
        rotateCloud (axis[i_axis], theta, transformed_cloud, rotated_cloud, min, max);

        //for each projection (XY, XZ and YZ) compute distribution matrix and central moments
        for (unsigned int i_proj = 0; i_proj < 3; i_proj++)
        {
          Eigen::MatrixXf distribution_matrix;
          distribution_matrix.resize (number_of_bins_, number_of_bins_);
          getDistributionMatrix (i_proj, min, max, rotated_cloud, distribution_matrix);

          std::vector <float> moments;
          computeCentralMoments (distribution_matrix, moments);

          feature.insert (feature.end (), moments.begin (), moments.end ());
        }

        theta += step_;
      } while (theta < 90.0f);
    }

    float norm = 0.0f;
    for (unsigned int i_dim = 0; i_dim < feature_size; i_dim++)
      norm += feature[i_dim];
    if (abs (norm) < std::numeric_limits <float>::epsilon ())
      norm = 1.0f / norm;
    else
      norm = 1.0f;<commit_msg>Fix the L1 normalization of the RoPS feature<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * Author : <NAME>
 * Email  : <EMAIL>
 *
 */

#ifndef PCL_ROPS_ESTIMATION_HPP_
#define PCL_ROPS_ESTIMATION_HPP_

#include <pcl/features/rops_estimation.h>

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT>
pcl::ROPSEstimation <PointInT, PointOutT>::ROPSEstimation () :
  number_of_bins_ (5),
  number_of_rotations_ (3),
  support_radius_ (1.0f),
  sqr_support_radius_ (1.0f),
  step_ (30.0f),
  triangles_ (0),
  triangles_of_the_point_ (0)
{
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT>
pcl::ROPSEstimation <PointInT, PointOutT>::~ROPSEstimation ()
{
  triangles_.clear ();
  triangles_of_the_point_.clear ();
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> void
pcl::ROPSEstimation <PointInT, PointOutT>::setNumberOfPartitionBins (unsigned int number_of_bins)
{
  if (number_of_bins != 0)
    number_of_bins_ = number_of_bins;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> unsigned int
pcl::ROPSEstimation <PointInT, PointOutT>::getNumberOfPartitionBins () const
{
  return (number_of_bins_);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> void
pcl::ROPSEstimation <PointInT, PointOutT>::setNumberOfRotations (unsigned int number_of_rotations)
{
  if (number_of_rotations != 0)
  {
    number_of_rotations_ = number_of_rotations;
    step_ = 90.0f / static_cast <float> (number_of_rotations_ + 1);
  }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> unsigned int
pcl::ROPSEstimation <PointInT, PointOutT>::getNumberOfRotations () const
{
  return (number_of_rotations_);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> void
pcl::ROPSEstimation <PointInT, PointOutT>::setSupportRadius (float support_radius)
{
  if (support_radius > 0.0f)
  {
    support_radius_ = support_radius;
    sqr_support_radius_ = support_radius * support_radius;
  }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> float
pcl::ROPSEstimation <PointInT, PointOutT>::getSupportRadius () const
{
  return (support_radius_);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> void
pcl::ROPSEstimation <PointInT, PointOutT>::setTriangles (const std::vector <pcl::Vertices>& triangles)
{
  triangles_ = triangles;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> void
pcl::ROPSEstimation <PointInT, PointOutT>::getTriangles (std::vector <pcl::Vertices>& triangles) const
{
  triangles = triangles_;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> void
pcl::ROPSEstimation <PointInT, PointOutT>::computeFeature (PointCloudOut &output)
{
  if (triangles_.size () == 0)
  {
    output.points.clear ();
    return;
  }

  buildListOfPointsTriangles ();

  //feature size = number_of_rotations * number_of_axis_to_rotate_around * number_of_projections * number_of_central_moments
  unsigned int feature_size = number_of_rotations_ * 3 * 3 * 5;
  unsigned int number_of_points = static_cast <unsigned int> (indices_->size ());
  output.points.resize (number_of_points, PointOutT ());

  for (unsigned int i_point = 0; i_point < number_of_points; i_point++)
  {
    std::set <unsigned int> local_triangles;
    std::vector <int> local_points;
    getLocalSurface (input_->points[(*indices_)[i_point]], local_triangles, local_points);

    Eigen::Matrix3f lrf_matrix;
    computeLRF (input_->points[(*indices_)[i_point]], local_triangles, lrf_matrix);

    PointCloudIn transformed_cloud;
    transformCloud (input_->points[(*indices_)[i_point]], lrf_matrix, local_points, transformed_cloud);

    PointInT axis[3];
    axis[0].x = 1.0f; axis[0].y = 0.0f; axis[0].z = 0.0f;
    axis[1].x = 0.0f; axis[1].y = 1.0f; axis[1].z = 0.0f;
    axis[2].x = 0.0f; axis[2].y = 0.0f; axis[2].z = 1.0f;
    std::vector <float> feature;
    for (unsigned int i_axis = 0; i_axis < 3; i_axis++)
    {
      float theta = step_;
      do
      {
        //rotate local surface and get bounding box
        PointCloudIn rotated_cloud;
        Eigen::Vector3f min, max;
        rotateCloud (axis[i_axis], theta, transformed_cloud, rotated_cloud, min, max);

        //for each projection (XY, XZ and YZ) compute distribution matrix and central moments
        for (unsigned int i_proj = 0; i_proj < 3; i_proj++)
        {
          Eigen::MatrixXf distribution_matrix;
          distribution_matrix.resize (number_of_bins_, number_of_bins_);
          getDistributionMatrix (i_proj, min, max, rotated_cloud, distribution_matrix);

          std::vector <float> moments;
          computeCentralMoments (distribution_matrix, moments);

          feature.insert (feature.end (), moments.begin (), moments.end ());
        }

        theta += step_;
      } while (theta < 90.0f);
    }

    float norm = 0.0f;
    for (unsigned int i_dim = 0; i_dim < feature_size; i_dim++)
      norm += abs (feature[i_dim]);
    if (norm < std::numeric_limits <float>::epsilon ())
      norm = 1.0f;
    else
      norm = 1.0f / norm;
{'fraction_non_alphanumeric': 0.24960102138525375, 'fraction_numerical': 0.008745611235237791, 'mean_word_length': 2.0549921996879874, 'pattern_counts': {'":': 0, '<': 83, '<?xml version=': 0, '>': 81, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6341530', 'n_tokens_mistral': 4396, 'n_tokens_neox': 4163, 'n_words': 1192}