Merge remote-tracking branch 'refs/remotes/origin/main'
commit
4b82f1bdb7
|
@ -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 |
|
@ -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)
|
||||||
//{
|
//{
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
84
src/main.cpp
84
src/main.cpp
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue