last update 20 Sep 2009 |
00001 /* 00002 * Copyright (C) 1998-2006 00003 * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany 00004 * 00005 * 00006 * This file is part of the Computer Vision and Robotics Library (CVR-Lib) 00007 * 00008 * The CVR-Lib is free software; you can redistribute it and/or 00009 * modify it under the terms of the BSD License. 00010 * 00011 * All rights reserved. 00012 * 00013 * Redistribution and use in source and binary forms, with or without 00014 * modification, are permitted provided that the following conditions are met: 00015 * 00016 * 1. Redistributions of source code must retain the above copyright notice, 00017 * this list of conditions and the following disclaimer. 00018 * 00019 * 2. Redistributions in binary form must reproduce the above copyright notice, 00020 * this list of conditions and the following disclaimer in the documentation 00021 * and/or other materials provided with the distribution. 00022 * 00023 * 3. Neither the name of the authors nor the names of its contributors may be 00024 * used to endorse or promote products derived from this software without 00025 * specific prior written permission. 00026 * 00027 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00028 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00029 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00030 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00031 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00032 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00033 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00034 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00035 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00036 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00037 * POSSIBILITY OF SUCH DAMAGE. 00038 */ 00039 00040 00041 00042 /** 00043 * \file cvrMergeHSIToImage.h 00044 * \author Pablo Alvarado 00045 * \author Stefan Syberichs 00046 * \author Thomas Rusert 00047 * \date 19.04.99 00048 * 00049 * $Id: cvrMergeHSIToImage.h,v 1.3 2006/01/06 05:02:10 alvarado Exp $ 00050 */ 00051 00052 #ifndef _CVR_MERGE_HSI_TO_IMAGE_H_ 00053 #define _CVR_MERGE_HSI_TO_IMAGE_H_ 00054 00055 #include "cvrMergeImage.h" 00056 00057 namespace cvr { 00058 00059 /** 00060 * Merge HSI (Hue Saturation Intensity) channels. 00061 * 00062 * It is assumed that all channels have "valid" values, i.e., if the inputs 00063 * are of type cvr::channel, the Hue has values between 0.0 and 1.0 (meaning 00064 * 0 to 360 degrees), Saturation and Intensity between 0.0 and 1.0. For 00065 * cvr::channel8, the possible value ranges are always valid. 00066 * 00067 * If any component is not valid, then unpredictible results have to be 00068 * expected, including segmentation faults, as the computations use some LUT 00069 * to improve speed. 00070 * 00071 * The transformation from HSI to RGB depends on the value range of hue (H). 00072 * It first computes chromaticity values r,g,b: 00073 * 00074 * If \f$0^\circ \leq H < 120^\circ\f$ 00075 * 00076 * \f[ 00077 * \begin{aligned} 00078 * r &= \frac{1}{3}\left[1+\frac{S \cos(H)}{\cos(60^\circ-H)}\right] \\ 00079 * g &= 1-(r+b) \\ 00080 * b &= \frac{1}{3}(1-S) 00081 * \end{aligned} 00082 * \f] 00083 * 00084 * If \f$120^\circ \leq H < 240^\circ\f$ 00085 * 00086 * \f[ 00087 * \begin{aligned} 00088 * r &= \frac{1}{3}(1-S) \\ 00089 * g &= \frac{1}{3}\left[1+\frac{S \cos(H-120^\circ)} 00090 * {\cos(180^\circ-H)}\right] \\ 00091 * b &= 1-(r+g) 00092 * \end{aligned} 00093 * \f] 00094 * 00095 * If \f$240^\circ \leq H < 360^\circ\f$ 00096 * 00097 * \f[ 00098 * \begin{aligned} 00099 * g &= \frac{1}{3}(1-S) \\ 00100 * b &= \frac{1}{3}\left[1+\frac{S \cos(H-240^\circ)} 00101 * {\cos(300^\circ-H)}\right] \\ 00102 * r &= 1-(g+b) 00103 * \end{aligned} 00104 * \f] 00105 * 00106 * With these chromaticity values, the RGB tuple can easily be computed as 00107 * 00108 * \f[ \begin{aligned} R &= 3rI \\ G &= 3gI \\ B &= 3bI \\ \end{aligned} \f] 00109 * 00110 * @see cvr::splitImageToHSI 00111 * 00112 * @ingroup gColor 00113 */ 00114 class mergeHSIToImage : public mergeImage { 00115 public: 00116 00117 /** 00118 * Constructor 00119 */ 00120 mergeHSIToImage(void); 00121 00122 /** 00123 * return the name of this type 00124 */ 00125 virtual const std::string& name() const; 00126 00127 /** 00128 * returns a pointer to a clone of the functor. 00129 */ 00130 virtual mergeHSIToImage* clone() const; 00131 00132 /** 00133 * returns a pointer to a new instance of the functor. 00134 */ 00135 virtual mergeHSIToImage* newInstance() const; 00136 00137 /** 00138 * merge hue channel H, saturation S and intensity 00139 * channel I to an image 00140 * @param H the hue channel 00141 * @param S the saturation channel 00142 * @param I the intensity channel 00143 * @param img the image to be splitted 00144 */ 00145 virtual bool apply(const matrix<float>& H, 00146 const matrix<float>& S, 00147 const matrix<float>& I, 00148 image& img) const; 00149 00150 00151 /** 00152 * merge hue channel H, saturation S and intensity 00153 * channel I to an image 00154 * @param H the hue channel 00155 * @param S the saturation channel 00156 * @param I the intensity channel 00157 * @param img the image to be splitted 00158 */ 00159 virtual bool apply(const matrix<ubyte>& H, 00160 const matrix<ubyte>& S, 00161 const matrix<ubyte>& I, 00162 image& img) const; 00163 00164 /** 00165 * merge the hue value H, saturation S and intensity value I 00166 * to a pixel 00167 * @param H the hue value 00168 * @param S the saturation value 00169 * @param I the intensity value 00170 * @param pixel the merged pixel 00171 */ 00172 virtual bool apply(const float& H, 00173 const float& S, 00174 const float& I, 00175 rgbaPixel& pixel) const; 00176 00177 /** 00178 * merge the hue value H, saturation S and intensity value I 00179 * to a pixel 00180 * @param H the hue value 00181 * @param S the saturation value 00182 * @param I the intensity value 00183 * @param pixel the merged pixel 00184 */ 00185 virtual bool apply(const ubyte& H, 00186 const ubyte& S, 00187 const ubyte& I, 00188 rgbaPixel& pixel) const; 00189 00190 private: 00191 /** 00192 * Some constants required to access the LUT 00193 */ 00194 enum { 00195 Reds = 360, // at least 120 degrees 00196 Greens = 2*Reds, 00197 Blues = 3*Reds, 00198 Sats = 384, // at least 256 00199 SatsMax = Sats-1 00200 }; 00201 00202 /** 00203 * matrix for HSI->RGB-conversion 00204 */ 00205 static const matrix<ubyte>* DeHSI_; 00206 00207 /** 00208 * Fix the representation in case RGB are not in a valid range. 00209 * 00210 * This method expects: 00211 * @param R red greater 0 00212 * @param G green greater 0 00213 * @param B blue greater 0 00214 * 00215 * The values R,G,B will be left unmodified if they are in a correct 00216 * range. 00217 */ 00218 inline void fix(float& R,float& G,float& B) const; 00219 00220 00221 }; 00222 00223 } 00224 00225 #endif 00226