nyah
parent
109af854ef
commit
a81d01113c
|
@ -1,5 +1,5 @@
|
||||||
cmake_minimum_required(VERSION 3.25)
|
cmake_minimum_required(VERSION 3.25)
|
||||||
project(image-gp-6 VERSION 0.0.24)
|
project(image-gp-6 VERSION 0.0.25)
|
||||||
|
|
||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
|
|
||||||
|
|
|
@ -221,6 +221,13 @@ inline blt::gp::operation_t hsv_to_rgb([](const full_image_t& a) {
|
||||||
}, "hsv");
|
}, "hsv");
|
||||||
|
|
||||||
inline blt::gp::operation_t lit([]() {
|
inline blt::gp::operation_t lit([]() {
|
||||||
|
full_image_t img{};
|
||||||
|
auto bw = program.get_random().get_float(0.0f, 1.0f);
|
||||||
|
for (auto& i : img.rgb_data)
|
||||||
|
i = bw;
|
||||||
|
return img;
|
||||||
|
}, "lit");
|
||||||
|
inline blt::gp::operation_t vec([]() {
|
||||||
full_image_t img{};
|
full_image_t img{};
|
||||||
auto r = program.get_random().get_float(0.0f, 1.0f);
|
auto r = program.get_random().get_float(0.0f, 1.0f);
|
||||||
auto g = program.get_random().get_float(0.0f, 1.0f);
|
auto g = program.get_random().get_float(0.0f, 1.0f);
|
||||||
|
@ -232,7 +239,7 @@ inline blt::gp::operation_t lit([]() {
|
||||||
img.rgb_data[i * CHANNELS + 2] = b;
|
img.rgb_data[i * CHANNELS + 2] = b;
|
||||||
}
|
}
|
||||||
return img;
|
return img;
|
||||||
}, "lit");
|
}, "vec");
|
||||||
inline blt::gp::operation_t random_val([]() {
|
inline blt::gp::operation_t random_val([]() {
|
||||||
full_image_t img{};
|
full_image_t img{};
|
||||||
for (auto& i : img.rgb_data)
|
for (auto& i : img.rgb_data)
|
||||||
|
@ -262,7 +269,7 @@ inline blt::gp::operation_t perlin_warped([](const full_image_t& u, const full_i
|
||||||
for (blt::size_t i = 0; i < DATA_CHANNELS_SIZE; i++)
|
for (blt::size_t i = 0; i < DATA_CHANNELS_SIZE; i++)
|
||||||
{
|
{
|
||||||
auto ctx = get_ctx(i);
|
auto ctx = get_ctx(i);
|
||||||
img.rgb_data[i] = perlin_noise(ctx.x / IMAGE_SIZE + u.rgb_data[i], ctx.y / IMAGE_SIZE + v.rgb_data[i],
|
img.rgb_data[i] = perlin_noise((ctx.x + + u.rgb_data[i]) / IMAGE_SIZE, (ctx.y + v.rgb_data[i]) / IMAGE_SIZE,
|
||||||
static_cast<float>(i % CHANNELS) / CHANNELS);
|
static_cast<float>(i % CHANNELS) / CHANNELS);
|
||||||
}
|
}
|
||||||
return img;
|
return img;
|
||||||
|
@ -397,6 +404,7 @@ void create_image_operations(blt::gp::operator_builder<context>& builder)
|
||||||
|
|
||||||
bool state = false;
|
bool state = false;
|
||||||
builder.add_operator(lit, true);
|
builder.add_operator(lit, true);
|
||||||
|
builder.add_operator(vec, true);
|
||||||
builder.add_operator(random_val);
|
builder.add_operator(random_val);
|
||||||
builder.add_operator(op_x_r, state);
|
builder.add_operator(op_x_r, state);
|
||||||
builder.add_operator(op_x_g, state);
|
builder.add_operator(op_x_g, state);
|
||||||
|
|
116
include/images.h
116
include/images.h
|
@ -24,6 +24,109 @@
|
||||||
#include <stb_image_resize2.h>
|
#include <stb_image_resize2.h>
|
||||||
#include <stb_image_write.h>
|
#include <stb_image_write.h>
|
||||||
|
|
||||||
|
struct stb_image_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
stb_image_t() = default;
|
||||||
|
|
||||||
|
stb_image_t(const stb_image_t& copy) noexcept: width(copy.width), height(copy.height), channels(copy.channels)
|
||||||
|
{
|
||||||
|
data = static_cast<float*>(std::malloc(width * height * channels));
|
||||||
|
std::memcpy(data, copy.data, width * height * channels);
|
||||||
|
}
|
||||||
|
|
||||||
|
stb_image_t(stb_image_t&& move) noexcept:
|
||||||
|
width(move.width), height(move.height), channels(move.channels), data(std::exchange(move.data, nullptr))
|
||||||
|
{}
|
||||||
|
|
||||||
|
stb_image_t& operator=(const stb_image_t& copy)
|
||||||
|
{
|
||||||
|
if (© == this)
|
||||||
|
return *this;
|
||||||
|
if (width != copy.width || height != copy.height || channels != copy.channels)
|
||||||
|
{
|
||||||
|
width = copy.width;
|
||||||
|
height = copy.height;
|
||||||
|
channels = copy.channels;
|
||||||
|
stbi_image_free(data);
|
||||||
|
data = static_cast<float*>(std::malloc(width * height * channels * sizeof(float)));
|
||||||
|
}
|
||||||
|
std::memcpy(data, copy.data, width * height * channels);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
stb_image_t& operator=(stb_image_t&& move) noexcept
|
||||||
|
{
|
||||||
|
width = move.width;
|
||||||
|
height = move.height;
|
||||||
|
channels = move.channels;
|
||||||
|
data = std::exchange(move.data, data);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
stb_image_t& load(const std::string& path)
|
||||||
|
{
|
||||||
|
data = stbi_loadf(path.c_str(), &width, &height, &channels, CHANNELS);
|
||||||
|
channels = CHANNELS;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
stb_image_t& save(const std::string& str)
|
||||||
|
{
|
||||||
|
if (data == nullptr)
|
||||||
|
return *this;
|
||||||
|
auto uc_data = std::unique_ptr<unsigned char[]>(new unsigned char[width * height * channels]);
|
||||||
|
for (int i = 0; i < width * height * channels; i++)
|
||||||
|
uc_data[i] = static_cast<unsigned char>(data[i] * std::numeric_limits<unsigned char>::max());
|
||||||
|
stbi_write_png(str.c_str(), width, height, channels, uc_data.get(), 0);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
stb_image_t& resize(int new_width, int new_height)
|
||||||
|
{
|
||||||
|
auto new_data = static_cast<float*>(malloc(new_width * new_height * channels * sizeof(float)));
|
||||||
|
stbir_resize_float_linear(data, width, height, 0, new_data, new_width, new_height, 0,
|
||||||
|
static_cast<stbir_pixel_layout>(CHANNELS));
|
||||||
|
stbi_image_free(data);
|
||||||
|
data = new_data;
|
||||||
|
width = new_width;
|
||||||
|
height = new_height;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] int get_width() const
|
||||||
|
{
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] int get_height() const
|
||||||
|
{
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
float* get_data()
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] const float* get_data() const
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
~stb_image_t()
|
||||||
|
{
|
||||||
|
stbi_image_free(data);
|
||||||
|
data = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int width{}, height{}, channels{};
|
||||||
|
|
||||||
|
float* data = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
struct full_image_t
|
struct full_image_t
|
||||||
{
|
{
|
||||||
float rgb_data[DATA_SIZE * CHANNELS]{};
|
float rgb_data[DATA_SIZE * CHANNELS]{};
|
||||||
|
@ -44,9 +147,18 @@ struct full_image_t
|
||||||
stbi_image_free(data);
|
stbi_image_free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void save(const std::string&)
|
void load(const stb_image_t& image)
|
||||||
{
|
{
|
||||||
//stbi_write_png(str.c_str(), IMAGE_SIZE, IMAGE_SIZE, CHANNELS, rgb_data, 0);
|
stbir_resize_float_linear(image.get_data(), image.get_width(), image.get_height(), 0, rgb_data, IMAGE_SIZE, IMAGE_SIZE, 0,
|
||||||
|
static_cast<stbir_pixel_layout>(CHANNELS));
|
||||||
|
}
|
||||||
|
|
||||||
|
void save(const std::string& str)
|
||||||
|
{
|
||||||
|
unsigned char data[DATA_SIZE * CHANNELS]{};
|
||||||
|
for (const auto& [index, value] : blt::enumerate(rgb_data))
|
||||||
|
data[index] = static_cast<unsigned char>(value * std::numeric_limits<unsigned char>::max());
|
||||||
|
stbi_write_png(str.c_str(), IMAGE_SIZE, IMAGE_SIZE, CHANNELS, data, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
friend std::ostream& operator<<(std::ostream& str, const full_image_t&)
|
friend std::ostream& operator<<(std::ostream& str, const full_image_t&)
|
||||||
|
|
34
src/main.cpp
34
src/main.cpp
|
@ -122,7 +122,9 @@ class image_crossover_t : public blt::gp::crossover_t
|
||||||
|
|
||||||
std::array<full_image_t, POP_SIZE> generation_images;
|
std::array<full_image_t, POP_SIZE> generation_images;
|
||||||
|
|
||||||
|
int match_method = cv::TM_SQDIFF;
|
||||||
full_image_t base_image;
|
full_image_t base_image;
|
||||||
|
stb_image_t full_base_image;
|
||||||
blt::size_t last_run = 0;
|
blt::size_t last_run = 0;
|
||||||
blt::i32 time_between_runs = 16;
|
blt::i32 time_between_runs = 16;
|
||||||
bool is_running = false;
|
bool is_running = false;
|
||||||
|
@ -246,6 +248,33 @@ constexpr auto create_fitness_function()
|
||||||
else
|
else
|
||||||
fitness.raw_fitness += raw.total + raw.combined + 1.0;
|
fitness.raw_fitness += raw.total + raw.combined + 1.0;
|
||||||
|
|
||||||
|
cv::Mat base_image_large{full_base_image.get_width(), full_base_image.get_height(), CV_32FC3, full_base_image.get_data()};
|
||||||
|
cv::Mat templ{IMAGE_SIZE, IMAGE_SIZE, CV_32FC3, v.rgb_data};
|
||||||
|
cv::Mat result;
|
||||||
|
|
||||||
|
int result_cols = base_image_large.cols - templ.cols + 1;
|
||||||
|
int result_rows = base_image_large.rows - templ.rows + 1;
|
||||||
|
|
||||||
|
result.create(result_rows, result_cols, CV_32FC1);
|
||||||
|
|
||||||
|
double minVal;
|
||||||
|
double maxVal;
|
||||||
|
cv::matchTemplate(base_image_large, templ, result, match_method);
|
||||||
|
|
||||||
|
minMaxLoc(result, &minVal, &maxVal, nullptr, nullptr, cv::Mat());
|
||||||
|
|
||||||
|
/// For SQDIFF and SQDIFF_NORMED, the best matches are lower values. For all the other methods, the higher the better
|
||||||
|
if (match_method == cv::TM_SQDIFF || match_method == cv::TM_SQDIFF_NORMED)
|
||||||
|
{
|
||||||
|
if (std::isinf(minVal) || std::isnan(minVal))
|
||||||
|
minVal = 200000;
|
||||||
|
fitness.raw_fitness += minVal * 0.01f;
|
||||||
|
//BLT_TRACE("%lf, %lf", minVal, maxVal);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
BLT_WARN("Hello!");
|
||||||
|
}
|
||||||
|
|
||||||
fitness.raw_fitness += last_fitness;
|
fitness.raw_fitness += last_fitness;
|
||||||
} else
|
} else
|
||||||
fitness.raw_fitness = fitness_values[index];
|
fitness.raw_fitness = fitness_values[index];
|
||||||
|
@ -323,7 +352,9 @@ void init(const blt::gfx::window_data&)
|
||||||
BLT_INFO("Using Seed: %ld", SEED);
|
BLT_INFO("Using Seed: %ld", SEED);
|
||||||
BLT_START_INTERVAL("Image Test", "Main");
|
BLT_START_INTERVAL("Image Test", "Main");
|
||||||
BLT_DEBUG("Setup Base Image");
|
BLT_DEBUG("Setup Base Image");
|
||||||
base_image.load(load_image);
|
full_base_image.load(load_image).resize(static_cast<int>(std::max(full_base_image.get_width() / 2ul, IMAGE_SIZE)),
|
||||||
|
static_cast<int>(std::max(full_base_image.get_height() / 2ul, IMAGE_SIZE)));
|
||||||
|
base_image.load(full_base_image);
|
||||||
|
|
||||||
BLT_DEBUG("Setup Types and Operators");
|
BLT_DEBUG("Setup Types and Operators");
|
||||||
type_system.register_type<full_image_t>();
|
type_system.register_type<full_image_t>();
|
||||||
|
@ -457,6 +488,7 @@ int main()
|
||||||
BLT_END_INTERVAL("Image Test", "Main");
|
BLT_END_INTERVAL("Image Test", "Main");
|
||||||
|
|
||||||
base_image.save("input.png");
|
base_image.save("input.png");
|
||||||
|
full_base_image.save("full_input.png");
|
||||||
|
|
||||||
auto v = get_fractal_value(base_image);
|
auto v = get_fractal_value(base_image);
|
||||||
BLT_INFO("Base image values per channel: %lf", v.total);
|
BLT_INFO("Base image values per channel: %lf", v.total);
|
||||||
|
|
Loading…
Reference in New Issue