diff --git a/SerialPrograms/CMakeLists.txt b/SerialPrograms/CMakeLists.txt index da51665b98..7581f0e101 100644 --- a/SerialPrograms/CMakeLists.txt +++ b/SerialPrograms/CMakeLists.txt @@ -1330,6 +1330,8 @@ file(GLOB MAIN_SOURCES Source/PokemonSV/Inference/Overworld/PokemonSV_LetsGoKillDetector.h Source/PokemonSV/Inference/Overworld/PokemonSV_OverworldDetector.cpp Source/PokemonSV/Inference/Overworld/PokemonSV_OverworldDetector.h + Source/PokemonSV/Inference/Overworld/PokemonSV_StationaryOverworldWatcher.cpp + Source/PokemonSV/Inference/Overworld/PokemonSV_StationaryOverworldWatcher.h Source/PokemonSV/Inference/Picnics/PokemonSV_PicnicDetector.cpp Source/PokemonSV/Inference/Picnics/PokemonSV_PicnicDetector.h Source/PokemonSV/Inference/Picnics/PokemonSV_SandwichHandDetector.cpp diff --git a/SerialPrograms/SerialPrograms.pro b/SerialPrograms/SerialPrograms.pro index 8f4cdea9a4..63d4c19371 100644 --- a/SerialPrograms/SerialPrograms.pro +++ b/SerialPrograms/SerialPrograms.pro @@ -665,6 +665,7 @@ SOURCES += \ Source/PokemonSV/Inference/Overworld/PokemonSV_LetsGoHpReader.cpp \ Source/PokemonSV/Inference/Overworld/PokemonSV_LetsGoKillDetector.cpp \ Source/PokemonSV/Inference/Overworld/PokemonSV_OverworldDetector.cpp \ + Source/PokemonSV/Inference/Overworld/PokemonSV_StationaryOverworldWatcher.cpp \ Source/PokemonSV/Inference/Picnics/PokemonSV_PicnicDetector.cpp \ Source/PokemonSV/Inference/Picnics/PokemonSV_SandwichHandDetector.cpp \ Source/PokemonSV/Inference/Picnics/PokemonSV_SandwichIngredientDetector.cpp \ @@ -1759,6 +1760,7 @@ HEADERS += \ Source/PokemonSV/Inference/Overworld/PokemonSV_LetsGoHpReader.h \ Source/PokemonSV/Inference/Overworld/PokemonSV_LetsGoKillDetector.h \ Source/PokemonSV/Inference/Overworld/PokemonSV_OverworldDetector.h \ + Source/PokemonSV/Inference/Overworld/PokemonSV_StationaryOverworldWatcher.h \ Source/PokemonSV/Inference/Picnics/PokemonSV_PicnicDetector.h \ Source/PokemonSV/Inference/Picnics/PokemonSV_SandwichHandDetector.h \ Source/PokemonSV/Inference/Picnics/PokemonSV_SandwichIngredientDetector.h \ diff --git a/SerialPrograms/Source/PokemonSV/Inference/Overworld/PokemonSV_StationaryOverworldWatcher.cpp b/SerialPrograms/Source/PokemonSV/Inference/Overworld/PokemonSV_StationaryOverworldWatcher.cpp new file mode 100644 index 0000000000..2fb9499603 --- /dev/null +++ b/SerialPrograms/Source/PokemonSV/Inference/Overworld/PokemonSV_StationaryOverworldWatcher.cpp @@ -0,0 +1,77 @@ +/* Stationary Overworld Detector + * + * From: https://github.com/PokemonAutomation/Arduino-Source + * + */ + +#include "Kernels/Waterfill/Kernels_Waterfill_Session.h" +#include "CommonFramework/Globals.h" +#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h" +#include "CommonFramework/ImageMatch/ImageDiff.h" +#include "CommonFramework/ImageMatch/ExactImageMatcher.h" +#include "CommonFramework/ImageTools/BinaryImage_FilterRgb32.h" +#include "CommonFramework/ImageTools/WaterfillUtilities.h" +#include "CommonFramework/ImageMatch/WaterfillTemplateMatcher.h" +#include "PokemonSV_StationaryOverworldWatcher.h" + +//#include +//using std::cout; +//using std::endl; + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonSV{ + + + + + +StationaryOverworldWatcher::StationaryOverworldWatcher(Color color, ImageFloatBox box, size_t seconds_stationary) + : VisualInferenceCallback("StationaryOverworldWatcher") + , m_color(color) + , m_box(box) + , m_overworld_detector(color) + , m_map_hold_duration(std::chrono::milliseconds(seconds_stationary * 1000)) +{} + +void StationaryOverworldWatcher::make_overlays(VideoOverlaySet& items) const{ + items.add(m_color, m_box); +} + +bool StationaryOverworldWatcher::process_frame(const VideoSnapshot& frame){ + if (!m_overworld_detector.detect(frame)){ + m_snapshot_start.clear(); + return false; + } + + if (!m_snapshot_start){ + m_snapshot_start = frame; + return false; + } + + // Check if radar map stays still for `m_map_hold_duration` + + // Mismatching image sizes. + ImageViewRGB32 start = extract_box_reference(m_snapshot_start, m_box); + ImageViewRGB32 current = extract_box_reference(frame, m_box); + if (start.width() != current.width() || start.height() != current.height()){ + m_snapshot_start = frame; + return false; + } + + double rmsd = ImageMatch::pixel_RMSD(start, current); +// cout << "rmsd = " << rmsd << endl; + if (rmsd > 2.0){ // Image of radar map has changed too much. + m_snapshot_start = frame; + return false; + } + + // Make sure radar map held for long enough. + return frame.timestamp - m_snapshot_start.timestamp >= m_map_hold_duration; +} + + + +} +} +} \ No newline at end of file diff --git a/SerialPrograms/Source/PokemonSV/Inference/Overworld/PokemonSV_StationaryOverworldWatcher.h b/SerialPrograms/Source/PokemonSV/Inference/Overworld/PokemonSV_StationaryOverworldWatcher.h new file mode 100644 index 0000000000..affb0938d3 --- /dev/null +++ b/SerialPrograms/Source/PokemonSV/Inference/Overworld/PokemonSV_StationaryOverworldWatcher.h @@ -0,0 +1,46 @@ +/* Stationary Overworld Detector + * + * From: https://github.com/PokemonAutomation/Arduino-Source + * + */ + +#ifndef PokemonAutomation_PokemonSV_StationaryOverworldWatcher_H +#define PokemonAutomation_PokemonSV_StationaryOverworldWatcher_H + +#include "Common/Cpp/Color.h" +#include "CommonFramework/ImageTools/ImageBoxes.h" +#include "CommonFramework/VideoPipeline/VideoFeed.h" +#include "CommonFramework/InferenceInfra/VisualInferenceCallback.h" +#include "CommonFramework/Inference/VisualDetector.h" +#include "PokemonSV/Inference/Overworld/PokemonSV_OverworldDetector.h" + + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonSV{ + + + +class StationaryOverworldWatcher : public VisualInferenceCallback{ +public: + StationaryOverworldWatcher(Color color = COLOR_RED, ImageFloatBox box = {0.865, 0.82, 0.08, 0.1}, size_t seconds_stationary = 5); + + virtual void make_overlays(VideoOverlaySet& items) const override; + // return true if the screen within `m_box` doesn't change for am amount of time as per `seconds_stationary` + // the overworld must be detected throughout this. + virtual bool process_frame(const VideoSnapshot& frame) override; + + +private: + const Color m_color; + const ImageFloatBox m_box; + const OverworldDetector m_overworld_detector; + const std::chrono::milliseconds m_map_hold_duration; + VideoSnapshot m_snapshot_start; +}; + + +} +} +} +#endif