25 #include <fvutils/statistical/histogram.h> 26 #include <fvutils/statistical/histogram_file.h> 27 #include <fvutils/statistical/histogram_block.h> 29 #include <core/exceptions/software.h> 58 Histogram::Histogram(
unsigned int width,
unsigned int height,
59 unsigned int depth,
unsigned int num_undos)
61 if ( (width == 0) || (height == 0) || (depth == 0) ) {
62 throw Exception(
"Width or height or depth is zero.");
66 this->height = height;
68 this->undo_num = num_undos;
69 this->undo_current = 0;
77 histogram_block =
new HistogramBlock(FIREVISION_HISTOGRAM_TYPE_32, H_UNKNOWN,
78 width, height, depth);
79 histogram = (
unsigned int*) histogram_block->data_ptr();
81 histogram_size = width * height * depth *
sizeof(
unsigned int);
83 undo_overlay = (
unsigned int **)malloc(undo_num *
sizeof(
unsigned int *));
84 for (
unsigned int i = 0; i < undo_num; ++i) {
85 undo_overlay[i] = (
unsigned int *)malloc(histogram_size);
88 undo_num_vals = (
unsigned int *)malloc(undo_num *
sizeof(
unsigned int));
99 width = block->
width();
101 depth = block->
depth();
112 histogram_block = block;
113 histogram = (
unsigned int*) histogram_block->
data_ptr();
114 histogram_size = width * height * depth *
sizeof(
unsigned int);
116 undo_overlay = (
unsigned int **)malloc(undo_num *
sizeof(
unsigned int *));
117 for (
unsigned int i = 0; i < undo_num; ++i) {
118 undo_overlay[i] = (
unsigned int *)malloc(histogram_size);
121 undo_num_vals = (
unsigned int *)malloc(undo_num *
sizeof(
unsigned int));
126 Histogram::~Histogram()
128 delete histogram_block;
129 for (
unsigned int i = 0; i < undo_num; ++i) {
130 free(undo_overlay[i]);
143 if ( dimension != 2 ) {
144 throw Exception(
"Trying to add 2-dim data to 3-dim histogram");
147 if (p->
x >= width || p->
y >= height) {
151 unsigned int index = p->
y * width + p->
x;
152 histogram[index] += 1;
153 undo_overlay[undo_current][index] += 1;
155 undo_num_vals[undo_current] += 1;
165 if ( dimension != 2 ) {
166 throw Exception(
"Trying to add 2-dim data to 3-dim histogram");
169 if (p.
x >= width || p.
y >= height) {
173 unsigned int index = p.
y * width + p.
x;
174 histogram[index] += 1;
175 undo_overlay[undo_current][index] += 1;
177 undo_num_vals[undo_current] += 1;
185 Histogram::get_histogram()
195 Histogram::get_histogram_block()
197 return histogram_block;
207 Histogram::get_dimensions(
unsigned int& width,
unsigned int& height,
unsigned int& depth)
210 height = this->height;
221 Histogram::get_value(
unsigned int x,
unsigned int y)
234 Histogram::get_value(
unsigned int x,
unsigned int y,
unsigned int z)
236 return histogram_block->get_value(x, y, z);
246 Histogram::set_value(
unsigned int x,
unsigned int y,
unsigned int value)
248 unsigned int old_value = histogram_block->get_value(x, y);
249 histogram_block->set_value(x, y, value);
250 number_of_values += value - old_value;
252 unsigned int index = y * width + x;
253 if ( value > old_value ) {
255 undo_overlay[undo_current][index] += value - old_value;
257 if ( (old_value - value) < undo_overlay[undo_current][index] ) {
258 undo_overlay[undo_current][index] -= (old_value - value);
262 undo_overlay[undo_current][index] = 0;
275 Histogram::set_value(
unsigned int x,
unsigned int y,
unsigned int z,
unsigned int value)
277 unsigned int old_value = histogram_block->get_value(x, y, z);
278 histogram_block->set_value(x, y, z, value);
280 number_of_values += value - old_value;
281 unsigned int index = z * width * height + y * width + x;
282 if ( value > old_value ) {
284 undo_overlay[undo_current][index] += value - old_value;
286 if ( (old_value - value) < undo_overlay[undo_current][index] ) {
287 undo_overlay[undo_current][index] -= (old_value - value);
291 undo_overlay[undo_current][index] = 0;
303 Histogram::inc_value(
unsigned int x,
unsigned int y,
unsigned int z)
305 unsigned int old_value = histogram_block->get_value(x, y, z);
306 histogram_block->set_value(x, y, z, ++old_value);
310 unsigned int index = z * width * height + y * width + x;
311 undo_overlay[undo_current][index] = 1;
322 Histogram::add(
unsigned int x,
unsigned int y,
unsigned int z,
unsigned int value)
324 unsigned int cur_value = histogram_block->get_value(x, y, z);
325 histogram_block->set_value(x, y, z, cur_value + value);
327 number_of_values += value;
329 unsigned int index = z * width * height + y * width + x;
330 undo_overlay[undo_current][index] = value;
341 Histogram::sub(
unsigned int x,
unsigned int y,
unsigned int z,
unsigned int value)
343 unsigned int cur_value = histogram_block->get_value(x, y, z);
344 if (value < cur_value) {
345 set_value(x, y, z, cur_value - value);
347 set_value(x, y, z, 0);
350 number_of_values -= value;
352 unsigned int index = z * width * height + y * width + x;
353 if ( value < undo_overlay[undo_current][index] )
355 undo_overlay[undo_current][index] -= value;
359 undo_overlay[undo_current][index] = 0;
368 histogram_block->reset();
370 number_of_values = 0;
371 for (
unsigned int i = 0; i < undo_num; ++i) {
383 Histogram::print_to_stream(std::ostream &s)
385 for (
unsigned int z = 0; z < depth; ++z) {
386 for (
unsigned int y = 0; y < height; ++y) {
387 for (
unsigned int x = 0; x < width; ++x) {
389 cout << histogram_block->get_value(x, y, z) <<
" ";
403 Histogram::save(
const char *filename,
bool formatted_output)
408 histogram_file.
write(filename);
410 cout <<
"Histogram: Saved histogram in file \"" << filename <<
"\"." << endl;
419 Histogram::load(
const char *filename)
422 histogram_file.
read(filename);
426 printf(
"load() aborted: file contains more than one histogram");
431 histogram = (
unsigned int*) histogram_block->data_ptr();
432 histogram_size = width * height * depth *
sizeof(
unsigned int);
434 for (
unsigned int i = 0; i < undo_num; ++i) {
435 free(undo_overlay[i]);
439 undo_overlay = (
unsigned int **)malloc(undo_num *
sizeof(
unsigned int *));
440 for (
unsigned int i = 0; i < undo_num; ++i) {
441 undo_overlay[i] = (
unsigned int *)malloc(histogram_size);
450 Histogram::reset_undo()
452 memset(undo_overlay[undo_current], 0, histogram_size);
453 undo_num_vals[undo_current] = 0;
461 for (
unsigned int z = 0; z < depth; ++z) {
462 for (
unsigned int y = 0; y < height; ++y) {
463 for (
unsigned int x = 0; x < width; ++x) {
464 unsigned int index = z * width * height + y * width + x;
465 histogram[index] -= undo_overlay[undo_current][index];
469 number_of_values -= undo_num_vals[undo_current];
479 Histogram::switch_undo(
unsigned int undo_id )
481 unsigned int undo_last = undo_current;
483 if (undo_id >= undo_num) {
484 cout <<
"Histogram::resetUndo: ID out of range" << endl;
486 undo_current = undo_id;
497 Histogram::get_num_undos()
507 Histogram::get_median()
509 vector< unsigned int > *values =
new vector< unsigned int >( width * height * depth);
512 for (
unsigned int z = 0; z < depth; ++z) {
513 for (
unsigned int y = 0; y < height; ++y) {
514 for (
unsigned int x = 0; x < width; ++x) {
515 values->push_back( histogram_block->get_value(x, y, z) );
520 sort(values->begin(), values->end());
522 unsigned int median = values->at( values->size() / 2 );
534 Histogram::get_average()
536 unsigned int sum = 0;
537 unsigned int num = 0;
538 for (
unsigned int z = 0; z < depth; ++z) {
539 for (
unsigned int y = 0; y < height; ++y) {
540 for (
unsigned int x = 0; x < width; ++x) {
541 if ( histogram[z * width * height + y * width + x ] ) {
542 sum += histogram_block->get_value(x, y, z);
557 Histogram::get_sum()
const 559 unsigned int sum = 0;
560 for (
unsigned int z = 0; z < depth; ++z) {
561 for (
unsigned int y = 0; y < height; ++y) {
562 for (
unsigned int x = 0; x < width; ++x) {
563 if ( histogram[z * width * height + y * width + x ] ) {
564 sum += histogram_block->get_value(x, y, z);
size_t num_blocks()
Get the number of available info blocks.
uint16_t depth() const
Returns the the depth of the histogram.
Fawkes library namespace.
unsigned int y
y coordinate
uint16_t width() const
Returns the the width of the histogram.
unsigned int x
x coordinate
virtual void write(const char *file_name)
Write file.
virtual void read(const char *file_name)
Read file.
void * data_ptr() const
Get data pointer.
Base class for exceptions in Fawkes.
void add_histogram_block(HistogramBlock *block)
Adds a new histogram block to the file.
Point with cartesian coordinates as unsigned integers.
void set_owns_blocks(bool owns_blocks)
Lets the file take over the ownership and give up the ownership of the blocks, respectively.
uint16_t height() const
Returns the the height of the histogram.
This class defines a file block for histograms.
uint32_t get_value(uint16_t x, uint16_t y)
Obtain a certain value from a 2-dimensional histogram.
A fileformat for histograms.
BlockList & blocks()
Get blocks.