The Machine Perception Toolbox

[Introduction]- [News]- [Download]- [Screenshots]- [Manual (pdf)]- [Forums]- [API Reference]- [Repository ]

 

Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

src/faceboxlist.h

Go to the documentation of this file.
00001 /* 
00002  *  FACEBOXLIST.h
00003  *
00004  *  Created by Ian Fasel on Feb 02, 2003.
00005  *  Fixes: 
00006  * 
00007  *  Copyright (c) 2003 Machine Perception Laboratory 
00008  *  University of California San Diego.
00009  * 
00010  * Please read the disclaimer and notes about redistribution 
00011  * at the end of this file.
00012  *  
00013  */
00014 
00015 #ifndef _FACEBOXLIST_H_
00016 #define _FACEBOXLIST_H_
00017 
00018 #include "square.h"
00019 #include <algorithm>
00020 #include <list>
00021 #include <math.h>
00022 #include <iostream>
00023 
00024 using namespace std;
00025 
00026 class avg_object {
00027  public:
00028   float  l, r, t, b; // left, right, top, bottom
00029   float  scale;
00030   int  nL, nR, nT, nB, nScale; // number of contributing boxes
00031   bool normalized;
00032 
00033   avg_object();
00034   avg_object(const avg_object &v);
00035   ~avg_object();
00036   avg_object operator+(const avg_object& v) const;
00037   avg_object & operator+=(const avg_object &v);
00038   void normalize();
00039   void unnormalize();  
00040 };
00041 
00042 template< class T >
00043 class ObjectList{
00044   typedef typename list<TSquare< T > >::iterator TSquare_iter;
00045  public:
00046   ObjectList() {};
00047   ObjectList(ObjectList &thelist):objects(thelist.objects){};
00048   ~ObjectList() {};
00049 
00050   void simplify(float tol);
00051   inline int size() const {return objects.size();}
00052   inline bool empty() const {return objects.empty(); }
00053   inline void clear() {objects.clear();}
00054   inline void sort() {objects.sort();}
00055   inline void erase(TSquare_iter &object){objects.erase(object);}
00056   inline void push_back(const TSquare< T >  &object){objects.push_back(object);}
00057   inline void push_front(const TSquare< T >  &object){objects.push_front(object);}
00058   inline void pop_front(){objects.pop_front();}
00059   inline TSquare_iter begin() { return objects.begin(); }
00060   inline TSquare_iter end() { return objects.end(); }
00061   inline TSquare< T >  front() const { return objects.front(); }
00062   inline TSquare< T >  back() const { return objects.back(); }
00063 
00064   list< TSquare< T > > objects;
00065   float  overlap(avg_object &a, avg_object &b);
00066 /*      ObjectList& operator=(const ObjectList &ob){
00067                 for( list< TSquare< T > >::const_iterator it = ob.objects.begin(); 
00068                                 it != ob.objects.end(); ++it){
00069                                         objects.push_back(*it);
00070                 }
00071                 return *this;
00072         }
00073 */
00074 };
00075 
00076 typedef ObjectList<int> FaceBoxList;
00077 
00078 #ifdef WIN32
00079 #include <windows.h>
00080 #else
00081 template <class T, class U>
00082 static inline T max(T x, U y){ return static_cast<T>(x > y ? x : y);}
00083 template <class T, class U>
00084 static inline T min(T x, U y){ return static_cast<T>(x < y ? x : y);}
00085 #endif
00086 
00087 template< class T >
00088 float ObjectList<T>::overlap(avg_object &a, avg_object &b) {
00089   float  x = max(0,min(a.r,b.r)-max(a.l,b.l));
00090   float  y = max(0,min(a.b,b.b)-max(a.t,b.t));
00091   float  intersection = x*y;
00092   float  total = (a.r-a.l)*(a.b-a.t) + (b.r-b.l)*(b.b-b.t);
00093   float  unin = total-intersection; // note: 'union' is reserved
00094   float  p = intersection/unin;
00095   return(p);
00096 }
00097 
00098 template< class T >
00099 void ObjectList<T>::simplify (float tol)
00100 {
00101   list<avg_object>* origObjects;
00102   avg_object tmp;
00103 
00104   if(objects.size() > 1){
00105     //
00106     // First, put objects into convenient form
00107     //
00108     TSquare<T> f;
00109     origObjects = new list<avg_object>;
00110     while(objects.size() > 0) {
00111       f = objects.front();
00112       //cout << "Simplifying from (x,y,scale,size): (" << f.x << ", " << f.y << ", " << f.scale<<", " << f.size << ")" << endl;
00113       tmp.l = f.x;
00114       tmp.r = f.x + f.size;
00115       tmp.t = f.y;
00116       tmp.b = f.y + f.size;
00117       //tmp.n = 1;
00118       tmp.scale = f.scale;
00119       origObjects->push_back(tmp);  // append the copy
00120       objects.pop_front();
00121     }
00122 
00123     //
00124     // Now, iterate through boxes and combine those that overlap with first
00125     // box.  Make a new list containing originals and combined boxes.  Now
00126     // repeat, using this new list in place of the original, until all boxes
00127     // have been checked with all other boxes.
00128     //
00129     list<avg_object> *newObjects;
00130     list<avg_object> *overlappingObjects;
00131     //float  collapsed;
00132                 if((int)origObjects->size() > 0){
00133      for(int i = 0; i < (int)origObjects->size(); i++){
00134       newObjects = new list<avg_object>;
00135       overlappingObjects = new list<avg_object>;
00136 
00137       //
00138       // store the first object in the overlapping list.
00139       //
00140       overlappingObjects->push_back(origObjects->front());
00141       origObjects->pop_front();
00142       //
00143       //        Loop through all boxes in list, and add them either to the new list,
00144       //  or the overlapping boxes list.
00145       //
00146       while ( origObjects->size() > 0 ) {
00147         float  o = overlap(overlappingObjects->front(),origObjects->front());
00148         if(o > tol)
00149           overlappingObjects->push_back(origObjects->front());
00150         else
00151           newObjects->push_back(origObjects->front());
00152         origObjects->pop_front();
00153       }
00154 
00155 
00156       //
00157       // Now average all the overlapping boxes, and add them to the new list.
00158       //
00159       list<avg_object>::iterator over_iter = overlappingObjects->begin(),
00160         over_iter_end = overlappingObjects->end();
00161       tmp = *over_iter;
00162       for ( over_iter++; over_iter != over_iter_end; over_iter++){
00163         tmp += *over_iter;
00164       }
00165       tmp.normalize();
00166       //cout << "tmp after normallizing: (" << tmp.t << ","<< tmp.b << ","<< tmp.l << ","<< tmp.r << ")"<<endl;
00167       newObjects->push_back(tmp);
00168 
00169       //
00170       //  Make the new list pose as the original list, and free memory so we
00171       //  can make a new new list and overlapping boxes list.
00172       //
00173       delete(origObjects);        // get rid of the old original list
00174       origObjects = newObjects; // make the new list pose as the original
00175       delete(overlappingObjects); // get rid of the overlapping list
00176      }
00177 
00178      // finally, write them back into object
00179      while( !newObjects->empty() ) {
00180       tmp = *(newObjects->begin());
00181       TSquare< T > square (static_cast<int>(tmp.r-tmp.l), static_cast<int>(tmp.l), static_cast<int>(tmp.t), static_cast<int>(floor(tmp.scale+.5)));
00182       objects.push_front(square);
00183       f = objects.front();
00184       newObjects->pop_front ( );
00185      }
00186      delete newObjects;
00187           }
00188   }
00189 }
00190 
00191 
00192 
00193 #endif
00194 
00195 /*
00196  * 
00197  * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
00198  * 
00199  *    1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
00200  *    2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
00201  *    3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
00202  * 
00203  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00204  * 
00205  */

Generated on Mon Nov 8 17:07:33 2004 for MPT by  doxygen 1.3.9.1