@@ -19,34 +19,90 @@ Recognizer::Recognizer(Tasker* tasker, Context& context, const cv::Mat& image_)
1919 : tasker_(tasker)
2020 , context_(context)
2121 , image_(image_)
22+ , sub_filtered_boxes_(std::make_shared<typename decltype (sub_filtered_boxes_)::element_type>())
23+ , sub_best_box_(std::make_shared<typename decltype (sub_best_box_)::element_type>())
2224{
2325}
2426
25- RecoResult Recognizer::recognize (const PipelineData& pipeline_data)
27+ Recognizer::Recognizer (const Recognizer& recognizer)
28+ : tasker_(recognizer.tasker_)
29+ , context_(recognizer.context_)
30+ , image_(recognizer.image_)
31+ // do not copy reco_id_
32+ , sub_filtered_boxes_(recognizer.sub_filtered_boxes_)
33+ , sub_best_box_(recognizer.sub_best_box_)
2634{
35+ }
36+
37+ RecoResult Recognizer::recognize (MAA_RES_NS ::Recognition::Type type, const MAA_RES_NS ::Recognition::Param& param, const std::string& name)
38+ {
39+ using namespace MAA_RES_NS ::Recognition;
40+ using namespace MAA_VISION_NS ;
41+
2742 if (!tasker_) {
2843 LogError << " tasker is null" ;
2944 return {};
3045 }
3146
32- RecoResult result = run_recognition (pipeline_data.reco_type , pipeline_data.reco_param , pipeline_data.name );
47+ RecoResult result;
48+
49+ switch (type) {
50+ case Type::DirectHit:
51+ result = direct_hit (std::get<DirectHitParam>(param), name);
52+ break ;
53+
54+ case Type::TemplateMatch:
55+ result = template_match (std::get<TemplateMatcherParam>(param), name);
56+ break ;
57+
58+ case Type::FeatureMatch:
59+ result = feature_match (std::get<FeatureMatcherParam>(param), name);
60+ break ;
61+
62+ case Type::ColorMatch:
63+ result = color_match (std::get<ColorMatcherParam>(param), name);
64+ break ;
65+
66+ case Type::OCR :
67+ result = ocr (std::get<OCRerParam>(param), name);
68+ break ;
69+
70+ case Type::NeuralNetworkClassify:
71+ result = nn_classify (std::get<NeuralNetworkClassifierParam>(param), name);
72+ break ;
73+
74+ case Type::NeuralNetworkDetect:
75+ result = nn_detect (std::get<NeuralNetworkDetectorParam>(param), name);
76+ break ;
77+
78+ case Type::And:
79+ result = and_ (std::get<std::shared_ptr<AndParam>>(param), name);
80+ break ;
81+
82+ case Type::Or:
83+ result = or_ (std::get<std::shared_ptr<OrParam>>(param), name);
84+ break ;
85+
86+ case Type::Custom:
87+ result = custom_recognize (std::get<CustomRecognitionParam>(param), name);
88+ break ;
89+
90+ default :
91+ LogError << " Unknown recognition type" << VAR (static_cast <int >(type)) << VAR (name);
92+ break ;
93+ }
3394
3495 if (debug_mode ()) {
3596 ImageEncodedBuffer png;
3697 cv::imencode (" .png" , image_, png);
3798 result.raw = std::move (png);
3899 }
39100
40- if (pipeline_data.inverse ) {
41- LogDebug << " pipeline_data.inverse is true, reverse the result" << VAR (pipeline_data.name ) << VAR (result.box );
42- result.box = result.box ? std::nullopt : std::make_optional<cv::Rect>();
43- }
44-
45101 LogInfo << " reco" << VAR (result);
46102 auto & rt_cache = tasker_->runtime_cache ();
47103 rt_cache.set_reco_detail (result.reco_id , result);
48104
49- save_draws (pipeline_data. name , result);
105+ save_draws (name, result);
50106
51107 return result;
52108}
@@ -82,8 +138,8 @@ RecoResult Recognizer::direct_hit(const MAA_VISION_NS::DirectHitParam& param, co
82138 // DirectHit: 使用第一个 ROI 作为 box
83139 cv::Rect box = rois.empty () ? cv::Rect {} : rois.front ();
84140
85- sub_filtered_boxes_. insert_or_assign (name, rois);
86- sub_best_box_. insert_or_assign (name, box);
141+ sub_filtered_boxes_-> insert_or_assign (name, rois);
142+ sub_best_box_-> insert_or_assign (name, box);
87143
88144 return RecoResult {
89145 .reco_id = reco_id_,
@@ -102,8 +158,8 @@ RecoResult Recognizer::template_match(const MAA_VISION_NS::TemplateMatcherParam&
102158 auto templs = context_.get_images (param.template_ );
103159 TemplateMatcher analyzer (image_, rois, param, templs, name);
104160
105- sub_filtered_boxes_. insert_or_assign (name, get_boxes (analyzer.filtered_results ()));
106- sub_best_box_. insert_or_assign (name, analyzer.best_result () ? analyzer.best_result ()->box : cv::Rect {});
161+ sub_filtered_boxes_-> insert_or_assign (name, get_boxes (analyzer.filtered_results ()));
162+ sub_best_box_-> insert_or_assign (name, analyzer.best_result () ? analyzer.best_result ()->box : cv::Rect {});
107163
108164 std::optional<cv::Rect> box = std::nullopt ;
109165 if (analyzer.best_result ()) {
@@ -127,8 +183,8 @@ RecoResult Recognizer::feature_match(const MAA_VISION_NS::FeatureMatcherParam& p
127183 auto templs = context_.get_images (param.template_ );
128184 FeatureMatcher analyzer (image_, rois, param, templs, name);
129185
130- sub_filtered_boxes_. insert_or_assign (name, get_boxes (analyzer.filtered_results ()));
131- sub_best_box_. insert_or_assign (name, analyzer.best_result () ? analyzer.best_result ()->box : cv::Rect {});
186+ sub_filtered_boxes_-> insert_or_assign (name, get_boxes (analyzer.filtered_results ()));
187+ sub_best_box_-> insert_or_assign (name, analyzer.best_result () ? analyzer.best_result ()->box : cv::Rect {});
132188
133189 std::optional<cv::Rect> box = std::nullopt ;
134190 if (analyzer.best_result ()) {
@@ -151,8 +207,8 @@ RecoResult Recognizer::color_match(const MAA_VISION_NS::ColorMatcherParam& param
151207
152208 ColorMatcher analyzer (image_, rois, param, name);
153209
154- sub_filtered_boxes_. insert_or_assign (name, get_boxes (analyzer.filtered_results ()));
155- sub_best_box_. insert_or_assign (name, analyzer.best_result () ? analyzer.best_result ()->box : cv::Rect {});
210+ sub_filtered_boxes_-> insert_or_assign (name, get_boxes (analyzer.filtered_results ()));
211+ sub_best_box_-> insert_or_assign (name, analyzer.best_result () ? analyzer.best_result ()->box : cv::Rect {});
156212
157213 std::optional<cv::Rect> box = std::nullopt ;
158214 if (analyzer.best_result ()) {
@@ -184,8 +240,8 @@ RecoResult Recognizer::ocr(const MAA_VISION_NS::OCRerParam& param, const std::st
184240
185241 OCRer analyzer (image_, rois, param, det_session, reco_session, ocr_session, name);
186242
187- sub_filtered_boxes_. insert_or_assign (name, get_boxes (analyzer.filtered_results ()));
188- sub_best_box_. insert_or_assign (name, analyzer.best_result () ? analyzer.best_result ()->box : cv::Rect {});
243+ sub_filtered_boxes_-> insert_or_assign (name, get_boxes (analyzer.filtered_results ()));
244+ sub_best_box_-> insert_or_assign (name, analyzer.best_result () ? analyzer.best_result ()->box : cv::Rect {});
189245
190246 std::optional<cv::Rect> box = std::nullopt ;
191247 if (analyzer.best_result ()) {
@@ -217,8 +273,8 @@ RecoResult Recognizer::nn_classify(const MAA_VISION_NS::NeuralNetworkClassifierP
217273
218274 NeuralNetworkClassifier analyzer (image_, rois, param, session, mem_info, name);
219275
220- sub_filtered_boxes_. insert_or_assign (name, get_boxes (analyzer.filtered_results ()));
221- sub_best_box_. insert_or_assign (name, analyzer.best_result () ? analyzer.best_result ()->box : cv::Rect {});
276+ sub_filtered_boxes_-> insert_or_assign (name, get_boxes (analyzer.filtered_results ()));
277+ sub_best_box_-> insert_or_assign (name, analyzer.best_result () ? analyzer.best_result ()->box : cv::Rect {});
222278
223279 std::optional<cv::Rect> box = std::nullopt ;
224280 if (analyzer.best_result ()) {
@@ -250,8 +306,8 @@ RecoResult Recognizer::nn_detect(const MAA_VISION_NS::NeuralNetworkDetectorParam
250306
251307 NeuralNetworkDetector analyzer (image_, rois, param, session, mem_info, name);
252308
253- sub_filtered_boxes_. insert_or_assign (name, get_boxes (analyzer.filtered_results ()));
254- sub_best_box_. insert_or_assign (name, analyzer.best_result () ? analyzer.best_result ()->box : cv::Rect {});
309+ sub_filtered_boxes_-> insert_or_assign (name, get_boxes (analyzer.filtered_results ()));
310+ sub_best_box_-> insert_or_assign (name, analyzer.best_result () ? analyzer.best_result ()->box : cv::Rect {});
255311
256312 std::optional<cv::Rect> box = std::nullopt ;
257313 if (analyzer.best_result ()) {
@@ -280,8 +336,8 @@ RecoResult Recognizer::custom_recognize(const MAA_VISION_NS::CustomRecognitionPa
280336 auto session = resource ()->custom_recognition (param.name );
281337 CustomRecognition analyzer (image_, rois.empty () ? cv::Rect {} : rois.front (), param, session, context_, name);
282338
283- sub_filtered_boxes_. insert_or_assign (name, get_boxes (analyzer.filtered_results ()));
284- sub_best_box_. insert_or_assign (name, analyzer.best_result () ? analyzer.best_result ()->box : cv::Rect {});
339+ sub_filtered_boxes_-> insert_or_assign (name, get_boxes (analyzer.filtered_results ()));
340+ sub_best_box_-> insert_or_assign (name, analyzer.best_result () ? analyzer.best_result ()->box : cv::Rect {});
285341
286342 std::optional<cv::Rect> box = std::nullopt ;
287343 if (analyzer.best_result ()) {
@@ -310,7 +366,8 @@ RecoResult Recognizer::and_(const std::shared_ptr<MAA_RES_NS::Recognition::AndPa
310366
311367 for (const auto & sub_reco : param->all_of ) {
312368 LogDebug << " And: run sub recognition" << VAR (sub_reco.type ) << VAR (sub_reco.sub_name );
313- RecoResult res = run_recognition (sub_reco.type , sub_reco.param , sub_reco.sub_name );
369+ Recognizer sub_recognizer (*this );
370+ RecoResult res = sub_recognizer.recognize (sub_reco.type , sub_reco.param , sub_reco.sub_name );
314371 all_hit &= res.box .has_value ();
315372
316373 sub_results.emplace_back (std::move (res));
@@ -336,25 +393,25 @@ RecoResult Recognizer::and_(const std::shared_ptr<MAA_RES_NS::Recognition::AndPa
336393
337394 if (!all_hit) {
338395 LogDebug << " And recognition failed" << VAR (name);
339- sub_filtered_boxes_. insert_or_assign (name, std::vector<cv::Rect> {});
340- sub_best_box_. insert_or_assign (name, cv::Rect {});
396+ sub_filtered_boxes_-> insert_or_assign (name, std::vector<cv::Rect> {});
397+ sub_best_box_-> insert_or_assign (name, cv::Rect {});
341398 return result;
342399 }
343400
344401 if (static_cast <int >(sub_results.size ()) <= param->box_index ) {
345402 LogError << " all hit, but box_index is out of range" << VAR (name) << VAR (sub_results.size ()) << VAR (param->box_index );
346403 result.box = std::nullopt ;
347- sub_filtered_boxes_. insert_or_assign (name, std::vector<cv::Rect> {});
348- sub_best_box_. insert_or_assign (name, cv::Rect {});
404+ sub_filtered_boxes_-> insert_or_assign (name, std::vector<cv::Rect> {});
405+ sub_best_box_-> insert_or_assign (name, cv::Rect {});
349406 return result;
350407 }
351408
352409 result.box = std::move (sub_results[param->box_index ].box );
353410
354411 cv::Rect final_box = result.box .value_or (cv::Rect {});
355412 // 按理说这里要从 sub 取的,但是太麻烦而且是 corner case,先不管了,后面有需要再加
356- sub_filtered_boxes_. insert_or_assign (name, std::vector<cv::Rect> { final_box });
357- sub_best_box_. insert_or_assign (name, final_box);
413+ sub_filtered_boxes_-> insert_or_assign (name, std::vector<cv::Rect> { final_box });
414+ sub_best_box_-> insert_or_assign (name, final_box);
358415
359416 return result;
360417}
@@ -374,7 +431,8 @@ RecoResult Recognizer::or_(const std::shared_ptr<MAA_RES_NS::Recognition::OrPara
374431
375432 for (const auto & sub_reco : param->any_of ) {
376433 LogDebug << " Or: run sub recognition" << VAR (sub_reco.type ) << VAR (sub_reco.sub_name );
377- RecoResult res = run_recognition (sub_reco.type , sub_reco.param , sub_reco.sub_name );
434+ Recognizer sub_recognizer (*this );
435+ RecoResult res = sub_recognizer.recognize (sub_reco.type , sub_reco.param , sub_reco.sub_name );
378436 has_hit = res.box .has_value ();
379437 sub_results.emplace_back (std::move (res));
380438
@@ -398,71 +456,28 @@ RecoResult Recognizer::or_(const std::shared_ptr<MAA_RES_NS::Recognition::OrPara
398456
399457 if (!has_hit) {
400458 LogDebug << " Or recognition failed" << VAR (name);
401- sub_filtered_boxes_. insert_or_assign (name, std::vector<cv::Rect> {});
402- sub_best_box_. insert_or_assign (name, cv::Rect {});
459+ sub_filtered_boxes_-> insert_or_assign (name, std::vector<cv::Rect> {});
460+ sub_best_box_-> insert_or_assign (name, cv::Rect {});
403461 return result;
404462 }
405463
406464 if (sub_results.empty ()) {
407465 LogError << " has hit, but no sub results" << VAR (name);
408- sub_filtered_boxes_. insert_or_assign (name, std::vector<cv::Rect> {});
409- sub_best_box_. insert_or_assign (name, cv::Rect {});
466+ sub_filtered_boxes_-> insert_or_assign (name, std::vector<cv::Rect> {});
467+ sub_best_box_-> insert_or_assign (name, cv::Rect {});
410468 return {};
411469 }
412470
413471 result.box = std::move (sub_results.back ().box );
414472
415473 cv::Rect final_box = result.box .value_or (cv::Rect {});
416474 // 按理说这里要从 sub 取的,但是太麻烦而且是 corner case,先不管了,后面有需要再加
417- sub_filtered_boxes_. insert_or_assign (name, std::vector<cv::Rect> { final_box });
418- sub_best_box_. insert_or_assign (name, final_box);
475+ sub_filtered_boxes_-> insert_or_assign (name, std::vector<cv::Rect> { final_box });
476+ sub_best_box_-> insert_or_assign (name, final_box);
419477
420478 return result;
421479}
422480
423- RecoResult
424- Recognizer::run_recognition (MAA_RES_NS ::Recognition::Type type, const MAA_RES_NS ::Recognition::Param& param, const std::string& name)
425- {
426- using namespace MAA_RES_NS ::Recognition;
427- using namespace MAA_VISION_NS ;
428-
429- switch (type) {
430- case Type::DirectHit:
431- return direct_hit (std::get<DirectHitParam>(param), name);
432-
433- case Type::TemplateMatch:
434- return template_match (std::get<TemplateMatcherParam>(param), name);
435-
436- case Type::FeatureMatch:
437- return feature_match (std::get<FeatureMatcherParam>(param), name);
438-
439- case Type::ColorMatch:
440- return color_match (std::get<ColorMatcherParam>(param), name);
441-
442- case Type::OCR :
443- return ocr (std::get<OCRerParam>(param), name);
444-
445- case Type::NeuralNetworkClassify:
446- return nn_classify (std::get<NeuralNetworkClassifierParam>(param), name);
447-
448- case Type::NeuralNetworkDetect:
449- return nn_detect (std::get<NeuralNetworkDetectorParam>(param), name);
450-
451- case Type::And:
452- return and_ (std::get<std::shared_ptr<AndParam>>(param), name);
453-
454- case Type::Or:
455- return or_ (std::get<std::shared_ptr<OrParam>>(param), name);
456-
457- case Type::Custom:
458- return custom_recognize (std::get<CustomRecognitionParam>(param), name);
459-
460- default :
461- LogError << " Unknown recognition type" << VAR (static_cast <int >(type)) << VAR (name);
462- return {};
463- }
464- }
465-
466481std::vector<cv::Rect> Recognizer::get_rois (const MAA_VISION_NS ::Target& roi, bool use_best)
467482{
468483 if (!tasker_) {
@@ -504,13 +519,13 @@ std::vector<cv::Rect> Recognizer::get_rois(const MAA_VISION_NS::Target& roi, boo
504519std::vector<cv::Rect> Recognizer::get_rois_from_pretask (const std::string& name, bool use_best)
505520{
506521 if (use_best) {
507- if (auto it = sub_best_box_. find (name); it != sub_best_box_. end ()) {
522+ if (auto it = sub_best_box_-> find (name); it != sub_best_box_-> end ()) {
508523 LogDebug << " pre task from sub_best_box_" << VAR (name) << VAR (it->second );
509524 return { it->second };
510525 }
511526 }
512527 else {
513- if (auto it = sub_filtered_boxes_. find (name); it != sub_filtered_boxes_. end ()) {
528+ if (auto it = sub_filtered_boxes_-> find (name); it != sub_filtered_boxes_-> end ()) {
514529 LogDebug << " pre task from sub_filtered_boxes_" << VAR (name) << VAR (it->second .size ());
515530 return it->second ;
516531 }
0 commit comments