feat: 支持识别长于一页的掉落列表 (#7202)

This commit is contained in:
MistEO
2023-11-10 14:20:23 +08:00
committed by GitHub
3 changed files with 74 additions and 2 deletions

View File

@@ -4,7 +4,9 @@
#include <regex>
#include <thread>
#include "Common/AsstTypes.h"
#include "Common/AsstVersion.h"
#include "Config/GeneralConfig.h"
#include "Config/Miscellaneous/ItemConfig.h"
#include "Config/Miscellaneous/StageDropsConfig.h"
#include "Config/TaskData.h"
@@ -13,6 +15,7 @@
#include "Task/ProcessTask.h"
#include "Task/ReportDataTask.h"
#include "Utils/Logger.hpp"
#include "Vision/Matcher.h"
#include "Vision/Miscellaneous/StageDropsImageAnalyzer.h"
bool asst::StageDropsTaskPlugin::verify(AsstMsg msg, const json::value& details) const
@@ -110,7 +113,33 @@ bool asst::StageDropsTaskPlugin::recognize_drops()
}
StageDropsImageAnalyzer analyzer(ctrler()->get_image());
bool ret = analyzer.analyze();
bool ret = false;
while (!need_exit()) {
ret = false;
// more materials to reveal?
auto swipe_begin = Point { WindowWidthDefault - 40, 632 };
const int swipe_dist = 200;
ctrler()->swipe(swipe_begin, swipe_begin + swipe_dist * Point::left(), 500, true, 2, 0);
sleep(Config.get_options().task_delay * 3);
auto new_img = ctrler()->get_image();
const auto offset_opt = analyzer.merge_image(new_img);
if (!offset_opt.has_value()) break;
const auto offset = offset_opt.value();
Log.trace("new image offset:", offset);
if (offset <= 4) {
ret = true;
break;
}
}
// image strip constructed, start main step
ret &= analyzer.analyze();
auto&& [code, difficulty] = analyzer.get_stage_key();
m_stage_code = std::move(code);

View File

@@ -1,6 +1,7 @@
#include "StageDropsImageAnalyzer.h"
#include <numbers>
#include <opencv2/core/mat.hpp>
#include <regex>
#include "Utils/Ranges.hpp"
@@ -361,10 +362,41 @@ bool asst::StageDropsImageAnalyzer::analyze_drops_for_12()
return !flag_analyzer.analyze();
}
std::optional<int> asst::StageDropsImageAnalyzer::merge_image(const cv::Mat& new_img)
{
LogTraceFunction;
const cv::Rect ref_roi = { m_image.cols - 320, 530, 280, 100 };
Matcher offset_match(new_img(cv::Rect { 0, ref_roi.y, new_img.cols, ref_roi.height }));
offset_match.set_templ(m_image(ref_roi));
offset_match.set_threshold(0.7);
if (!offset_match.analyze()) {
Log.error("Unable to merge images");
return std::nullopt;
}
const int offset = (new_img.cols - offset_match.get_result().rect.x) - (m_image.cols - ref_roi.x);
const int rel_x = offset + m_image.cols - new_img.cols;
const cv::Rect overlay_rect = { 540, 500, 740, 220 };
cv::Rect overlay_rect_on_strip = overlay_rect;
overlay_rect_on_strip.x += rel_x;
cv::Mat new_strip = cv::Mat { m_image.rows, overlay_rect_on_strip.br().x, m_image.type(), cv::Scalar(0) };
m_image.copyTo(new_strip(cv::Rect { 0, 0, m_image.cols, m_image.rows }));
new_img(overlay_rect).copyTo(new_strip(overlay_rect_on_strip));
m_image = new_strip;
return offset;
}
bool asst::StageDropsImageAnalyzer::analyze_baseline()
{
LogTraceFunction;
m_baseline.clear();
auto task_ptr = Task.get<MatchTaskInfo>("StageDrops-BaseLine");
cv::Mat preprocessed_roi;
@@ -386,7 +418,9 @@ bool asst::StageDropsImageAnalyzer::analyze_baseline()
cv::getStructuringElement(cv::MORPH_RECT, { 3, 1 }));
// cropping after derivatives, dilation, and erosion
cv::cvtColor(preprocessed_roi(make_rect<cv::Rect>(task_ptr->roi)), preprocessed_roi, cv::COLOR_BGR2GRAY);
auto roi = make_rect<cv::Rect>(task_ptr->roi);
roi.width = WindowWidthDefault - roi.br().x + m_image.cols; // image may be wider than 1280
cv::cvtColor(preprocessed_roi(roi), preprocessed_roi, cv::COLOR_BGR2GRAY);
}
cv::Mat preprocessed_bin;
@@ -457,6 +491,10 @@ bool asst::StageDropsImageAnalyzer::analyze_baseline()
Log.trace(__FUNCTION__, "baseline", key.to_string());
}
if (m_image.cols - (x_offset + bounding_rect.width) < 30 + max_spacing) {
Log.trace("bounding_rect.right=", x_offset + bounding_rect.width, ", more materials to reveal?");
} // TODO: else tell caller to prevent unnecessary swipe
return !m_baseline.empty();
}

View File

@@ -23,6 +23,11 @@ namespace asst
// <drop_type, <item_id, quantity>>
const auto& get_drops() const noexcept { return m_drops; }
// merge a new image with a different material position into m_image
// might resize m_image.
// return offset in pixels
std::optional<int> merge_image(const cv::Mat& new_img);
protected:
bool analyze_stage_code();
bool analyze_times();