25 #include <core/exceptions/software.h>
26 #include <fvutils/statistical/histogram.h>
27 #include <fvutils/statistical/histogram_block.h>
28 #include <fvutils/statistical/histogram_file.h>
40 namespace firevision {
53 Histogram::Histogram(
unsigned int width,
56 unsigned int num_undos)
58 if ((width == 0) || (height == 0) || (depth == 0)) {
59 throw Exception(
"Width or height or depth is zero.");
63 this->height = height;
65 this->undo_num = num_undos;
66 this->undo_current = 0;
75 new HistogramBlock(FIREVISION_HISTOGRAM_TYPE_32, H_UNKNOWN, width, height, depth);
76 histogram = (
unsigned int *)histogram_block->data_ptr();
78 histogram_size = (size_t)width * height * depth *
sizeof(
unsigned int);
80 undo_overlay = (
unsigned int **)malloc(undo_num *
sizeof(
unsigned int *));
81 for (
unsigned int i = 0; i < undo_num; ++i) {
82 undo_overlay[i] = (
unsigned int *)malloc(histogram_size);
85 undo_num_vals = (
unsigned int *)malloc(undo_num *
sizeof(
unsigned int));
95 width = block->
width();
97 depth = block->
depth();
108 histogram_block = block;
109 histogram = (
unsigned int *)histogram_block->
data_ptr();
110 histogram_size = (size_t)width * height * depth *
sizeof(
unsigned int);
112 undo_overlay = (
unsigned int **)malloc(undo_num *
sizeof(
unsigned int *));
113 for (
unsigned int i = 0; i < undo_num; ++i) {
114 undo_overlay[i] = (
unsigned int *)malloc(histogram_size);
117 undo_num_vals = (
unsigned int *)malloc(undo_num *
sizeof(
unsigned int));
121 Histogram::~Histogram()
123 delete histogram_block;
124 for (
unsigned int i = 0; i < undo_num; ++i) {
125 free(undo_overlay[i]);
137 if (dimension != 2) {
138 throw Exception(
"Trying to add 2-dim data to 3-dim histogram");
141 if (p->
x >= width || p->
y >= height) {
145 unsigned int index = p->
y * width + p->
x;
146 histogram[index] += 1;
147 undo_overlay[undo_current][index] += 1;
149 undo_num_vals[undo_current] += 1;
158 if (dimension != 2) {
159 throw Exception(
"Trying to add 2-dim data to 3-dim histogram");
162 if (p.
x >= width || p.
y >= height) {
166 unsigned int index = p.
y * width + p.
x;
167 histogram[index] += 1;
168 undo_overlay[undo_current][index] += 1;
170 undo_num_vals[undo_current] += 1;
177 Histogram::get_histogram()
186 Histogram::get_histogram_block()
188 return histogram_block;
197 Histogram::get_dimensions(
unsigned int &width,
unsigned int &height,
unsigned int &depth)
200 height = this->height;
210 Histogram::get_value(
unsigned int x,
unsigned int y)
222 Histogram::get_value(
unsigned int x,
unsigned int y,
unsigned int z)
224 return histogram_block->get_value(x, y, z);
233 Histogram::set_value(
unsigned int x,
unsigned int y,
unsigned int value)
235 unsigned int old_value = histogram_block->get_value(x, y);
236 histogram_block->set_value(x, y, value);
237 number_of_values += value - old_value;
239 unsigned int index = y * width + x;
240 if (value > old_value) {
242 undo_overlay[undo_current][index] += value - old_value;
244 if ((old_value - value) < undo_overlay[undo_current][index]) {
245 undo_overlay[undo_current][index] -= (old_value - value);
249 undo_overlay[undo_current][index] = 0;
261 Histogram::set_value(
unsigned int x,
unsigned int y,
unsigned int z,
unsigned int value)
263 unsigned int old_value = histogram_block->get_value(x, y, z);
264 histogram_block->set_value(x, y, z, value);
266 number_of_values += value - old_value;
267 unsigned int index = z * width * height + y * width + x;
268 if (value > old_value) {
270 undo_overlay[undo_current][index] += value - old_value;
272 if ((old_value - value) < undo_overlay[undo_current][index]) {
273 undo_overlay[undo_current][index] -= (old_value - value);
277 undo_overlay[undo_current][index] = 0;
288 Histogram::inc_value(
unsigned int x,
unsigned int y,
unsigned int z)
290 unsigned int old_value = histogram_block->get_value(x, y, z);
291 histogram_block->set_value(x, y, z, ++old_value);
295 unsigned int index = z * width * height + y * width + x;
296 undo_overlay[undo_current][index] = 1;
306 Histogram::add(
unsigned int x,
unsigned int y,
unsigned int z,
unsigned int value)
308 unsigned int cur_value = histogram_block->get_value(x, y, z);
309 histogram_block->set_value(x, y, z, cur_value + value);
311 number_of_values += value;
313 unsigned int index = z * width * height + y * width + x;
314 undo_overlay[undo_current][index] = value;
324 Histogram::sub(
unsigned int x,
unsigned int y,
unsigned int z,
unsigned int value)
326 unsigned int cur_value = histogram_block->get_value(x, y, z);
327 if (value < cur_value) {
328 set_value(x, y, z, cur_value - value);
330 set_value(x, y, z, 0);
333 number_of_values -= value;
335 unsigned int index = z * width * height + y * width + x;
336 if (value < undo_overlay[undo_current][index]) {
337 undo_overlay[undo_current][index] -= value;
339 undo_overlay[undo_current][index] = 0;
347 histogram_block->reset();
349 number_of_values = 0;
350 for (
unsigned int i = 0; i < undo_num; ++i) {
361 Histogram::print_to_stream(std::ostream &s)
363 for (
unsigned int z = 0; z < depth; ++z) {
364 for (
unsigned int y = 0; y < height; ++y) {
365 for (
unsigned int x = 0; x < width; ++x) {
367 cout << histogram_block->get_value(x, y, z) <<
" ";
380 Histogram::save(
const char *filename,
bool formatted_output)
385 histogram_file.
write(filename);
387 cout <<
"Histogram: Saved histogram in file \"" << filename <<
"\"." << endl;
395 Histogram::load(
const char *filename)
398 histogram_file.
read(filename);
401 printf(
"load() aborted: file contains more than one histogram");
406 histogram = (
unsigned int *)histogram_block->data_ptr();
407 histogram_size = (size_t)width * height * depth *
sizeof(
unsigned int);
409 for (
unsigned int i = 0; i < undo_num; ++i) {
410 free(undo_overlay[i]);
414 undo_overlay = (
unsigned int **)malloc(undo_num *
sizeof(
unsigned int *));
415 for (
unsigned int i = 0; i < undo_num; ++i) {
416 undo_overlay[i] = (
unsigned int *)malloc(histogram_size);
424 Histogram::reset_undo()
426 memset(undo_overlay[undo_current], 0, histogram_size);
427 undo_num_vals[undo_current] = 0;
434 for (
unsigned int z = 0; z < depth; ++z) {
435 for (
unsigned int y = 0; y < height; ++y) {
436 for (
unsigned int x = 0; x < width; ++x) {
437 unsigned int index = z * width * height + y * width + x;
438 histogram[index] -= undo_overlay[undo_current][index];
442 number_of_values -= undo_num_vals[undo_current];
451 Histogram::switch_undo(
unsigned int undo_id)
453 unsigned int undo_last = undo_current;
455 if (undo_id >= undo_num) {
456 cout <<
"Histogram::resetUndo: ID out of range" << endl;
458 undo_current = undo_id;
468 Histogram::get_num_undos()
477 Histogram::get_median()
479 vector<unsigned int> *values =
new vector<unsigned int>((
size_t)width * height * depth);
482 for (
unsigned int z = 0; z < depth; ++z) {
483 for (
unsigned int y = 0; y < height; ++y) {
484 for (
unsigned int x = 0; x < width; ++x) {
485 values->push_back(histogram_block->get_value(x, y, z));
490 sort(values->begin(), values->end());
492 unsigned int median = values->at(values->size() / 2);
503 Histogram::get_average()
505 unsigned int sum = 0;
506 unsigned int num = 0;
507 for (
unsigned int z = 0; z < depth; ++z) {
508 for (
unsigned int y = 0; y < height; ++y) {
509 for (
unsigned int x = 0; x < width; ++x) {
510 if (histogram[z * width * height + y * width + x]) {
511 sum += histogram_block->get_value(x, y, z);
525 Histogram::get_sum()
const
527 unsigned int sum = 0;
528 for (
unsigned int z = 0; z < depth; ++z) {
529 for (
unsigned int y = 0; y < height; ++y) {
530 for (
unsigned int x = 0; x < width; ++x) {
531 if (histogram[z * width * height + y * width + x]) {
532 sum += histogram_block->get_value(x, y, z);