48bool ObjMapper::SolveCenterFromNearestVerticalEdge(
const float *bbox,
49 const float *hwl,
float ry,
51 float *center_2d)
const {
52 center[0] = center[1] = center[2] = 0.0f;
53 float height_bbox = bbox[3] - bbox[1];
54 float width_bbox = bbox[2] - bbox[0];
55 if (width_bbox <= 0.0f || height_bbox <= 0.0f) {
56 AERROR <<
"width or height of bbox is 0";
64 float f = (k_mat_[0] + k_mat_[4]) / 2;
68 const float PI = algorithm::Constant<float>::PI();
69 float theta_bbox =
static_cast<float>(atan(hwl[1] *
algorithm::IRec(hwl[2])));
73 float abs_ry = fabsf(ry);
74 float theta_z = std::min(abs_ry,
PI - abs_ry) + theta_bbox;
75 theta_z = std::min(theta_z,
PI - theta_z);
76 depth +=
static_cast<float>(fabs(radius_bbox * sin(theta_z)));
79 center_2d[0] = (bbox[0] + bbox[2]) / 2;
80 center_2d[1] = (bbox[1] + bbox[3]) / 2;
82 GetCenter(bbox, depth, ry, hwl, center, center_2d);
85 UpdateCenterViaBackProjectZ(bbox, hwl, center_2d, center);
91bool ObjMapper::Solve3dBboxGivenOneFullBboxDimensionOrientation(
92 const float *bbox,
const float *hwl,
float *ry,
float *center) {
93 const float PI = algorithm::Constant<float>::PI();
94 const float PI_HALF =
PI / 2;
95 const float small_angle_diff =
97 float center_2d[2] = {0};
99 SolveCenterFromNearestVerticalEdge(bbox, hwl, *ry, center, center_2d);
102 float max_x =
static_cast<float>(width_ - params_.
boundary_len);
103 float max_y =
static_cast<float>(height_ - params_.
boundary_len);
104 bool truncated = bbox[0] <= min_x || bbox[2] >= max_x || bbox[1] <= min_y ||
108 bool ry_pred_is_not_reliable = dist_rough > params_.
dist_far &&
110 if (ry_pred_is_not_reliable || std::abs(*ry - PI_HALF) < small_angle_diff ||
111 std::abs(*ry + PI_HALF) < small_angle_diff) {
112 *ry = *ry > 0.0f ? PI_HALF : -PI_HALF;
115 PostRefineOrientation(bbox, hwl, center, ry);
117 SolveCenterFromNearestVerticalEdge(bbox, hwl, *ry, center, center_2d);
118 PostRefineZ(bbox, hwl, center_2d, *ry, center);
120 FillRyScoreSingleBin(*ry);
123 GetProjectionScore(*ry, bbox, hwl, center,
true) > params_.
iou_suc;
127 float hwl[3],
float *ry) {
130 float var_yaw = 0.0f;
134 memcpy(hwl, options.
hwl,
sizeof(
float) * 3);
136 memcpy(bbox, options.
bbox,
sizeof(
float) * 4);
142 if (options.
is_veh && check_dimension) {
143 assert(type_min_vol_index >= 0);
145 const float *tmplt_with_min_vol = &kVehHwl[type_min_vol_index];
146 float min_tmplt_vol =
147 tmplt_with_min_vol[0] * tmplt_with_min_vol[1] * tmplt_with_min_vol[2];
149 shrink_ratio_vol *= shrink_ratio_vol;
152 hwl[0] * hwl[1] * hwl[2] < min_tmplt_vol * shrink_ratio_vol) {
153 memcpy(hwl, tmplt_with_min_vol,
sizeof(
float) * 3);
155 float hwl_tmplt[3] = {hwl[0], hwl[1], hwl[2]};
156 int tmplt_index = -1;
158 hwl_tmplt, &tmplt_index);
159 float thres_min_score = shrink_ratio_vol;
162 bool search_success = score > thres_min_score;
163 bool is_same_type = (type_min_vol_index / kNrDimPerTmplt) == tmplt_index;
164 const std::map<TemplateIndex, int> &kLookUpTableMinVolumeIndex =
167 type_min_vol_index ==
170 bool hwl_is_reliable = search_success && is_same_type;
171 if (hwl_is_reliable) {
172 memcpy(hwl, hwl_tmplt,
sizeof(
float) * 3);
173 }
else if (is_car_pred) {
174 const float *tmplt_with_median_vol =
175 tmplt_with_min_vol + kNrDimPerTmplt;
176 memcpy(hwl, tmplt_with_median_vol,
sizeof(
float) * 3);
183 Solve3dBboxGivenOneFullBboxDimensionOrientation(bbox, hwl, ry, center);
186 float yaw_score_mean =
188 float yaw_score_sdv =
algorithm::ISdv(ry_score_.data(), yaw_score_mean,
189 static_cast<int>(ry_score_.size()));
195 float nr_bins_z =
static_cast<float>(params_.
nr_bins_z);
196 std::vector<float> buffer(
static_cast<size_t>(2 * nr_bins_z), 0);
197 float *score_z = buffer.data();
198 float dz = 2 * rz / nr_bins_z;
199 float z_start = std::max(z - rz, params_.
depth_min);
200 float z_end = z + rz;
201 int count_z_test = 0;
202 for (
float z_test = z_start; z_test <= z_end; z_test += dz) {
203 float center_test[3] = {center[0], center[1], center[2]};
206 float score_test = GetProjectionScore(*ry, bbox, hwl, center_test);
207 score_z[count_z_test++] = score_test;
210 float z_score_sdv =
algorithm::ISdv(score_z, z_score_mean, count_z_test);
214 orientation_variance_(0) = var_yaw;
215 float bbox_cx = (bbox[0] + bbox[2]) / 2;
216 float focal = (k_mat_[0] + k_mat_[4]) / 2;
219 float var_xz = sf_z_to_x * var_z;
220 position_uncertainty_(0, 0) = var_x;
221 position_uncertainty_(2, 2) = var_z;
222 position_uncertainty_(0, 2) = position_uncertainty_(2, 0) = var_xz;
226void ObjMapper::PostRefineOrientation(
const float *bbox,
const float *hwl,
227 const float *center,
float *ry) {
228 const int kNrBinsRy =
static_cast<int>(ry_score_.size());
230 const float PI_HALF =
PI * 0.5f;
231 const float D_RY = 2 *
PI /
static_cast<float>(kNrBinsRy);
235 float score_best = 0.0f;
236 float score_cur = GetProjectionScore(*ry, bbox, hwl, center,
true);
241 ry_score_[count_bin++ % kNrBinsRy] = 0.0f;
245 float score_test = GetProjectionScore(ry_test, bbox, hwl, center,
true);
246 if (score_test > score_best) {
247 score_best = score_test;
251 ry_score_[count_bin++ % kNrBinsRy] = score_test;
258 float bbox_res[4] = {0};
260 GetProjectionScore(*ry, bbox, hwl, center,
true, bbox_res);
261 if (score_final > params_.
iou_high) {
263 }
else if (bbox[2] - bbox[0] <
265 *ry = *ry > 0 ? PI_HALF : -PI_HALF;
266 FillRyScoreSingleBin(*ry);
268 bbox_res[2] - bbox_res[0]) {
270 FillRyScoreSingleBin(*ry);
274void ObjMapper::GetCenter(
const float *bbox,
const float &z_ref,
275 const float &ry,
const float *hwl,
float *center,
277 float x_target[2] = {(bbox[0] + bbox[2]) / 2, (bbox[1] + bbox[3]) / 2};
279 const float EPS_COST_DELTA = params_.
eps_mapper;
283 float cost_pre = 2.0f *
static_cast<float>(width_);
284 float cost_delta = 0.0f;
285 float center_test[3] = {0};
293 float x_corners[8] = {0};
294 float y_corners[8] = {0};
295 float z_corners[8] = {0};
296 GenCorners(h, w, l, x_corners, y_corners, z_corners);
298 float x_max_flt =
static_cast<float>(width_ - 1);
299 float y_max_flt =
static_cast<float>(height_ - 1);
304 center_test[1] += hwl[0] / 2;
305 float x_min = std::numeric_limits<float>::max();
306 float x_max = -std::numeric_limits<float>::max();
307 float y_min = std::numeric_limits<float>::max();
308 float y_max = -std::numeric_limits<float>::max();
309 float x_proj[3] = {0};
311 for (
int i = 0; i < 8; ++i) {
313 float x_box[3] = {x_corners[i], y_corners[i], z_corners[i]};
317 x_min = std::min(x_min, x_proj[0]);
318 x_max = std::max(x_max, x_proj[0]);
319 y_min = std::min(y_min, x_proj[1]);
320 y_max = std::max(y_max, x_proj[1]);
323 x_min = std::min(std::max(x_min, 0.0f), x_max_flt);
324 x_max = std::min(std::max(x_max, 0.0f), x_max_flt);
325 y_min = std::min(std::max(y_min, 0.0f), y_max_flt);
326 y_max = std::min(std::max(y_max, 0.0f), y_max_flt);
328 float x_cur[2] = {(x_min + x_max) / 2, (y_min + y_max) / 2};
332 if (cost_cur >= cost_pre) {
335 memcpy(center, center_test,
sizeof(
float) * 3);
336 cost_delta = (cost_pre - cost_cur) / cost_pre;
338 x[0] += (x_target[0] - x_cur[0]) * LR;
339 x[1] += (x_target[1] - x_cur[1]) * LR;
341 stop = iter >= MAX_ITERATION || cost_delta < EPS_COST_DELTA ||
void set_default_variance()
Set the default variance object
ObjectTemplateManager * object_template_manager_
bool Solve3dBbox(const ObjMapperOptions &options, float center[3], float hwl[3], float *ry)
Calculate 3d result
const std::map< TemplateIndex, int > & LookUpTableMinVolumeIndex()
const int NrDimPerTmplt()
float VehObjHwlBySearchTemplates(float *hwl, int *index=nullptr, bool *is_flip=nullptr)
const std::vector< float > & VehHwl()
float IDegreeToRadians(float d)
T IMean(const T *x, int n)
void IUnitize(double *x, int n)
T ISdv(const T *x, T mean, int n)
void IProjectThroughKRt(const T *K, const T *R, const T *t, const T *X, T *x)
void IBackprojectCanonical(const T *x, const T *K, T depth, T *X)
void IScale3(T x[3], T sf)
void GenCorners(T h, T w, T l, T *x_cor, T *y_cor, T *z_cor)
void GenRotMatrix(const T &ry, T *rot)
T CalAngleDiff(const T a1, const T a2)
float angle_resolution_degree