1+ #pragma once
2+
3+ #include < memory>
4+ #include < vector>
5+
6+ #include < cpp-toolbox/cpp-toolbox_export.hpp>
7+ #include < cpp-toolbox/pcl/correspondence/base_correspondence_generator.hpp>
8+ #include < cpp-toolbox/pcl/registration/registration_result.hpp>
9+ #include < cpp-toolbox/types/point.hpp>
10+
11+ namespace toolbox ::pcl
12+ {
13+
14+ /* *
15+ * @brief 粗配准算法的基类(CRTP模式) / Base class for coarse registration
16+ * algorithms (CRTP pattern)
17+ *
18+ * @tparam Derived 派生类类型 / Derived class type
19+ * @tparam DataType 数据类型(如float或double) / Data type (e.g., float or
20+ * double)
21+ */
22+ template <typename Derived, typename DataType>
23+ class CPP_TOOLBOX_EXPORT base_coarse_registration_t
24+ {
25+ public:
26+ using point_cloud = toolbox::types::point_cloud_t <DataType>;
27+ using point_cloud_ptr = std::shared_ptr<point_cloud>;
28+ using correspondences_ptr = std::shared_ptr<std::vector<correspondence_t >>;
29+ using result_type = registration_result_t <DataType>;
30+
31+ base_coarse_registration_t () = default ;
32+ virtual ~base_coarse_registration_t () = default ;
33+
34+ // 删除拷贝,允许移动 / Delete copy, allow move
35+ base_coarse_registration_t (const base_coarse_registration_t &) = delete ;
36+ base_coarse_registration_t & operator =(const base_coarse_registration_t &) =
37+ delete ;
38+ base_coarse_registration_t (base_coarse_registration_t &&) = default ;
39+ base_coarse_registration_t & operator =(base_coarse_registration_t &&) = default ;
40+
41+ /* *
42+ * @brief 设置源点云 / Set source point cloud
43+ */
44+ void set_source (const point_cloud_ptr& source)
45+ {
46+ m_source_cloud = source;
47+ return static_cast <Derived*>(this )->set_source_impl (source);
48+ }
49+
50+ /* *
51+ * @brief 设置目标点云 / Set target point cloud
52+ */
53+ void set_target (const point_cloud_ptr& target)
54+ {
55+ m_target_cloud = target;
56+ return static_cast <Derived*>(this )->set_target_impl (target);
57+ }
58+
59+ /* *
60+ * @brief 设置初始对应关系(可选,主要用于RANSAC类算法) / Set initial
61+ * correspondences (optional, mainly for RANSAC-like algorithms)
62+ */
63+ void set_correspondences (const correspondences_ptr& correspondences)
64+ {
65+ m_correspondences = correspondences;
66+ return static_cast <Derived*>(this )->set_correspondences (correspondences);
67+ }
68+
69+ /* *
70+ * @brief 设置最大迭代次数 / Set maximum iterations
71+ */
72+ void set_max_iterations (std::size_t max_iterations)
73+ {
74+ m_max_iterations = max_iterations;
75+ return static_cast <Derived*>(this )->set_max_iterations (max_iterations);
76+ }
77+
78+ /* *
79+ * @brief 设置内点距离阈值 / Set inlier distance threshold
80+ */
81+ void set_inlier_threshold (DataType threshold)
82+ {
83+ m_inlier_threshold = threshold;
84+ return static_cast <Derived*>(this )->set_inlier_threshold (threshold);
85+ }
86+
87+ /* *
88+ * @brief 设置收敛阈值 / Set convergence threshold
89+ */
90+ void set_convergence_threshold (DataType threshold)
91+ {
92+ m_convergence_threshold = threshold;
93+ return static_cast <Derived*>(this )->set_convergence_threshold (threshold);
94+ }
95+
96+ /* *
97+ * @brief 设置最小内点数量 / Set minimum number of inliers
98+ */
99+ void set_min_inliers (std::size_t min_inliers)
100+ {
101+ m_min_inliers = min_inliers;
102+ return static_cast <Derived*>(this )->set_min_inliers (min_inliers);
103+ }
104+
105+ /* *
106+ * @brief 执行配准 / Perform registration
107+ * @param result [out] 配准结果 / Registration result
108+ * @return 是否成功 / Whether successful
109+ */
110+ bool align (result_type& result)
111+ {
112+ // 验证输入 / Validate input
113+ if (!validate_input ()) {
114+ return false ;
115+ }
116+
117+ // 调用派生类的实现 / Call derived class implementation
118+ return static_cast <Derived*>(this )->align_impl (result);
119+ }
120+
121+ /* *
122+ * @brief 获取算法名称 / Get algorithm name
123+ */
124+ [[nodiscard]] std::string get_algorithm_name () const
125+ {
126+ return static_cast <const Derived*>(this )->get_algorithm_name_impl ();
127+ }
128+
129+ protected:
130+ /* *
131+ * @brief 验证输入数据 / Validate input data
132+ */
133+ [[nodiscard]] bool validate_input () const
134+ {
135+ if (!m_source_cloud || !m_target_cloud) {
136+ LOG_ERROR_S << " 错误:源点云或目标点云未设置 / Error: Source or target "
137+ " cloud not set" ;
138+ return false ;
139+ }
140+
141+ if (m_source_cloud->empty () || m_target_cloud->empty ()) {
142+ LOG_ERROR_S << " 错误:点云为空 / Error: Point cloud is empty" ;
143+ return false ;
144+ }
145+
146+ // 派生类可能需要额外的验证 / Derived class may need additional validation
147+ return static_cast <const Derived*>(this )->validate_input_impl ();
148+ }
149+
150+ /* *
151+ * @brief 派生类的额外输入验证(可选) / Additional input validation for
152+ * derived class (optional)
153+ */
154+ [[nodiscard]] bool validate_input_impl () const { return true ; }
155+
156+ /* *
157+ * @brief 计算配准质量评分 / Compute registration fitness score
158+ */
159+ [[nodiscard]] DataType compute_fitness_score (
160+ const Eigen::Matrix<DataType, 4 , 4 >& transformation,
161+ const std::vector<std::size_t >& inliers) const
162+ {
163+ // 基类提供默认实现,派生类可重写 / Base class provides default
164+ // implementation, derived class can override
165+ if (inliers.empty ()) {
166+ return std::numeric_limits<DataType>::max ();
167+ }
168+
169+ // 计算平均内点距离 / Compute average inlier distance
170+ DataType total_distance = 0 ;
171+ for (std::size_t idx : inliers) {
172+ // 这里简化了,实际需要根据对应关系计算距离
173+ // Simplified here, actual implementation needs to compute distance based
174+ // on correspondences
175+ total_distance += m_inlier_threshold; // 占位符 / Placeholder
176+ }
177+
178+ return total_distance / inliers.size ();
179+ }
180+
181+ private:
182+ // 数据成员 / Data members
183+ point_cloud_ptr m_source_cloud;
184+ point_cloud_ptr m_target_cloud;
185+ correspondences_ptr m_correspondences; // /< 可选的初始对应关系 / Optional
186+ // /< initial correspondences
187+
188+ // 参数 / Parameters
189+ std::size_t m_max_iterations = 1000 ;
190+ DataType m_inlier_threshold = 0.05 ;
191+ DataType m_convergence_threshold = 1e-6 ;
192+ std::size_t m_min_inliers = 3 ;
193+ };
194+
195+ }; // namespace toolbox::pcl
0 commit comments