1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
|
/* kernel.h
Mark Jenkinson, FMRIB Image Analysis Group
Copyright (C) 2001 University of Oxford */
/* CCOPYRIGHT */
// General kernel interpolation class
#if !defined(kernel_h)
#define kernel_h
#include <iostream>
#include <string>
#include <set>
#include <cmath>
#include "newmat.h"
using namespace NEWMAT;
using namespace std;
namespace MISCMATHS {
/////////////////////////////////////////////////////////////////////////
// Interpolation kernel storage class
class kernelstorage
{
private:
// NB: all widths are kernel half-widths (i.e. x \in [ -w, +w ] )
int p_widthx;
int p_widthy;
int p_widthz;
ColumnVector p_kernelx;
ColumnVector p_kernely;
ColumnVector p_kernelz;
// stop all forms of creation except the constructors below
kernelstorage();
const kernelstorage& operator=(kernelstorage&);
kernelstorage(kernelstorage&);
public:
float *storex;
float *storey;
float *storez;
kernelstorage(const ColumnVector& kx, const ColumnVector& ky,
const ColumnVector& kz, int wx, int wy, int wz)
{
p_kernelx = kx; p_kernely = ky; p_kernelz = kz;
p_widthx = wx; p_widthy = wy; p_widthz = wz;
storez = new float[2*wz+1];
storey = new float[2*wy+1];
storex = new float[2*wx+1];
}
~kernelstorage()
{
delete storex;
delete storey;
delete storez;
}
class comparer
{
public:
bool operator()(const kernelstorage* k1,
const kernelstorage* k2) const
{
// comparison of sizes and values (toleranced)
if ( (k1->p_widthx!=k2->p_widthx) ||
(k1->p_widthy!=k2->p_widthy) ||
(k1->p_widthz!=k2->p_widthz) )
return false;
if ( ( (k1->p_kernelx - k2->p_kernelx).MaximumAbsoluteValue()
> 1e-8 * k1->p_kernelx.MaximumAbsoluteValue() ) ||
( (k1->p_kernely - k2->p_kernely).MaximumAbsoluteValue()
> 1e-8 * k1->p_kernely.MaximumAbsoluteValue() ) ||
( (k1->p_kernelz - k2->p_kernelz).MaximumAbsoluteValue()
> 1e-8 * k1->p_kernelz.MaximumAbsoluteValue() ) )
return false;
return true;
}
};
friend class comparer;
int widthx() const { return p_widthx; }
int widthy() const { return p_widthy; }
int widthz() const { return p_widthz; }
const ColumnVector& kernelx() const { return p_kernelx; }
const ColumnVector& kernely() const { return p_kernely; }
const ColumnVector& kernelz() const { return p_kernelz; }
};
/////////////////////////////////////////////////////////////////////////////
class kernel
{
private:
static set<kernelstorage*, kernelstorage::comparer> existingkernels;
kernelstorage* storedkernel;
public:
kernel() { storedkernel = 0; }
const kernel& operator=(const kernel& source)
{
// am allowed to copy pointers if other class either
// always exists or manages reference counts and self-deletes
this->existingkernels = source.existingkernels;
this->storedkernel = source.storedkernel;
// signal storedkernel has an extra reference
// and that old storedkernel has one less reference
return *this;
}
kernel(const kernel& source)
{
this->operator=(source);
}
virtual ~kernel()
{
// signal storedkernel it has one less reference
}
void setkernel(const ColumnVector& kx, const ColumnVector& ky,
const ColumnVector& kz, int wx, int wy, int wz)
{
// see if already in list:
storedkernel = new kernelstorage(kx,ky,kz,wx,wy,wz);
set<kernelstorage*, kernelstorage::comparer>::iterator
it = existingkernels.find(storedkernel);
if (it==existingkernels.end()) {
existingkernels.insert(storedkernel);
// signal that this is the first reference for storedkernel
} else {
delete storedkernel;
storedkernel = *it;
// signal that *it has another reference now
}
}
const kernelstorage* kernelvals() { return storedkernel; }
};
/////////////////////////////////////////////////////////////////////////
//////// Support functions /////////
float kernelval(float x, int w, const ColumnVector& kernel);
float sincfn(float x);
float hanning(float x, int w);
float blackman(float x, int w);
float rectangular(float x, int w);
ColumnVector sinckernel1D(const string& sincwindowtype, int w, int n);
kernel sinckernel(const string& sincwindowtype, int w, int nstore);
kernel sinckernel(const string& sincwindowtype,
int wx, int wy, int wz, int nstore);
float extrapolate_1d(const ColumnVector& data, const int index);
float interpolate_1d(const ColumnVector& data, const float index);
float kernelinterpolation_1d(const ColumnVector& data, float index, const ColumnVector& userkernel, int width);
float kernelinterpolation_1d(const ColumnVector& data, float index);
float kernelinterpolation_1d(RowVector data, float index);
float hermiteinterpolation_1d(const ColumnVector& data, int p1, int p4, float t);
}
#endif
|