initial commit
This commit is contained in:
24
d2/exposure/exposure.cc
Normal file
24
d2/exposure/exposure.cc
Normal file
@@ -0,0 +1,24 @@
|
||||
// Copyright 2004 David Hilvert <dhilvert@auricle.dyndns.org>,
|
||||
// <dhilvert@ugcs.caltech.edu>
|
||||
|
||||
/* This file is part of the Anti-Lamenessing Engine.
|
||||
|
||||
The Anti-Lamenessing Engine is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
The Anti-Lamenessing Engine is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the Anti-Lamenessing Engine; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "exposure.h"
|
||||
|
||||
ale_real exposure::confidence_exponent = (ale_real) 1.0;
|
||||
ale_real exposure::_gain_reference = 1;
|
||||
258
d2/exposure/exposure.h
Normal file
258
d2/exposure/exposure.h
Normal file
@@ -0,0 +1,258 @@
|
||||
// Copyright 2004 David Hilvert <dhilvert@auricle.dyndns.org>,
|
||||
// <dhilvert@ugcs.caltech.edu>
|
||||
|
||||
/* This file is part of the Anti-Lamenessing Engine.
|
||||
|
||||
The Anti-Lamenessing Engine is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
The Anti-Lamenessing Engine is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the Anti-Lamenessing Engine; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* exposure.h: A superclass for all exposure classes.
|
||||
*/
|
||||
|
||||
#ifndef __exposure_h__
|
||||
#define __exposure_h__
|
||||
|
||||
#include "../pixel.h"
|
||||
|
||||
/*
|
||||
* This class models a non-linear response function. More information can be
|
||||
* found here:
|
||||
*
|
||||
* http://wearcam.org/comparametrics.pdf
|
||||
*/
|
||||
|
||||
class exposure {
|
||||
private:
|
||||
static ale_real confidence_exponent;
|
||||
pixel _multiplier;
|
||||
ale_real _gain_multiplier;
|
||||
static ale_real _gain_reference;
|
||||
ale_real _black_level;
|
||||
|
||||
public:
|
||||
|
||||
/*
|
||||
* confidence/uniform static mutators
|
||||
*/
|
||||
static void set_confidence(ale_real exponent) {
|
||||
confidence_exponent = exponent;
|
||||
}
|
||||
|
||||
/*
|
||||
* confidence accessor
|
||||
*/
|
||||
static ale_real get_confidence() {
|
||||
return confidence_exponent;
|
||||
}
|
||||
|
||||
/*
|
||||
* Event listener interface
|
||||
*/
|
||||
|
||||
class listener {
|
||||
friend class exposure;
|
||||
private:
|
||||
listener *next;
|
||||
const char *name;
|
||||
const exposure *target;
|
||||
public:
|
||||
virtual void trigger(pixel multiplier) = 0;
|
||||
|
||||
listener () {
|
||||
next = NULL;
|
||||
target = NULL;
|
||||
}
|
||||
|
||||
virtual ~listener() {
|
||||
if (target) {
|
||||
target->remove_listener(this);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
mutable listener *listener_head;
|
||||
public:
|
||||
|
||||
void add_listener(listener *l, const char *name) const {
|
||||
|
||||
/*
|
||||
* This is a metafunction, so we consider it
|
||||
* to leave the object constant.
|
||||
*/
|
||||
assert (l->next == NULL);
|
||||
assert (l->target == NULL);
|
||||
l->next = listener_head;
|
||||
l->target = this;
|
||||
l->name = name;
|
||||
listener_head = l;
|
||||
}
|
||||
|
||||
void remove_listener(listener *l) const {
|
||||
|
||||
assert (listener_head != NULL);
|
||||
|
||||
if (listener_head == l) {
|
||||
listener_head = listener_head->next;
|
||||
} else {
|
||||
assert (listener_head->next != NULL);
|
||||
|
||||
listener *a = listener_head;
|
||||
listener *b = listener_head->next;
|
||||
|
||||
while (b != l) {
|
||||
assert (b->next != NULL);
|
||||
a = b;
|
||||
b = b->next;
|
||||
}
|
||||
|
||||
a->next = b->next;
|
||||
}
|
||||
|
||||
l->target = NULL;
|
||||
}
|
||||
|
||||
void set_multiplier(pixel _multiplier) {
|
||||
listener *cl = listener_head;
|
||||
|
||||
while(cl != NULL) {
|
||||
cl->trigger(_multiplier / this->_multiplier);
|
||||
cl = cl->next;
|
||||
}
|
||||
|
||||
this->_multiplier = _multiplier;
|
||||
}
|
||||
|
||||
void set_gain_multiplier(ale_real g) {
|
||||
_gain_multiplier = g;
|
||||
}
|
||||
|
||||
ale_real get_gain_multiplier() {
|
||||
return _gain_multiplier;
|
||||
}
|
||||
|
||||
void set_black_level(ale_real b) {
|
||||
_black_level = b;
|
||||
}
|
||||
|
||||
ale_real get_black_level() {
|
||||
return _black_level;
|
||||
}
|
||||
|
||||
static void set_gain_reference(ale_real r) {
|
||||
_gain_reference = r;
|
||||
}
|
||||
|
||||
static ale_real get_gain_reference() {
|
||||
return _gain_reference;
|
||||
}
|
||||
|
||||
pixel get_multiplier() const {
|
||||
return _multiplier;
|
||||
}
|
||||
|
||||
virtual ale_real confidence(unsigned int k, ale_real input,
|
||||
ale_real confidence_floor = ale_real_confidence_floor) const {
|
||||
|
||||
ale_real _0 = (ale_real) 0;
|
||||
ale_real _4 = (ale_real) 4;
|
||||
ale_real _2 = (ale_real) 2;
|
||||
ale_real _1 = (ale_real) 1;
|
||||
|
||||
if (confidence_exponent == _0)
|
||||
return 1;
|
||||
|
||||
ale_real input_scaled = input / _multiplier[k];
|
||||
|
||||
ale_real unexponentiated = _1 - _4 * ((_1 / _2) - input_scaled)
|
||||
* ((_1 / _2) - input_scaled);
|
||||
|
||||
// ale_real unexponentiated = _4 * ((_1 / _4) - (ale_real) ((_1 / _2) - input_scaled)
|
||||
// * ((_1 / _2) - input_scaled));
|
||||
|
||||
// ale_real unexponentiated = 4 * input_scaled * (0.25 - pow(0.5 - input_scaled, 2));
|
||||
|
||||
ale_real exponentiated;
|
||||
|
||||
if (confidence_exponent != _1) {
|
||||
|
||||
if (unexponentiated < _0)
|
||||
return confidence_floor;
|
||||
|
||||
exponentiated = pow(unexponentiated, confidence_exponent);
|
||||
|
||||
} else {
|
||||
exponentiated = unexponentiated;
|
||||
}
|
||||
|
||||
if (exponentiated < confidence_floor || !finite(exponentiated))
|
||||
return confidence_floor;
|
||||
|
||||
return exponentiated;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a very hackish confidence function. It's zero at the
|
||||
* extremes of camera response and maximal at the center.
|
||||
*/
|
||||
virtual pixel confidence(pixel input,
|
||||
ale_real confidence_floor = ale_real_confidence_floor) const {
|
||||
|
||||
if (confidence_exponent != 0) {
|
||||
return pixel(confidence(0, input[0], confidence_floor),
|
||||
confidence(1, input[1], confidence_floor),
|
||||
confidence(2, input[2], confidence_floor));
|
||||
} else {
|
||||
return pixel(1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Confidence that the real value is lower or higher than the given
|
||||
* value.
|
||||
*
|
||||
* XXX: This function now applies the one-sided condition only to
|
||||
* responses greater than 50%. Should it be called
|
||||
* 'upper_one_sided_confidence' instead?
|
||||
*/
|
||||
virtual pixel one_sided_confidence(pixel input, pixel sign) const {
|
||||
if (confidence_exponent != 0) {
|
||||
pixel result = confidence(input);
|
||||
for (unsigned int k = 0; k < 3; k++) {
|
||||
if (sign[k] > 0 && input[k] / _multiplier[k] > 1 / (ale_real) 2)
|
||||
result[k] = 1;
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
return pixel(1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
virtual pixel linearize(pixel input) const = 0;
|
||||
virtual pixel unlinearize(pixel input) const = 0;
|
||||
|
||||
exposure() {
|
||||
listener_head = NULL;
|
||||
_multiplier = pixel(1, 1, 1);
|
||||
_gain_multiplier = 1;
|
||||
_black_level = 0;
|
||||
}
|
||||
|
||||
virtual ~exposure() {
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
46
d2/exposure/exposure_boolean.h
Normal file
46
d2/exposure/exposure_boolean.h
Normal file
@@ -0,0 +1,46 @@
|
||||
// Copyright 2004 David Hilvert <dhilvert@auricle.dyndns.org>,
|
||||
// <dhilvert@ugcs.caltech.edu>
|
||||
|
||||
/* This file is part of the Anti-Lamenessing Engine.
|
||||
|
||||
The Anti-Lamenessing Engine is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
The Anti-Lamenessing Engine is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the Anti-Lamenessing Engine; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* exposure_boolean.h: Boolean exposure properties.
|
||||
*/
|
||||
|
||||
#ifndef __exposure_boolean_h__
|
||||
#define __exposure_boolean_h__
|
||||
|
||||
/*
|
||||
* Boolean exposure.
|
||||
*/
|
||||
|
||||
class exposure_boolean : public exposure {
|
||||
public:
|
||||
pixel linearize(pixel input) const {
|
||||
for (int k = 0; k < 3; k++)
|
||||
input[k] = (input[k] == 0) ? 0 : 1;
|
||||
return input;
|
||||
}
|
||||
pixel unlinearize(pixel input) const {
|
||||
for (int k = 0; k < 3; k++)
|
||||
input[k] = (input[k] == 0) ? 0 : 1;
|
||||
return input;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
160
d2/exposure/exposure_default.h
Normal file
160
d2/exposure/exposure_default.h
Normal file
@@ -0,0 +1,160 @@
|
||||
// Copyright 2004 David Hilvert <dhilvert@auricle.dyndns.org>,
|
||||
// <dhilvert@ugcs.caltech.edu>
|
||||
|
||||
/* This file is part of the Anti-Lamenessing Engine.
|
||||
|
||||
The Anti-Lamenessing Engine is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
The Anti-Lamenessing Engine is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the Anti-Lamenessing Engine; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* exposure_default.h: Default exposure properties.
|
||||
*/
|
||||
|
||||
#ifndef __exposure_default_h__
|
||||
#define __exposure_default_h__
|
||||
|
||||
/*
|
||||
* The default exposure is modeled after the simple power transfer function
|
||||
* described in
|
||||
*
|
||||
* http://netpbm.sourceforge.net/doc/pnmgamma.html
|
||||
*
|
||||
* Note: optimizations in d2/image_rw.h depend on the details of this function.
|
||||
*/
|
||||
|
||||
class exposure_default : public exposure {
|
||||
public:
|
||||
pixel linearize(pixel input) const {
|
||||
#if 0
|
||||
/*
|
||||
* Calling pow() may be expensive on some platforms (e.g.,
|
||||
* those lacking hardware support for floating point).
|
||||
*/
|
||||
|
||||
return ppow(input, 1/0.45) * get_multiplier();
|
||||
#else
|
||||
const int table_size = 1024;
|
||||
const int table_bits = 10;
|
||||
const int interp_bits = 6;
|
||||
static int table_is_built = 0;
|
||||
static ale_real table[table_size];
|
||||
|
||||
pixel result;
|
||||
|
||||
if (!table_is_built) {
|
||||
for (int i = 0; i < table_size; i++) {
|
||||
table[i] = pow((float) i / (float) (table_size - 1), 1/0.45);
|
||||
}
|
||||
table_is_built = 1;
|
||||
}
|
||||
|
||||
for (int k = 0; k < 3; k++) {
|
||||
/*
|
||||
* Clamp.
|
||||
*/
|
||||
if (input[k] >= 1) {
|
||||
result[k] = 1;
|
||||
continue;
|
||||
} else if (input[k] <= 0) {
|
||||
result[k] = 0;
|
||||
continue;
|
||||
} else if (isnan(input[k])) {
|
||||
result[k] = input[k];
|
||||
continue;
|
||||
}
|
||||
|
||||
int index1 = ale_real_to_int(input[k], 65535);
|
||||
|
||||
int index2 = index1 >> (16 - table_bits);
|
||||
int index3 = (index1 >> (16 - table_bits - interp_bits))
|
||||
& ((1 << interp_bits) - 1);
|
||||
|
||||
if (index2 >= table_size - 1) {
|
||||
result[k] = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
ale_real frac = ale_real_from_int((index3 << (16 - interp_bits)), 65535);
|
||||
|
||||
result[k] = (1 - frac) * table[index2] + frac * table[index2 + 1];
|
||||
}
|
||||
|
||||
return result * get_multiplier();
|
||||
#endif
|
||||
}
|
||||
pixel unlinearize(pixel input) const {
|
||||
#if 0
|
||||
/*
|
||||
* Calling pow() may be expensive on some platforms (e.g.,
|
||||
* those lacking hardware support for floating point).
|
||||
*/
|
||||
|
||||
return ppow(input / get_multiplier(), 0.45);
|
||||
#else
|
||||
|
||||
input /= get_multiplier();
|
||||
|
||||
const int table_size = 1024;
|
||||
const int table_bits = 10;
|
||||
const int interp_bits = 6;
|
||||
static int table_is_built = 0;
|
||||
static ale_real table[table_size];
|
||||
|
||||
pixel result;
|
||||
|
||||
if (!table_is_built) {
|
||||
for (int i = 0; i < table_size; i++) {
|
||||
table[i] = pow((float) i / (float) (table_size - 1), 0.45);
|
||||
}
|
||||
table_is_built = 1;
|
||||
}
|
||||
|
||||
for (int k = 0; k < 3; k++) {
|
||||
/*
|
||||
* Clamp.
|
||||
*/
|
||||
if (input[k] >= 1) {
|
||||
result[k] = 1;
|
||||
continue;
|
||||
} else if (input[k] <= 0) {
|
||||
result[k] = 0;
|
||||
continue;
|
||||
} else if (isnan(input[k])) {
|
||||
result[k] = input[k];
|
||||
continue;
|
||||
}
|
||||
|
||||
int index1 = ale_real_to_int(input[k], 65535);
|
||||
|
||||
int index2 = index1 >> (16 - table_bits);
|
||||
int index3 = (index1 >> (16 - table_bits - interp_bits))
|
||||
& ((1 << interp_bits) - 1);
|
||||
|
||||
if (index2 >= table_size - 1) {
|
||||
result[k] = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
ale_real frac = ale_real_from_int((index3 << (16 - interp_bits)), 65535);
|
||||
|
||||
result[k] = (1 - frac) * table[index2] + frac * table[index2 + 1];
|
||||
}
|
||||
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
42
d2/exposure/exposure_linear.h
Normal file
42
d2/exposure/exposure_linear.h
Normal file
@@ -0,0 +1,42 @@
|
||||
// Copyright 2004 David Hilvert <dhilvert@auricle.dyndns.org>,
|
||||
// <dhilvert@ugcs.caltech.edu>
|
||||
|
||||
/* This file is part of the Anti-Lamenessing Engine.
|
||||
|
||||
The Anti-Lamenessing Engine is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
The Anti-Lamenessing Engine is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the Anti-Lamenessing Engine; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* exposure_linear.h: Linear exposure properties.
|
||||
*/
|
||||
|
||||
#ifndef __exposure_linear_h__
|
||||
#define __exposure_linear_h__
|
||||
|
||||
/*
|
||||
* Linear exposure.
|
||||
*/
|
||||
|
||||
class exposure_linear : public exposure {
|
||||
public:
|
||||
pixel linearize(pixel input) const {
|
||||
return input * get_multiplier();
|
||||
}
|
||||
pixel unlinearize(pixel input) const {
|
||||
return input / get_multiplier();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user