-
Notifications
You must be signed in to change notification settings - Fork 11
/
IntensityTransformations.hpp
149 lines (129 loc) · 3.71 KB
/
IntensityTransformations.hpp
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
#ifndef INTENSITYTRANSFORMATIONS_HPP_
#define INTENSITYTRANSFORMATIONS_HPP_
#include "Types.hpp"
#include "Exceptions.hpp"
#include <typeinfo>
#include <iostream>
namespace SIPL {
enum TransformationType { DEFAULT, HOUNSEFIELD, AVERAGE, NORMALIZED, CUSTOM };
template <class T>
inline float toSingleValue(T value) {
return (float)(value);
};
template <>
inline float toSingleValue<color_uchar>(color_uchar value) {
return (float)(0.33f*(value.red+value.blue+value.green));
};
template <>
inline float toSingleValue<float3>(float3 value) {
return (float)(0.33f*(value.x+value.y+value.z));
};
template <>
inline float toSingleValue<float2>(float2 value) {
return (float)(0.33f*(value.x+value.y));
};
template <class T>
inline float3 toVectorData(T value) {
float3 v(value,value,value);
return v;
}
template <>
inline float3 toVectorData(float3 value) {
return value;
}
template <>
inline float3 toVectorData(float2 value) {
return float3(value.x,value.y,0);
}
template <>
inline float3 toVectorData(color_uchar value) {
return float3(value.red,value.green,value.blue);
}
class IntensityTransformation {
private:
TransformationType type;
void(*func)(const void *, void *, unsigned int, unsigned int);
public:
IntensityTransformation() { this->type = DEFAULT; };
IntensityTransformation(void(*func)(const void *, void *, unsigned int, unsigned int)) {
this->func = func;
this->type = CUSTOM;
};
IntensityTransformation(TransformationType type) { this->type = type; };
template <class S, class T>
void transform(const S * from, T * to, unsigned int length, unsigned int start = 0) {
switch(type) {
case HOUNSEFIELD:
// Target must be short
if(typeid(T) != typeid(short))
throw SIPLException("Has to be short.");
if(typeid(S) == typeid(short)) {
// Do a simple copy
this->copy(from, to, length, start);
} else if(typeid(S) == typeid(ushort)) {
for(unsigned int i = start; i < start+length; i++) {
to[i] = toSingleValue(from[i]) - 1024;
}
} else {
throw SIPLException("Source has to be ushort or short");
}
break;
case AVERAGE:
// Check that S is a vector type
if(!isVectorType(from)) {
throw SIPLException("Cannot convert scalar image using average intensity transformation");
}
this->copy(from, to, length, start);
break;
case CUSTOM:
func(from,to,length,start);
break;
case NORMALIZED:
if(typeid(T) != typeid(float)) {
throw SIPLException("Target has to float");
} else {
// find min and max
float min = toSingleValue(from[start]);
float max = toSingleValue(from[start]);
for(unsigned int i = start; i < start+length; i++) {
if(toSingleValue(from[i]) < min)
min = toSingleValue(from[i]);
if(toSingleValue(from[i]) > max)
max = toSingleValue(from[i]);
}
for(unsigned int i = start; i < start+length; i++) {
to[i] = ((float)toSingleValue(from[i])-min)/(max+min);
}
}
break;
case DEFAULT:
if(isVectorType(from) && !isVectorType(to)) {
// Use AVERAGE instead
this->type = AVERAGE;
this->transform(from,to,length,start);
} else {
this->copy(from, to, length, start);
}
break;
default:
throw SIPLException("Invalid transformation type");
break;
}
}
template <class S, class T>
static void copy(const S * from, T * to, unsigned int length, unsigned int start) {
for(unsigned int i = start; i < length+start; i++) {
to[i] = toSingleValue(from[i]);
}
}
template <class T>
static bool isVectorType(T * from) {
const std::type_info * i = &typeid(T);
return *i == typeid(float3) ||
*i == typeid(float2) ||
*i == typeid(color_uchar) ||
*i == typeid(color_float);
}
};
}
#endif /* INTENSITYTRANSFORMATIONS_HPP_ */