前置声明
在很多头文件中有很多这样的代码,参考PointCloud.h
namespace open3d {namespace camera {
class PinholeCameraIntrinsic;
}namespace geometry {class Image;
class RGBDImage;
class TriangleMesh;
class VoxelGrid;
}
}
- 直接声明其他类型避免包含这些类型的头文件,大大的减少依赖时间。
- 缺点就是没包含头文件这些类只能用来声明,不能进行实例化。通常用作函数声明或者使用智能指针进行声明,使用较为受限
static std::shared_ptr<PointCloud> CreateFromDepthImage(const Image &depth,const camera::PinholeCameraIntrinsic &intrinsic, // 作为函数声明的参数const Eigen::Matrix4d &extrinsic = Eigen::Matrix4d::Identity(),double depth_scale = 1000.0,double depth_trunc = 1000.0,int stride = 1,bool project_valid_depth_only = true);
面试考点:基类需要为虚函数
便于继承的类进行资源释放,参考Geometry.h
class Geometry {
public:virtual ~Geometry() {}
};class Geometry3D : public Geometry {
public:~Geometry3D() override {}
}class PointCloud : public Geometry3D {~PointCloud() override {}
}
限定作用域的枚举
主要是防止命名空间被污染,和C++尽可能少使用宏的动机一样
enum class GeometryType {/// Unspecified geometry type.Unspecified = 0,/// PointCloudPointCloud = 1,/// VoxelGridVoxelGrid = 2,/// OctreeOctree = 3,/// LineSetLineSet = 4,/// MeshBaseMeshBase = 5,/// TriangleMeshTriangleMesh = 6,/// HalfEdgeTriangleMeshHalfEdgeTriangleMesh = 7,/// ImageImage = 8,/// RGBDImageRGBDImage = 9,/// TetraMeshTetraMesh = 10,/// OrientedBoundingBoxOrientedBoundingBox = 11,/// AxisAlignedBoundingBoxAxisAlignedBoundingBox = 12,
};
函数传参尽量使用const&
- 参数传递使用引用可减少拷贝构造,尤其是对于复杂类型的参数
- 任何时候能用const尽量用const,参考effective C++第三条
PointCloud(const std::vector<Eigen::Vector3d> &points): Geometry3D(Geometry::GeometryType::PointCloud), points_(points) {}
构造函数列表初始化
相比在构造函数中赋值,初始化列表可以在成员变量初始化的时候直接赋值,而不是初始化之后再赋值
PointCloud(const std::vector<Eigen::Vector3d> &points): Geometry3D(Geometry::GeometryType::PointCloud), points_(points) {}
运算符重载
PointCloud &PointCloud::operator+=(const PointCloud &cloud);
最大值最小值的使用
if (voxel_size * std::numeric_limits<int>::max() <(voxel_max_bound - voxel_min_bound).maxCoeff()) {utility::LogError("[VoxelDownSample] voxel_size is too small.");
}
随机数的使用
比C语言的rand要更好用
std::random_device rd;
std::mt19937 prng(rd());
std::shuffle(indices.begin(), indices.end(), prng);
omp加速
#pragma omp parallel for schedule(static) \num_threads(utility::EstimateMaxThreads())for (int i = 0; i < int(points_.size()); i++) {std::vector<int> tmp_indices;std::vector<double> dist;size_t nb_neighbors = kdtree.SearchRadius(points_[i], search_radius,tmp_indices, dist);mask[i] = (nb_neighbors > nb_points);}
参数使用类进行封装
调用更加清晰明了
class ICPConvergenceCriteria {
public:/// \brief Parameterized Constructor.////// \param relative_fitness If relative change (difference) of fitness score/// is lower than relative_fitness, the iteration stops. \param/// relative_rmse If relative change (difference) of inliner RMSE score is/// lower than relative_rmse, the iteration stops. \param max_iteration/// Maximum iteration before iteration stops.ICPConvergenceCriteria(double relative_fitness = 1e-6,double relative_rmse = 1e-6,int max_iteration = 30): relative_fitness_(relative_fitness),relative_rmse_(relative_rmse),max_iteration_(max_iteration) {}~ICPConvergenceCriteria() {}public:/// If relative change (difference) of fitness score is lower than/// `relative_fitness`, the iteration stops.double relative_fitness_;/// If relative change (difference) of inliner RMSE score is lower than/// `relative_rmse`, the iteration stops.double relative_rmse_;/// Maximum iteration before iteration stops.int max_iteration_;
};auto result = pipelines::registration::RegistrationColoredICP(*source_down, *target_down, 0.07, trans,pipelines::registration::TransformationEstimationForColoredICP(),pipelines::registration::ICPConvergenceCriteria(1e-6, 1e-6,iterations[i]));