Skip to content

Commit 421828a

Browse files
feat: add registration result and base coarse registration class
1 parent 6aa2a4c commit 421828a

File tree

2 files changed

+220
-0
lines changed

2 files changed

+220
-0
lines changed
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
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
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#pragma once
2+
3+
#include <vector>
4+
5+
#include <Eigen/Dense>
6+
7+
namespace toolbox::pcl
8+
{
9+
10+
/**
11+
* @brief 配准结果结构体 / Registration result structure
12+
*/
13+
template<typename DataType>
14+
struct registration_result_t
15+
{
16+
using transformation_t = Eigen::Matrix<DataType, 4, 4>;
17+
18+
transformation_t transformation; ///< 变换矩阵 / Transformation matrix
19+
DataType fitness_score; ///< 配准质量评分 / Registration fitness score
20+
std::vector<std::size_t> inliers; ///< 内点索引 / Inlier indices
21+
std::size_t num_iterations = 0; ///< 实际迭代次数 / Actual iteration count
22+
bool converged = false; ///< 是否收敛 / Whether converged
23+
};
24+
25+
} // namespace toolbox::pcl

0 commit comments

Comments
 (0)