00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef _VISUALINTEGRALCOLORDESC_H_
00019 #define _VISUALINTEGRALCOLORDESC_H_
00020
00021 #include <math.h>
00022 #include "VisualFeatureDesc.h"
00023
00024 namespace RobotFlow {
00025
00026 typedef enum
00027 {
00028 e_VISUALINTDESC_EuclideanDist = 0,
00029
00030 e_VISUALINTDESC_UnknownSimilarity
00031 } e_VISUALINTDESC_similarityType;
00032
00033
00034
00035
00036
00037
00038 template <class FeatType>
00039 class VisualIntegralDesc : public VisualFeatureDesc<FeatType>
00040 {
00041 public:
00042 VisualIntegralDesc()
00043 : VisualFeatureDesc<FeatType>(e_VISUALDESCRIPTOR_integral),
00044 m_simType(e_VISUALINTDESC_UnknownSimilarity), m_numClrChannels(0),
00045 m_numIntValues(0), m_featSize(0), m_valid(false), m_useRectDiff(false),
00046 m_useBoundary(false), m_intFeatures(NULL)
00047 {
00048 SetSimilarityFct();
00049 }
00050
00051 VisualIntegralDesc(e_VISUALINTDESC_similarityType i_simType,
00052 unsigned int i_numClrChannels, unsigned int i_numIntValues,
00053 FeatType i_maxValue, bool i_useRectDiff, bool i_useBoundary)
00054 : VisualFeatureDesc<FeatType>(e_VISUALDESCRIPTOR_integral),
00055 m_simType(i_simType), m_numClrChannels(i_numClrChannels),
00056 m_numIntValues(i_numIntValues), m_maxValue(i_maxValue),
00057 m_valid(true), m_useRectDiff(i_useRectDiff),
00058 m_useBoundary(i_useBoundary), m_intFeatures(NULL)
00059 {
00060 m_featSize = m_numClrChannels*m_numIntValues;
00061
00062 if (m_useRectDiff) {
00063 m_maxDiffValue = m_maxValue;
00064 m_maxValue = (FeatType)((double)(m_maxDiffValue)*0.5);
00065 m_numMeanValues = (unsigned int)(sqrt((float)(m_numIntValues)));
00066 m_numIntValues -= m_numMeanValues;
00067 }
00068
00069 if (m_useBoundary) {
00070 m_featSize += 4;
00071 }
00072
00073 m_intFeatures = new FeatType[m_featSize];
00074
00075 SetSimilarityFct();
00076 }
00077
00078 VisualIntegralDesc(const VisualIntegralDesc<FeatType> &i_ref)
00079 {
00080 try {
00081 this->SetType(i_ref.GetType());
00082 m_simType = i_ref.m_simType;
00083 m_numClrChannels = i_ref.m_numClrChannels;
00084 m_numIntValues = i_ref.m_numIntValues;
00085 m_featSize = i_ref.m_featSize;
00086 m_maxValue = i_ref.m_maxValue;
00087 m_valid = i_ref.m_valid;
00088 m_useRectDiff = i_ref.m_useRectDiff;
00089 m_useBoundary = i_ref.m_useBoundary;
00090 m_maxDiffValue = i_ref.m_maxDiffValue;
00091 m_numMeanValues = i_ref.m_numMeanValues;
00092
00093 m_intFeatures = new FeatType[m_featSize];
00094
00095 for (int i=0; i<m_featSize; i++) {
00096 m_intFeatures[i] = i_ref.m_intFeatures[i];
00097 }
00098
00099 SetSimilarityFct();
00100 }
00101 catch (FD::BaseException *e) {
00102 throw e->add(new FD::GeneralException("Exception caught in VisualIntegralDesc::VisualIntegralDesc:",__FILE__,__LINE__));
00103 }
00104 }
00105
00106 ~VisualIntegralDesc()
00107 {
00108 delete [] m_intFeatures;
00109 }
00110
00111 VisualIntegralDesc<FeatType> & operator =(const VisualIntegralDesc<FeatType> &i_ref)
00112 {
00113
00114 if (&i_ref == this) {
00115 return *this;
00116 }
00117
00118 this->SetType(i_ref.GetType());
00119 m_simType = i_ref.m_simType;
00120 m_numClrChannels = i_ref.m_numClrChannels;
00121 m_numIntValues = i_ref.m_numIntValues;
00122 m_featSize = i_ref.m_featSize;
00123 m_maxValue = i_ref.m_maxValue;
00124 m_valid = i_ref.m_valid;
00125 m_useRectDiff = i_ref.m_useRectDiff;
00126 m_useBoundary = i_ref.m_useBoundary;
00127 m_maxDiffValue = i_ref.m_maxDiffValue;
00128 m_numMeanValues = i_ref.m_numMeanValues;
00129
00130 delete [] m_intFeatures;
00131 m_intFeatures = new FeatType[m_featSize];
00132
00133 for (int i=0; i<m_featSize; i++) {
00134 m_intFeatures[i] = i_ref.m_intFeatures[i];
00135 }
00136
00137 SetSimilarityFct();
00138
00139 return *this;
00140 }
00141
00142 VisualIntegralDesc<FeatType>* clone() const
00143 {
00144 return new VisualIntegralDesc<FeatType>(*this);
00145 }
00146
00147
00148 void printOn(std::ostream &out) const
00149 {
00150 throw new FD::GeneralException("Exception in VisualIntegralDesc::printOn: cannot use base class routine.",__FILE__,__LINE__);
00151 }
00152
00153
00154 void readFrom(std::istream &in)
00155 {
00156 throw new FD::GeneralException("Exception in VisualIntegralDesc::readFrom: cannot use base class routine.",__FILE__,__LINE__);
00157 }
00158
00159 double Similarity(const FeatType *i_candidate, unsigned int i_size) const
00160 {
00161 try {
00162 if (!i_candidate) {
00163 throw new FD::GeneralException("VisualIntegralDesc::Similarity: invalid (NULL) candidate features.",__FILE__,__LINE__);
00164 }
00165
00166 if (i_size != m_featSize) {
00167 throw new FD::GeneralException("VisualIntegralDesc::Similarity: candidate features size differs from current features descriptor size.",__FILE__,__LINE__);
00168 }
00169
00170 if (!m_similarityFct) {
00171 throw new FD::GeneralException("VisualIntegralDesc::Similarity: invalid or unknown similarity type.",__FILE__,__LINE__);
00172 }
00173
00174 if (!m_valid) {
00175
00176 return 0.0;
00177 }
00178
00179
00180 return (this->*m_similarityFct)(i_candidate);
00181 }
00182 catch (FD::BaseException *e) {
00183 throw e->add(new FD::GeneralException("Exception caught in VisualIntegralDesc::Similarity:",__FILE__,__LINE__));
00184 }
00185 }
00186
00187 void Adapt(const FeatType *i_candidate, unsigned int i_size, double i_rate)
00188 {
00189 try {
00190 if (!i_candidate) {
00191 throw new FD::GeneralException("VisualIntegralDesc::Adapt: invalid (NULL) candidate features.",__FILE__,__LINE__);
00192 }
00193
00194 if (i_size != m_featSize) {
00195 throw new FD::GeneralException("VisualIntegralDesc::Adapt: candidate features size differs from current features descriptor size.",__FILE__,__LINE__);
00196 }
00197
00198 if (i_rate < 0.0 || i_rate > 1.0) {
00199 throw new FD::GeneralException ("VisualHistogramDesc::Adapt : adaptation rate must be in the interval [0.0,1.0]",__FILE__,__LINE__);
00200 }
00201
00202 if (i_rate == 0.0) {
00203
00204 return;
00205 }
00206
00207 if (i_rate == 1.0) {
00208 SetFeatures(i_candidate, i_size);
00209 return;
00210 }
00211
00212 int i;
00213 const FeatType *p_adaptFeat = i_candidate;
00214 double compRate = 1.0 - i_rate;
00215
00216 for (i=0; i<m_featSize; i++) {
00217 m_intFeatures[i] = (FeatType)(compRate*(double)(m_intFeatures[i]) + i_rate*(double)(p_adaptFeat[i]));
00218 }
00219 }
00220 catch (FD::BaseException *e) {
00221 throw e->add(new FD::GeneralException("Exception caught in VisualIntegralDesc::Adapt:",__FILE__,__LINE__));
00222 }
00223 }
00224
00225 unsigned int GetSize() const
00226 {
00227 return m_featSize;
00228 }
00229
00230 FeatType *GetFeatures()
00231 {
00232 return m_intFeatures;
00233 }
00234
00235 const FeatType *GetCstFeatures() const
00236 {
00237 return (const FeatType *)m_intFeatures;
00238 }
00239
00240 bool GetValidity() const
00241 {
00242 return m_valid;
00243 }
00244
00245 void SetSize(unsigned int i_size)
00246 {
00247 throw new FD::GeneralException("Exception in VisualIntegralDesc::SetSize: cannot use base class routine.",__FILE__,__LINE__);
00248 }
00249
00250 void SetFeatures(const FeatType *i_ref, unsigned int i_size)
00251 {
00252 try {
00253 if (!i_ref) {
00254 throw new FD::GeneralException("VisualIntegralDesc::SetFeatures: invalid (NULL) input features.",__FILE__,__LINE__);
00255 }
00256
00257 if (i_size != m_featSize) {
00258 throw new FD::GeneralException("VisualIntegralDesc::SetFeatures: candidate features size differs from current features descriptor size.",__FILE__,__LINE__);
00259 }
00260
00261 int i;
00262 const FeatType *p_inFeat = i_ref;
00263
00264 for (i=0; i<m_featSize; i++) {
00265 m_intFeatures[i] = *p_inFeat++;
00266 }
00267 }
00268 catch (FD::BaseException *e) {
00269 throw e->add(new FD::GeneralException("Exception caught in VisualIntegralDesc::SetFeatures:",__FILE__,__LINE__));
00270 }
00271 }
00272
00273 void SetValidity(bool i_flag) {
00274 m_valid = i_flag;
00275 }
00276
00277 private:
00278 void SetSimilarityFct()
00279 {
00280 if (m_simType == e_VISUALINTDESC_EuclideanDist) {
00281 if (m_useRectDiff) {
00282 if (m_useBoundary) {
00283 m_similarityFct = &VisualIntegralDesc::EuclideanDistWDiffWBound;
00284 }
00285 else {
00286 m_similarityFct = &VisualIntegralDesc::EuclideanDistWDiff;
00287 }
00288 }
00289 else {
00290 if (m_useBoundary) {
00291 m_similarityFct = &VisualIntegralDesc::EuclideanDistWBound;
00292 }
00293 else {
00294 m_similarityFct = &VisualIntegralDesc::EuclideanDist;
00295 }
00296 }
00297 }
00298 else {
00299 m_similarityFct = NULL;
00300 }
00301 }
00302
00303 double EuclideanDist(const FeatType *i_candidate) const
00304 {
00305 FeatType diff;
00306 double dist = 0.0;
00307 const FeatType *p_curFeat = (const FeatType *)m_intFeatures;
00308 const FeatType *p_candFeat = i_candidate;
00309
00310 for (int i=0; i<m_numIntValues; i++) {
00311 double clrDist = 0.0;
00312 for (int c=0; c<m_numClrChannels; c++) {
00313 diff = ((*p_curFeat) - (*p_candFeat))/m_maxValue;
00314 clrDist += (double)(diff*diff);
00315 p_curFeat++;
00316 p_candFeat++;
00317 }
00318 dist += sqrt(clrDist);
00319 }
00320
00321 dist /= m_numIntValues;
00322
00323 if (dist > 1.0) {
00324 return 0.0;
00325 }
00326
00327 return 1.0-dist;
00328 }
00329
00330 double EuclideanDistWDiff(const FeatType *i_candidate) const
00331 {
00332 int i, c;
00333 FeatType diff;
00334 double dist, dist1 = 0.0, dist2 = 0.0;
00335 const FeatType *p_curFeat = (const FeatType *)m_intFeatures;
00336 const FeatType *p_candFeat = i_candidate;
00337
00338 for (i=0; i<m_numMeanValues; i++) {
00339 double clrDist = 0.0;
00340 for (c=0; c<m_numClrChannels; c++) {
00341 diff = ((*p_curFeat) - (*p_candFeat))/m_maxValue;
00342 clrDist += (double)(diff*diff);
00343 p_curFeat++;
00344 p_candFeat++;
00345 }
00346 dist1 += sqrt(clrDist);
00347 }
00348
00349 dist1 /= m_numMeanValues;
00350
00351 if (dist1 > 1.0) {
00352 return 0.0;
00353 }
00354
00355 for (i=0; i<m_numIntValues; i++) {
00356 double clrDist = 0.0;
00357 for (c=0; c<m_numClrChannels; c++) {
00358 diff = ((*p_curFeat) - (*p_candFeat))/m_maxDiffValue;
00359 clrDist += (double)(diff*diff);
00360
00361 p_curFeat++;
00362 p_candFeat++;
00363 }
00364 dist2 += sqrt(clrDist);
00365 }
00366
00367 dist2 /= m_numIntValues;
00368
00369 if (dist2 > 1.0) {
00370 return 0.0;
00371 }
00372
00373 dist = (dist1+dist2)*0.5;
00374
00375 if (dist > 1.0) {
00376 return 0.0;
00377 }
00378
00379 return 1.0-dist;
00380 }
00381
00382 double EuclideanDistWBound(const FeatType *i_candidate) const
00383 {
00384 int i;
00385 FeatType diff;
00386 double dist = 0.0;
00387 const FeatType *p_curFeat = (const FeatType *)m_intFeatures;
00388 const FeatType *p_candFeat = i_candidate;
00389
00390 for (i=0; i<m_numIntValues; i++) {
00391 double clrDist = 0.0;
00392 for (int c=0; c<m_numClrChannels; c++) {
00393 diff = ((*p_curFeat) - (*p_candFeat))/m_maxValue;
00394 clrDist += (double)(diff*diff);
00395 p_curFeat++;
00396 p_candFeat++;
00397 }
00398 dist += sqrt(clrDist);
00399 }
00400
00401 dist /= m_numIntValues;
00402
00403 if (dist > 1.0) {
00404 return 0.0;
00405 }
00406
00407
00408 int numBoundary = 0;
00409 int numUnknown = 0;
00410 for (i=0; i<4; i++) {
00411 if (*p_candFeat == 1) {
00412 numUnknown++;
00413 }
00414 else if (*p_candFeat == 2) {
00415 numBoundary++;
00416 }
00417 }
00418
00419 if (numUnknown < 4) {
00420 int numValid = 4-numUnknown;
00421 dist += (double)(numValid-numBoundary)/(double)(numValid);
00422
00423 if (dist > 1.0) {
00424 return 0.0;
00425 }
00426 }
00427
00428 return 1.0-dist;
00429 }
00430
00431 double EuclideanDistWDiffWBound(const FeatType *i_candidate) const
00432 {
00433 int i, c;
00434 FeatType diff;
00435 double dist, dist1 = 0.0, dist2 = 0.0;
00436 const FeatType *p_curFeat = (const FeatType *)m_intFeatures;
00437 const FeatType *p_candFeat = i_candidate;
00438
00439 for (i=0; i<m_numMeanValues; i++) {
00440 double clrDist = 0.0;
00441 for (c=0; c<m_numClrChannels; c++) {
00442 diff = ((*p_curFeat) - (*p_candFeat))/m_maxValue;
00443 clrDist += (double)(diff*diff);
00444 p_curFeat++;
00445 p_candFeat++;
00446 }
00447 dist1 += sqrt(clrDist);
00448 }
00449
00450 dist1 /= m_numMeanValues;
00451
00452 if (dist1 > 1.0) {
00453 return 0.0;
00454 }
00455
00456 for (i=0; i<m_numIntValues; i++) {
00457 double clrDist = 0.0;
00458 for (c=0; c<m_numClrChannels; c++) {
00459 diff = ((*p_curFeat) - (*p_candFeat))/m_maxDiffValue;
00460 clrDist += (double)(diff*diff);
00461 p_curFeat++;
00462 p_candFeat++;
00463 }
00464 dist2 += sqrt(clrDist);
00465 }
00466
00467 dist2 /= m_numIntValues;
00468
00469 if (dist2 > 1.0) {
00470 return 0.0;
00471 }
00472
00473 dist = (dist1+dist2)*0.5;
00474
00475 if (dist > 1.0) {
00476 return 0.0;
00477 }
00478
00479
00480 int numBoundary = 0;
00481 int numUnknown = 0;
00482 for (i=0; i<4; i++) {
00483 if (*p_candFeat == 1) {
00484 numUnknown++;
00485 }
00486 else if (*p_candFeat == 2) {
00487 numBoundary++;
00488 }
00489 }
00490
00491 if (numUnknown < 4) {
00492 int numValid = 4-numUnknown;
00493 dist += (double)(numValid-numBoundary)/(double)(numValid);
00494
00495 if (dist > 1.0) {
00496 return 0.0;
00497 }
00498 }
00499
00500 return 1.0-dist;
00501 }
00502
00503 private:
00504
00505 e_VISUALINTDESC_similarityType m_simType;
00506
00507
00508 unsigned int m_numClrChannels;
00509
00510
00511 unsigned int m_numIntValues;
00512
00513
00514 unsigned int m_featSize;
00515
00516
00517 FeatType m_maxValue;
00518
00519 unsigned int m_numMeanValues;
00520 FeatType m_maxDiffValue;
00521
00522 bool m_useRectDiff;
00523
00524 bool m_useBoundary;
00525
00526
00527 bool m_valid;
00528
00529
00530 FeatType *m_intFeatures;
00531
00532
00533 double (VisualIntegralDesc::*m_similarityFct)(const FeatType *) const;
00534 };
00535
00536 }
00537
00538 #endif