@@ -82,8 +82,8 @@ struct Identifier::Impl {
8282 const auto y = result.green_light ->y ;
8383
8484 const auto pred = [=](const Armor2d& armor) {
85- const auto is_building
86- = (armor.genre == ArmorGenre::OUTPOST ) || (armor.genre == ArmorGenre::BASE );
85+ const auto is_building =
86+ (armor.genre == ArmorGenre::OUTPOST ) || (armor.genre == ArmorGenre::BASE );
8787 return is_building && armor.bl .y < 1 . * y;
8888 };
8989 std::erase_if (detected, pred);
@@ -92,12 +92,8 @@ struct Identifier::Impl {
9292
9393 // 邻侧灯条:单装甲板机器人 → 扩展 ROI + 识别
9494 {
95- constexpr auto kHorizontalCoeff = 2.5 ;
96- constexpr auto kVerticalConstant = 40 ;
97- constexpr auto kGap = 10 ;
98-
99- const auto & mat = src.details ().mat ;
100- const auto image_bounds = cv::Rect2i { 0 , 0 , mat.cols , mat.rows };
95+ const auto & mat = src.details ().mat ;
96+ const auto bounds = cv::Rect2i { 0 , 0 , mat.cols , mat.rows };
10197
10298 for (const auto & [genre, armors] : robots) {
10399 if (armors.size () != 1 ) continue ;
@@ -107,64 +103,76 @@ struct Identifier::Impl {
107103 const auto max_x = std::max ({ armor.tl .x , armor.tr .x , armor.br .x , armor.bl .x });
108104 const auto min_y = std::min ({ armor.tl .y , armor.tr .y , armor.br .y , armor.bl .y });
109105 const auto max_y = std::max ({ armor.tl .y , armor.tr .y , armor.br .y , armor.bl .y });
110- const auto width = std::abs (armor.tr .x - armor.tl .x );
111106
112- const auto h_extend = static_cast <int >(width * kHorizontalCoeff );
113- const auto top = static_cast <int >(min_y - kVerticalConstant );
114- const auto height = static_cast <int >(max_y - min_y + 2 * kVerticalConstant );
107+ const auto aw = std::abs (max_x - min_x);
108+ const auto ah = std::abs (max_y - min_y);
109+
110+ const auto top = static_cast <int >(min_y - ah * 2 .);
111+ const auto gap = static_cast <int >(aw * 1.0 );
115112
116- const auto camp = armor_color2camp_color (armor.color );
113+ const auto rh = static_cast <int >(aw * 2.5 );
114+ const auto rw = static_cast <int >(aw * 1.5 );
117115
116+ const auto point = [](auto x, auto y) {
117+ return cv::Point2i {
118+ static_cast <int >(std::round (x)),
119+ static_cast <int >(std::round (y)),
120+ };
121+ };
118122 const auto rois = std::array {
119- cv::Rect2i { static_cast < int > (min_x) - h_extend - kGap , top, h_extend, height },
120- cv::Rect2i { static_cast < int > (max_x) + kGap , top, h_extend, height },
123+ cv::Rect2i { point (min_x - 1 . * gap - 1 . * rw , top), cv::Size2i { rw, rh } },
124+ cv::Rect2i { point (max_x + 1 . * gap - 0 . * rw , top), cv::Size2i { rw, rh } },
121125 };
122- for (const auto & roi : rois) {
123126
124- const auto clipped = roi & image_bounds;
127+ for (const auto & roi : rois) {
128+ const auto clipped = roi & bounds;
125129 if (clipped.width <= 0 || clipped.height <= 0 ) continue ;
126130
127131 result.areas .push_back (clipped);
128132
129133 auto finder = LightbarFinder { };
130134 {
135+ const auto camp = armor_color2camp_color (armor.color );
136+
131137 finder.input .source = mat (clipped).clone ();
132138 finder.input .color = camp;
133139 if (!finder.solve ()) continue ;
134140 }
135141 { // 长度筛选
136- const auto armor_length
137- = std::hypot (armor.tl .x - armor.bl .x , armor.tl .y - armor.bl .y );
138- const auto detected_length = std::hypot (
139- finder.result .upper .x - finder.result .lower .x ,
140- finder.result .upper .y - finder.result .lower .y );
142+ const auto armor_length =
143+ std::hypot (armor.tl .x - armor.bl .x , armor.tl .y - armor.bl .y );
144+ const auto detected_length =
145+ std::hypot ( finder.result .upper .x - finder.result .lower .x ,
146+ finder.result .upper .y - finder.result .lower .y );
141147 if (std::abs (detected_length - armor_length) / armor_length > 0.2 ) continue ;
142148 }
143149 { // 角度筛选
144- const auto armor_direction
145- = cv::Point2d { armor.tl .x - armor.bl .x , armor.tl .y - armor.bl .y };
150+ const auto armor_direction =
151+ cv::Point2d { armor.tl .x - armor.bl .x , armor.tl .y - armor.bl .y };
146152 const auto detected_direction = cv::Point2d {
147153 static_cast <double >(finder.result .upper .x - finder.result .lower .x ),
148154 static_cast <double >(finder.result .upper .y - finder.result .lower .y ),
149155 };
150156 const auto armor_angle = std::atan2 (armor_direction.y , armor_direction.x );
151- const auto detected_angle
152- = std::atan2 (detected_direction.y , detected_direction.x );
153- const auto angle_diff
154- = std::abs (util::normalize_angle (detected_angle - armor_angle));
157+ const auto detected_angle =
158+ std::atan2 (detected_direction.y , detected_direction.x );
159+ const auto angle_diff =
160+ std::abs (util::normalize_angle (detected_angle - armor_angle));
155161 if (angle_diff > util::deg2rad (20.0 )) continue ;
156162 }
157163 result.lightbars .push_back ({
158164 .genre = genre,
159165 .color = armor.color ,
160- .upper = Point2d {
161- static_cast <double >(finder.result .upper .x + clipped.x ),
162- static_cast <double >(finder.result .upper .y + clipped.y ),
163- },
164- .lower = Point2d {
165- static_cast <double >(finder.result .lower .x + clipped.x ),
166- static_cast <double >(finder.result .lower .y + clipped.y ),
167- },
166+ .upper =
167+ Point2d {
168+ static_cast <double >(finder.result .upper .x + clipped.x ),
169+ static_cast <double >(finder.result .upper .y + clipped.y ),
170+ },
171+ .lower =
172+ Point2d {
173+ static_cast <double >(finder.result .lower .x + clipped.x ),
174+ static_cast <double >(finder.result .lower .y + clipped.y ),
175+ },
168176 });
169177 }
170178 }
0 commit comments