90 lines
2.7 KiB
C
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;
|
|
}
|