blocky/liblocky/extractor.c
2022-06-22 11:48:52 +09:00

90 lines
2.7 KiB
C

#include "liblocky.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
void blky_extractor_init(blky_extractor_t* ex) {
assert(ex->block_num_x > 0);
assert(ex->block_num_y > 0);
assert(ex->sensor_num_block_x > 0);
assert(ex->sensor_num_block_y > 0);
assert(ex->samples_per_pix > 0);
assert(ex->utime > 0);
assert(ex->utime <= BLKY_SENSOR_MAX_DUR);
assert(ex->pix_stride > 0);
assert(ex->pix_stride > ex->samples_per_pix);
assert(ex->correl_max_var >= 0);
assert(ex->correl_min_avg >= 0);
assert(ex->correl_min_avg <= 1);
// set immutable params
ex->block_num = ex->block_num_x * ex->block_num_y;
ex->sensor_num_block =
ex->sensor_num_block_x * ex->sensor_num_block_y *
ex->samples_per_pix;
ex->sensor_num_whole = ex->sensor_num_block * ex->block_num;
ex->block_w = 1./ex->block_num_x;
ex->block_h = 1./ex->block_num_y;
ex->sensor_interval_x = ex->block_w / ex->sensor_num_block_x;
ex->sensor_interval_y = ex->block_h / ex->sensor_num_block_y;
// clear states
ex->time = 0;
const uint64_t sensors_bytes = sizeof(ex->sensors[0]) * ex->sensor_num_whole;
const uint64_t probs_bytes = sizeof(ex->probs[0]) * ex->block_num;
const uint64_t mem_bytes = sensors_bytes + probs_bytes;
ex->mem = calloc(mem_bytes, 1);
assert(ex->mem);
ex->sensors = (blky_sensor_t*) ex->mem;
ex->probs = (double*) (ex->mem + sensors_bytes);
}
void blky_extractor_deinit(blky_extractor_t* ex) {
free(ex->mem);
}
bool blky_extractor_feed(
blky_extractor_t* ex,
const uint8_t* img, uint32_t w, uint32_t h, const double verts[8]) {
blky_sensor_t* s = ex->sensors;
for (uint32_t by = 0; by < ex->block_num_y; ++by) {
const double byf = by*ex->block_h + ex->sensor_interval_y/2.;
for (uint32_t bx = 0; bx < ex->block_num_x; ++bx) {
const double bxf = bx*ex->block_w + ex->sensor_interval_x/2.;
for (uint32_t sy = 0; sy < ex->sensor_num_block_y; ++sy) {
const double syf = byf + ex->sensor_interval_y*sy;
for (uint32_t sx = 0; sx < ex->sensor_num_block_x; ++sx) {
const double sxf = bxf + ex->sensor_interval_x*sx;
const uint8_t* base = img +
ex->pix_stride*blky_image_offset(w, h, verts, sxf, syf);
for (uint8_t off = 0; off < ex->samples_per_pix; ++off) {
const float v = base[off]*1.f / UINT8_MAX;
blky_sensor_feed(s++, &v, 1);
}
}
}
}
}
++ex->time;
if (ex->time%ex->utime > 0) return false;
for (uint64_t bi = 0; bi < ex->block_num; ++bi) {
blky_sensor_t* s = ex->sensors + (bi*ex->sensor_num_block);
ex->probs[bi] = blky_block_estimate(
s, ex->sensor_num_block, ex->correl_max_var, ex->correl_min_avg);
memset(s, 0, ex->sensor_num_block*sizeof(*s));
}
return true;
}