Home Page Toolkit Overview Using GML User Input Services Finger Tracker Calibrator Frame Grabber Service protocol Obtaining GML Installing GML Licence Developer Documentation Tcl/Tk API The GML Canvas Image processing Tcl Scripts Library List of Classes List of Files C/C++ API List of Classes List of Files |
gml_HSVColor.h00001 // gml_HSVColor.h -- 00002 // 00003 // Defines the gml_TColor_HSV class template 00004 // 00005 // Copyright (c) 2004 CLIPS-IMAG 00006 // 00007 // See the file "gml_LicenseTerms.txt" for information on usage and redistribution 00008 // of this file, and for a DISCLAIMER OF ALL WARRANTIES. 00009 // 00010 // Created on January 9, 2004 (JL). 00011 00012 00013 #ifndef __GML_HSVCOLOR__ 00014 #define __GML_HSVCOLOR__ 00015 00016 #include <assert.h> 00017 #include "gml/base/gml_Types.h" 00018 #include "gml/base/gml_Attributes.h" 00019 #include "gml/math/gml_Math.h" 00020 00021 /// 00022 /// gml_TColor_HSV_FFF -- 00023 /// A union type used to represent HSV-encoded color pixels. 00024 /// HSV is Smith's Hue, Saturation, Value colorspace. 00025 /// The type (and bitwidth) used for each channel is the template parameter. 00026 /// 00027 /// Some of this code is adapted from section 15.3.4 of "Computer Graphics: 00028 /// Principles and Practice", by J.D. Foley and A. van Dam. 00029 /// 00030 class gml_TColor_HSV_FFF 00031 { 00032 public: 00033 00034 /// 00035 /// Constructor -- 00036 /// Convert a 24-bit RGB triplet into HSV and fill in the object. 00037 /// 00038 gml_TColor_HSV_FFF (UInt8 const r, UInt8 const g, UInt8 const b) { 00039 00040 UInt32 min = Min (r, g, b); 00041 UInt32 max = Max (r, g, b); 00042 Float32 delta, h, s, v; 00043 00044 v = Divide (max , 255.0F); 00045 s = (max == 0) ? 0.0F : (Divide ((max-min) , max)); 00046 00047 if (s == 0.0F) { // achromatic case 00048 h = 0.0F; 00049 } else { 00050 delta = max - min; 00051 if (r == max) { 00052 h = Divide (Float32(g) - Float32(b), delta); 00053 if (h < 0.0) h += 6.0; 00054 } else if (g == max) { 00055 h = 2.0F + Divide (Float32(b) - Float32(r), delta); 00056 } else /*if (b == max)*/ { 00057 h = 4.0F + Divide (Float32(r) - Float32(g), delta); 00058 } 00059 } 00060 H = (1.0F / 6.0F) * h; 00061 S = s; 00062 V = v; 00063 00064 assert (H >= 0.0F && H <= 1.0F); 00065 assert (S >= 0.0F && S <= 1.0F); 00066 assert (V >= 0.0F && V <= 1.0F); 00067 } 00068 00069 00070 /// 00071 /// Constructor -- 00072 /// Fill the structure from data in memory 00073 /// 00074 gml_TColor_HSV_FFF (const void * const ptr) { 00075 *this = *((gml_TColor_HSV_FFF*)ptr); 00076 } 00077 00078 00079 /// 00080 /// Constructor -- 00081 /// Leave the structure `as is'. 00082 /// I.e. probably zero. 00083 /// 00084 gml_TColor_HSV_FFF () {} 00085 00086 00087 /// 00088 /// Print -- 00089 /// Dump a representation of the pixel to stdout: channels in hex and 00090 /// in degrees, percent, percent format. 00091 /// @warning no newline appended ! 00092 /// 00093 void Print () { 00094 printf ("%f %f %f (%3d %3d%% %3d%%)", 00095 H, S, V, 00096 (int) LRound (fmod(360.0 * H + 360.0, 360.0)), 00097 (int) LRound (100 * S), 00098 (int) LRound (100 * V) 00099 ); 00100 } 00101 00102 00103 /// 00104 /// Store -- 00105 /// Place the structure's data in memory 00106 /// 00107 void Store (void * const ptr) { 00108 *((gml_TColor_HSV_FFF*)ptr) = *this; 00109 } 00110 00111 /// 00112 /// Convert -- 00113 /// Convert the HSV data in this object to a 24 bit RGB triplet. 00114 /// 00115 void Convert (UInt8 &r, UInt8 &g, UInt8 &b) { 00116 Float32 fr = 0.0f; 00117 Float32 fg = 0.0f; 00118 Float32 fb = 0.0f; 00119 00120 if (S == 0.0F) { 00121 r = g = b = (UInt8) LRound (V * 255.0); 00122 } else { 00123 Float32 i = Floor (6.0F * H); 00124 Float32 f = 6.0F * H - i; 00125 Float32 p = V * (1.0F - S); 00126 Float32 q = V * (1.0F - S * f); 00127 Float32 t = V * (1.0F - S * (1.0F - f)); 00128 assert (p >= 0.0F && p <= 1.0F); 00129 assert (q >= 0.0F && q <= 1.0F); 00130 assert (t >= 0.0F && t <= 1.0F); 00131 assert (V >= 0.0F && V <= 1.0F); 00132 switch ((int) i) { 00133 case 0: fr = V; fg = t; fb = p; break; 00134 case 1: fr = q; fg = V; fb = p; break; 00135 case 2: fr = p; fg = V; fb = t; break; 00136 case 3: fr = p; fg = q; fb = V; break; 00137 case 4: fr = t; fg = p; fb = V; break; 00138 case 5: fr = V; fg = p; fb = q; break; 00139 } 00140 assert (fr <= 255.0 && fr >= 0.0); 00141 assert (fg <= 255.0 && fg >= 0.0); 00142 assert (fb <= 255.0 && fb >= 0.0); 00143 r = (UInt8) LRound (fr * 255.0); 00144 g = (UInt8) LRound (fg * 255.0); 00145 b = (UInt8) LRound (fb * 255.0); 00146 } 00147 } 00148 00149 00150 /// 00151 /// Distance -- 00152 /// Compute the 16-bit distance to another HSV pixel. 00153 /// The euclidian distance in the hue, saturation disc is used. 00154 /// 00155 UInt16 Distance (const gml_TColor_HSV_FFF other) { 00156 const Float32 pi = 3.14159265358979323846F; 00157 Float32 x0, x1, y0, y1, res; 00158 x0 = S * Cos (2.0F * pi * H); 00159 y0 = S * Sin (2.0F * pi * H); 00160 x1 = other.S * Cos (2.0F * pi * other.H); 00161 y1 = other.S * Sin (2.0F * pi * other.H); 00162 res = Min (1.0F, Norm (x0, y0, x1, y1)); 00163 assert (res >= 0.0F && res <= 1.0F); 00164 return (UInt16) LFloor (res * 65535.0F); 00165 } 00166 00167 00168 struct { ///< structure for transparent channel access 00169 #if BYTE_ORDER == BIG_ENDIAN 00170 Float32 H; ///< hue channel 00171 Float32 S; ///< saturation channel 00172 Float32 V; ///< value channel 00173 #else 00174 Float32 V; ///< value channel 00175 Float32 S; ///< saturation channel 00176 Float32 H; ///< hue channel 00177 #endif 00178 } GML_PACKED; 00179 00180 }; 00181 00182 00183 /// 00184 /// gml_TColor_HSV -- 00185 /// A union type used to represent HSV-encoded color pixels. 00186 /// HSV is Smith's Hue, Saturation, Value colorspace. 00187 /// The type (and bitwidth) used for each channel is the template parameter. 00188 /// 00189 template <typename Channel> 00190 class gml_TColor_HSV 00191 { 00192 public: 00193 00194 /// 00195 /// Constructor -- 00196 /// Convert a 24-bit RGB triplet into HSV and fill in the object. 00197 /// 00198 gml_TColor_HSV (UInt8 const r, UInt8 const g, UInt8 const b) { 00199 gml_TColor_HSV_FFF const pix (r, g, b); 00200 H = LFloor (pix.H * sChannelMax); 00201 S = LFloor (pix.S * sChannelMax); 00202 V = LFloor (pix.V * sChannelMax); 00203 } 00204 00205 00206 /// 00207 /// Constructor -- 00208 /// Fill the structure from data in memory 00209 /// 00210 gml_TColor_HSV (const void * const ptr) { 00211 *this = *((gml_TColor_HSV<Channel>*)ptr); 00212 } 00213 00214 00215 /// 00216 /// Constructor -- 00217 /// Leave the structure `as is'. 00218 /// I.e. probably zero. 00219 /// 00220 gml_TColor_HSV () {} 00221 00222 00223 /// 00224 /// Print -- 00225 /// Dump a representation of the pixel to stdout: channels in hex and 00226 /// in degrees, percent, percent format. 00227 /// @warning no newline appended ! 00228 /// 00229 void Print () { 00230 printf ("% 8X % 8X % 8X (%3d %3d%% %3d%%)", 00231 H, S, V, 00232 (UInt32) round (fmod(360.0 * H / sChannelMax + 360.0, 360.0)), 00233 100 * S / sChannelMax, 00234 100 * V / sChannelMax 00235 ); 00236 } 00237 00238 00239 /// 00240 /// Store -- 00241 /// Place the structure's data in memory 00242 /// 00243 void Store (void * const ptr) { 00244 *((gml_TColor_HSV<Channel>*)ptr) = *this; 00245 } 00246 00247 00248 /// 00249 /// Convert -- 00250 /// Convert the HSV data in this object to a 24 bit RGB triplet. 00251 /// 00252 void Convert (UInt8 &r, UInt8 &g, UInt8 &b) { 00253 gml_TColor_HSV_FFF pix; 00254 pix.H = Divide (H, sChannelMax); 00255 pix.S = Divide (S, sChannelMax); 00256 pix.V = Divide (V, sChannelMax); 00257 pix.Convert (r, g, b); 00258 } 00259 00260 00261 /// 00262 /// Distance -- 00263 /// Compute the 16-bit distance to another HSV pixel. 00264 /// The euclidian distance in the hue, saturation disc is used. 00265 /// 00266 UInt16 Distance (const gml_TColor_HSV<Channel> other) { 00267 gml_TColor_HSV_FFF pix0, pix1; 00268 pix0.H = Divide ( H, sChannelMax); 00269 pix0.S = Divide ( S, sChannelMax); 00270 pix0.V = Divide ( V, sChannelMax); 00271 pix1.H = Divide (other.H, other.sChannelMax); 00272 pix1.S = Divide (other.S, other.sChannelMax); 00273 pix1.V = Divide (other.V, other.sChannelMax); 00274 return pix0.Distance (pix1); 00275 } 00276 00277 00278 static UInt8 const sChannelBits = 8 * sizeof (Channel); ///< bits per channel 00279 static UInt64 const sChannelMax = (1 << sChannelBits) - 1; ///< max channel value 00280 00281 struct { ///< structure for transparent channel access 00282 #if BYTE_ORDER == BIG_ENDIAN 00283 Channel H; ///< hue channel 00284 Channel S; ///< saturation channel 00285 Channel V; ///< value channel 00286 #else 00287 Channel V; ///< value channel 00288 Channel S; ///< saturation channel 00289 Channel H; ///< hue channel 00290 #endif 00291 } GML_PACKED; 00292 00293 }; 00294 00295 // 00296 // gml_TColor_HSV_888, gml_TColor_HSV_SSS, gml_TColor_HSV_LLL -- 00297 // 00298 typedef gml_TColor_HSV<UInt8> gml_TColor_HSV_888; 00299 typedef gml_TColor_HSV<UInt16> gml_TColor_HSV_SSS; 00300 typedef gml_TColor_HSV<UInt32> gml_TColor_HSV_LLL; 00301 00302 00303 00304 #endif /* __GML_HSVCOLOR__ */ 00305
Generated on Tue Jun 12 14:03:27 2007 for gml by
Doxygen 1.5.2.
|
Contact: julien (dot) letessier (at) gmail (dot) com.
Copyright (c) 2000-2007 CLIPS-IMAG Laboratory, Grenoble, France. All rights reserved. W3CXHTML 1.0 W3CCSS 2.0 |