41 std::string config_file =
45 AERROR <<
"Read config failed: " << config_file;
48 AINFO <<
"Load transformer parameters from " << config_file
55void SingleStageTransformer::FillResults(
56 float object_center[3],
float dimension_hwl[3],
float rotation_y,
57 const Eigen::Affine3d &camera2world_pose,
float theta_ray,
62 object_center[1] -= dimension_hwl[0] / 2;
63 obj->camera_supplement.local_center(0) = object_center[0];
64 obj->camera_supplement.local_center(1) = object_center[1];
65 obj->camera_supplement.local_center(2) = object_center[2];
66 ADEBUG <<
"Obj id: " << obj->track_id;
67 ADEBUG <<
"Obj type: " <<
static_cast<int>(obj->sub_type);
68 ADEBUG <<
"Obj ori dimension: " << obj->size[2] <<
", " << obj->size[1]
69 <<
", " << obj->size[0];
70 obj->center(0) =
static_cast<double>(object_center[0]);
71 obj->center(1) =
static_cast<double>(object_center[1]);
72 obj->center(2) =
static_cast<double>(object_center[2]);
73 obj->center = camera2world_pose * obj->center;
75 obj->size(2) = dimension_hwl[0];
76 obj->size(1) = dimension_hwl[1];
77 obj->size(0) = dimension_hwl[2];
79 obj->center_uncertainty(0) =
static_cast<float>(0);
80 obj->center_uncertainty(1) =
static_cast<float>(0);
81 obj->center_uncertainty(2) =
static_cast<float>(0);
83 float theta = rotation_y;
84 Eigen::Vector3d dir = (camera2world_pose.matrix().block(0, 0, 3, 3) *
85 Eigen::Vector3d(cos(theta), 0, -sin(theta)));
86 obj->direction[0] =
static_cast<float>(dir[0]);
87 obj->direction[1] =
static_cast<float>(dir[1]);
88 obj->direction[2] =
static_cast<float>(dir[2]);
89 obj->theta =
static_cast<float>(atan2(dir[1], dir[0]));
90 obj->theta_variance =
static_cast<float>(1.0);
92 obj->camera_supplement.alpha = rotation_y - theta_ray;
94 ADEBUG <<
"Dimension hwl: " << dimension_hwl[0] <<
", " << dimension_hwl[1]
95 <<
", " << dimension_hwl[2];
96 ADEBUG <<
"Obj ry:" << rotation_y;
97 ADEBUG <<
"Obj theta: " << obj->theta;
98 ADEBUG <<
"Obj center from transformer: " << obj->center.transpose();
103 ADEBUG <<
"No object input to transformer.";
108 float k_mat[9] = {0};
109 for (
size_t i = 0; i < 3; i++) {
111 for (
size_t j = 0; j < 3; j++) {
112 k_mat[i3 + j] = camera_k_matrix(i, j);
115 ADEBUG <<
"Camera k matrix input to transformer: \n"
116 << k_mat[0] <<
", " << k_mat[1] <<
", " << k_mat[2] <<
"\n"
117 << k_mat[3] <<
", " << k_mat[4] <<
", " << k_mat[5] <<
"\n"
118 << k_mat[6] <<
", " << k_mat[7] <<
", " << k_mat[8] <<
"\n";
123 int nr_transformed_obj = 0;
126 if (obj ==
nullptr) {
127 ADEBUG <<
"Empty object input to transformer.";
132 float theta_ray = atan2(obj->camera_supplement.local_center[0],
133 obj->camera_supplement.local_center[2]);
136 float object_center[3] = {obj->camera_supplement.local_center[0],
137 obj->camera_supplement.local_center[1],
138 obj->camera_supplement.local_center[2]};
139 float dimension_hwl[3] = {obj->size(2), obj->size(1), obj->size(0)};
141 theta_ray +
static_cast<float>(obj->camera_supplement.alpha);
142 if (rotation_y < -
PI) {
143 rotation_y += 2 *
PI;
144 }
else if (rotation_y >=
PI) {
145 rotation_y -= 2 *
PI;
150 bbox[0] = obj->camera_supplement.box.xmin;
151 bbox[1] = obj->camera_supplement.box.ymin;
152 bbox[2] = obj->camera_supplement.box.xmax;
153 bbox[3] = obj->camera_supplement.box.ymax;
154 float center2d[3] = {0};
156 CenterPointFromBbox(bbox, dimension_hwl, rotation_y, object_center,
157 center2d, k_mat, height, width);
159 FillResults(object_center, dimension_hwl, rotation_y, camera2world_pose,
162 ++nr_transformed_obj;
164 return nr_transformed_obj > 0;
167float SingleStageTransformer::CenterPointFromBbox(
168 const float *bbox,
const float *hwl,
float ry,
float *center,
169 float *center_2d,
const float *k_mat,
int height,
int width) {
170 float height_bbox = bbox[3] - bbox[1];
171 float width_bbox = bbox[2] - bbox[0];
172 if (width_bbox <= 0.0f || height_bbox <= 0.0f) {
173 AERROR <<
"Check predict bounding box, width or height is 0";
177 float f = (k_mat[0] + k_mat[4]) / 2;
182 float theta_bbox =
static_cast<float>(atan(hwl[1] *
algorithm::IRec(hwl[2])));
186 float abs_ry = fabsf(ry);
187 float theta_z = std::min(abs_ry,
PI - abs_ry) + theta_bbox;
188 theta_z = std::min(theta_z,
PI - theta_z);
189 depth +=
static_cast<float>(fabs(radius_bbox * sin(theta_z)));
192 float location[3] = {center[0], center[1] - hwl[0] / 2, center[2]};
197 ConstraintCenterPoint(bbox, center[2], ry, hwl, k_mat, center, center_2d,
203void SingleStageTransformer::ConstraintCenterPoint(
204 const float *bbox,
const float &z_ref,
const float &ry,
const float *hwl,
205 const float *k_mat,
float *center,
float *x,
int height,
int width) {
206 float center_2d_target[2] = {(bbox[0] + bbox[2]) / 2,
207 (bbox[1] + bbox[3]) / 2};
209 const float EPS_COST_DELTA = params_.
eps_cost;
213 float cost_pre = 2.0f *
static_cast<float>(
width);
214 float cost_delta = 0.0f;
215 float center_temp[3] = {0};
216 float rot_y[9] = {0};
231 float x_corners[8] = {0};
232 float y_corners[8] = {0};
233 float z_corners[8] = {0};
235 float x_upper_bound =
static_cast<float>(
width - 1);
236 float y_upper_bound =
static_cast<float>(
height - 1);
244 GenCorners(h, w, l, x_corners, y_corners, z_corners);
249 center_temp[1] += hwl[0] / 2;
250 float x_min = std::numeric_limits<float>::max();
251 float x_max = -std::numeric_limits<float>::max();
252 float y_min = std::numeric_limits<float>::max();
253 float y_max = -std::numeric_limits<float>::max();
254 float x_images[3] = {0};
256 for (
int i = 0; i < 8; ++i) {
258 float x_box[3] = {x_corners[i], y_corners[i], z_corners[i]};
262 x_min = std::min(x_min, x_images[0]);
263 x_max = std::max(x_max, x_images[0]);
264 y_min = std::min(y_min, x_images[1]);
265 y_max = std::max(y_max, x_images[1]);
269 x_min = std::min(std::max(x_min, 0.0f), x_upper_bound);
270 x_max = std::min(std::max(x_max, 0.0f), x_upper_bound);
271 y_min = std::min(std::max(y_min, 0.0f), y_upper_bound);
272 y_max = std::min(std::max(y_max, 0.0f), y_upper_bound);
276 float center_cur[2] = {(x_min + x_max) / 2, (y_min + y_max) / 2};
282 if (cost_cur >= cost_pre) {
285 memcpy(center, center_temp,
sizeof(
float) * 3);
286 cost_delta = (cost_pre - cost_cur) / cost_pre;
289 x[0] += (center_2d_target[0] - center_cur[0]) * LEARNING_RATE;
290 x[1] += (center_2d_target[1] - center_cur[1]) * LEARNING_RATE;
293 stop = iter >= MAX_ITERATION || cost_delta < EPS_COST_DELTA ||
294 cost_pre < K_MIN_COST;
bool GetProtoFromFile(const std::string &file_name, google::protobuf::Message *message)
Parses the content of the file specified by the file_name as a representation of protobufs,...
uint32_t height
Height of point cloud
uint32_t width
Width of point cloud
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 IProjectThroughIntrinsic(const T *K, const T *X, T *x)
std::shared_ptr< Object > ObjectPtr
void GenCorners(T h, T w, T l, T *x_cor, T *y_cor, T *z_cor)
void GenRotMatrix(const T &ry, T *rot)
std::string GetConfigFile(const std::string &config_path, const std::string &config_file)
optional float min_dimension_val
optional bool check_dimension
std::vector< base::ObjectPtr > detected_objects
Eigen::Matrix3f camera_k_matrix
Eigen::Affine3d camera2world_pose
std::shared_ptr< camera::DataProvider > data_provider