MultiColorBandChannel.C
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef MULTICOLORBANDCHANNEL_C_DEFINED
00039 #define MULTICOLORBANDCHANNEL_C_DEFINED
00040
00041 #include "Channels/MultiColorBandChannel.H"
00042
00043 #include "Channels/ChannelOpts.H"
00044 #include "Channels/ColorBandChannel.H"
00045 #include "Component/OptionManager.H"
00046 #include "Image/Pixels.H"
00047 #include "rutz/trace.h"
00048
00049 #include <vector>
00050
00051
00052
00053
00054
00055
00056 MultiColorBandChannel::MultiColorBandChannel(OptionManager& mgr) :
00057 ComplexChannel(mgr, "MultiColorBand", "multicolorband", COLBAND),
00058 itsNumBands(&OPT_NumColorBands, this),
00059 itsSatBands(&OPT_NumSatBands, this),
00060 itsHueSigma(&OPT_HueBandWidth, this),
00061 itsSatSigma(&OPT_SatBandWidth, this)
00062 {
00063 GVX_TRACE(__PRETTY_FUNCTION__);
00064
00065
00066 buildSubChans();
00067 }
00068
00069
00070 void MultiColorBandChannel::buildSubChans()
00071 {
00072 GVX_TRACE(__PRETTY_FUNCTION__);
00073
00074 this->removeAllSubChans();
00075
00076
00077
00078
00079
00080 LINFO("Using %d hue bands", itsNumBands.getVal());
00081 for (uint i = 0; i < itsNumBands.getVal(); i ++)
00082 {
00083 nub::ref<ColorBandChannel> chan
00084 (makeSharedComp(new ColorBandChannel(getManager(), i)));
00085
00086 this->addSubChan(chan);
00087
00088
00089 chan->exportOptions(MC_RECURSE);
00090 }
00091
00092 LINFO("Using %d saturation bands", itsSatBands.getVal());
00093 for (uint i = 0; i < itsSatBands.getVal(); i ++)
00094 {
00095 nub::ref<ColorBandChannel> chan
00096 (makeSharedComp(new ColorBandChannel
00097 (getManager(), itsNumBands.getVal()+i)));
00098
00099 this->addSubChan(chan);
00100
00101
00102 chan->exportOptions(MC_RECURSE);
00103 }
00104 }
00105
00106
00107 void MultiColorBandChannel::paramChanged(ModelParamBase* const param,
00108 const bool valueChanged,
00109 ParamClient::ChangeStatus* status)
00110 {
00111 GVX_TRACE(__PRETTY_FUNCTION__);
00112 ComplexChannel::paramChanged(param, valueChanged, status);
00113
00114
00115
00116 if (param == &itsNumBands &&
00117 numChans() != (itsNumBands.getVal() + itsSatBands.getVal()))
00118 buildSubChans();
00119
00120 else if (param == &itsSatBands &&
00121 numChans() != (itsNumBands.getVal() + itsSatBands.getVal()))
00122 buildSubChans();
00123 }
00124
00125
00126 MultiColorBandChannel::~MultiColorBandChannel()
00127 {
00128 GVX_TRACE(__PRETTY_FUNCTION__);
00129 }
00130
00131
00132 ColorBandChannel& MultiColorBandChannel::band(const uint idx) const
00133 {
00134 GVX_TRACE(__PRETTY_FUNCTION__);
00135
00136
00137 return *(dynCast<ColorBandChannel>(subChan(idx)));
00138 }
00139
00140
00141 void MultiColorBandChannel::doInput(const InputFrame& inframe)
00142 {
00143 GVX_TRACE(__PRETTY_FUNCTION__);
00144 ASSERT(inframe.colorFloat().initialized());
00145
00146
00147
00148
00149
00150
00151 uint numHue = itsNumBands.getVal(), numSat = itsSatBands.getVal();
00152 std::vector<Image<float> > sub_input(numHue + numSat);
00153 Image<float>::iterator bptr[sub_input.size()];
00154
00155 for (uint i = 0; i < sub_input.size(); ++i) {
00156 sub_input[i].resize(inframe.getDims(), true);
00157 bptr[i] = sub_input[i].beginw();
00158 }
00159
00160 float hue_range = 360/numHue;
00161 float c1 = 10000.0f / (sqrt(6.28) * itsHueSigma.getVal());
00162 float c2 = 2.0f * itsHueSigma.getVal() * itsHueSigma.getVal();
00163 float c3 = 10000.0f / (sqrt(6.28) * itsSatSigma.getVal());
00164 float c4 = 2.0f * itsSatSigma.getVal() * itsSatSigma.getVal();
00165
00166 Image<PixRGB<float> >::const_iterator aptr = inframe.colorFloat().begin();
00167 Image<PixRGB<float> >::const_iterator astop = inframe.colorFloat().end();
00168 while (aptr != astop)
00169 {
00170 float h, s, v;
00171 PixHSV<float>(*aptr).getHSV(h, s, v);
00172 aptr++;
00173
00174 for (uint i = 0; i < numHue; i++){
00175 if (v == 0.0f || s == 0.0f)
00176 *(bptr[i]) = 0.0f;
00177 else {
00178 float mean = i * hue_range;
00179 float dist = h-mean;
00180 if (dist > 180) dist = 360 - dist;
00181 else if (dist < -180) dist = dist + 360;
00182 *(bptr[i]) = c1 * exp(-1.0f * dist * dist / c2);
00183 }
00184 bptr[i] = bptr[i] + 1;
00185 }
00186
00187 for (uint i = 0; i < numSat; i++){
00188 if (v == 0.0f)
00189 *(bptr[numHue+i]) = 0.0f;
00190 else {
00191 float mean = (i+0.5)/numSat;
00192 float dist = s-mean;
00193 *(bptr[numHue+i]) = c3 * exp(-1.0f * dist * dist / c4);
00194 }
00195 bptr[numHue+i] = bptr[numHue+i] + 1;
00196 }
00197 }
00198 for (uint i = 0; i < sub_input.size(); ++i)
00199 subChan(i)->input(InputFrame::fromGrayFloat
00200 (&sub_input[i], inframe.time(),
00201 &inframe.clipMask(), inframe.pyrCache()));
00202 }
00203
00204
00205
00206
00207
00208
00209
00210 #endif // MULTICOLORBANDCHANNEL_C_DEFINED