Apollo 10.0
自动驾驶开放平台
object_template_manager.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2018 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
17
18#include <algorithm>
19#include <limits>
20#include <tuple>
21#include <utility>
22
23#include "cyber/common/file.h"
24#include "cyber/common/log.h"
27
28namespace {
29constexpr float kFloatEpsilon = std::numeric_limits<float>::epsilon();
30} // namespace
31
32namespace apollo {
33namespace perception {
34namespace camera {
35
36std::vector<base::ObjectSubType> kTypeCanBeRef = {base::ObjectSubType::CAR,
38
45
51
52ObjectTemplateManager::ObjectTemplateManager() {}
53
55 lib::MutexLock lock(&mutex_);
56 if (inited_) {
57 return true;
58 }
59
60 nr_dim_per_tmplt_ = 3;
61
62 std::string config_file = GetCommonConfigFile(FLAGS_object_template_file);
64 if (!cyber::common::GetProtoFromFile(config_file, &proto)) {
65 AERROR << "Read config failed: " << config_file;
66 return false;
67 }
68
69 ACHECK(proto.has_max_dim_change_ratio());
70
71 ACHECK(proto.has_unknown());
72 ACHECK(proto.has_unknown_movable());
73 ACHECK(proto.has_unknown_unmovable());
74 ACHECK(proto.has_car());
75 ACHECK(proto.has_van());
76 ACHECK(proto.has_truck());
77 ACHECK(proto.has_bus());
78 ACHECK(proto.has_cyclist());
79 ACHECK(proto.has_motorcyclist());
80 ACHECK(proto.has_tricyclist());
81 ACHECK(proto.has_pedestrian());
82 ACHECK(proto.has_trafficcone());
83
84 CHECK_LE(proto.car().dim_size(), 3);
85 CHECK_LE(proto.van().dim_size(), 3);
86 CHECK_LE(proto.truck().dim_size(), 3);
87 CHECK_LE(proto.bus().dim_size(), 3);
88 CHECK_LE(proto.cyclist().dim_size(), 3);
89 CHECK_LE(proto.motorcyclist().dim_size(), 3);
90 CHECK_LE(proto.tricyclist().dim_size(), 3);
91 CHECK_LE(proto.pedestrian().dim_size(), 3);
92 CHECK_LE(proto.trafficcone().dim_size(), 3);
93
94 ACHECK(proto.unknown().has_speed_limit());
95 ACHECK(proto.unknown_movable().has_speed_limit());
96 ACHECK(proto.unknown_unmovable().has_speed_limit());
97 ACHECK(proto.car().has_speed_limit());
98 ACHECK(proto.van().has_speed_limit());
99 ACHECK(proto.truck().has_speed_limit());
100 ACHECK(proto.bus().has_speed_limit());
101 ACHECK(proto.cyclist().has_speed_limit());
102 ACHECK(proto.motorcyclist().has_speed_limit());
103 ACHECK(proto.tricyclist().has_speed_limit());
104 ACHECK(proto.pedestrian().has_speed_limit());
105 ACHECK(proto.trafficcone().has_speed_limit());
106
107 max_dim_change_ratio_ = proto.max_dim_change_ratio();
108
109 total_nr_tmplts_veh_ = proto.car().dim_size() + proto.van().dim_size() +
110 proto.truck().dim_size() + proto.bus().dim_size();
111
112 look_up_table_min_volume_index_.clear();
113 veh_hwl_.resize(0);
114 look_up_table_min_volume_index_[TemplateIndex::CAR_MIN_VOLUME_INDEX] =
115 static_cast<int>(veh_hwl_.size());
116 LoadVehTemplates(proto.car());
117 look_up_table_min_volume_index_[TemplateIndex::VAN_MIN_VOLUME_INDEX] =
118 static_cast<int>(veh_hwl_.size());
119 LoadVehTemplates(proto.van());
120 look_up_table_min_volume_index_[TemplateIndex::TRUCK_MIN_VOLUME_INDEX] =
121 static_cast<int>(veh_hwl_.size());
122 LoadVehTemplates(proto.truck());
123 look_up_table_min_volume_index_[TemplateIndex::BUS_MIN_VOLUME_INDEX] =
124 static_cast<int>(veh_hwl_.size());
125 LoadVehTemplates(proto.bus());
126
127 min_template_hwl_.clear();
128 mid_template_hwl_.clear();
129 max_template_hwl_.clear();
130 LoadVehMinMidMaxTemplates(base::ObjectSubType::CAR, proto.car());
131 LoadVehMinMidMaxTemplates(base::ObjectSubType::VAN, proto.van());
132 LoadVehMinMidMaxTemplates(base::ObjectSubType::TRUCK, proto.truck());
133 LoadVehMinMidMaxTemplates(base::ObjectSubType::BUS, proto.bus());
134 LoadVehMinMidMaxTemplates(base::ObjectSubType::CYCLIST, proto.cyclist());
135 LoadVehMinMidMaxTemplates(base::ObjectSubType::MOTORCYCLIST,
136 proto.motorcyclist());
137 LoadVehMinMidMaxTemplates(base::ObjectSubType::TRICYCLIST,
138 proto.tricyclist());
139 LoadVehMinMidMaxTemplates(base::ObjectSubType::PEDESTRIAN,
140 proto.pedestrian());
141 LoadVehMinMidMaxTemplates(base::ObjectSubType::TRAFFICCONE,
142 proto.trafficcone());
143
144 template_hwl_.resize(0);
145 template_hwl_.push_back(min_template_hwl_);
146 template_hwl_.push_back(mid_template_hwl_);
147 template_hwl_.push_back(max_template_hwl_);
148
149 type_speed_limit_.clear();
150 type_speed_limit_[base::ObjectSubType::UNKNOWN] =
151 proto.unknown().speed_limit();
152 type_speed_limit_[base::ObjectSubType::UNKNOWN_MOVABLE] =
154 type_speed_limit_[base::ObjectSubType::UNKNOWN_UNMOVABLE] =
156 type_speed_limit_[base::ObjectSubType::CAR] = proto.car().speed_limit();
157 type_speed_limit_[base::ObjectSubType::VAN] = proto.van().speed_limit();
158 type_speed_limit_[base::ObjectSubType::TRUCK] = proto.truck().speed_limit();
159 type_speed_limit_[base::ObjectSubType::BUS] = proto.bus().speed_limit();
160 type_speed_limit_[base::ObjectSubType::CYCLIST] =
161 proto.cyclist().speed_limit();
162 type_speed_limit_[base::ObjectSubType::MOTORCYCLIST] =
163 proto.motorcyclist().speed_limit();
164 type_speed_limit_[base::ObjectSubType::TRICYCLIST] =
165 proto.tricyclist().speed_limit();
166 type_speed_limit_[base::ObjectSubType::PEDESTRIAN] =
167 proto.pedestrian().speed_limit();
168 type_speed_limit_[base::ObjectSubType::TRAFFICCONE] =
169 proto.trafficcone().speed_limit();
170
171 type_can_be_ref_ = kTypeCanBeRef;
172 type_refined_by_template_ = kTypeRefinedByTemplate;
173 type_refined_by_ref_ = kTypeRefinedByRef;
174
175 inited_ = true;
176 AINFO << "Init object_template_manager success.";
177 return true;
178}
179
180void ObjectTemplateManager::LoadVehTemplates(const ObjectTemplate &tmplt) {
181 std::vector<std::tuple<float, float, float>> list_tpl;
182 list_tpl.resize(0);
183 for (int i = 0; i < tmplt.dim_size(); ++i) {
184 Dim dim = tmplt.dim(i);
185 list_tpl.push_back(std::make_tuple(dim.h(), dim.w(), dim.l()));
186 }
187 std::sort(list_tpl.begin(), list_tpl.end());
188 for (size_t i = 0; i < list_tpl.size(); ++i) {
189 veh_hwl_.push_back(std::get<0>(list_tpl[i]));
190 veh_hwl_.push_back(std::get<1>(list_tpl[i]));
191 veh_hwl_.push_back(std::get<2>(list_tpl[i]));
192 }
193}
194
195void ObjectTemplateManager::LoadVehMinMidMaxTemplates(
196 const base::ObjectSubType &type, const ObjectTemplate &tmplt) {
197 std::vector<std::tuple<float, float, float>> list_tpl;
198 list_tpl.resize(0);
199 for (int i = 0; i < tmplt.dim_size(); ++i) {
200 Dim dim = tmplt.dim(i);
201 list_tpl.push_back(std::make_tuple(dim.h(), dim.w(), dim.l()));
202 }
203
204 std::sort(list_tpl.begin(), list_tpl.end());
205
206 int ind_min = 0;
207 int ind_max = static_cast<int>(list_tpl.size()) - 1;
208 int ind_mid = (ind_min + ind_max) / 2;
209 std::vector<float> tmplt_min = {std::get<0>(list_tpl[ind_min]),
210 std::get<1>(list_tpl[ind_min]),
211 std::get<2>(list_tpl[ind_min])};
212 std::vector<float> tmplt_mid = {std::get<0>(list_tpl[ind_mid]),
213 std::get<1>(list_tpl[ind_mid]),
214 std::get<2>(list_tpl[ind_mid])};
215 std::vector<float> tmplt_max = {std::get<0>(list_tpl[ind_max]),
216 std::get<1>(list_tpl[ind_max]),
217 std::get<2>(list_tpl[ind_max])};
218 min_template_hwl_[type] = tmplt_min;
219 mid_template_hwl_[type] = tmplt_mid;
220 max_template_hwl_[type] = tmplt_max;
221}
222
223// util for tmplt search
224float ObjectTemplateManager::Get3dDimensionSimilarity(const float *hwl1,
225 const float *hwl2) {
226 ACHECK(hwl1 != nullptr);
227 ACHECK(hwl2 != nullptr);
228
229 float max_h = std::max(hwl1[0], hwl2[0]);
230 float min_h = hwl1[0] + hwl2[0] - max_h;
231 float max_w = std::max(hwl1[1], hwl2[1]);
232 float min_w = hwl1[1] + hwl2[1] - max_w;
233 float max_l = std::max(hwl1[2], hwl2[2]);
234 float min_l = hwl1[2] + hwl2[2] - max_l;
235
236 float iou_h = min_h / (kFloatEpsilon + max_h);
237 float iou_w = min_w / (kFloatEpsilon + max_w);
238 float iou_l = min_l / (kFloatEpsilon + max_l);
239
240 return iou_h * iou_h * iou_w * iou_l; // h^2 * w * l
241}
242
243// for general visual obj
245 bool *is_flip) {
246 ACHECK(inited_);
247 ACHECK(hwl != nullptr);
248
249 float hwl_flip[3] = {hwl[0], hwl[2], hwl[1]};
250 float score_best = -std::numeric_limits<float>::max();
251 int i_best = -1;
252 int i3 = 0;
253 bool from_flip = false;
254 for (int i = 0; i < total_nr_tmplts_veh_; ++i) {
255 float score = Get3dDimensionSimilarity(hwl, &veh_hwl_[i3]);
256 float score_flip = Get3dDimensionSimilarity(hwl_flip, &veh_hwl_[i3]);
257 bool from_flip_cur = false;
258 if (score_flip > score) {
259 score = score_flip;
260 from_flip_cur = true;
261 }
262 if (score > score_best) {
263 score_best = score;
264 i_best = i;
265 from_flip = from_flip_cur;
266 }
267 i3 += 3;
268 }
269 int i_best_by_3 = i_best * 3;
270 float hwl_tmplt_matched[3] = {veh_hwl_[i_best_by_3],
271 veh_hwl_[i_best_by_3 + 1],
272 veh_hwl_[i_best_by_3 + 2]};
273 if (from_flip) {
274 std::swap(hwl_tmplt_matched[1], hwl_tmplt_matched[2]);
275 }
276
277 float dh = fabsf(hwl[0] - hwl_tmplt_matched[0]);
278 float dh_ratio = dh / hwl_tmplt_matched[0];
279 float dw = fabsf(hwl[1] - hwl_tmplt_matched[1]);
280 float dw_ratio = dw / hwl_tmplt_matched[1];
281 float dl = fabsf(hwl[2] - hwl_tmplt_matched[2]);
282 float dl_ratio = dl / hwl_tmplt_matched[2];
283 float dh_dw_dl_ratio_mean = (dh_ratio + dw_ratio + dl_ratio) / 3;
284 float dh_ratio_check = std::min(dh_ratio, dh_dw_dl_ratio_mean);
285 if (score_best < kFloatEpsilon || dh_ratio_check > max_dim_change_ratio_) {
286 return -1.0f;
287 }
288 ADEBUG << dh_ratio << ", " << dw_ratio << ", " << dl_ratio;
289
290 hwl[0] = veh_hwl_[i_best_by_3];
291 hwl[1] = veh_hwl_[i_best_by_3 + 1];
292 hwl[2] = veh_hwl_[i_best_by_3 + 2];
293 if (index != nullptr) {
294 *index = i_best;
295 }
296 if (is_flip != nullptr) {
297 *is_flip = from_flip;
298 }
299 return score_best;
300}
301
302} // namespace camera
303} // namespace perception
304} // namespace apollo
float VehObjHwlBySearchTemplates(float *hwl, int *index=nullptr, bool *is_flip=nullptr)
#define ACHECK(cond)
Definition log.h:80
#define ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
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,...
Definition file.cc:132
std::vector< base::ObjectSubType > kTypeRefinedByTemplate
std::vector< base::ObjectSubType > kTypeCanBeRef
std::vector< base::ObjectSubType > kTypeRefinedByRef
std::string GetCommonConfigFile(const std::string &config_file)
Get the perception common config path
Definition util.cc:28
constexpr float kFloatEpsilon
Definition lane_object.h:32
class register implement
Definition arena_queue.h:37