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 #include "Channels/Jet.H"
00039
00040 #include "Util/Assert.H"
00041 #include "Image/Image.H"
00042 #include "rutz/compat_cmath.h"
00043
00044 #include <iostream>
00045
00046
00047 JetSpec::JetSpec()
00048 { spec = NULL; freeMem(); }
00049
00050
00051 JetSpec::JetSpec(const JetSpec& js)
00052 { spec = NULL; freeMem(); *this = js; }
00053
00054
00055 JetSpec& JetSpec::operator=(const JetSpec& js)
00056 {
00057 freeMem(); JF *jfp = js.spec;
00058 while(jfp) {
00059 if (addFeature(jfp->feature) == false)
00060 LFATAL("Cannot add feature");
00061 JFT *jftp = jfp->jft;
00062 while(jftp) {
00063 if (addFeatureType(jfp->feature, jftp->ftype) == false)
00064 LFATAL("Cannot add feature type");
00065 for (int i = 0; i < jftp->nbidx; i++)
00066 if (addIndexRange(jfp->feature, jftp->ftype,
00067 jftp->idxmin[i], jftp->idxmax[i]) == false)
00068 LFATAL("Cannot add index range");
00069 jftp = jftp->next;
00070 }
00071 jfp = jfp->next;
00072 }
00073 return *this;
00074 }
00075
00076
00077 void JetSpec::freeMem()
00078 {
00079 JF *jfp = spec;
00080 while(jfp) {
00081 JFT *jftp = jfp->jft;
00082 while(jftp) {
00083 if (jftp->nbidx) { delete [] jftp->idxmin; delete [] jftp->idxmax; }
00084 JFT *del = jftp; jftp = jftp->next; delete del;
00085 }
00086 JF *del = jfp; jfp = jfp->next; delete del;
00087 }
00088 spec = NULL; jetSize = 0;
00089 for (int f = 0; f < NBVISUALFEATURES; f ++)
00090 for (int t = 0; t < NBVISUALFEATURETYPES; t ++)
00091 dataIdx[f][t] = NULL;
00092 }
00093
00094
00095 JetSpec::~JetSpec()
00096 { freeMem(); }
00097
00098
00099 bool JetSpec::addFeature(const VisualFeature f)
00100 {
00101 JF *jfp = spec;
00102 if (spec == NULL) { spec = new JF; jfp = spec; }
00103 else
00104 while(true) {
00105 if (jfp->feature == f)
00106 { LERROR("Feature %s already exists!", featureName(f)); return false; }
00107 if (jfp->next) jfp = jfp->next;
00108 else { jfp->next = new JF; jfp = jfp->next; break; }
00109 }
00110 jfp->feature = f; jfp->jft = NULL; jfp->next = NULL;
00111
00112 return true;
00113 }
00114
00115
00116 bool JetSpec::addFeatureType(const VisualFeature f, const VisualFeatureType t)
00117 {
00118
00119 if (hasFeature(f) == false) addFeature(f);
00120
00121
00122 if (hasFeatureType(f, t)) {
00123 LERROR("Already have %s/%s", featureName(f), featureTypeName(t));
00124 return false;
00125 }
00126
00127
00128 JF *jfp = spec;
00129 while(jfp) {
00130 if (jfp->feature == f) {
00131 JFT *jftp = jfp->jft;
00132 if (jfp->jft == NULL)
00133 { jfp->jft = new JFT; jftp = jfp->jft; }
00134 else
00135 while(true) {
00136 if (jftp->ftype == t)
00137 { LERROR("Feature type %s for feature %s already exists!",
00138 featureTypeName(t), featureName(f)); return false; }
00139 if (jftp->next) jftp = jftp->next;
00140 else { jftp->next = new JFT; jftp = jftp->next; break; }
00141 }
00142 jftp->ftype = t; jftp->nbidx = 0; jftp->idxmin = NULL;
00143 jftp->idxmax = NULL; jftp->next = NULL;
00144 updateDataIdx();
00145
00146 return true;
00147 }
00148 jfp = jfp->next;
00149 }
00150 LERROR("Feature %s not found?", featureName(f));
00151 return false;
00152 }
00153
00154
00155 bool JetSpec::addIndexRange(const VisualFeature f, const VisualFeatureType t,
00156 const int indexmin, const int indexmax)
00157 {
00158
00159 if (hasFeature(f) == false) addFeature(f);
00160
00161
00162 if (hasFeatureType(f, t) == false) addFeatureType(f, t);
00163
00164
00165 JFT *jftp = dataIdx[f][t];
00166 int n = jftp->nbidx;
00167 int *nmin = new int[n + 1], *nmax = new int[n + 1];
00168 if (n) {
00169 memcpy(nmin, jftp->idxmin, n * sizeof(int));
00170 memcpy(nmax, jftp->idxmax, n * sizeof(int));
00171 delete [] jftp->idxmin; delete [] jftp->idxmax;
00172 }
00173 nmin[n] = indexmin; nmax[n] = indexmax;
00174 jftp->nbidx ++; jftp->idxmin = nmin; jftp->idxmax = nmax;
00175 updateDataIdx();
00176
00177
00178 return true;
00179 }
00180
00181
00182 void JetSpec::print() const
00183 {
00184 JF *jfp = spec; std::cout<<"=== JetSpec [size = "<<jetSize<<']'<<std::endl;
00185 while(jfp) {
00186 std::cout<<featureName(jfp->feature)<<':'<<std::endl;
00187 JFT *jftp = jfp->jft;
00188 while(jftp) {
00189 std::cout<<" "<<featureTypeName(jftp->ftype)<<": [base = "<<
00190 jftp->indexBase<<", size = "<<jftp->siz<<"]: ";
00191 for (int i = 0; i < jftp->nbidx; i ++)
00192 std::cout<<'['<<jftp->idxmin[i]<<".."<<jftp->idxmax[i]<<"] ";
00193 std::cout<<std::endl;
00194 jftp = jftp->next;
00195 }
00196 jfp = jfp->next;
00197 }
00198 }
00199
00200
00201 void JetSpec::updateDataIdx()
00202 {
00203 JF *jfp = spec; jetSize = 0;
00204 while(jfp) {
00205 JFT *jftp = jfp->jft;
00206 while(jftp) {
00207
00208 jftp->indexBase = jetSize;
00209
00210
00211 dataIdx[jfp->feature][jftp->ftype] = jftp;
00212
00213
00214 int siz = 0;
00215 if (jftp->nbidx) {
00216 siz = 1;
00217 for (int i = 0; i < jftp->nbidx; i ++)
00218 siz *= jftp->idxmax[i] - jftp->idxmin[i] + 1;
00219 }
00220 jftp->siz = siz;
00221 jetSize += siz;
00222
00223
00224 jftp = jftp->next;
00225 }
00226
00227 jfp = jfp->next;
00228 }
00229 }
00230
00231
00232
00233 template <class T>
00234 Jet<T>::Jet(const rutz::shared_ptr<JetSpec> js) : Image<T>()
00235 { spec = js; this->resize(spec->getJetSize(), 1); }
00236
00237
00238 template <class T>
00239 Jet<T>::Jet() : Image<T>(), spec(NULL)
00240 { }
00241
00242
00243 template <class T>
00244 void Jet<T>::init(const rutz::shared_ptr<JetSpec> js)
00245 { ASSERT(spec.get()); spec = js; this->resize(spec->getJetSize(), 1); }
00246
00247
00248 template <class T>
00249 Jet<T>::~Jet()
00250 { this->freeMem(); }
00251
00252
00253 double raodistance(const Jet<float>& j1, const Jet<float>& j2,
00254 const int idxmin, const int idxmax)
00255 {
00256
00257 double sumsq[idxmax - idxmin + 1];
00258
00259 for (int i = 0; i < idxmax - idxmin + 1; i++)
00260 sumsq[i] = 0.0;
00261
00262 for (int f = 0; f < NBVISUALFEATURES; f ++)
00263 {
00264 VisualFeature ff = VisualFeature(f);
00265 if (j1.hasFeatureType(ff, RAW))
00266 {
00267 int nr = j1.getNbIndexRanges(ff, RAW);
00268 switch(nr)
00269 {
00270 case 1:
00271 {
00272 int imin = 0, imax = 0;
00273 j1.getIndexRange(ff, RAW, 0, imin, imax);
00274 ASSERT(idxmin >= imin && idxmax <= imax);
00275 for (int i = idxmin; i <= idxmax; i ++)
00276 {
00277 float val1 = j1.getVal(ff, RAW, i);
00278 float val2 = j2.getVal(ff, RAW, i);
00279 double val;
00280 if (isnan(val1) || isnan(val2))
00281 val = 0.0;
00282 else
00283 val = double(val1 - val2);
00284 sumsq[i - idxmin] += val * val;
00285 }
00286
00287 }
00288 break;
00289 case 2:
00290 {
00291 int rmin = 0, rmax = 0;
00292 j1.getIndexRange(ff, RAW, 0, rmin, rmax);
00293 for (int r = rmin; r <= rmax; r ++)
00294 {
00295 int imin = 0, imax = 0;
00296 j1.getIndexRange(ff, RAW, 1, imin, imax);
00297 ASSERT(idxmin >= imin && idxmax <= imax);
00298 for (int i = idxmin; i <= idxmax; i ++)
00299 {
00300 float val1 = j1.getVal(ff, RAW, r, i);
00301 float val2 = j2.getVal(ff, RAW, r, i);
00302 double val;
00303 if (isnan(val1) || isnan(val2))
00304 val = 0.0;
00305 else
00306 val = double(val1 - val2);
00307 sumsq[i - idxmin] += val * val;
00308 }
00309
00310 }
00311 }
00312 break;
00313 default:
00314 LFATAL("Deep hierarchical Jets not supported");
00315 }
00316 }
00317 }
00318 double d = 0.0;
00319 for (int i = 0; i <= idxmax - idxmin; i ++) d += sumsq[i];
00320 return d;
00321 }
00322
00323
00324
00325 #ifdef INVT_INST_BYTE
00326 template class Jet<byte>;
00327 #endif
00328 #ifdef INVT_INST_INT16
00329 template class Jet<int16>;
00330 #endif
00331 #ifdef INVT_INST_INT32
00332 template class Jet<int32>;
00333 #endif
00334 #ifdef INVT_INST_FLOAT
00335 template class Jet<float>;
00336 #endif
00337
00338
00339
00340
00341
00342
00343