mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-17 10:00:44 +08:00
@@ -9602,7 +9602,7 @@
|
||||
"DepotSlowlySwipeToTheRight": {
|
||||
"baseTask": "SlowlySwipeToTheRight",
|
||||
"specificRect": [
|
||||
1100,
|
||||
1150,
|
||||
340,
|
||||
20,
|
||||
20
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <meojson/json.hpp>
|
||||
|
||||
#include "Config/GeneralConfig.h"
|
||||
#include "Config/Miscellaneous/ItemConfig.h"
|
||||
#include "Config/TaskData.h"
|
||||
#include "Controller/Controller.h"
|
||||
#include "Task/ProcessTask.h"
|
||||
@@ -26,37 +25,29 @@ bool asst::DepotRecognitionTask::swipe_and_analyze()
|
||||
{
|
||||
LogTraceFunction;
|
||||
m_all_items.clear();
|
||||
// 获取item总长度
|
||||
const auto& item_size = ItemData.get_ordered_material_item_id().size();
|
||||
|
||||
size_t pre_pos = 0ULL;
|
||||
cv::Mat index_roi {};
|
||||
// size_t pre_pos = item_size;
|
||||
while (true) {
|
||||
// 如果已经遍历完了所有item直接退出
|
||||
if (pre_pos == item_size) {
|
||||
break;
|
||||
}
|
||||
DepotImageAnalyzer analyzer(ctrler()->get_image());
|
||||
|
||||
auto future = std::async(std::launch::async, [&]() { swipe(); });
|
||||
|
||||
// 第一页不用检索item,后续都需要检索上一页最后一个item
|
||||
|
||||
analyzer.set_match_begin_pos(pre_pos);
|
||||
analyzer.set_index_roi(index_roi);
|
||||
// 因为滑动不是完整的一页,有可能上一次识别过的物品,这次仍然在页面中
|
||||
// 所以这个 begin pos 不能设置
|
||||
// analyzer.set_match_begin_pos(pre_pos);
|
||||
if (!analyzer.analyze()) {
|
||||
break;
|
||||
}
|
||||
size_t cur_pos = analyzer.get_match_begin_pos();
|
||||
if (cur_pos == DepotImageAnalyzer::NPos) {
|
||||
if (cur_pos == pre_pos || cur_pos == DepotImageAnalyzer::NPos) {
|
||||
break;
|
||||
}
|
||||
pre_pos = cur_pos;
|
||||
index_roi = analyzer.get_index_roi();
|
||||
|
||||
auto cur_result = analyzer.get_result();
|
||||
m_all_items.merge(std::move(cur_result));
|
||||
|
||||
future.get();
|
||||
future.wait();
|
||||
callback_analyze_result(false);
|
||||
}
|
||||
return !m_all_items.empty();
|
||||
|
||||
@@ -44,11 +44,6 @@ size_t asst::DepotImageAnalyzer::get_match_begin_pos() const noexcept
|
||||
return m_match_begin_pos;
|
||||
}
|
||||
|
||||
void asst::DepotImageAnalyzer::set_index_roi(cv::Mat last_roi) noexcept
|
||||
{
|
||||
m_index_roi = last_roi;
|
||||
}
|
||||
|
||||
void asst::DepotImageAnalyzer::resize()
|
||||
{
|
||||
LogTraceFunction;
|
||||
@@ -128,44 +123,17 @@ bool asst::DepotImageAnalyzer::analyze_all_items()
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
std::size_t roi_index = 0;
|
||||
|
||||
// skip rois in the left till the last item in previous image was found
|
||||
for (; roi_index < m_all_items_roi.size(); ++roi_index) {
|
||||
const auto& roi = m_all_items_roi[roi_index];
|
||||
if (m_index_roi.empty() || check_roi_empty(roi)) {
|
||||
roi_index = m_all_items_roi.size();
|
||||
for (const Rect& roi : m_all_items_roi) {
|
||||
if (check_roi_empty(roi)) { // roi 是竖着有序的
|
||||
break;
|
||||
}
|
||||
|
||||
if (search_item(roi)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// bad luck, all rois are new? did we overshoot when swipping
|
||||
if (roi_index >= m_all_items_roi.size()) {
|
||||
roi_index = 0;
|
||||
m_match_begin_pos = 0;
|
||||
}
|
||||
|
||||
Log.trace("Analyzing from roi", roi_index, "item index", m_match_begin_pos);
|
||||
|
||||
for (; roi_index < m_all_items_roi.size(); ++roi_index) {
|
||||
const auto& roi = m_all_items_roi[roi_index];
|
||||
if (check_roi_empty(roi)) {
|
||||
break;
|
||||
}
|
||||
// roi 是竖着有序的
|
||||
ItemInfo info;
|
||||
// todo:如果不是第一页 需要调转到相应的位置,最后一个有背景影响换倒数第二。
|
||||
|
||||
Log.trace("Analyzing item at", roi_index);
|
||||
size_t cur_pos = match_item(roi, info, m_match_begin_pos);
|
||||
if (cur_pos == NPos) {
|
||||
break;
|
||||
}
|
||||
std::string item_id = info.item_id;
|
||||
|
||||
m_match_begin_pos = cur_pos + 1;
|
||||
info.quantity = match_quantity(info);
|
||||
info.item_name = ItemData.get_item_name(item_id);
|
||||
@@ -174,8 +142,6 @@ bool asst::DepotImageAnalyzer::analyze_all_items()
|
||||
cv::Scalar(0, 0, 255), 2);
|
||||
cv::putText(m_image_draw_resized, std::to_string(info.quantity), cv::Point(roi.x, roi.y + 10),
|
||||
cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 255), 2);
|
||||
cv::putText(m_image_draw_resized, std::to_string(cur_pos), cv::Point(roi.x + 80, roi.y + 10),
|
||||
cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 255), 2);
|
||||
#endif
|
||||
if (item_id.empty() || info.quantity == 0) {
|
||||
Log.error(__FUNCTION__, item_id, info.item_name, " quantity is zero");
|
||||
@@ -189,12 +155,6 @@ bool asst::DepotImageAnalyzer::analyze_all_items()
|
||||
cv::cvtColor(m_image_resized, hsv, cv::COLOR_BGR2HSV);
|
||||
#endif
|
||||
|
||||
// 获取倒数第二个roi存到Mat中,应该放到最后进行这一步操作。
|
||||
auto roi_sizes = m_all_items_roi.size();
|
||||
if (roi_sizes >= 2)
|
||||
m_index_roi = m_image_resized(make_rect<cv::Rect>(m_all_items_roi.at(roi_sizes - 2)));
|
||||
else
|
||||
m_index_roi = cv::Mat {};
|
||||
return !m_result.empty();
|
||||
}
|
||||
|
||||
@@ -211,6 +171,7 @@ size_t asst::DepotImageAnalyzer::match_item(const Rect& roi, /* out */ ItemInfo&
|
||||
LogTraceFunction;
|
||||
|
||||
const auto& all_items = ItemData.get_ordered_material_item_id();
|
||||
|
||||
Matcher analyzer(m_image_resized);
|
||||
analyzer.set_task_info("DepotMatchData");
|
||||
// spacing 有时候算的差一个像素,干脆把 roi 扩大一点好了
|
||||
@@ -223,8 +184,7 @@ size_t asst::DepotImageAnalyzer::match_item(const Rect& roi, /* out */ ItemInfo&
|
||||
MatchRect matched;
|
||||
std::string matched_item_id;
|
||||
size_t matched_index = NPos;
|
||||
for (size_t index = begin_index; index < all_items.size(); ++index) {
|
||||
// for (size_t index = begin_index, extra_count = 0; index < all_items.size(); ++index) {
|
||||
for (size_t index = begin_index, extra_count = 0; index < all_items.size(); ++index) {
|
||||
const std::string& item_id = all_items.at(index);
|
||||
// analyzer.set_templ(item_id);
|
||||
// TODO: too slow? find a way to set mask directly
|
||||
@@ -234,11 +194,15 @@ size_t asst::DepotImageAnalyzer::match_item(const Rect& roi, /* out */ ItemInfo&
|
||||
if (!analyzer.analyze()) {
|
||||
continue;
|
||||
}
|
||||
/*根据模板匹配得分修改,不能太高也不能太低*/
|
||||
if (double score = analyzer.get_result().score; score >= 0.8) {
|
||||
if (double score = analyzer.get_result().score; score >= matched.score) {
|
||||
matched = analyzer.get_result();
|
||||
matched_item_id = item_id;
|
||||
matched_index = index;
|
||||
}
|
||||
// 匹配到了任一结果后,再往后匹配几个。
|
||||
// 因为有些相邻的材料长得很像(同一种类的)
|
||||
constexpr size_t MaxExtraMatch = 8;
|
||||
if (matched_index != NPos && ++extra_count >= MaxExtraMatch) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -251,34 +215,6 @@ size_t asst::DepotImageAnalyzer::match_item(const Rect& roi, /* out */ ItemInfo&
|
||||
return matched_index;
|
||||
}
|
||||
|
||||
bool asst::DepotImageAnalyzer::search_item(const Rect& roi)
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
if (m_index_roi.empty()) return false;
|
||||
|
||||
Matcher analyzer(m_image_resized);
|
||||
analyzer.set_task_info("DepotMatchData");
|
||||
Rect enlarged_roi = roi;
|
||||
enlarged_roi = Rect(roi.x - 20, roi.y - 5, roi.width + 40, roi.height + 10);
|
||||
analyzer.set_roi(enlarged_roi);
|
||||
|
||||
// 减小mat
|
||||
cv::Mat templ = m_index_roi(cv::Rect { 10, 10, 100, 100 });
|
||||
|
||||
analyzer.set_templ(templ);
|
||||
if (!analyzer.analyze()) {
|
||||
return false;
|
||||
}
|
||||
// 将匹配度改到足够大
|
||||
double score = analyzer.get_result().score;
|
||||
if (score >= 0.95) {
|
||||
// 把位置移到上一页倒数第二个
|
||||
m_match_begin_pos -= 2;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
int asst::DepotImageAnalyzer::match_quantity(const ItemInfo& item)
|
||||
{
|
||||
auto task_ptr = Task.get<MatchTaskInfo>("DepotQuantity");
|
||||
|
||||
@@ -24,18 +24,15 @@ namespace asst
|
||||
void set_match_begin_pos(size_t pos) noexcept;
|
||||
size_t get_match_begin_pos() const noexcept;
|
||||
const auto& get_result() const noexcept { return m_result; }
|
||||
cv::Mat get_index_roi() const noexcept { return m_index_roi; }
|
||||
void set_index_roi(cv::Mat last_roi) noexcept;
|
||||
|
||||
private:
|
||||
void resize();
|
||||
bool analyze_base_rect();
|
||||
bool analyze_all_items();
|
||||
cv::Mat m_index_roi;
|
||||
|
||||
bool check_roi_empty(const Rect& roi);
|
||||
size_t match_item(const Rect& roi, /* out */ ItemInfo& item_info, size_t begin_index = 0ULL,
|
||||
bool with_enlarge = true);
|
||||
bool search_item(const Rect& roi);
|
||||
int match_quantity(const ItemInfo& item);
|
||||
Rect resize_rect_to_raw_size(const Rect& rect);
|
||||
|
||||
@@ -51,4 +48,4 @@ namespace asst
|
||||
std::vector<Rect> m_all_items_roi;
|
||||
std::unordered_map<std::string, ItemInfo> m_result;
|
||||
};
|
||||
} // namespace asst
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user