00001 /*!@file Channels/H2SVChannel.C */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00005 // by the University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: T. Nathan Mundhenk <mundhenk@usc.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Channels/H2SVChannel.C $ 00035 // $Id: H2SVChannel.C 12962 2010-03-06 02:13:53Z irock $ 00036 // 00037 00038 #ifndef H2SVCHANNEL_C_DEFINED 00039 #define H2SVCHANNEL_C_DEFINED 00040 00041 #include "Channels/H2SVChannel.H" 00042 00043 #include "Channels/Hue1Channel.H" 00044 #include "Channels/Hue2Channel.H" 00045 #include "Channels/SaturationChannel.H" 00046 #include "Channels/ValueIntensityChannel.H" 00047 #include "Channels/ChannelOpts.H" 00048 #include "Component/OptionManager.H" 00049 #include "Image/ColorOps.H" 00050 #include "rutz/trace.h" 00051 00052 // ###################################################################### 00053 // Double Opponent ColorChannel member definitions: 00054 // ###################################################################### 00055 00056 H2SVChannel::H2SVChannel(OptionManager& mgr) : 00057 ComplexChannel(mgr, "H2SV", "H2SV", H2SV), 00058 itsUseH2SV1(&OPT_UseH2SV1, this), 00059 itsH1(new Hue1Channel(mgr)), 00060 itsH2(new Hue2Channel(mgr)), 00061 itsS(new SaturationChannel(mgr)), 00062 itsV(new ValueIntensityChannel(mgr)), 00063 itsUseSigmoid(false), 00064 itsSigAlpha(40.0F), 00065 itsSigBeta(4.0F) 00066 { 00067 GVX_TRACE(__PRETTY_FUNCTION__); 00068 this->addSubChan(itsH1); 00069 this->addSubChan(itsH2); 00070 this->addSubChan(itsS); 00071 this->addSubChan(itsV); 00072 } 00073 00074 // ###################################################################### 00075 Hue1Channel& H2SVChannel::H1() const 00076 { 00077 GVX_TRACE(__PRETTY_FUNCTION__); 00078 return *itsH1; 00079 } 00080 00081 // ###################################################################### 00082 Hue2Channel& H2SVChannel::H2() const 00083 { 00084 GVX_TRACE(__PRETTY_FUNCTION__); 00085 return *itsH2; 00086 } 00087 00088 // ###################################################################### 00089 SaturationChannel& H2SVChannel::S() const 00090 { 00091 GVX_TRACE(__PRETTY_FUNCTION__); 00092 return *itsS; 00093 } 00094 00095 // ###################################################################### 00096 ValueIntensityChannel& H2SVChannel::V() const 00097 { 00098 GVX_TRACE(__PRETTY_FUNCTION__); 00099 return *itsV; 00100 } 00101 00102 // ###################################################################### 00103 H2SVChannel::~H2SVChannel() 00104 { 00105 GVX_TRACE(__PRETTY_FUNCTION__); 00106 } 00107 00108 // ###################################################################### 00109 void H2SVChannel::doInput(const InputFrame& inframe) 00110 { 00111 GVX_TRACE(__PRETTY_FUNCTION__); 00112 ASSERT(inframe.colorFloat().initialized()); 00113 00114 if(!itsH1img.initialized()) 00115 { 00116 itsH1img.resize(inframe.getDims()); 00117 itsH2img.resize(inframe.getDims()); 00118 itsSimg.resize(inframe.getDims()); 00119 itsVimg.resize(inframe.getDims()); 00120 } 00121 00122 Image<float>::iterator h1imgItr = itsH1img.beginw(); 00123 Image<float>::iterator h2imgItr = itsH2img.beginw(); 00124 Image<float>::iterator simgItr = itsSimg.beginw(); 00125 Image<float>::iterator vimgItr = itsVimg.beginw(); 00126 00127 Image<PixRGB<float> >::const_iterator colItr = inframe.colorFloat().begin(); 00128 00129 // H2SV2 is more R/G B/Y opponent in nature while 00130 // H2SV1 is more simple and symetric 00131 00132 // To get H2SV we take a basic RGB image and convert each PixRGB pixel 00133 // in that image to a PixH2SV2 or PixH2SV1 pixel. We then get the 00134 // H1, H2, S and V parts and split those into four gray scale images 00135 00136 if(itsUseH2SV1.getVal()) 00137 { 00138 while(colItr != inframe.colorFloat().end()) 00139 { 00140 const PixH2SV1<float> pix = PixH2SV1<float>(*colItr++); 00141 if(itsUseSigmoid) 00142 { 00143 const float S = logsig2(pix.p[2],itsSigAlpha,itsSigBeta); 00144 *h1imgItr++ = ((pix.p[0] - 0.5F)*S + 0.5F) * 85.0F; // 1/3 00145 *h2imgItr++ = ((pix.p[1] - 0.5F)*S + 0.5F) * 85.0F; // 1/3 00146 } 00147 else 00148 { 00149 *h1imgItr++ = pix.p[0] * 85.0F; // 1/3 00150 *h2imgItr++ = pix.p[1] * 85.0F; // 1/3 00151 } 00152 00153 *simgItr++ = pix.p[2] * 1.0F; // leave out 00154 *vimgItr++ = pix.p[3] * 85.0F; // 1/3 00155 } 00156 } 00157 else 00158 { 00159 while(colItr != inframe.colorFloat().end()) 00160 { 00161 const PixH2SV2<float> pix = PixH2SV2<float>(*colItr++); 00162 00163 if(itsUseSigmoid) 00164 { 00165 const float S = logsig2(pix.p[2],itsSigAlpha,itsSigBeta); 00166 //*h1imgItr++ = pix.p[0] * 85.0F; // 1/3 00167 *h1imgItr++ = ((pix.p[0] - 0.5F)*S + 0.5F) * 85.0F; // 1/3 00168 //*h2imgItr++ = pix.p[1] * 85.0F; // 1/3 00169 *h2imgItr++ = ((pix.p[1] - 0.5F)*S + 0.5F) * 85.0F; // 1/3 00170 } 00171 else 00172 { 00173 *h1imgItr++ = pix.p[0] * 85.0F; // 1/3 00174 *h2imgItr++ = pix.p[1] * 85.0F; // 1/3 00175 } 00176 00177 *simgItr++ = pix.p[2] * 1.0F; // leave out 00178 *vimgItr++ = pix.p[3] * 85.0F; // 1/3 00179 } 00180 } 00181 00182 itsH1->input(InputFrame::fromGrayFloat(&itsH1img, inframe.time(), &inframe.clipMask(), inframe.pyrCache())); 00183 itsH2->input(InputFrame::fromGrayFloat(&itsH2img, inframe.time(), &inframe.clipMask(), inframe.pyrCache())); 00184 itsS->input(InputFrame::fromGrayFloat(&itsSimg, inframe.time(), &inframe.clipMask(), inframe.pyrCache())); 00185 itsV->input(InputFrame::fromGrayFloat(&itsVimg, inframe.time(), &inframe.clipMask(), inframe.pyrCache())); 00186 00187 LINFO("H2SV Color channel ok."); 00188 } 00189 00190 // ###################################################################### 00191 void H2SVChannel::setH1(nub::ref<Hue1Channel> h1) 00192 { 00193 this->removeSubChan(itsH1); 00194 itsH1 = h1; 00195 this->addSubChan(itsH1); 00196 } 00197 00198 // ###################################################################### 00199 void H2SVChannel::setH2(nub::ref<Hue2Channel> h2) 00200 { 00201 this->removeSubChan(itsH2); 00202 itsH2 = h2; 00203 this->addSubChan(itsH2); 00204 } 00205 00206 // ###################################################################### 00207 void H2SVChannel::setS(nub::ref<SaturationChannel> s) 00208 { 00209 this->removeSubChan(itsS); 00210 itsS = s; 00211 this->addSubChan(itsS); 00212 } 00213 00214 // ###################################################################### 00215 void H2SVChannel::setV(nub::ref<ValueIntensityChannel> v) 00216 { 00217 this->removeSubChan(itsV); 00218 itsV = v; 00219 this->addSubChan(itsV); 00220 } 00221 00222 00223 // ###################################################################### 00224 /* So things look consistent in everyone's emacs... */ 00225 /* Local Variables: */ 00226 /* indent-tabs-mode: nil */ 00227 /* End: */ 00228 00229 #endif // COLORCHANNEL_C_DEFINED