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 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
|
#ifndef VECTORTOSCALARIMAGEACCESSOR_H
#define VECTORTOSCALARIMAGEACCESSOR_H
#include "itkDefaultVectorPixelAccessor.h"
namespace itk
{
template <class TImage, class TAccessor> class ImageAdaptor;
template <class TPixel, unsigned int Vdim> class VectorImage;
}
/**
* An accessor very similar to itk::VectorImageToImageAccessor that allows us
* to extract certain computed quantities from the vectors, such as magnitude
*/
template <class TFunctor>
class VectorToScalarImageAccessor
: private itk::DefaultVectorPixelAccessor< typename TFunctor::InputPixelType >
{
public:
typedef itk::DefaultVectorPixelAccessor< typename TFunctor::InputPixelType > Superclass;
typedef typename TFunctor::OutputPixelType ExternalType;
typedef typename TFunctor::InputPixelType InternalType;
typedef itk::SizeValueType SizeValueType;
typedef itk::VariableLengthVector<ExternalType> ActualPixelType;
typedef unsigned int VectorLengthType;
inline void Set(ActualPixelType output, const ExternalType &input) const
{ output.Fill(input); }
inline void Set(InternalType &output, const ExternalType &input,
const SizeValueType offset) const
{ Set( Superclass::Get(output, offset), input); }
inline ExternalType Get(const ActualPixelType &input) const
{ return m_Functor.Get(input); }
inline ExternalType Get(const InternalType *incomp) const
{ return m_Functor.Get(incomp, Superclass::GetVectorLength()); }
inline ExternalType Get(const InternalType &input,
const SizeValueType offset) const
{ return Get(Superclass::Get(input, offset)); }
void SetVectorLength(VectorLengthType l)
{
m_Functor.SetVectorLength(l);
Superclass::SetVectorLength(l);
}
VectorLengthType GetVectorLength() const
{
return Superclass::GetVectorLength();
}
/**
* Set the linear mapping from the vector image internal values to the
* native data type. The mapping is native = internal * scale + shift
*/
void SetSourceNativeMapping(double scale, double shift)
{
m_Functor.SetSourceNativeMapping(scale, shift);
}
protected:
TFunctor m_Functor;
};
/**
* This is the parent class for the functors below, encompassing shared
* functionality
*/
class AbstractVectorToDerivedQuantityFunctor
{
public:
AbstractVectorToDerivedQuantityFunctor()
{
m_Length = 1;
m_Scale = 1;
m_Shift = 0;
this->ParametersUpdated();
}
virtual ~AbstractVectorToDerivedQuantityFunctor() {}
virtual void SetSourceNativeMapping(double scale, double shift)
{
m_Shift = shift;
m_Scale = scale;
this->ParametersUpdated();
}
virtual void SetVectorLength(unsigned int l)
{
m_Length = l;
this->ParametersUpdated();
}
virtual void ParametersUpdated() {};
protected:
// Mapping from internal to native in the wrapped image
double m_Shift, m_Scale;
unsigned int m_Length;
};
/**
* This class returns the magnitude of the vector. Since the vector is stored
* internally as a shifted and scaled version of the native intensity value,
* to compute magnitude, we first need to map the input values back to the
* native value, take magnitude, and map back to the stored integral value
*
* TODO: magnitude adapters should be treated as float images, not short,
* which will allow us to avoid this mess.
*/
template <class TInputPixel, class TOutputPixel>
class VectorToScalarMagnitudeFunctor : public AbstractVectorToDerivedQuantityFunctor
{
public:
typedef TInputPixel InputPixelType;
typedef TOutputPixel OutputPixelType;
OutputPixelType Get(const itk::VariableLengthVector<InputPixelType> &input) const
{
return this->Get(input.GetDataPointer(), input.Size());
}
OutputPixelType Get(const InputPixelType *input, int n_comp) const
{
double sumT2 = 0.0, sumT = 0.0;
for(int i = 0; i < n_comp; i++)
{
double t = input[i];
sumT2 += t * t;
sumT += t;
}
double norm_raw_out =
sqrt(m_CoeffT2 * sumT2 + m_CoeffT1 * sumT + m_CoeffT0);
return static_cast<OutputPixelType>(norm_raw_out);
}
virtual void ParametersUpdated()
{
m_CoeffT2 = (this->m_Scale * this->m_Scale);
m_CoeffT1 = (2 * this->m_Scale * this->m_Shift);
m_CoeffT0 = (this->m_Shift * this->m_Shift) * this->m_Length;
}
protected:
// Used internally to compute norm with fewest operations
double m_CoeffT2, m_CoeffT1, m_CoeffT0;
};
template <class TInputPixel, class TOutputPixel>
class VectorToScalarMaxFunctor : public AbstractVectorToDerivedQuantityFunctor
{
public:
typedef TInputPixel InputPixelType;
typedef TOutputPixel OutputPixelType;
OutputPixelType Get(const itk::VariableLengthVector<InputPixelType> &input) const
{
return this->Get(input.GetDataPointer(), input.Size());
}
OutputPixelType Get(const InputPixelType *input, int n_comp) const
{
InputPixelType mymax = input[0];
for(int i = 1; i < n_comp; i++)
mymax = std::max(input[i], mymax);
return static_cast<OutputPixelType>(mymax * this->m_Scale + this->m_Shift);
}
};
template <class TInputPixel, class TOutputPixel>
class VectorToScalarMeanFunctor : public AbstractVectorToDerivedQuantityFunctor
{
public:
typedef TInputPixel InputPixelType;
typedef TOutputPixel OutputPixelType;
OutputPixelType Get(const itk::VariableLengthVector<InputPixelType> &input) const
{
return this->Get(input.GetDataPointer(), input.Size());
}
OutputPixelType Get(const InputPixelType *input, int n_comp) const
{
double mean = 0.0;
for(int i = 0; i < n_comp; i++)
mean += input[i];
mean /= n_comp;
return static_cast<OutputPixelType>(mean * this->m_Scale + this->m_Shift);
}
};
// Typedefs for GreyType
typedef VectorToScalarMagnitudeFunctor<GreyType, float> GreyVectorToScalarMagnitudeFunctor;
typedef VectorToScalarImageAccessor<GreyVectorToScalarMagnitudeFunctor>
GreyVectorMagnitudeImageAccessor;
typedef itk::ImageAdaptor< itk::VectorImage<GreyType, 3>, GreyVectorMagnitudeImageAccessor>
GreyVectorMagnitudeImageAdaptor;
typedef VectorToScalarMaxFunctor<GreyType, float> GreyVectorToScalarMaxFunctor;
typedef VectorToScalarImageAccessor<GreyVectorToScalarMaxFunctor>
GreyVectorMaxImageAccessor;
typedef itk::ImageAdaptor< itk::VectorImage<GreyType, 3>, GreyVectorMaxImageAccessor>
GreyVectorMaxImageAdaptor;
typedef VectorToScalarMeanFunctor<GreyType,float> GreyVectorToScalarMeanFunctor;
typedef VectorToScalarImageAccessor<GreyVectorToScalarMeanFunctor>
GreyVectorMeanImageAccessor;
typedef itk::ImageAdaptor< itk::VectorImage<GreyType, 3>, GreyVectorMeanImageAccessor>
GreyVectorMeanImageAdaptor;
#endif // VECTORTOSCALARIMAGEACCESSOR_H
|