From b8e55a102e4310e067e5e9f977735592beb0873c Mon Sep 17 00:00:00 2001 From: Brett Date: Sun, 4 Feb 2024 18:54:38 -0500 Subject: [PATCH] asd --- CMakeLists.txt | 5 +- images/029a_-_Survival_of_the_Idiots_349.jpg | Bin 0 -> 40308 bytes include/functions.h | 2 + include/image.h | 6 +- src/functions.cpp | 50 +++++++-- src/main.cpp | 111 ++++++++++++------- 6 files changed, 119 insertions(+), 55 deletions(-) create mode 100755 images/029a_-_Survival_of_the_Idiots_349.jpg diff --git a/CMakeLists.txt b/CMakeLists.txt index c89645f..2516c13 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,7 +29,10 @@ add_subdirectory(libraries/BLT-With-Graphics-Template) include_directories(include/) file(GLOB_RECURSE PROJECT_BUILD_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") -add_dependencies(BLT stats_lib_bindings_rust) +#set(META_LIBS common/pdqhashtypes.cpp io/hashio.cpp common/pdqhamming.cpp hashing/pdqhashing.cpp downscaling/downscaling.cpp hashing/torben.cpp) +#include_directories(libraries/ThreatExchange) +# +#list(TRANSFORM META_LIBS PREPEND ${CMAKE_SOURCE_DIR}/libraries/ThreatExchange/pdq/cpp/) add_executable(gp_image_test ${PROJECT_BUILD_FILES}) diff --git a/images/029a_-_Survival_of_the_Idiots_349.jpg b/images/029a_-_Survival_of_the_Idiots_349.jpg new file mode 100755 index 0000000000000000000000000000000000000000..5a9cdbf0f64df8c124be107ab204bca842fe27a3 GIT binary patch literal 40308 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 T#D6hKLjCW{`Or*%h>!o-%znT@ literal 0 HcmV?d00001 diff --git a/include/functions.h b/include/functions.h index 0095899..cff6082 100644 --- a/include/functions.h +++ b/include/functions.h @@ -264,6 +264,8 @@ float eval_DNF_SW(const image& img); float eval_DNF_SW_1(const image& img); +float eval_BAM(const image& img, const image& compare, float allowed_diff); + //template //bool isNan(F f) //{ diff --git a/include/image.h b/include/image.h index c0f4cf5..2ecc374 100644 --- a/include/image.h +++ b/include/image.h @@ -62,7 +62,7 @@ class image }, copy.data); } - image(image&& move) + image(image&& move) noexcept { data = std::move(move.data); move.data = nullptr; @@ -92,7 +92,7 @@ class image return *this; }; - image& operator=(image&& move) + image& operator=(image&& move) noexcept { std::swap(move.data, data); return *this; @@ -165,7 +165,7 @@ class image return std::visit(blt::lambda_visitor{ [x, y](const image_data_t* d) -> blt::vec3 { if (x < 0 || y < 0 || x >= width || y >= height) - return blt::vec3{0,0,0}; + return blt::vec3{0, 0, 0}; return (*d)[y * height + x]; }, [](const blt::vec3& v) -> blt::vec3 { diff --git a/src/functions.cpp b/src/functions.cpp index 7c74cb0..56fb804 100644 --- a/src/functions.cpp +++ b/src/functions.cpp @@ -243,9 +243,9 @@ void f_equ(image& img, float x, float y, blt::size_t argc, const image** argv, c GET_IMAGE(i2, 1); if (f_comp(i1.x(), i2.x()) && f_comp(i1.y(), i2.y()) && f_comp(i1.z(), i2.z())) - img.set({1,1,1}, xi, yi); + img.set({1, 1, 1}, xi, yi); else - img.set({0,0,0}, xi, yi); + img.set({0, 0, 0}, xi, yi); } void f_lt(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data) @@ -255,9 +255,9 @@ void f_lt(image& img, float x, float y, blt::size_t argc, const image** argv, co GET_IMAGE(i2, 1); if (i1.x() < i2.x() && i1.y() < i2.y() && i1.z() < i2.z()) - img.set({1,1,1}, xi, yi); + img.set({1, 1, 1}, xi, yi); else - img.set({0,0,0}, xi, yi); + img.set({0, 0, 0}, xi, yi); } void f_gt(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data) @@ -267,9 +267,9 @@ void f_gt(image& img, float x, float y, blt::size_t argc, const image** argv, co GET_IMAGE(i2, 1); if (i1.x() > i2.x() && i1.y() > i2.y() && i1.z() > i2.z()) - img.set({1,1,1}, xi, yi); + img.set({1, 1, 1}, xi, yi); else - img.set({0,0,0}, xi, yi); + img.set({0, 0, 0}, xi, yi); } void f_lte(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data) @@ -279,9 +279,9 @@ void f_lte(image& img, float x, float y, blt::size_t argc, const image** argv, c GET_IMAGE(i2, 1); if (i1.x() <= i2.x() && i1.y() <= i2.y() && i1.z() <= i2.z()) - img.set({1,1,1}, xi, yi); + img.set({1, 1, 1}, xi, yi); else - img.set({0,0,0}, xi, yi); + img.set({0, 0, 0}, xi, yi); } void f_gte(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data) @@ -291,9 +291,9 @@ void f_gte(image& img, float x, float y, blt::size_t argc, const image** argv, c GET_IMAGE(i2, 1); if (i1.x() >= i2.x() && i1.y() >= i2.y() && i1.z() >= i2.z()) - img.set({1,1,1}, xi, yi); + img.set({1, 1, 1}, xi, yi); else - img.set({0,0,0}, xi, yi); + img.set({0, 0, 0}, xi, yi); } double on_data(const double* data, blt::size_t len) @@ -349,11 +349,13 @@ float eval_DNF_SW_1(const image& img) std::vector order(width * height); for (const auto& v : img.getData()) + { order.push_back(v.magnitude()); + } std::sort(order.begin(), order.end()); - blt::size_t len = width; + blt::size_t len = width * 4; blt::size_t current_pos = 0; double total = 0; while (true) @@ -371,3 +373,29 @@ float eval_DNF_SW_1(const image& img) return static_cast(total); } +float eval_BAM(const image& img, const image& compare, float allowed_diff) +{ + float values = 1; + for (blt::i32 i = 0; i < width; i++) + { + for (blt::i32 j = 0; j < height; j++) + { + auto v1 = img.get(i, j); + auto v2 = compare.get(i, j); + + auto r = std::abs(v1.x() - v2.x()); + auto g = std::abs(v1.y() - v2.y()); + auto b = std::abs(v1.z() - v2.z()); + + if (r <= allowed_diff) + values += 1 - r; + if (g <= allowed_diff) + values += 1 - g; + if (b <= allowed_diff) + values += 1 - b; + + } + } + return values; +} + diff --git a/src/main.cpp b/src/main.cpp index b3a9271..d080927 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include "blt/gfx/renderer/resource_manager.h" #include "blt/gfx/renderer/batch_2d_renderer.h" @@ -25,9 +26,38 @@ blt::gfx::matrix_state_manager global_matrices; blt::gfx::resource_manager resources; blt::gfx::batch_renderer_2d renderer_2d(resources); +image compare; + class tree { public: +#define CROSSOVER_ERRORS \ + INST_ENUM(NULL_PARENT1) \ + INST_ENUM(NULL_PARENT2) \ + INST_ENUM(NULL_TREE1) \ + INST_ENUM(NULL_TREE2) \ + INST_ENUM(TYPE_NOT_ALLOWED_CHILD1) \ + INST_ENUM(TYPE_NOT_ALLOWED_CHILD2) + +#define INST_ENUM(TYPE) TYPE, + + enum class crossover_error_t + { + CROSSOVER_ERRORS + }; + +#undef INST_ENUM +#define INST_ENUM(TYPE) case crossover_error_t::TYPE: return #TYPE; + + static inline std::string crossover_error_to_string(crossover_error_t error) + { + switch (error) + { + CROSSOVER_ERRORS + } + return ""; + } + struct search_result_t { node* child; @@ -93,7 +123,7 @@ class tree while (true) { std::uniform_int_distribution children(0, current->argc - 1); - if (select(engine) == 0 || current->argc == 0) + if (parent != nullptr && (select(engine) == 0 || current->argc == 0)) break; index = children(engine); auto* next = current->sub_nodes[index]; @@ -102,6 +132,7 @@ class tree parent = current; current = next; } + return {current, parent, index}; } @@ -142,26 +173,30 @@ class tree return max_depth; } - static std::optional crossover(tree* p1, tree* p2) + static blt::expected crossover(tree* p1, tree* p2) { - if (p1 == nullptr || p2 == nullptr) - return {}; + if (p1 == nullptr) + return blt::unexpected(crossover_error_t::NULL_TREE1); + if (p2 == nullptr) + return blt::unexpected(crossover_error_t::NULL_TREE2); auto c1 = p1->clone(); auto c2 = p2->clone(); auto n1 = c1->select_random_child(); auto n2 = c2->select_random_child(); - if (n1.parent == nullptr || n2.parent == nullptr) - return {}; + if (n1.parent == nullptr) + return blt::unexpected(crossover_error_t::NULL_PARENT1); + if (n2.parent == nullptr) + return blt::unexpected(crossover_error_t::NULL_PARENT2); const auto& p1_allowed = function_arg_allowed_set_map[to_underlying(n1.parent->type)][n1.index]; const auto& p2_allowed = function_arg_allowed_set_map[to_underlying(n2.parent->type)][n2.index]; if (!p1_allowed.contains(n2.child->type)) - return {}; + return blt::unexpected(crossover_error_t::TYPE_NOT_ALLOWED_CHILD1); if (!p2_allowed.contains(n1.child->type)) - return {}; + return blt::unexpected(crossover_error_t::TYPE_NOT_ALLOWED_CHILD2); n1.parent->sub_nodes[n1.index] = n2.child; n2.parent->sub_nodes[n2.index] = n1.child; @@ -216,7 +251,7 @@ class tree float fitness() { auto& img = root->getImage(); - return eval_DNF_SW(img) * eval_DNF_SW_1(img) * static_cast(std::min(depth(root.get()), 5ul)); + return eval_BAM(img, compare, 0.1) * eval_DNF_SW_1(img) * static_cast(std::min(depth(root.get()), 5ul)); } void printTree() @@ -228,10 +263,6 @@ class tree class gp_population { public: - enum class crossover_error_t - { - - }; struct selection { blt::size_t index; @@ -329,6 +360,9 @@ class gp_population new_pop[p1.index] = {std::move(r->c1)}; new_pop[p2.index] = {std::move(r->c2)}; crossover_count++; + } else + { + BLT_ERROR(tree::crossover_error_to_string(r.error())); } } } @@ -417,33 +451,6 @@ void print_bits(float f) std::cout << std::endl; } -enum class error -{ - S1, S2, S3 -}; - -struct simple -{ - float f; - - simple(const simple& nontrival) - { - if (nontrival.f < 50) - f = 5000; - else - f = nontrival.f; - } -}; - -blt::expected t1(bool b) -{ - float f = 50.0f * b; - if (b) - return f; - else - return blt::unexpected(error::S1); -} - void init() { global_matrices.create_internals(); @@ -453,6 +460,30 @@ void init() resources.set("img", texture); resources.enqueue("../libraries/BLT-With-Graphics-Template/resources/textures/parkerfemBOY.png", "cum"); + int x, y, channels; + auto data = stbi_load("../images/029a_-_Survival_of_the_Idiots_349.jpg", &x, &y, &channels, 3); + + if (data == nullptr) + throw std::runtime_error("failed to load compare image!"); + + auto resized = stbir_resize_uint8_linear(data, x, y, 0, nullptr, width, height, 0, (stbir_pixel_layout) 3); + + for (int j = 0; j < height; j++) + { + for (int i = 0; i < width; i++) + { + blt::size_t loc = (j * width + i) * 3; +#define CONVERT(v) static_cast(v) / static_cast(std::numeric_limits::max()) + compare.set(blt::vec3{CONVERT(resized[loc]), CONVERT(resized[loc + 1]), CONVERT(resized[loc + 2])}, i, height - 1 - j); +#undef CONVERT + } + } + + texture->upload((void*) compare.getData().data(), GL_RGB, 0, 0, 0, -1, -1, GL_FLOAT); + + stbi_image_free(data); + stbi_image_free(resized); + resources.load_resources(); }