From b5f3748dc3381db14ac3cd2c183981052d86200c Mon Sep 17 00:00:00 2001 From: Brett Date: Wed, 7 Aug 2024 00:59:10 -0400 Subject: [PATCH] silly little functions --- CMakeLists.txt | 2 +- include/config.h | 9 ++-- include/float_operations.h | 6 +++ include/image_operations.h | 103 ++++++++++++++++++++++++++++++------- lib/blt-gp | 2 +- src/custom_transformer.cpp | 18 ++++--- src/main.cpp | 14 ++++- 7 files changed, 121 insertions(+), 33 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1232fc6..9af9f26 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.25) -project(image-gp-6 VERSION 0.0.21) +project(image-gp-6 VERSION 0.0.22) include(FetchContent) diff --git a/include/config.h b/include/config.h index ae49026..5a91e88 100644 --- a/include/config.h +++ b/include/config.h @@ -32,9 +32,8 @@ inline constexpr blt::size_t IMAGE_SIZE = 128; inline constexpr blt::size_t IMAGE_PADDING = 16; inline constexpr blt::size_t POP_SIZE = 64; inline constexpr blt::size_t CHANNELS = 3; -inline constexpr blt::size_t DATA_SIZE = IMAGE_SIZE * IMAGE_SIZE; -inline constexpr blt::size_t DATA_CHANNELS_SIZE = DATA_SIZE * CHANNELS; -inline constexpr blt::size_t BOX_COUNT = static_cast(log2(IMAGE_SIZE / 2)); +inline constexpr blt::u64 u64_size_min = 1; +inline constexpr blt::u64 u64_size_max = 9; inline constexpr float THRESHOLD = 0.3; inline constexpr auto load_image = "../GSab4SWWcAA1TNR.png"; @@ -56,6 +55,10 @@ inline blt::gp::prog_config_t config = blt::gp::prog_config_t() .set_pop_size(POP_SIZE) .set_thread_count(0); +inline constexpr blt::size_t DATA_SIZE = IMAGE_SIZE * IMAGE_SIZE; +inline constexpr blt::size_t DATA_CHANNELS_SIZE = DATA_SIZE * CHANNELS; +inline constexpr blt::size_t BOX_COUNT = static_cast(log2(IMAGE_SIZE / 2)); + inline blt::gp::type_provider type_system; inline blt::gp::gp_program program{type_system, SEED, config}; diff --git a/include/float_operations.h b/include/float_operations.h index 8101c02..9665ec6 100644 --- a/include/float_operations.h +++ b/include/float_operations.h @@ -39,6 +39,11 @@ inline blt::gp::operation_t f_literal([]() { return program.get_random().get_float(0.0, 1.0); }, "float_lit"); +// used for blur size +inline blt::gp::operation_t i_literal([]() { + return program.get_random().get_u64(u64_size_min, u64_size_max); +}, "int_lit"); + template void create_float_operations(blt::gp::operator_builder& builder) { @@ -47,6 +52,7 @@ void create_float_operations(blt::gp::operator_builder& builder) // builder.add_operator(f_mul); // builder.add_operator(f_pro_div); builder.add_operator(f_literal, true); + builder.add_operator(i_literal, true); } #endif //IMAGE_GP_6_FLOAT_OPERATIONS_H diff --git a/include/image_operations.h b/include/image_operations.h index 0998569..9d9cb4f 100644 --- a/include/image_operations.h +++ b/include/image_operations.h @@ -21,6 +21,8 @@ #include #include #include +#include "opencv2/imgcodecs.hpp" +#include "opencv2/imgproc.hpp" #ifndef IMAGE_GP_6_IMAGE_OPERATIONS_H #define IMAGE_GP_6_IMAGE_OPERATIONS_H @@ -44,6 +46,7 @@ inline blt::gp::operation_t op_atan(make_single((float (*)(float)) &std::atan), inline blt::gp::operation_t op_exp(make_single((float (*)(float)) &std::exp), "exp"); inline blt::gp::operation_t op_abs(make_single((float (*)(float)) &std::abs), "abs"); inline blt::gp::operation_t op_log(make_single((float (*)(float)) &std::log), "log"); +inline blt::gp::operation_t op_round(make_single((float (*)(float)) &std::round), "round"); inline blt::gp::operation_t op_v_mod([](const full_image_t& a, const full_image_t& b) { full_image_t img{}; for (blt::size_t i = 0; i < DATA_CHANNELS_SIZE; i++) @@ -99,29 +102,86 @@ inline blt::gp::operation_t dissolve([](const full_image_t& a, const full_image_ return img; }, "dissolve"); -inline blt::gp::operation_t band_pass([](const full_image_t& a, float min, float max) { - using blt::mem::type_cast; +inline blt::gp::operation_t band_pass([](const full_image_t& a, float fa, float fb, blt::u64 size) { + cv::Mat src(IMAGE_SIZE, IMAGE_SIZE, CV_32FC3, const_cast(a.rgb_data)); full_image_t img{}; - for (blt::size_t i = 0; i < DATA_CHANNELS_SIZE; i++) - { - if (a.rgb_data[i] >= min && a.rgb_data[i] <= max) - { - img.rgb_data[i] = a.rgb_data[i]; - } else if (a.rgb_data[i] < min) - { - auto dist_min = min == 0 ? 0.0f : (a.rgb_data[i] / min); - img.rgb_data[i] = a.rgb_data[i] * dist_min; - } else if (a.rgb_data[i] > max) - { - auto dist_max = max == 0 ? 0.0f : ((a.rgb_data[i] - max) / max); - img.rgb_data[i] = a.rgb_data[i] * dist_max; - } else { - img.rgb_data[i] = 0; - } - } + std::memcpy(img.rgb_data, a.rgb_data, DATA_CHANNELS_SIZE * sizeof(float)); + + cv::Mat dst{IMAGE_SIZE, IMAGE_SIZE, CV_32FC3, img.rgb_data}; + if (size % 2 == 0) + size++; + + auto min = fa < fb ? fa : fb; + auto max = fa > fb ? fa : fb; + + auto low = cv::getGaussianKernel(static_cast(size), min * ((static_cast(size) - 1) * 0.5 - 1) + 0.8, CV_32F); + auto high = cv::getGaussianKernel(static_cast(size), max * ((static_cast(size) - 1) * 0.5 - 1) + 0.8, CV_32F); + + auto func = high - low; + cv::Mat funcY; + cv::transpose(func, funcY); + cv::sepFilter2D(src, dst, 3, func, funcY); + return img; }, "band_pass"); +inline blt::gp::operation_t high_pass([](const full_image_t& a, blt::u64 size) { + full_image_t blur{}; + std::memcpy(blur.rgb_data, a.rgb_data, DATA_CHANNELS_SIZE * sizeof(float)); + full_image_t base{}; + std::memcpy(blur.rgb_data, a.rgb_data, DATA_CHANNELS_SIZE * sizeof(float)); + full_image_t ret{}; + + cv::Mat blur_mat{IMAGE_SIZE, IMAGE_SIZE, CV_32FC3, blur.rgb_data}; + cv::Mat base_mat{IMAGE_SIZE, IMAGE_SIZE, CV_32FC3, base.rgb_data}; + cv::Mat ret_mat{IMAGE_SIZE, IMAGE_SIZE, CV_32FC3, ret.rgb_data}; + if (size % 2 == 0) + size++; + + for (blt::u64 i = 1; i < size; i += 2) + cv::GaussianBlur(blur_mat, blur_mat, cv::Size(static_cast(i), static_cast(i)), 0, 0); + + cv::subtract(base_mat, blur_mat, ret_mat); + + return ret; +}, "high_pass"); + +inline blt::gp::operation_t gaussian_blur([](const full_image_t& a, blt::u64 size) { + full_image_t img{}; + std::memcpy(img.rgb_data, a.rgb_data, DATA_CHANNELS_SIZE * sizeof(float)); + + cv::Mat dst{IMAGE_SIZE, IMAGE_SIZE, CV_32FC3, img.rgb_data}; + if (size % 2 == 0) + size++; + + for (blt::u64 i = 1; i < size; i += 2) + cv::GaussianBlur(dst, dst, cv::Size(static_cast(i), static_cast(i)), 0, 0); + + return img; +}, "gaussian_blur"); + +inline blt::gp::operation_t median_blur([](const full_image_t& a, blt::u64 size) { + cv::Mat src(IMAGE_SIZE, IMAGE_SIZE, CV_32FC3, const_cast(a.rgb_data)); + full_image_t img{}; + cv::Mat dst{IMAGE_SIZE, IMAGE_SIZE, CV_32FC3, img.rgb_data}; + if (size % 2 == 0) + size++; + if (size > 5) + size = 5; + cv::medianBlur(src, dst, static_cast(size)); + return img; +}, "median_blur"); + +inline blt::gp::operation_t bilateral_filter([](const full_image_t& a, blt::u64 size) { + cv::Mat src(IMAGE_SIZE, IMAGE_SIZE, CV_32FC3, const_cast(a.rgb_data)); + full_image_t img{}; + cv::Mat dst{IMAGE_SIZE, IMAGE_SIZE, CV_32FC3, img.rgb_data}; + if (size % 2 == 0) + size++; + cv::bilateralFilter(src, dst, static_cast(size), static_cast(size) * 2, static_cast(size) / 2.0); + return img; +}, "bilateral_filter"); + inline blt::gp::operation_t hsv_to_rgb([](const full_image_t& a) { using blt::mem::type_cast; full_image_t img{}; @@ -316,6 +376,7 @@ void create_image_operations(blt::gp::operator_builder& builder) builder.add_operator(op_exp); builder.add_operator(op_log); builder.add_operator(op_abs); + //builder.add_operator(op_round); builder.add_operator(op_v_mod); builder.add_operator(bitwise_and); builder.add_operator(bitwise_or); @@ -324,6 +385,10 @@ void create_image_operations(blt::gp::operator_builder& builder) builder.add_operator(dissolve); builder.add_operator(band_pass); builder.add_operator(hsv_to_rgb); + builder.add_operator(gaussian_blur); + builder.add_operator(median_blur); + builder.add_operator(bilateral_filter); + builder.add_operator(high_pass); bool state = false; builder.add_operator(lit, true); diff --git a/lib/blt-gp b/lib/blt-gp index b10b438..407273d 160000 --- a/lib/blt-gp +++ b/lib/blt-gp @@ -1 +1 @@ -Subproject commit b10b4388897b1673b0dbe84b1db34584db0e9660 +Subproject commit 407273d0dcd86cb3f2030ca9b470cfa78958f23d diff --git a/src/custom_transformer.cpp b/src/custom_transformer.cpp index 18481b9..9032ff6 100644 --- a/src/custom_transformer.cpp +++ b/src/custom_transformer.cpp @@ -84,11 +84,15 @@ namespace blt::gp if (node.type_size == sizeof(float)) { auto& val = vals.from(bytes_from_head); - auto old = val; val += f_literal.get_function()(); val /= 2.0f; - if (std::isnan(val)) - val = old; + } else if (node.type_size == sizeof(blt::u64)) // is u64 + { + auto& val = vals.from(bytes_from_head); + if (program.get_random().choice()) + val = program.get_random().get_u64(val, u64_size_max); + else + val = program.get_random().get_u64(u64_size_min, val + 1); } else // is an image { auto& val = vals.from(bytes_from_head); @@ -97,9 +101,10 @@ namespace blt::gp // Annoying. TODO: fix all of this. operator_id id; - do{ + do + { id = program.get_random().select(terminals); - } while(!program.is_static(id)); + } while (!program.is_static(id)); stack_allocator stack; @@ -110,12 +115,9 @@ namespace blt::gp for (const auto& [index, value] : blt::enumerate(val.rgb_data)) { - auto old = value; // add and normalize. value += adjustment.rgb_data[index]; value /= 2.0f; - if (std::isnan(value)) - value = old; } } } diff --git a/src/main.cpp b/src/main.cpp index d0a55f0..a868079 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -42,7 +42,7 @@ blt::gfx::resource_manager resources; blt::gfx::batch_renderer_2d renderer_2d(resources, global_matrices); blt::gfx::first_person_camera_2d camera; -static constexpr blt::size_t TYPE_COUNT = 2; +static constexpr blt::size_t TYPE_COUNT = 3; std::array fitness_values{}; double last_fitness = 0; @@ -51,6 +51,7 @@ double hovered_fitness_value = 0; bool evaluate = true; std::array has_literal_converter = { + true, true, true }; @@ -75,6 +76,16 @@ std::array(c1_out_ptr); auto& c2_out = *static_cast(c2_out_ptr); + auto diff = p1_in - p2_in; + c1_out = p1_in - diff; + c2_out = p2_in + diff; + }, + [](blt::gp::gp_program&, void* p1_in_ptr, void* p2_in_ptr, void* c1_out_ptr, void* c2_out_ptr) { + auto& p1_in = *static_cast(p1_in_ptr); + auto& p2_in = *static_cast(p2_in_ptr); + auto& c1_out = *static_cast(c1_out_ptr); + auto& c2_out = *static_cast(c2_out_ptr); + auto diff = p1_in - p2_in; c1_out = p1_in - diff; c2_out = p2_in + diff; @@ -317,6 +328,7 @@ void init(const blt::gfx::window_data&) BLT_DEBUG("Setup Types and Operators"); type_system.register_type(); type_system.register_type(); + type_system.register_type(); blt::gp::operator_builder builder{type_system}; create_image_operations(builder);