146 {
151 const std::vector<TemplateMap> &kTemplateHWL =
153
154 for (auto &obj : frame->detected_objects) {
155 float volume_object = obj->size[0] * obj->size[1] * obj->size[2];
156 ADEBUG <<
"Det " << frame->frame_id <<
" (" << obj->id <<
") "
157 << "ori size:" << obj->size.transpose() << " "
158 << "type: " << static_cast<int>(obj->sub_type) << " "
159 << volume_object << " " << frame->data_provider->sensor_name();
160 base::CameraObjectSupplement &supplement = obj->camera_supplement;
161
163 obj->sub_type)) {
164 float min_template_volume = 0.0f;
165 float max_template_volume = 0.0f;
166 auto min_tmplt = kMinTemplateHWL.at(obj->sub_type);
167 auto max_tmplt = kMaxTemplateHWL.at(obj->sub_type);
168 min_template_volume = min_tmplt[0] * min_tmplt[1] * min_tmplt[2];
169 max_template_volume = max_tmplt[0] * max_tmplt[1] * max_tmplt[2];
170 if (volume_object < min_template_volume ||
172 obj->size[0] = min_tmplt[2];
173 obj->size[1] = min_tmplt[1];
174 obj->size[2] = min_tmplt[0];
175 } else if (volume_object > max_template_volume ||
176 obj->size[2] >
178 obj->size[0] = max_tmplt[2];
179 obj->size[1] = max_tmplt[1];
180 obj->size[2] = max_tmplt[0];
181 }
182 }
183
185 std::string sensor = frame->data_provider->sensor_name();
186 std::vector<float>
height;
187
188 double z_obj = frame->camera_k_matrix(1, 1) * obj->size[2] /
189 (supplement.box.ymax - supplement.box.ymin);
190
191
192 SyncGroundEstimator(sensor, frame->camera_k_matrix,
193 static_cast<int>(img_width_),
194 static_cast<int>(img_height_));
195 auto &ground_estimator = ground_estimator_mapper_[sensor];
196 float l[3] = {0};
197 if (ground_estimator.GetGroundModel(l)) {
198 double z_ground_reversed =
201 z_ground = std::max(z_ground, z_obj);
202 float k2 = static_cast<float>(z_ground / frame->camera_k_matrix(1, 1));
203 float h = k2 * (supplement.box.ymax - supplement.box.ymin);
204 h = std::max(std::min(h, kMaxTemplateHWL.at(obj->sub_type).at(0)),
205 kMinTemplateHWL.at(obj->sub_type).at(0));
207 }
208
209
210 if (frame->calibration_service != nullptr) {
211 double z_calib = 0.0;
212 bool success = frame->calibration_service->QueryDepthOnGroundPlane(
213 static_cast<int>(supplement.box.Center().x),
214 static_cast<int>(supplement.box.ymax), &z_calib);
215 if (success) {
216 z_calib = std::max(z_calib, z_obj);
217 float k2 = static_cast<float>(z_calib / frame->camera_k_matrix(1, 1));
218 float h = k2 * (supplement.box.ymax - supplement.box.ymin);
219 h = std::max(std::min(h, kMaxTemplateHWL.at(obj->sub_type).at(0)),
220 kMinTemplateHWL.at(obj->sub_type).at(0));
222 } else {
223 height.push_back(kMaxTemplateHWL.at(obj->sub_type).at(0));
224 }
225 Eigen::Vector4d plane_param;
226
227
228 }
229
230
232 float cy = frame->camera_k_matrix(1, 2);
233 cy = std::min(supplement.box.ymax - 1, cy);
234 for (auto &&reference : reference_[sensor]) {
235
236 float dy = std::abs(reference.ymax - supplement.box.ymax);
237 float scale_y = (supplement.box.ymax - cy) / (img_height_ - cy);
238 float thres_dy =
239 std::max(
static_cast<float>(ref_param_.
down_sampling()) * scale_y,
240 static_cast<float>(ref_param_.
margin()) * 2.0f);
241 if (dy < thres_dy) {
242 float k2 = reference.k;
243 k2 *= (reference.ymax - cy) / (supplement.box.ymax - cy);
244 float h = k2 * (supplement.box.ymax - supplement.box.ymin);
245
246 h = std::max(std::min(h, kMaxTemplateHWL.at(obj->sub_type).at(0)),
247 kMinTemplateHWL.at(obj->sub_type).at(0));
249 }
250 }
251 height.push_back(obj->size[2]);
252 }
253
255 AERROR <<
"height vector is empty";
256 continue;
257 }
259 int nr_hs =
static_cast<int>(
height.size());
260 float h_updated =
height[nr_hs / 2];
261 AINFO <<
"Estimate " << h_updated <<
" with " <<
height.size();
262 obj->size[2] =
263 std::min(h_updated, kMaxTemplateHWL.at(obj->sub_type).at(0));
264 obj->size[2] =
265 std::max(obj->size[2], kMinTemplateHWL.at(obj->sub_type).at(0));
266 std::vector<float> height_error(kTemplateHWL.size(), 0);
267
268 float obj_h = obj->size[2];
269 for (size_t i = 0; i < height_error.size(); ++i) {
270 height_error[i] =
271 std::abs(kTemplateHWL[i].at(obj->sub_type).at(0) - obj_h);
272 }
273 auto min_error =
274 std::min_element(height_error.begin(), height_error.end());
275 auto min_index = std::distance(height_error.begin(), min_error);
276 auto &tmplt = kTemplateHWL.at(min_index).at(obj->sub_type);
277 float scale_factor = obj->size[2] / tmplt[0];
278 obj->size[1] = tmplt[1] * scale_factor;
279 obj->size[0] = tmplt[2] * scale_factor;
280 }
281 ADEBUG <<
"correct size:" << obj->size.transpose();
282 }
283}
const std::vector< base::ObjectSubType > & TypeRefinedByTemplate()
const TemplateMap & MinTemplateHWL()
const std::vector< TemplateMap > & TemplateHWL()
const TemplateMap & MaxTemplateHWL()
const std::vector< base::ObjectSubType > & TypeRefinedByRef()
ObjectTemplateManager * object_template_manager_
uint32_t height
Height of point cloud
bool Contain(const std::vector< T > &array, const T &element)
std::map< base::ObjectSubType, std::vector< float > > TemplateMap
optional int32 down_sampling
optional float height_diff_ratio