135 lines
5.6 KiB
C++
135 lines
5.6 KiB
C++
/*
|
|
* See Copyright Notice in atomorph.h
|
|
*/
|
|
|
|
#include "atomorph.h"
|
|
|
|
namespace am {
|
|
|
|
class thread {
|
|
public:
|
|
thread();
|
|
~thread();
|
|
|
|
void next_state() {skip_state = true;}
|
|
unsigned get_state() {return state;}
|
|
size_t get_identifier() {return identifier;}
|
|
void set_identifier(size_t id) {if (paused) identifier = id;}
|
|
frame *get_frame(size_t nr) {return (has_frame(nr) ? &(frames[nr]) : nullptr);}
|
|
const std::map<size_t, chain> *get_chains() {return (const std::map<size_t, chain> *) &chains;}
|
|
unsigned get_seed() {return seed;}
|
|
double get_energy();
|
|
void set_frame(size_t nr, frame* f);
|
|
size_t get_blob_count(size_t frame);
|
|
size_t get_blob_count();
|
|
void set_bbox(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
|
|
void set_blob_weights(unsigned char rgba, unsigned char size, unsigned char xy);
|
|
|
|
bool clear();
|
|
void set_seed(unsigned seed);
|
|
void set_blob_delimiter(unsigned char d) {if (paused) blob_delimiter = d;} // Color distance formula.
|
|
void set_blob_threshold(double t) {if (paused) blob_threshold = t;} // Color difference toleration.
|
|
void set_blob_max_size (size_t s) {if (paused) blob_max_size = s;} // Maximum size of a blob.
|
|
void set_blob_min_size (size_t s) {if (paused) blob_min_size = s;} // Minimum size of a blob.
|
|
void set_blob_box_grip (uint16_t g) {if (paused) blob_box_grip = g;} // Defines the bounding box.
|
|
void set_blob_box_samples(size_t s) {if (paused) blob_box_samples=s;} // Number of dust samples.
|
|
void set_blob_number (size_t n) {if (paused) blob_number = n;} // Preferred number of blobs.
|
|
void set_degeneration (size_t d) {if (paused) degenerate = d;} // Degeneration period.
|
|
void set_density (uint16_t d) {if (paused) point_density = d;} // Key points per pixel.
|
|
void set_threads (size_t n) {if (paused) thread_count = n;} // Number of threads to spawn.
|
|
void set_cycle_length (size_t l) {if (paused) cycle_length = l;} // Steps per iteration to repeat.
|
|
|
|
bool is_running() const {return running;}
|
|
bool is_paused() const {return paused;}
|
|
|
|
void stop() { signal_stop = true; while(running) std::this_thread::sleep_for(std::chrono::milliseconds(0)); step_thread.join();}
|
|
void start() { running = true; step_thread = std::thread(&thread::run, this);}
|
|
void pause() { signal_pause = true; }
|
|
void resume() { paused = false;}
|
|
|
|
void start (size_t iterations);
|
|
void resume(size_t iterations);
|
|
void start (double seconds);
|
|
void resume(double seconds);
|
|
|
|
private:
|
|
double blob_distance(const blob *b1, const blob *b2);
|
|
pixel get_pixel(size_t frame, size_t position);
|
|
|
|
bool blobify ();
|
|
bool unify ();
|
|
bool match ();
|
|
bool morph ();
|
|
bool blobify_frame (size_t f);
|
|
bool unify_frame (size_t f);
|
|
bool init_morph ();
|
|
double get_energy (struct blob ***map);
|
|
double get_energy (chain *ch);
|
|
void fix_volatiles (std::vector<blob *> *to_be_fixed);
|
|
inline bool has_frame (size_t f ) const {return (frames.find(f) != frames.end());}
|
|
inline bool has_pixel (size_t f, size_t pos) {return (has_frame(f) && frames[f].pixels.find(pos) != frames[f].pixels.end());}
|
|
inline bool has_blob (size_t f, size_t b ) {return (has_frame(f) && frames[f].blobs.size() > b);}
|
|
inline bool can_expand (size_t frame, size_t from_pos, size_t to_pos);
|
|
|
|
void run();
|
|
void step();
|
|
|
|
std::map<size_t, frame> frames;
|
|
std::map<size_t, chain> chains; // Key is the blob's group.
|
|
|
|
uint16_t point_density = 1; // How many key points to create per pixel at minimum.
|
|
|
|
struct blob *** blob_map;
|
|
size_t blob_map_w; // Number of blobs per key frame.
|
|
size_t blob_map_h; // Number of key frames.
|
|
double blob_map_e; // Energy of the current blob map.
|
|
double best_blob_map_e;
|
|
|
|
double chain_map_e;
|
|
|
|
// Minimum Bounding Box that fits all pixels of all frames:
|
|
uint16_t bbox_x1 = UINT16_MAX;
|
|
uint16_t bbox_y1 = UINT16_MAX;
|
|
uint16_t bbox_x2 = 0;
|
|
uint16_t bbox_y2 = 0;
|
|
uint32_t bbox_d = 0; // Squared diagonal length.
|
|
|
|
unsigned char blob_delimiter = HSP;
|
|
double blob_threshold = 1.0;
|
|
size_t blob_max_size = SIZE_MAX;
|
|
size_t blob_min_size = 1;
|
|
uint16_t blob_box_grip = UINT16_MAX;
|
|
size_t blob_box_samples = 10;
|
|
size_t blob_number = 1;
|
|
size_t thread_count = 0;
|
|
size_t cycle_length = 1;
|
|
|
|
double blob_rgba_weight = 0.33;
|
|
double blob_size_weight = 0.33;
|
|
double blob_xy_weight = 0.34;
|
|
|
|
size_t identifier = SIZE_MAX;
|
|
unsigned state = STATE_BLOB_DETECTION;
|
|
unsigned seed = 0;
|
|
bool skip_state = false;
|
|
size_t degenerate = 0;
|
|
size_t counter = 0;
|
|
double best_e;
|
|
bool deviant; // True when a bad solution has been accepted lately.
|
|
|
|
std::default_random_engine e1;
|
|
|
|
std::atomic<size_t> iterations;
|
|
std::atomic<double> seconds;
|
|
|
|
std::atomic<bool> signal_stop;
|
|
std::atomic<bool> signal_pause;
|
|
std::atomic<bool> running;
|
|
std::atomic<bool> paused;
|
|
std::thread step_thread;
|
|
};
|
|
|
|
}
|
|
|
|
|