diff --git a/SerialPrograms/Source/Tests/Kernels_Tests.cpp b/SerialPrograms/Source/Tests/Kernels_Tests.cpp index 247bee862..9ed097174 100644 --- a/SerialPrograms/Source/Tests/Kernels_Tests.cpp +++ b/SerialPrograms/Source/Tests/Kernels_Tests.cpp @@ -6,9 +6,16 @@ #include "Common/Compiler.h" +#include "Common/Cpp/Color.h" +#include "Common/Cpp/CpuId/CpuId.h" #include "Common/Cpp/Time.h" +#include "CommonFramework/ImageTypes/BinaryImage.h" +#include "CommonFramework/ImageTools/ImageBoxes.h" #include "CommonFramework/ImageTypes/ImageRGB32.h" +#include "CommonFramework/ImageTools/ImageFilter.h" #include "CommonFramework/ImageTypes/ImageViewRGB32.h" +#include "Kernels/BinaryMatrix/Kernels_BinaryMatrix.h" +#include "Kernels/BinaryImageFilters/Kernels_BinaryImage_BasicFilters.h" #include "Kernels/ImageScaleBrightness/Kernels_ImageScaleBrightness.h" #include "Kernels_Tests.h" @@ -16,16 +23,29 @@ using std::cout; using std::cerr; using std::endl; +using std::flush; namespace PokemonAutomation{ using namespace Kernels; -// using namespace NintendoSwitch::PokemonLA; +namespace Kernels{ + +std::unique_ptr make_PackedBinaryMatrix_64x4_Default(size_t width, size_t height); + +void compress_rgb32_to_binary_range_64x4_Default( + const uint32_t* image, size_t bytes_per_row, + PackedBinaryMatrix_IB& matrix0, uint32_t mins0, uint32_t maxs0 +); + + +} + + int test_kernels_ImageScaleBrightness(const ImageViewRGB32& image){ ImageRGB32 new_image = image.copy(); - int num_iterations = 5000; + int num_iterations = 500; auto time_start = current_time(); for(int i = 0; i < num_iterations; i++){ scale_brightness(new_image.width(), new_image.height(), new_image.data(), new_image.bytes_per_row(), 1.2f, 1.3f, 0.5f); @@ -40,4 +60,142 @@ int test_kernels_ImageScaleBrightness(const ImageViewRGB32& image){ return 0; } + +int test_kernels_BinaryMatrix(const ImageViewRGB32& image){ + const size_t width = image.width(); + const size_t height = image.height(); + + const uint32_t mins = combine_rgb(0, 0, 0); + // uint32_t maxs = combine_rgb(255, 255, 255); + const uint32_t maxs = combine_rgb(63, 63, 63); + + bool have_error = false; + + auto matrix_default = make_PackedBinaryMatrix_64x4_Default(width, height); + + compress_rgb32_to_binary_range_64x4_Default( + image.data(), image.bytes_per_row(), *matrix_default, mins, maxs + ); + + const size_t num_iter = 3000; + + { + auto time_start = current_time(); + for(size_t i = 0; i < num_iter; i++){ + compress_rgb32_to_binary_range_64x4_Default( + image.data(), image.bytes_per_row(), *matrix_default, mins, maxs + ); + } + auto time_end = current_time(); + const auto ms = std::chrono::duration_cast(time_end - time_start).count(); + cout << "Default impl. time: " << ms << " ms" << endl; + } + + // cout << matrix_default->dump() << flush; + + cout << "Testing current binary matrix construction from image" << endl; + auto matrix_type = get_BinaryMatrixType(); + auto matrix_current = make_PackedBinaryMatrix(matrix_type, width, height); + + compress_rgb32_to_binary_range( + image.data(), image.bytes_per_row(), *matrix_current, mins, maxs + ); + + for (size_t r = 0; r < height; r++){ + for (size_t c = 0; c < width; c++){ + const bool v_default = matrix_default->get(c, r); + const bool v_m1 = matrix_current->get(c, r); + if (v_default != v_m1){ + cout << "Error: matrix (" << c << ", " << r << ") not same: default: " + << v_default << ", M1: " << v_m1 << endl; + have_error = true; + } + } + } + if (have_error){ + return 1; + } + + { + auto time_start = current_time(); + for(size_t i = 0; i < num_iter; i++){ + compress_rgb32_to_binary_range( + image.data(), image.bytes_per_row(), *matrix_current, mins, maxs + ); + } + auto time_end = current_time(); + const auto ms = std::chrono::duration_cast(time_end - time_start).count(); + cout << "Cur impl. time: " << ms << " ms" << endl; + } + + return 0; +} + +int test_kernels_FilterRGB32(const ImageViewRGB32& image){ + + const size_t width = image.width(); + const size_t height = image.height(); + + const uint32_t mins = combine_rgb(0, 0, 0); + // uint32_t maxs = combine_rgb(255, 255, 255); + const uint32_t maxs = combine_rgb(63, 63, 63); + + bool have_error = false; + + const bool replace_color_within_range = true; + auto new_image = filter_rgb32_range(image, mins, maxs, COLOR_WHITE, replace_color_within_range); + + for (size_t r = 0; r < height; r++){ + for (size_t c = 0; c < width; c++){ + const Color color(image.pixel(c, r)); + const Color new_color(new_image.pixel(c, r)); + bool in_range = (color.red() <= 63 && color.green() <= 63 && color.blue() <= 63); + if (in_range && uint32_t(new_color) != uint32_t(COLOR_WHITE)){ + cout << "Error: wrong filter result: old color " << color.to_string() << ", (x,y) = " + << c << ", " << r << endl; + have_error = true; + return 1; + } + } + } + + // const size_t num_iter = 3000; + // auto time_start = current_time(); + // for(size_t i = 0; i < num_iter; i++){ + // filter_rgb32( + // matrix, new_image.data(), new_image.bytes_per_row(), uint32_t(COLOR_WHITE), replace_if_zero + // ); + // } + // auto time_end = current_time(); + // const auto ms = std::chrono::duration_cast(time_end - time_start).count(); + // cout << "Filter time: " << ms << " ms" << endl; + + + + if (have_error){ + return 1; + } + + return 0; +} + +int test_kernels_Waterfill(const ImageViewRGB32& image){ + + ImagePixelBox box(0, 0, image.width(), image.height()); + ImageViewRGB32 sub_image = extract_box_reference(image, box); + + PackedBinaryMatrix matrix(sub_image.width(), sub_image.height()); + uint32_t mins = combine_rgb(0, 0, 0); + // uint32_t maxs = combine_rgb(255, 255, 255); + uint32_t maxs = combine_rgb(63, 63, 63); + Kernels::compress_rgb32_to_binary_range( + sub_image.data(), sub_image.bytes_per_row(), + matrix, mins, maxs + ); + + cout << matrix.dump() << flush; + + return 0; +} + } diff --git a/SerialPrograms/Source/Tests/Kernels_Tests.h b/SerialPrograms/Source/Tests/Kernels_Tests.h index af35619f4..c9b70c3e2 100644 --- a/SerialPrograms/Source/Tests/Kernels_Tests.h +++ b/SerialPrograms/Source/Tests/Kernels_Tests.h @@ -15,6 +15,14 @@ class ImageViewRGB32; int test_kernels_ImageScaleBrightness(const ImageViewRGB32& image); +int test_kernels_BinaryMatrix(const ImageViewRGB32& image); + +int test_kernels_FilterRGB32(const ImageViewRGB32& image); + + +int test_kernels_Waterfill(const ImageViewRGB32& image); + + } #endif diff --git a/SerialPrograms/Source/Tests/PokemonLA_Tests.cpp b/SerialPrograms/Source/Tests/PokemonLA_Tests.cpp index ab50e69c2..d0619fcb1 100644 --- a/SerialPrograms/Source/Tests/PokemonLA_Tests.cpp +++ b/SerialPrograms/Source/Tests/PokemonLA_Tests.cpp @@ -449,10 +449,12 @@ int test_pokemonLA_MapMissionTabReader(const ImageViewRGB32& image, bool target) return 0; } -void test_pokemonLA_BerryTreeDetector(const ImageViewRGB32& image){ +int test_pokemonLA_BerryTreeDetector(const ImageViewRGB32& image){ BerryTreeDetector detector; detector.process_frame(image, current_time()); + + return 0; } int test_pokemonLA_SaveScreenDetector(const ImageViewRGB32& image, const std::vector& keywords){ diff --git a/SerialPrograms/Source/Tests/PokemonLA_Tests.h b/SerialPrograms/Source/Tests/PokemonLA_Tests.h index ceac03344..204a57541 100644 --- a/SerialPrograms/Source/Tests/PokemonLA_Tests.h +++ b/SerialPrograms/Source/Tests/PokemonLA_Tests.h @@ -51,7 +51,7 @@ int test_pokemonLA_BattleSpriteArrowDetector(const ImageViewRGB32& image, int ta int test_pokemonLA_MapMissionTabReader(const ImageViewRGB32& image, bool target); -void test_pokemonLA_BerryTreeDetector(const ImageViewRGB32& image); +int test_pokemonLA_BerryTreeDetector(const ImageViewRGB32& image); int test_pokemonLA_shinySoundDetector(const std::vector& spectrums, bool target); diff --git a/SerialPrograms/Source/Tests/TestMap.cpp b/SerialPrograms/Source/Tests/TestMap.cpp index 6426f53c4..b978727ee 100644 --- a/SerialPrograms/Source/Tests/TestMap.cpp +++ b/SerialPrograms/Source/Tests/TestMap.cpp @@ -44,7 +44,7 @@ using ImageIntDetectorFunction = std::function& words)>; -using ImageVoidDetectorFunction = std::function; +using ImageVoidDetectorFunction = std::function; using SoundBoolDetectorFunction = std::function& spectrums, bool target)>; @@ -159,8 +159,7 @@ int image_int_detector_helper(ImageIntDetectorFunction test_func, const std::str // debugging output. So no need to get target values from the test framework. int image_void_detector_helper(ImageVoidDetectorFunction test_func, const std::string& test_path){ auto run_test = [&](const ImageViewRGB32& image, const std::string&) -> int{ - test_func(image); - return 0; + return test_func(image); }; return image_filename_detector_helper(run_test, test_path); @@ -221,6 +220,9 @@ int sound_bool_detector_helper(SoundBoolDetectorFunction test_func, const std::s const std::map TEST_MAP = { {"Kernels_ImageScaleBrightness", std::bind(image_void_detector_helper, test_kernels_ImageScaleBrightness, _1)}, + {"Kernels_BinaryMatrix", std::bind(image_void_detector_helper, test_kernels_BinaryMatrix, _1)}, + {"Kernels_FilterRGB32", std::bind(image_void_detector_helper, test_kernels_FilterRGB32, _1)}, + {"Kernels_Waterfill", std::bind(image_void_detector_helper, test_kernels_Waterfill, _1)}, {"CommonFramework_BlackBorderDetector", std::bind(image_bool_detector_helper, test_CommonFramework_BlackBorderDetector, _1)}, {"NintendoSwitch_UpdateMenuDetector", std::bind(image_bool_detector_helper, test_NintendoSwitch_UpdateMenuDetector, _1)}, {"PokemonSwSh_YCommMenuDetector", std::bind(image_bool_detector_helper, test_pokemonSwSh_YCommMenuDetector, _1)},