head	1.1;
access;
symbols;
locks; strict;
comment	@// @;


1.1
date	95.01.05.03.11.30;	author rjj;	state Exp;
branches;
next	;


desc
@First version of file to be placed under RCS for Histogram Modification
  section.  Previous version have been integrated into fewer files.
@


1.1
log
@Initial revision
@
text
@// histo-mod.c          Section: 2.10, Histogram Modification
//      Copyright 1995, Center for Computer Vision and Visualization,
//      University of Florida.  All rights reserved.

#include "histo-mod.h"

/////////////////////////////////////////////////////////////////////////////
//
// Uniform Histogram modification
//
/////////////////////////////////////////////////////////////////////////////


IA_Point<int>
value_to_point( int value ) {
    return IA_Point<int>(value);
}


template<class P, class T>
class image_as_function: public IA_Closure<P,T> {
private:
    IA_Image<IA_Point<P>,T> im;

public:
    image_as_function( const IA_Image<IA_Point<P>,T> & _im )
    : im( _im ) {}
    T operator() (const P & inVal) const {
	return im( IA_Point<P>(inVal) );
    }
    IA_Closure<P,T> * clone_self() const {
	return new image_as_function(*this);
    }
};



// Assumptions:
//    o  Inputs are g , g , and the image
//                   1   m
//    o  The image range is [0..image.range().max()]
//
template <class P, class T>
IA_Image<IA_Point<int>,float>
uniform_histo_mod( const IA_Image<P,T> &a,
		   double g1, double gm ) {

    image_as_function<int,float>
	nch_func( normalized_cumulative_histogram( a ) );

    IA_Image<IA_Point<int>,float>  b;

    b = (gm - g1) * compose( nch_func, a ) + g1;

    return b;
}


template <class P, class T>
IA_Image<IA_Point<int>,float>
exponential_histo_mod( const IA_Image<P,T> &a,
		       double g1, double alpha) {

    image_as_function<int,float>
	nch_func( normalized_cumulative_histogram( a ) );

    IA_Image<IA_Point<int>,float>  b;

    b = g1 - ln( 1 - compose( nch_func, a ) )/alpha;

    return b;
}


template <class P, class T>
IA_Image<IA_Point<int>,float>
rayleigh_histo_mod( const IA_Image<P,T> &a,
		    double g1, double alpha) {

    image_as_function<int,float>
	nch_func( normalized_cumulative_histogram( a ) );

    IA_Image<IA_Point<int>,float>  b;

    alpha = 2*alpha*alpha;
    b = g1 + sqrt( alpha*compose( nch_func, a ) );

    return b;
}


double cube_root( double x ) {
    if (x==0) {
	return 0;
    } else if (x>0) {
	return exp( log(x)/3 );
    } else {
	return -exp( log(fabs(x))/3 );
    }
}


template <class P, class T>
IA_Image<IA_Point<int>,float>
hyperbolic_cube_root_histo_mod( const IA_Image<P,T> &a,
				double g1, double gm) {

    double g1_3 = cube_root(g1), gm_3 = cube_root(gm);

    image_as_function<int,float>
	nch_func( normalized_cumulative_histogram( a ) );

    IA_Image<IA_Point<int>,float>  b;

    b = (gm_3 - g1_3) * compose( nch_func, a ) + g1_3;
    b *= sqr(b);

    return b;
}



// Basically we do this to Curry the value for the pow() function out
template<class InT, class OutT>
class
value_raised_to_image_power: public IA_Closure<InT,OutT> {
private:
    double  val;

public:
    value_raised_to_image_power( double _val ) : val(_val) {}

    OutT operator() (const InT & imageVal) const {
	return pow(val, imageVal);
    }
    IA_Closure<InT,OutT> * clone_self() const {
	return new value_raised_to_image_power(*this);
    }
};


template <class P, class T>
IA_Image<IA_Point<int>,float>
hyperbolic_logarithmic_histo_mod( const IA_Image<P,T> &a,
				  double g1, double gm) {

    value_raised_to_image_power<T,float> g(gm/g1);
    IA_Image<IA_Point<int>,float>  b;

    b = g1 * compose( g, normalized_cumulative_histogram( a ) );

    return b;
}
@
