Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ColourGradient.cpp
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 #include <Utils/ColourGradient.hh>
26 
27 using namespace std;
28 using namespace BIAS;
29 
30 
31 template <class StorageType>
34 {
35  // define colours
36  std::vector<StorageType> black(3, 0);
37  std::vector<StorageType> white(3, 1);
38 
39  // init members
40  numChannels_ = 3;
41 
42  GradientStep<StorageType> left;
43  left.pos = 0.0f;
44  left.colour = black;
45  gradientSteps_.push_front(left);
46 
47  GradientStep<StorageType> right;
48  right.pos = 1.0f;
49  right.colour = white;
50  gradientSteps_.push_back(right);
51 }
52 
53 
54 template <class StorageType>
57  const StorageType max)
58 {
59  numChannels_ = 3;
60 
61  switch (mapType)
62  {
63  case Gray:
64  AddRGBColour(0.0f, 0, 0, 0);
65  AddRGBColour(1.0f, max, max, max);
66  break;
67  case Cool:
68  AddRGBColour(0.0f, 0, max, max);
69  AddRGBColour(1.0f, max, 0, max);
70  break;
71  case Hot:
72  AddRGBColour(0.00f, (StorageType)(41.0/255.0 * max), 0, 0);
73  AddRGBColour(0.33f, max, 0, 0);
74  AddRGBColour(0.73f, max, max, 0);
75  AddRGBColour(1.00f, max, max, max);
76  break;
77  case Bone:
78  AddRGBColour(0.00f, 0, 0, (StorageType)(5.0/255.0 * max));
79  AddRGBColour(0.33f, (StorageType)(74.0/255.0 * max),
80  (StorageType)(74.0/255.0 * max),
81  (StorageType)(106.0/255.0 * max));
82  AddRGBColour(0.73f, (StorageType)(164.0/255.0 * max),
83  (StorageType)(196.0/255.0 * max),
84  (StorageType)(196.0/255.0 * max));
85  AddRGBColour(1.00f, max, max, max);
86  break;
87  case Jet:
88  AddRGBColour(0.00f, 0, 0, (StorageType)(189.0/255.0 * max));
89  AddRGBColour(0.33f, 0, max, max);
90  AddRGBColour(0.60f, max, max, 0);
91  AddRGBColour(0.87f, max, 0, 0);
92  AddRGBColour(1.00f, (StorageType)(132.0/255.0 * max), 0, 0);
93  break;
94  default:
95  cerr << "unknown colour gradient type! using gray scale..." << endl;
96  AddRGBColour(0.0f, 0, 0, 0);
97  AddRGBColour(1.0f, max, max, max);
98  break;
99  }
100 }
101 
102 
103 template <class StorageType>
105 ColourGradient(std::vector<StorageType> colourLeft,
106  std::vector<StorageType> colourRight)
107 {
108  BIASASSERT(colourLeft.size() == colourRight.size())
109  BIASASSERT(colourLeft.size() > 0)
110 
111  numChannels_ = colourLeft.size();
112 
113  GradientStep<StorageType> left;
114  left.pos = 0.0f;
115  left.colour = colourLeft;
116  gradientSteps_.push_front(left);
117 
118  GradientStep<StorageType> right;
119  right.pos = 1.0f;
120  right.colour = colourRight;
121  gradientSteps_.push_back(right);
122 }
123 
124 
125 template <class StorageType>
127 AddColour(float pos,
128  const std::vector<StorageType> &colour)
129 {
130  BIASASSERT(pos >= 0.0 && pos <= 1.0);
131  BIASASSERT(colour.size() == numChannels_);
132 
133  if (gradientSteps_.size() == 0)
134  {
135  GradientStep<StorageType> step;
136  step.pos = pos;
137  step.colour = colour;
138  gradientSteps_.push_back(step);
139  return;
140  }
141 
142  typename list<GradientStep<StorageType> >::iterator it = gradientSteps_.begin();
143 
144  bool itLargerEqual = false; // set to true if it points to value with pos larger or equal the new input's pos
145 
146  while (it != gradientSteps_.end() && !itLargerEqual)
147  {
148  if (it->pos < pos)
149  {
150  it++;
151  }
152  else
153  {
154  itLargerEqual = true;
155  }
156  }
157 
158  if (it->pos == pos)
159  {
160  it->colour = colour;
161  }
162  else // it->pos is bigger than pos or is at the end so insert a new element
163  {
164  GradientStep<StorageType> step;
165  step.pos = pos;
166  step.colour = colour;
167  gradientSteps_.insert(it, step);
168  }
169 }
170 
171 
172 template <class StorageType>
174 GetColour(float pos,
175  std::vector<StorageType> &colour)
176 {
177  BIASASSERT(pos >= 0.0f && pos <= 1.0f)
178 
179  colour.clear();
180  colour.resize(numChannels_);
181 
182  typename std::list<GradientStep<StorageType> >::iterator left
183  = gradientSteps_.begin();
184  typename std::list<GradientStep<StorageType> >::iterator right
185  = ++(gradientSteps_.begin());
186 
187  do
188  {
189  if (pos >= left->pos && pos <= right->pos)
190  {
191  const float delta = right->pos - left->pos;
192  const float weight = (pos - left->pos) / delta;
193 
194  for (unsigned int c = 0; c < numChannels_; c++)
195  {
196  colour[c] = (StorageType)(((1.0f - weight) * left->colour[c]) +
197  (weight * right->colour[c]));
198  }
199 
200  return;
201  }
202 
203  // prepare next iteration
204  ++left;
205  ++right;
206  }
207  while (right != gradientSteps_.end());
208 }
209 
210 
211 template <class StorageType>
213 AddRGBColour(float pos,
214  const StorageType r, const StorageType g, const StorageType b)
215 {
216  vector<StorageType> colour(3);
217  colour[0] = r;
218  colour[1] = g;
219  colour[2] = b;
220  AddColour(pos, colour);
221 }
222 
223 
224 //
225 // solve explicit instantiation
226 //
227 
228 
229 #define INSTANCE_ColourGradient(type)\
230 template class BIASUtils_EXPORT ColourGradient<type>;
231 
232 namespace BIAS{
233 INSTANCE_ColourGradient(unsigned char)
234 INSTANCE_ColourGradient(float)
235 #ifdef BUILD_IMAGE_INT
236  INSTANCE_ColourGradient(int)
237 #endif
238 #ifdef BUILD_IMAGE_CHAR
239  INSTANCE_ColourGradient(char)
240 #endif
241 #ifdef BUILD_IMAGE_SHORT
242  INSTANCE_ColourGradient(short)
243 #endif
244 #if defined(BUILD_IMAGE_USHORT)
245  INSTANCE_ColourGradient(unsigned short)
246 #endif
247 #ifdef BUILD_IMAGE_DOUBLE
248  INSTANCE_ColourGradient(double)
249 #endif
250 #ifdef BUILD_IMAGE_UINT
251  INSTANCE_ColourGradient(unsigned int)
252 #endif
253 }
Represents a colour gradient.
ColourGradient()
Default Constructor.
ColourGradientType
Different types of predefined color gradients that can be generated.
void AddRGBColour(float pos, const StorageType r, const StorageType g, const StorageType b)
Convenience wrapper.
void GetColour(float pos, std::vector< StorageType > &colour)
Returns the interpolated colour at a given position.