29static const float kEpsilon = 1e-6f;
30static const float kEpsilonForSize = 1e-2f;
31static const float kEpsilonForLine = 1e-3f;
34using ObjectPtr = std::shared_ptr<apollo::perception::base::Object>;
44 if (frame ==
nullptr) {
48 for (
size_t i = 0; i < objects->size(); ++i) {
50 objects->
at(i)->id =
static_cast<int>(i);
51 ComputePolygon2D(objects->at(i));
52 ComputePolygonSizeCenter(objects->at(i));
53 ComputeOtherObjectInformation(objects->at(i));
59void ObjectBuilder::ComputePolygon2D(
ObjectPtr object) {
60 Eigen::Vector3f min_pt;
61 Eigen::Vector3f max_pt;
63 GetMinMax3D(cloud, &min_pt, &max_pt);
64 if (cloud.
size() < 4u) {
65 SetDefaultValue(min_pt, max_pt,
object);
68 LinePerturbation(&cloud);
74void ObjectBuilder::ComputeOtherObjectInformation(
ObjectPtr object) {
75 object->anchor_point =
object->center;
78void ObjectBuilder::ComputePolygonSizeCenter(
ObjectPtr object) {
79 if (object->radar4d_supplement.cloud.size() < 4u) {
82 Eigen::Vector3f dir =
object->direction;
84 object->radar4d_supplement.cloud,
85 dir, &(object->size), &(object->center));
86 if (object->radar4d_supplement.is_background) {
87 float length =
object->size(0);
88 float width =
object->size(1);
89 Eigen::Matrix<float, 3, 1> ortho_dir(-object->direction(1),
90 object->direction(0), 0.0);
92 object->direction = ortho_dir;
93 object->size(0) =
width;
94 object->size(1) = length;
97 for (
size_t i = 0; i < 3; ++i) {
98 if (object->size(i) < kEpsilonForSize) {
99 object->size(i) = kEpsilonForSize;
103 static_cast<float>(atan2(object->direction(1), object->direction(0)));
106void ObjectBuilder::SetDefaultValue(
const Eigen::Vector3f& min_pt_in,
107 const Eigen::Vector3f& max_pt_in,
109 Eigen::Vector3f min_pt = min_pt_in;
110 Eigen::Vector3f max_pt = max_pt_in;
112 for (
int i = 0; i < 3; i++) {
113 if (max_pt[i] - min_pt[i] < kEpsilonForSize) {
114 max_pt[i] = max_pt[i] + kEpsilonForSize / 2;
115 min_pt[i] = min_pt[i] - kEpsilonForSize / 2;
118 Eigen::Vector3f center((min_pt[0] + max_pt[0]) / 2,
119 (min_pt[1] + max_pt[1]) / 2,
120 (min_pt[2] + max_pt[2]) / 2);
121 object->center = Eigen::Vector3d(
static_cast<double>(center(0)),
122 static_cast<double>(center(1)),
123 static_cast<double>(center(2)));
124 float length = max_pt[0] - min_pt[0];
125 float width = max_pt[1] - min_pt[1];
126 float height = max_pt[2] - min_pt[2];
127 if (length < width) {
128 object->size = Eigen::Vector3f(width, length, height);
129 object->direction = Eigen::Vector3f(0.0, 1.0, 0.0);
131 object->size = Eigen::Vector3f(length, width, height);
132 object->direction = Eigen::Vector3f(1.0, 0.0, 0.0);
135 if (object->radar4d_supplement.cloud.size() < 4) {
136 object->polygon.resize(4);
137 object->polygon[0].x =
static_cast<double>(min_pt[0]);
138 object->polygon[0].y =
static_cast<double>(min_pt[1]);
139 object->polygon[0].z =
static_cast<double>(min_pt[2]);
141 object->polygon[1].x =
static_cast<double>(max_pt[0]);
142 object->polygon[1].y =
static_cast<double>(min_pt[1]);
143 object->polygon[1].z =
static_cast<double>(min_pt[2]);
145 object->polygon[2].x =
static_cast<double>(max_pt[0]);
146 object->polygon[2].y =
static_cast<double>(max_pt[1]);
147 object->polygon[2].z =
static_cast<double>(min_pt[2]);
149 object->polygon[3].x =
static_cast<double>(min_pt[0]);
150 object->polygon[3].y =
static_cast<double>(max_pt[1]);
151 object->polygon[3].z =
static_cast<double>(min_pt[2]);
156 if (cloud->size() >= 3) {
159 float diff_x = cloud->at(start_point).x - cloud->at(end_point).x;
160 float diff_y = cloud->at(start_point).y - cloud->at(end_point).y;
162 for (idx = 2; idx < cloud->size(); ++idx) {
163 float tdiff_x = cloud->at(idx).x - cloud->at(start_point).x;
164 float tdiff_y = cloud->at(idx).y - cloud->at(start_point).y;
165 if (fabs(diff_x * tdiff_y - tdiff_x * diff_y) > kEpsilonForLine) {
169 cloud->at(0).x += kEpsilonForLine;
170 cloud->at(1).y += kEpsilonForLine;
177 Eigen::Vector3f* min_pt,
178 Eigen::Vector3f* max_pt) {
179 (*min_pt)[0] = (*min_pt)[1] = (*min_pt)[2] =
180 std::numeric_limits<float>::max();
181 (*max_pt)[0] = (*max_pt)[1] = (*max_pt)[2] =
182 -std::numeric_limits<float>::max();
183 for (
size_t i = 0; i < cloud.size(); ++i) {
184 if (std::isnan(cloud[i].x) || std::isnan(cloud[i].y) ||
185 std::isnan(cloud[i].z)) {
188 (*min_pt)[0] = std::min((*min_pt)[0], cloud[i].x);
189 (*max_pt)[0] = std::max((*max_pt)[0], cloud[i].x);
190 (*min_pt)[1] = std::min((*min_pt)[1], cloud[i].y);
191 (*max_pt)[1] = std::max((*max_pt)[1], cloud[i].y);
192 (*min_pt)[2] = std::min((*min_pt)[2], cloud[i].z);
193 (*max_pt)[2] = std::max((*max_pt)[2], cloud[i].z);
bool GetConvexHull(const CLOUD_IN_TYPE &in_cloud, CLOUD_OUT_TYPE *out_polygon)
const RadarPointT * at(size_t col, size_t row) const
bool Init(const DetectorInitOptions &options=DetectorInitOptions())
Init the Object Builder object with initialization options
bool Build(const DetectorOptions &options, RadarFrame *frame)
Calculate and fill object size, center, directions.
uint32_t height
Height of point cloud
uint32_t width
Width of point cloud
void CalculateBBoxSizeCenter2DXY(const PointCloudT &cloud, const Eigen::Vector3f &dir, Eigen::Vector3f *size, Eigen::Vector3d *center, float minimum_edge_length=std::numeric_limits< float >::epsilon())
RadarPoint< double > RadarPointD
std::shared_ptr< apollo::perception::base::Object > ObjectPtr
apollo::perception::base::RadarPointCloud< RadarPointF > RadarPointFCloud
std::vector< std::shared_ptr< base::Object > > segmented_objects