Merge remote-tracking branch 'refs/remotes/origin/main'

main
Brett 2024-03-23 19:41:09 -04:00
commit 4b82f1bdb7
6 changed files with 119 additions and 28 deletions

View File

@ -29,7 +29,10 @@ add_subdirectory(libraries/BLT-With-Graphics-Template)
include_directories(include/) include_directories(include/)
file(GLOB_RECURSE PROJECT_BUILD_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") 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}) add_executable(gp_image_test ${PROJECT_BUILD_FILES})

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View File

@ -264,6 +264,8 @@ float eval_DNF_SW(const image& img);
float eval_DNF_SW_1(const image& img); float eval_DNF_SW_1(const image& img);
float eval_BAM(const image& img, const image& compare, float allowed_diff);
//template<typename F> //template<typename F>
//bool isNan(F f) //bool isNan(F f)
//{ //{

View File

@ -62,7 +62,7 @@ class image
}, copy.data); }, copy.data);
} }
image(image&& move) image(image&& move) noexcept
{ {
data = std::move(move.data); data = std::move(move.data);
move.data = nullptr; move.data = nullptr;
@ -92,7 +92,7 @@ class image
return *this; return *this;
}; };
image& operator=(image&& move) image& operator=(image&& move) noexcept
{ {
std::swap(move.data, data); std::swap(move.data, data);
return *this; return *this;
@ -165,7 +165,7 @@ class image
return std::visit(blt::lambda_visitor{ return std::visit(blt::lambda_visitor{
[x, y](const image_data_t* d) -> blt::vec3 { [x, y](const image_data_t* d) -> blt::vec3 {
if (x < 0 || y < 0 || x >= width || y >= height) 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]; return (*d)[y * height + x];
}, },
[](const blt::vec3& v) -> blt::vec3 { [](const blt::vec3& v) -> blt::vec3 {

View File

@ -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); GET_IMAGE(i2, 1);
if (f_comp(i1.x(), i2.x()) && f_comp(i1.y(), i2.y()) && f_comp(i1.z(), i2.z())) 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 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) 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); GET_IMAGE(i2, 1);
if (i1.x() < i2.x() && i1.y() < i2.y() && i1.z() < i2.z()) 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 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) 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); GET_IMAGE(i2, 1);
if (i1.x() > i2.x() && i1.y() > i2.y() && i1.z() > i2.z()) 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 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) 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); GET_IMAGE(i2, 1);
if (i1.x() <= i2.x() && i1.y() <= i2.y() && i1.z() <= i2.z()) 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 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) 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); GET_IMAGE(i2, 1);
if (i1.x() >= i2.x() && i1.y() >= i2.y() && i1.z() >= i2.z()) 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 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) double on_data(const double* data, blt::size_t len)
@ -349,11 +349,13 @@ float eval_DNF_SW_1(const image& img)
std::vector<double> order(width * height); std::vector<double> order(width * height);
for (const auto& v : img.getData()) for (const auto& v : img.getData())
{
order.push_back(v.magnitude()); order.push_back(v.magnitude());
}
std::sort(order.begin(), order.end()); std::sort(order.begin(), order.end());
blt::size_t len = width; blt::size_t len = width * 4;
blt::size_t current_pos = 0; blt::size_t current_pos = 0;
double total = 0; double total = 0;
while (true) while (true)
@ -371,3 +373,29 @@ float eval_DNF_SW_1(const image& img)
return static_cast<float>(total); return static_cast<float>(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;
}

View File

@ -3,6 +3,7 @@
#include <blt/gfx/window.h> #include <blt/gfx/window.h>
#include <blt/gfx/state.h> #include <blt/gfx/state.h>
#include <blt/gfx/stb/stb_image.h> #include <blt/gfx/stb/stb_image.h>
#include <blt/gfx/stb/stb_image_resize2.h>
#include <functions.h> #include <functions.h>
#include "blt/gfx/renderer/resource_manager.h" #include "blt/gfx/renderer/resource_manager.h"
#include "blt/gfx/renderer/batch_2d_renderer.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::resource_manager resources;
blt::gfx::batch_renderer_2d renderer_2d(resources); blt::gfx::batch_renderer_2d renderer_2d(resources);
image compare;
class tree class tree
{ {
public: 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 struct search_result_t
{ {
node* child; node* child;
@ -93,7 +123,7 @@ class tree
while (true) while (true)
{ {
std::uniform_int_distribution<size_t> children(0, current->argc - 1); std::uniform_int_distribution<size_t> children(0, current->argc - 1);
if (select(engine) == 0 || current->argc == 0) if (parent != nullptr && (select(engine) == 0 || current->argc == 0))
break; break;
index = children(engine); index = children(engine);
auto* next = current->sub_nodes[index]; auto* next = current->sub_nodes[index];
@ -102,6 +132,7 @@ class tree
parent = current; parent = current;
current = next; current = next;
} }
return {current, parent, index}; return {current, parent, index};
} }
@ -142,26 +173,30 @@ class tree
return max_depth; return max_depth;
} }
static std::optional<crossover_result_t> crossover(tree* p1, tree* p2) static blt::expected<crossover_result_t, crossover_error_t> crossover(tree* p1, tree* p2)
{ {
if (p1 == nullptr || p2 == nullptr) if (p1 == nullptr)
return {}; return blt::unexpected(crossover_error_t::NULL_TREE1);
if (p2 == nullptr)
return blt::unexpected(crossover_error_t::NULL_TREE2);
auto c1 = p1->clone(); auto c1 = p1->clone();
auto c2 = p2->clone(); auto c2 = p2->clone();
auto n1 = c1->select_random_child(); auto n1 = c1->select_random_child();
auto n2 = c2->select_random_child(); auto n2 = c2->select_random_child();
if (n1.parent == nullptr || n2.parent == nullptr) if (n1.parent == nullptr)
return {}; 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& 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]; const auto& p2_allowed = function_arg_allowed_set_map[to_underlying(n2.parent->type)][n2.index];
if (!p1_allowed.contains(n2.child->type)) 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)) 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; n1.parent->sub_nodes[n1.index] = n2.child;
n2.parent->sub_nodes[n2.index] = n1.child; n2.parent->sub_nodes[n2.index] = n1.child;
@ -216,7 +251,7 @@ class tree
float fitness() float fitness()
{ {
auto& img = root->getImage(); auto& img = root->getImage();
return eval_DNF_SW(img) * eval_DNF_SW_1(img) * static_cast<float>(std::min(depth(root.get()), 5ul)); return eval_BAM(img, compare, 0.1) * eval_DNF_SW_1(img) * static_cast<float>(std::min(depth(root.get()), 5ul));
} }
void printTree() void printTree()
@ -228,10 +263,6 @@ class tree
class gp_population class gp_population
{ {
public: public:
enum class crossover_error_t
{
};
struct selection struct selection
{ {
blt::size_t index; blt::size_t index;
@ -329,6 +360,9 @@ class gp_population
new_pop[p1.index] = {std::move(r->c1)}; new_pop[p1.index] = {std::move(r->c1)};
new_pop[p2.index] = {std::move(r->c2)}; new_pop[p2.index] = {std::move(r->c2)};
crossover_count++; crossover_count++;
} else
{
BLT_ERROR(tree::crossover_error_to_string(r.error()));
} }
} }
} }
@ -426,6 +460,30 @@ void init()
resources.set("img", texture); resources.set("img", texture);
resources.enqueue("../libraries/BLT-With-Graphics-Template/resources/textures/parkerfemBOY.png", "cum"); 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<float>(v) / static_cast<float>(std::numeric_limits<unsigned char>::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(); resources.load_resources();
} }