11 #include <Eigen/Geometry>
13 #include <opencv2/core/types.hpp>
14 #include <opencv2/imgproc.hpp>
16 #include <VirtualRobot/MathTools.h>
17 #include <VirtualRobot/VirtualRobot.h>
18 #include <VirtualRobot/math/Helpers.h>
22 #include <RobotAPI/interface/units/LaserScannerUnit.h>
39 std::vector<Ellipsoid>
49 const Eigen::Vector2f center = (segment.first + segment.second) / 2;
50 const Eigen::Vector2f
v = segment.second - center;
51 const float angle = math::Helpers::Angle(
v);
52 const float r =
v.norm();
55 globalPose.translation().head<2>() = center;
57 Eigen::AngleAxisf(
angle, Eigen::Vector3f::UnitZ()).toRotationMatrix();
59 return Ellipsoid{.
pose = globalPose, .radii = Eigen::Vector2f{r, axisLength}};
64 std::vector<Ellipsoid> ellipsoids;
66 segments.begin(), segments.end(), std::back_inserter(ellipsoids), asEllipsoid);
75 scanClusteringParams(scanClusteringParams),
76 chainApproximationParams(chainApproximationParams)
84 const auto clustersWithFeatures = features(
data.data);
87 return clustersWithFeatures;
91 FeatureExtractor::features(
const LaserScan& scan)
const
93 const auto clusters = detectClusters(scan);
95 std::vector<Features> fs;
98 std::back_inserter(fs),
99 [&](
const LaserScan& cluster)
101 const auto points = toCartesian<Eigen::Vector2f>(cluster);
102 const auto hull = convexHull(points);
106 .circle = circle(points),
107 .ellipsoid = std::nullopt,
108 .chain = chainApproximation(points, hull, chainApproximationParams),
115 std::vector<LaserScan>
116 FeatureExtractor::detectClusters(
const LaserScan& scan)
const
118 ScanClustering clustering(scanClusteringParams);
119 return clustering.detectClusters(scan);
122 std::optional<VirtualRobot::MathTools::ConvexHull2D>
126 if (points.size() < 3)
133 return *VirtualRobot::MathTools::createConvexHull2D(points);
135 catch (std::exception& e)
168 std::optional<Ellipsoid>
169 FeatureExtractor::ellipsoid(
const std::optional<VirtualRobot::MathTools::ConvexHull2D>& hull)
180 if (hull->vertices.size() < 5)
189 std::optional<Circle>
190 FeatureExtractor::circle(
const Points& points)
193 if (points.size() < 5)
199 const auto points2i = conversions::cast<cv::Point2i>(points2f);
203 cv::minEnclosingCircle(points2i, center, radius);
208 std::optional<FeatureExtractor::Points>
209 FeatureExtractor::chainApproximation(
211 const std::optional<VirtualRobot::MathTools::ConvexHull2D>&
convexHull,
222 if (result.condition !=