#include "IdentifyOperTask.h" #include #include #include #include #include #include #include "Configer.h" #include "InfrastConfiger.h" #include "Identify.h" #include "WinMacro.h" using namespace asst; asst::IdentifyOperTask::IdentifyOperTask(AsstCallback callback, void* callback_arg) : OcrAbstractTask(callback, callback_arg) { ; } bool asst::IdentifyOperTask::run() { if (m_view_ptr == nullptr || m_identify_ptr == nullptr || m_control_ptr == nullptr) { m_callback(AsstMsg::PtrIsNull, json::value(), m_callback_arg); return false; } json::value task_start_json = json::object{ { "task_type", "InfrastStationTask" }, { "task_chain", OcrAbstractTask::m_task_chain}, }; m_callback(AsstMsg::TaskStart, task_start_json, m_callback_arg); std::unordered_map feature_cond = InfrastConfiger::get_instance().m_oper_name_feat; std::unordered_set feature_whatever = InfrastConfiger::get_instance().m_oper_name_feat_whatever; std::unordered_set detected_opers; //auto swipe_foo = std::bind(&IdentifyOperTask::swipe, *this); // 一边识别一边滑动,把所有干员名字抓出来 while (true) { const cv::Mat& image = OcrAbstractTask::get_format_image(true); // 异步进行滑动操作 std::future swipe_future = std::async(std::launch::async, &IdentifyOperTask::swipe, this, false); auto cur_name_textarea = detect_opers(image, feature_cond, feature_whatever); int oper_numer = detected_opers.size(); for (const TextArea& textarea : cur_name_textarea) { cv::Rect elite_rect; // 因为有的名字长有的名字短,但是右对齐的,所以跟着右边走 // TODO,这些长宽的参数要跟着分辨率缩放,最好放到配置文件里 elite_rect.x = textarea.rect.x + textarea.rect.width - 250; elite_rect.y = textarea.rect.y - 200; if (elite_rect.x < 0 || elite_rect.y < 0) { continue; } elite_rect.width = 100; elite_rect.height = 150; cv::Mat elite_mat = image(elite_rect); // for debug static cv::Mat elite1 = cv::imread(GetResourceDir() + "operators\\Elite1.png"); static cv::Mat elite2 = cv::imread(GetResourceDir() + "operators\\Elite2.png"); auto&& [score1, point1] = OcrAbstractTask::m_identify_ptr->match_template(elite_mat, elite1); auto&& [score2, point2] = OcrAbstractTask::m_identify_ptr->match_template(elite_mat, elite2); #ifdef LOG_TRACE std::cout << "elite1:" << score1 << ", elite2:" << score2 << std::endl; #endif OperInfrastInfo info; info.name = textarea.text; if (score1 > score2 && score1 > 0.7) { info.elite = 1; } else if (score2 > score1 && score2 > 0.7) { info.elite = 2; } else { info.elite = 0; } detected_opers.emplace(std::move(info)); } json::value opers_json; std::vector opers_json_vec; for (const OperInfrastInfo& info : detected_opers) { json::value info_json; info_json["name"] = Utf8ToGbk(info.name); info_json["elite"] = info.elite; //info_json["level"] = info.level; opers_json_vec.emplace_back(std::move(info_json)); } opers_json["all"] = json::array(opers_json_vec); m_callback(AsstMsg::InfrastOpers, opers_json, m_callback_arg); // 阻塞等待滑动结束 if (!swipe_future.get()) { return false; } // 说明本次识别一个新的都没识别到,应该是滑动到最后了,直接结束循环 if (oper_numer == detected_opers.size()) { break; } } return true; } std::vector