iLab Neuromorphic Robotics Toolkit  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PixHSVImpl.H
Go to the documentation of this file.
1 /*! @file
2  @author
3  @copyright GNU Public License (GPL v3)
4  @section License
5  @verbatim
6  // ////////////////////////////////////////////////////////////////////////
7  // The iLab Neuromorphic Robotics Toolkit (NRT) //
8  // Copyright 2010-2012 by the University of Southern California (USC) //
9  // and the iLab at USC. //
10  // //
11  // iLab - University of Southern California //
12  // Hedco Neurociences Building, Room HNB-10 //
13  // Los Angeles, Ca 90089-2520 - USA //
14  // //
15  // See http://ilab.usc.edu for information about this project. //
16  // ////////////////////////////////////////////////////////////////////////
17  // This file is part of The iLab Neuromorphic Robotics Toolkit. //
18  // //
19  // The iLab Neuromorphic Robotics Toolkit is free software: you can //
20  // redistribute it and/or modify it under the terms of the GNU General //
21  // Public License as published by the Free Software Foundation, either //
22  // version 3 of the License, or (at your option) any later version. //
23  // //
24  // The iLab Neuromorphic Robotics Toolkit is distributed in the hope //
25  // that it will be useful, but WITHOUT ANY WARRANTY; without even the //
26  // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //
27  // PURPOSE. See the GNU General Public License for more details. //
28  // //
29  // You should have received a copy of the GNU General Public License //
30  // along with The iLab Neuromorphic Robotics Toolkit. If not, see //
31  // <http://www.gnu.org/licenses/>. //
32  // ////////////////////////////////////////////////////////////////////////
33  @endverbatim */
34 
35 
36 
37 //// ######################################################################
38 template <class T>
39 PixHSV<T>::PixHSV() : PixelBase<T, 3, nrt::PixHSV>()
40 { }
41 
42 // ######################################################################
43 template <class T>
44 template <typename T1>
45 PixHSV<T>::PixHSV(T1 value) :
46  PixelBase<T, 3, nrt::PixHSV>(value)
47 { }
48 
49 // ######################################################################
50 template <class T>
51 PixHSV<T>::PixHSV(T h, T s, T v)
52 {
53  this->channels[0] = h;
54  this->channels[1] = s;
55  this->channels[2] = v;
56 }
57 
58 // ######################################################################
59 template<class T>
60 template<class T2>
61 PixHSV<T>::PixHSV(PixHSV<T2> const& other) :
62  PixelBase<T, 3, nrt::PixHSV>(other)
63 { }
64 
65 // ######################################################################
66 template <class T>
67 template <class hType, class sType, class vType>
68 PixHSV<T>::PixHSV(hType h, sType s, vType v)
69 {
70  this->channels[0] = clamped_convert<T>(h);
71  this->channels[1] = clamped_convert<T>(s);
72  this->channels[2] = clamped_convert<T>(v);
73 }
74 
75 // ######################################################################
76 template <class T>
77 T PixHSV<T>::h() const
78 { return this->channels[0]; }
79 
80 // ######################################################################
81 template <class T>
82 T PixHSV<T>::s() const
83 { return this->channels[1]; }
84 
85 // ######################################################################
86 template <class T>
87 T PixHSV<T>::v() const
88 { return this->channels[2]; }
89 
90 // ######################################################################
91 template <class T>
92 void PixHSV<T>::setH(T value)
93 { this->channels[0] = value; }
94 
95 // ######################################################################
96 template <class T>
97 void PixHSV<T>::setS(T value)
98 { this->channels[1] = value; }
99 
100 // ######################################################################
101 template <class T>
102 void PixHSV<T>::setV(T value)
103 { this->channels[2] = value; }
104 
105 // ######################################################################
106 template <class T>
107 template<class T2>
108 void PixHSV<T>::setH(T2 value)
109 { this->channels[0] = clamped_convert<T>(value); }
110 
111 // ######################################################################
112 template <class T>
113 template<class T2>
114 void PixHSV<T>::setS(T2 value)
115 { this->channels[1] = clamped_convert<T>(value); }
116 
117 // ######################################################################
118 template <class T>
119 template<class T2>
120 void PixHSV<T>::setV(T2 value)
121 { this->channels[2] = clamped_convert<T>(value); }
122 
123 // ######################################################################
124 template <class T>
126 {
127  // From Wikipedia:
128 
129  double H = h() * 360.0 / 255.0;
130  double S = s() / 255.0;
131  double V = v() / 255.0;
132 
133  double C = V * S;
134 
135  double H_p = H / 60.0;
136  double X = C * (1 - fabs(fmod(H_p, 2) - 1));
137 
138  double R1 = 0;
139  double G1 = 0;
140  double B1 = 0;
141 
142  int i = floor(H_p);
143  switch (i)
144  {
145  case 0:
146  R1 = C;
147  G1 = X;
148  B1 = 0;
149  break;
150  case 1:
151  R1 = X;
152  G1 = C;
153  B1 = 0;
154  break;
155  case 2:
156  R1 = 0;
157  G1 = C;
158  B1 = X;
159  break;
160  case 3:
161  R1 = 0;
162  G1 = X;
163  B1 = C;
164  break;
165  case 4:
166  R1 = X;
167  G1 = 0;
168  B1 = C;
169  break;
170  case 5:
171  R1 = C;
172  G1 = 0;
173  B1 = X;
174  break;
175  default:
176  NRT_FATAL("Bad Color Conversion in File " << __FILE__ << " Line: " << __LINE__ << " (i=" << i << ")");
177  }
178 
179  double m = V - C;
180 
181  double R = (R1+m)*255.0;
182  double G = (G1+m)*255.0;
183  double B = (B1+m)*255.0;
184 
185  return PixRGB<T>(R, G, B);
186 }
187 
188 // ######################################################################
189 template <class T>
191 {
192 
193  // From Wikipedia:
194 
195  const double R = other.r()/255.0;
196  const double G = other.g()/255.0;
197  const double B = other.b()/255.0;
198 
199  const double M = std::max(std::max(R, G), B);
200  const double m = std::min(std::min(R, G), B);
201  const double C = M - m;
202 
203  double V = M;
204 
205  double H_p = 0;
206  if (C == 0)
207  {
208  H_p = 0;
209  }
210  else if (M == R)
211  {
212  H_p = fmod((G-B)/C, 6);
213  if(H_p < 0 ){H_p = H_p + 6;} // otherwise for magenta H_p=-60 and get clamped and so magenta = red !
214  }
215  else if (M == G)
216  {
217  H_p = (B-R)/C + 2;
218  }
219  else if (M == B)
220  {
221  H_p = (R-G)/C + 4;
222  }
223  double H = H_p * 60.0;
224 
225  double S;
226  if (C == 0)
227  {
228  S = 0;
229  }
230  else
231  {
232  S = C/V;
233  }
234 
235 
236  // Renormalize all values to be from 0-255
237  H *= 255.0 / 360.0;
238  S *= 255.0;
239  V *= 255.0;
240 
241  return PixHSV<T>(H, S, V);
242 }
243 
244