diff --git a/SerialPrograms/CMakeLists.txt b/SerialPrograms/CMakeLists.txt index d139fd72f..ff7b79f24 100644 --- a/SerialPrograms/CMakeLists.txt +++ b/SerialPrograms/CMakeLists.txt @@ -1306,6 +1306,8 @@ file(GLOB MAIN_SOURCES Source/PokemonSV/Inference/ItemPrinter/PokemonSV_ItemPrinterMaterialDetector.h Source/PokemonSV/Inference/ItemPrinter/PokemonSV_ItemPrinterPrizeReader.cpp Source/PokemonSV/Inference/ItemPrinter/PokemonSV_ItemPrinterPrizeReader.h + Source/PokemonSV/Inference/Map/PokemonSV_DestinationMarkerDetector.cpp + Source/PokemonSV/Inference/Map/PokemonSV_DestinationMarkerDetector.h Source/PokemonSV/Inference/Map/PokemonSV_FastTravelDetector.cpp Source/PokemonSV/Inference/Map/PokemonSV_FastTravelDetector.h Source/PokemonSV/Inference/Map/PokemonSV_MapDetector.cpp diff --git a/SerialPrograms/SerialPrograms.pro b/SerialPrograms/SerialPrograms.pro index ef4b5fa72..0ce0e5072 100644 --- a/SerialPrograms/SerialPrograms.pro +++ b/SerialPrograms/SerialPrograms.pro @@ -653,6 +653,7 @@ SOURCES += \ Source/PokemonSV/Inference/ItemPrinter/PokemonSV_ItemPrinterJobsDetector.cpp \ Source/PokemonSV/Inference/ItemPrinter/PokemonSV_ItemPrinterMaterialDetector.cpp \ Source/PokemonSV/Inference/ItemPrinter/PokemonSV_ItemPrinterPrizeReader.cpp \ + Source/PokemonSV/Inference/Map/PokemonSV_DestinationMarkerDetector.cpp \ Source/PokemonSV/Inference/Map/PokemonSV_FastTravelDetector.cpp \ Source/PokemonSV/Inference/Map/PokemonSV_MapDetector.cpp \ Source/PokemonSV/Inference/Map/PokemonSV_MapMenuDetector.cpp \ @@ -1734,6 +1735,7 @@ HEADERS += \ Source/PokemonSV/Inference/ItemPrinter/PokemonSV_ItemPrinterJobsDetector.h \ Source/PokemonSV/Inference/ItemPrinter/PokemonSV_ItemPrinterMaterialDetector.h \ Source/PokemonSV/Inference/ItemPrinter/PokemonSV_ItemPrinterPrizeReader.h \ + Source/PokemonSV/Inference/Map/PokemonSV_DestinationMarkerDetector.h \ Source/PokemonSV/Inference/Map/PokemonSV_FastTravelDetector.h \ Source/PokemonSV/Inference/Map/PokemonSV_MapDetector.h \ Source/PokemonSV/Inference/Map/PokemonSV_MapMenuDetector.h \ diff --git a/SerialPrograms/Source/PokemonSV/Inference/Map/PokemonSV_DestinationMarkerDetector.cpp b/SerialPrograms/Source/PokemonSV/Inference/Map/PokemonSV_DestinationMarkerDetector.cpp new file mode 100644 index 000000000..7380f194d --- /dev/null +++ b/SerialPrograms/Source/PokemonSV/Inference/Map/PokemonSV_DestinationMarkerDetector.cpp @@ -0,0 +1,98 @@ +/* Destination Marker Detector + * + * From: https://github.com/PokemonAutomation/Arduino-Source + * + */ + +#include "Common/Cpp/Containers/FixedLimitVector.tpp" +#include "CommonFramework/ImageMatch/WaterfillTemplateMatcher.h" +#include "CommonFramework/ImageTypes/ImageViewRGB32.h" +#include "CommonFramework/ImageTools/WaterfillUtilities.h" +#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h" +#include "Kernels/Waterfill/Kernels_Waterfill_Types.h" +#include "PokemonSV_DestinationMarkerDetector.h" + +// #include +//using std::cout; +//using std::endl; + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonSV{ + +class DestinationMarkerMatcher : public ImageMatch::WaterfillTemplateMatcher{ +public: + + DestinationMarkerMatcher() : WaterfillTemplateMatcher( + "PokemonSV/Map/DestinationMarkerIcon-Template.png", Color(180,80,0), Color(255, 130, 50), 50 + ){ + m_aspect_ratio_lower = 0.8; + m_aspect_ratio_upper = 1.2; + m_area_ratio_lower = 0.8; + m_area_ratio_upper = 1.2; + + } + + static const ImageMatch::WaterfillTemplateMatcher& instance(){ + static DestinationMarkerMatcher matcher; + return matcher; + } +}; + + +DestinationMarkerDetector::~DestinationMarkerDetector() = default; + +DestinationMarkerDetector::DestinationMarkerDetector(Color color, const ImageFloatBox& box) + : m_color(color) + , m_box(box) +{} + +void DestinationMarkerDetector::make_overlays(VideoOverlaySet& items) const{ + items.add(m_color, m_box); +} + +bool DestinationMarkerDetector::detect(const ImageViewRGB32& screen) const{ + std::vector hits = detect_all(screen); + return !hits.empty(); +} + +std::vector DestinationMarkerDetector::detect_all(const ImageViewRGB32& screen) const{ + const std::vector> filters = { + {combine_rgb(180, 80, 0), combine_rgb(255, 130, 50)}, + + }; + + + const double rmsd_threshold = 80.0; // from my testing: RMSD is 15 at 1080p, 60 at 720p + + const double min_object_size = 150.0; + + const double screen_rel_size = (screen.height() / 1080.0); + const size_t min_size = size_t(screen_rel_size * screen_rel_size * min_object_size); + + std::vector found_locations; + + ImagePixelBox pixel_search_area = floatbox_to_pixelbox(screen.width(), screen.height(), m_box); + match_template_by_waterfill( + extract_box_reference(screen, m_box), + DestinationMarkerMatcher::instance(), + filters, + {min_size, SIZE_MAX}, + rmsd_threshold, + [&](Kernels::Waterfill::WaterfillObject& object) -> bool { + ImagePixelBox found_box( + object.min_x + pixel_search_area.min_x, object.min_y + pixel_search_area.min_y, + object.max_x + pixel_search_area.min_x, object.max_y + pixel_search_area.min_y); + found_locations.emplace_back(pixelbox_to_floatbox(screen.width(), screen.height(), found_box)); + return true; + } + ); + + return found_locations; +} + + + +} +} +} diff --git a/SerialPrograms/Source/PokemonSV/Inference/Map/PokemonSV_DestinationMarkerDetector.h b/SerialPrograms/Source/PokemonSV/Inference/Map/PokemonSV_DestinationMarkerDetector.h new file mode 100644 index 000000000..96702a5d4 --- /dev/null +++ b/SerialPrograms/Source/PokemonSV/Inference/Map/PokemonSV_DestinationMarkerDetector.h @@ -0,0 +1,60 @@ +/* Destination Marker Detector + * From: https://github.com/PokemonAutomation/Arduino-Source + * + */ + +#ifndef PokemonAutomation_PokemonSV_DestinationMarkerDetector_H +#define PokemonAutomation_PokemonSV_DestinationMarkerDetector_H + +#include +#include "Common/Cpp/Color.h" +#include "Common/Cpp/Containers/FixedLimitVector.h" +#include "CommonFramework/ImageTools/ImageBoxes.h" +#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h" +#include "CommonFramework/InferenceInfra/VisualInferenceCallback.h" +#include "CommonFramework/Inference/VisualDetector.h" + +namespace PokemonAutomation{ + +class VideoOverlaySet; +class VideoOverlay; +class OverlayBoxScope; + +namespace NintendoSwitch{ +namespace PokemonSV{ + +class DestinationMarkerDetector : public StaticScreenDetector{ +public: + DestinationMarkerDetector(Color color, const ImageFloatBox& box); + virtual ~DestinationMarkerDetector(); + + virtual void make_overlays(VideoOverlaySet& items) const override; + virtual bool detect(const ImageViewRGB32& screen) const override; + + std::vector detect_all(const ImageViewRGB32& screen) const; + +protected: + Color m_color; + ImageFloatBox m_box; +}; + + + +class DestinationMarkerWatcher : public DetectorToFinder{ + public: + DestinationMarkerWatcher( + Color color, + const ImageFloatBox& box, + std::chrono::milliseconds duration = std::chrono::milliseconds(250) + ) + : DetectorToFinder("DestinationMarkerWatcher", std::chrono::milliseconds(250), color, box) + {} +}; + + + + +} +} +} +#endif