mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-19 10:32:19 +08:00
完成进入指定序号宿舍的接口
This commit is contained in:
@@ -304,7 +304,8 @@ asst::Identify::FindImageResult asst::Identify::find_image(
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<asst::Identify::FindImageResult> asst::Identify::find_all_images(const cv::Mat& image, const std::string& templ_name, double threshold)
|
||||
std::vector<asst::Identify::FindImageResult> asst::Identify::find_all_images(
|
||||
const cv::Mat& image, const std::string& templ_name, double threshold) const
|
||||
{
|
||||
if (m_mat_map.find(templ_name) == m_mat_map.cend()) {
|
||||
return std::vector<FindImageResult>();
|
||||
@@ -319,17 +320,37 @@ std::vector<asst::Identify::FindImageResult> asst::Identify::find_all_images(con
|
||||
Mat matched;
|
||||
matchTemplate(image_hsv, templ_hsv, matched, cv::TM_CCOEFF_NORMED);
|
||||
|
||||
std::vector<FindImageResult> result;
|
||||
std::vector<FindImageResult> results;
|
||||
for (int i = 0; i != matched.rows; ++i) {
|
||||
for (int j = 0; j != matched.cols; ++j) {
|
||||
auto value = matched.at<float>(i, j);
|
||||
if (value >= threshold) {
|
||||
Rect rect = Rect(j, i, templ_mat.cols, templ_mat.rows).center_zoom(0.8);
|
||||
result.emplace_back(AlgorithmType::MatchTemplate, value, std::move(rect));
|
||||
|
||||
bool need_push = true;
|
||||
// 如果有两个点离得太近,只取里面得分高的那个
|
||||
// 一般相邻的都是刚刚push进去的,这里倒序快一点
|
||||
for (auto iter = results.rbegin(); iter != results.rend(); ++ iter) {
|
||||
if (std::abs(j - iter->rect.x) < 5
|
||||
|| std::abs(i - iter->rect.y) < 5) {
|
||||
if (iter->score < value) {
|
||||
iter->rect = rect;
|
||||
iter->score = value;
|
||||
need_push = false;
|
||||
} // else 这个点就放弃了
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (need_push) {
|
||||
results.emplace_back(AlgorithmType::MatchTemplate, value, std::move(rect));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
std::sort(results.begin(), results.end(), [](const auto& lhs, const auto& rhs) -> bool {
|
||||
return lhs.score > rhs.score;
|
||||
});
|
||||
return results;
|
||||
}
|
||||
|
||||
std::optional<TextArea> asst::Identify::feature_match(const cv::Mat& mat, const std::string& key)
|
||||
|
||||
@@ -20,9 +20,9 @@ namespace asst {
|
||||
struct FindImageResult {
|
||||
FindImageResult() = default;
|
||||
FindImageResult(AlgorithmType algorithm, double value, asst::Rect rect)
|
||||
: algorithm(algorithm), value(value), rect(rect) { ; }
|
||||
: algorithm(algorithm), score(value), rect(rect) { ; }
|
||||
AlgorithmType algorithm;
|
||||
double value = 0.0;
|
||||
double score = 0.0;
|
||||
asst::Rect rect;
|
||||
};
|
||||
public:
|
||||
@@ -38,7 +38,7 @@ namespace asst {
|
||||
FindImageResult find_image(
|
||||
const cv::Mat& image, const std::string& templ_name, double add_cache_thres = NotAddCache);
|
||||
std::vector<FindImageResult> find_all_images(
|
||||
const cv::Mat& image, const std::string& templ_name, double threshold = 0);
|
||||
const cv::Mat& image, const std::string& templ_name, double threshold = 0) const;
|
||||
|
||||
// return pair< suitability, raw opencv::point>
|
||||
std::pair<double, cv::Point> match_template(const cv::Mat& cur, const cv::Mat& templ);
|
||||
|
||||
@@ -23,15 +23,16 @@ bool asst::InfrastDormTask::run()
|
||||
return false;
|
||||
}
|
||||
|
||||
enter_upper_dorm();
|
||||
enter_dorm(2);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool asst::InfrastDormTask::enter_upper_dorm()
|
||||
bool asst::InfrastDormTask::enter_dorm(int index)
|
||||
{
|
||||
cv::Mat image = get_format_image();
|
||||
// 普通的和mini的,正常情况应该只有一个有结果,另一个是empty
|
||||
// 为了防止识别漏了,这里阈值先放低一点
|
||||
auto dorm_result = m_identify_ptr->find_all_images(image, "Dorm", 0.8);
|
||||
auto dorm_mini_result = m_identify_ptr->find_all_images(image, "DormMini", 0.8);
|
||||
|
||||
@@ -46,16 +47,16 @@ bool asst::InfrastDormTask::enter_upper_dorm()
|
||||
else if (dorm_mini_result.empty()) {
|
||||
cur_dorm_result = std::move(dorm_result);
|
||||
}
|
||||
// 最顶上的宿舍(第一个宿舍)
|
||||
auto upper_iter = std::min_element(cur_dorm_result.cbegin(), cur_dorm_result.cend(), [](
|
||||
if (index >= cur_dorm_result.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::sort(cur_dorm_result.begin(), cur_dorm_result.end(), [](
|
||||
const auto& lhs, const auto& rhs) -> bool {
|
||||
return lhs.rect.y < rhs.rect.y;
|
||||
});
|
||||
if (upper_iter == cur_dorm_result.cend()) {
|
||||
// 按理说走不到这里,TODO 报错
|
||||
return false;
|
||||
}
|
||||
m_control_ptr->click(upper_iter->rect);
|
||||
|
||||
m_control_ptr->click(cur_dorm_result.at(index).rect);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace asst {
|
||||
virtual bool run() override;
|
||||
|
||||
protected:
|
||||
bool enter_upper_dorm();
|
||||
// 进入宿舍,index为从上到下的编号
|
||||
bool enter_dorm(int index = 0);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -41,8 +41,8 @@ bool asst::InfrastStationTask::run()
|
||||
facility_number_rect.emplace_back(Rect()); // 假装给01 push一个,后面循环好写=。=
|
||||
|
||||
for (const std::string& key : facility_number_key) {
|
||||
auto&& [algorithm, value, temp_rect] = m_identify_ptr->find_image(image, key);
|
||||
if (value >= Configer::TemplThresholdDefault) {
|
||||
auto&& [algorithm, score, temp_rect] = m_identify_ptr->find_image(image, key);
|
||||
if (score >= Configer::TemplThresholdDefault) {
|
||||
facility_number_rect.emplace_back(temp_rect);
|
||||
}
|
||||
else {
|
||||
@@ -57,15 +57,15 @@ bool asst::InfrastStationTask::run()
|
||||
image = get_format_image();
|
||||
}
|
||||
// 如果当前界面没有添加干员的按钮,那就不换班
|
||||
auto&& [algorithm, value, add_rect] = m_identify_ptr->find_image(image, "AddOperator");
|
||||
if (value < Configer::TemplThresholdDefault) {
|
||||
auto&& [algorithm, score, add_rect] = m_identify_ptr->find_image(image, "AddOperator");
|
||||
if (score < Configer::TemplThresholdDefault) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 识别当前正在造什么
|
||||
for (const auto& [key, useless_value] : InfrastConfiger::get_instance().m_infrast_combs) {
|
||||
auto&& [algorithm, value, useless_rect] = m_identify_ptr->find_image(image, key);
|
||||
if (value >= Configer::TemplThresholdDefault) {
|
||||
auto&& [algorithm, score, useless_rect] = m_identify_ptr->find_image(image, key);
|
||||
if (score >= Configer::TemplThresholdDefault) {
|
||||
m_facility = key;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -166,21 +166,21 @@ std::shared_ptr<TaskInfo> ProcessTask::match_image(Rect* matched_rect)
|
||||
double hist_threshold = process_task_info_ptr->hist_threshold;
|
||||
double add_cache_thres = process_task_info_ptr->cache ? templ_threshold : Identify::NotAddCache;
|
||||
|
||||
auto&& [algorithm, value, temp_rect] = m_identify_ptr->find_image(cur_image, task_name, add_cache_thres);
|
||||
auto&& [algorithm, score, temp_rect] = m_identify_ptr->find_image(cur_image, task_name, add_cache_thres);
|
||||
rect = std::move(temp_rect);
|
||||
callback_json["value"] = value;
|
||||
callback_json["value"] = score;
|
||||
|
||||
if (algorithm == AlgorithmType::MatchTemplate) {
|
||||
callback_json["threshold"] = templ_threshold;
|
||||
callback_json["algorithm"] = "MatchTemplate";
|
||||
if (value >= templ_threshold) {
|
||||
if (score >= templ_threshold) {
|
||||
matched = true;
|
||||
}
|
||||
}
|
||||
else if (algorithm == AlgorithmType::CompareHist) {
|
||||
callback_json["threshold"] = hist_threshold;
|
||||
callback_json["algorithm"] = "CompareHist";
|
||||
if (value >= hist_threshold) {
|
||||
if (score >= hist_threshold) {
|
||||
matched = true;
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 3.7 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 2.5 KiB |
Reference in New Issue
Block a user