Home || Architecture || Video Search || Visual Search || Scripts || Applications || Important Messages || OGL || Src

FuncQueueBased.h

Go to the documentation of this file.
00001 #ifndef Impala_Core_Array_Pattern_FuncQueueBased_h
00002 #define Impala_Core_Array_Pattern_FuncQueueBased_h
00003 
00004 #include <iostream>
00005 #include "Core/Array/Pattern/Categories.h"
00006 #include "Core/Array/Pattern/ArrayFunc.h"
00007 #include "Core/Array/Pattern/PtrFunc.h"
00008 #include "Core/Geometry/PointZ.h"
00009 #include "Core/Array/Pattern/FcvArray.h"
00010 #include "Core/Array/Pattern/QAction.h"
00011 
00012 namespace Impala
00013 {
00014 namespace Core
00015 {
00016 namespace Array
00017 {
00018 namespace Pattern
00019 {
00020 
00021 
00022 // version with mask
00023 template <class DstArrayT, class SrcArrayT, class MaskArrayT, class VecPointT,
00024           class VecNeighborT, class NeighborsT>
00025 inline void
00026 FuncQueueBased_FillNeighborValues(DstArrayT* dst, SrcArrayT* src,
00027                                   MaskArrayT* mask, Geometry::PointZ centralPoint,
00028                                   const VecPointT& neighborCoordinates, 
00029                                   VecNeighborT& vecneighbors, NeighborsT)
00030 {
00031     typedef typename DstArrayT::StorType DstStorT;
00032     typedef typename DstArrayT::ArithType DstArithT;
00033     typedef typename SrcArrayT::StorType SrcStorT;
00034     typedef typename SrcArrayT::ArithType SrcArithT;
00035     typedef typename MaskArrayT::StorType MaskStorT;
00036     typedef typename MaskArrayT::ArithType MaskArithT;
00037 
00038     vecneighbors.clear();
00039     int imgsizex = ArrayCW(dst);
00040     int imgsizey = ArrayCW(dst);
00041     for (int i=0; i<neighborCoordinates.size(); i++)
00042     {
00043         Geometry::PointZ p = neighborCoordinates[i]+centralPoint;
00044         int tempx=p.mX, tempy=p.mY;
00045         if (tempx>=0 && tempy>=0 && tempx<imgsizex && tempy<imgsizey)
00046         {
00047             DstStorT* dPtr = ArrayCPB(dst, tempx, tempy);
00048             SrcStorT* sPtr = ArrayCPB(src, tempx, tempy);
00049             SrcStorT* mPtr = ArrayCPB(mask, tempx, tempy);
00050             NeighborsT neighbors;
00051             neighbors.point=p; 
00052             neighbors.arith=PtrRead(dPtr, DstArithT()); 
00053             neighbors.img=PtrRead(sPtr, SrcArithT()); 
00054             neighbors.mask=PtrRead(mPtr, MaskArithT());
00055             vecneighbors.push_back(neighbors);
00056         }
00057     }
00058 }
00059 
00060 // version without mask
00061 template <class DstArrayT, class SrcArrayT, class VecPointT,
00062           class VecNeighborT, class NeighborsT>
00063 inline void
00064 FuncQueueBased_FillNeighborValues(DstArrayT* dst, SrcArrayT* src,
00065                                   Geometry::PointZ centralPoint,
00066                                   const VecPointT& neighborCoordinates, 
00067                                   VecNeighborT& vecneighbors, NeighborsT)
00068 {
00069     typedef typename DstArrayT::StorType DstStorT;
00070     typedef typename DstArrayT::ArithType DstArithT;
00071     typedef typename SrcArrayT::StorType SrcStorT;
00072     typedef typename SrcArrayT::ArithType SrcArithT;
00073 
00074     vecneighbors.clear();
00075     int imgsizex = ArrayCW(dst);
00076     int imgsizey = ArrayCW(dst);
00077     for (int i=0; i<neighborCoordinates.size(); i++)
00078     {
00079         Geometry::PointZ p = neighborCoordinates[i]+centralPoint;
00080         int tempx=p.mX, tempy=p.mY;
00081         if (tempx>=0 && tempy>=0 && tempx<imgsizex && tempy<imgsizey)
00082         {
00083             DstStorT* dPtr = ArrayCPB(dst, tempx, tempy);
00084             SrcStorT* sPtr = ArrayCPB(src, tempx, tempy);
00085             NeighborsT neighbors;
00086             neighbors.point=p; 
00087             neighbors.arith=PtrRead(dPtr, DstArithT()); 
00088             neighbors.img=PtrRead(sPtr, SrcArithT()); 
00089             vecneighbors.push_back(neighbors);
00090         }
00091     }
00092 }
00093 
00094 template <class VecPointT>
00095 void
00096 FuncQueueBased_ComputeNeighbors(VecPointT& neighborCoordinates,
00097                                 int connectivity, int radiusSqr)
00098 {
00099     neighborCoordinates.clear();
00100     if (radiusSqr<0 && connectivity==4)
00101         radiusSqr = 1;
00102     if (radiusSqr<0 && connectivity==8)
00103         radiusSqr = 2;
00104 
00105     int radius;
00106     for (radius=0 ; radius*radius <= radiusSqr ; radius++)
00107         ;
00108     for (int y=-radius ; y<=radius ; y++)
00109     {
00110         for (int x=-radius ; x<=radius ; x++)
00111         {
00112             if (x||y)
00113             { //skip (0,0,0)
00114                 if (x*x+y*y <= radiusSqr)
00115                     neighborCoordinates.push_back(Geometry::PointZ(x,y));
00116             }
00117         }
00118     }
00119 }
00120 
00121 // version with mask
00122 template <class DstArrayT, class SrcArrayT, class MaskArrayT, class FunctorT>
00123 void
00124 FuncQueueBasedDispatch(DstArrayT* dst, SrcArrayT* src, MaskArrayT* mask,
00125                        FunctorT& functor, int connectivity, int radiusSqr)
00126 {
00127     typedef typename DstArrayT::StorType DstStorT;
00128     typedef typename DstArrayT::ArithType DstArithT;
00129     typedef typename SrcArrayT::StorType SrcStorT;
00130     typedef typename SrcArrayT::ArithType SrcArithT;
00131     typedef typename MaskArrayT::StorType MaskStorT;
00132     typedef typename MaskArrayT::ArithType MaskArithT;
00133 
00134     typedef typename FunctorT::PointValueT PointValueT;
00135     typedef typename FunctorT::QT QT; 
00136     typedef typename FunctorT::NeighborsT NeighborsT;
00137     typedef typename FunctorT::VecNeighborsT VecNeighborsT;
00138 
00139     typedef Pattern::FcvArray<Geometry::PointZ> VecPointT;
00140 
00141     QT theQueue;
00142     int imgsizex = ArrayCW(dst);
00143     int imgsizey = ArrayCH(dst);
00144 
00145     // GLOBAL INIT
00146     { // local scope
00147         for (int y=0 ; y<imgsizey ; y++)
00148         {
00149             DstStorT* dPtr = ArrayCPB(dst, 0, y);
00150             SrcStorT* sPtr = ArrayCPB(src, 0, y);
00151             SrcStorT* mPtr = ArrayCPB(mask, 0, y);
00152             for (int x=0 ; x<imgsizex ; x++)
00153             {
00154                 PointValueT vp;
00155                 Geometry::PointZ p(x, y);
00156                 vp.point=p;
00157                 DstArithT d = PtrRead(dPtr, DstArithT());
00158                 SrcArithT s = PtrRead(sPtr, SrcArithT());
00159                 MaskArithT m = PtrRead(mPtr, MaskArithT());
00160                 bool q = functor.GlobalPixelInit(vp, d, s, m);
00161                 if (q)
00162                     theQueue.push(vp); // NOTE: bool ok=queue.insert(vp).second is NEVER false
00163                 PtrWrite(dPtr, d);
00164                 dPtr += DstArrayT::ElemSize();
00165                 sPtr += SrcArrayT::ElemSize();
00166                 mPtr += MaskArrayT::ElemSize();
00167             }
00168         }
00169     } // end local scope
00170 
00171     // NEW: array of points to simplify loop 4/8/... connectivity, now skip (0,0,0)
00172     VecPointT neighborCoordinates;
00173     FuncQueueBased_ComputeNeighbors(neighborCoordinates, connectivity, radiusSqr);
00174 
00175     // clear speedup startpoint for localPixelInit() in large do while loop
00176     //__asm int 3
00177     Geometry::PointZ startpoint(0,0);
00178     VecNeighborsT vecneighbors;
00179 
00180     // LOOP until done with INIT local + PROPAGATE
00181     do
00182     {
00183 
00184         // INIT: FILL QUEUE
00185         { // local scope
00186             bool freshstart = functor.WantFreshStartLocalPixelInit();
00187             if (freshstart)
00188             {
00189                 startpoint.mX=0;
00190                 startpoint.mY=0;
00191             }
00192             bool continueloop=true;
00193             int x=startpoint.mX;
00194             int y=startpoint.mY;
00195             bool wenttonewpoint=false;
00196             if (wenttonewpoint)
00197                 y=0;
00198             for (; y<imgsizey; y++)
00199             {
00200                 if (wenttonewpoint)
00201                     x=0;
00202                 DstStorT* dPtr = ArrayCPB(dst, x, y);
00203                 SrcStorT* sPtr = ArrayCPB(src, x, y);
00204                 SrcStorT* mPtr = ArrayCPB(mask, x, y);
00205                 for (; x<imgsizex; x++)
00206                 {
00207                     if (!wenttonewpoint)
00208                     {
00209                         wenttonewpoint=true;
00210                     }
00211                     PointValueT vp;
00212                     vp.point.mX = x;
00213                     vp.point.mY = y;
00214                     DstArithT d = PtrRead(dPtr, DstArithT());
00215                     SrcArithT s = PtrRead(sPtr, SrcArithT());
00216                     MaskArithT m = PtrRead(mPtr, MaskArithT());
00217                     bool q = functor.LocalPixelInit(vp, d, s, m, continueloop);
00218                     if (q)
00219                         theQueue.push(vp); // NOTE: bool ok=queue.insert(vp).second is NEVER false
00220                     PtrWrite(dPtr, d);
00221                     if (!continueloop)
00222                         break;
00223                     dPtr += DstArrayT::ElemSize();
00224                     sPtr += SrcArrayT::ElemSize();
00225                     mPtr += MaskArrayT::ElemSize();
00226                 }
00227                 if (!continueloop)
00228                     break;
00229             }
00230             // remember startpoint for next time
00231             startpoint.mX = x;
00232             startpoint.mY = y;
00233 
00234         } // end local scope
00235 
00236         // PROPAGATION
00237         { // local scope
00238             while (!theQueue.empty())
00239             { // line 4
00240                 PointValueT vp(theQueue.top());
00241                 theQueue.pop(); // line 5
00242 
00243                 // give functor first=this=center data
00244                 { // local scope
00245                     int tempx=vp.point.mX, tempy=vp.point.mY;
00246                     DstStorT* dPtr = ArrayCPB(dst, tempx, tempy);
00247                     SrcStorT* sPtr = ArrayCPB(src, tempx, tempy);
00248                     SrcStorT* mPtr = ArrayCPB(mask, tempx, tempy);
00249                     functor.First(vp, PtrRead(dPtr, DstArithT()),
00250                                   PtrRead(sPtr, SrcArithT()),
00251                                   PtrRead(mPtr, MaskArithT()));
00252                 } // local scope
00253 
00254                 // give functor the neighbour pixels
00255                 // NOT yet optimized for iterator++ or LUT for coords
00256                 // NEW: use vector to pass neighbors, here be compatible with sequential code
00257                 { //local scope
00258                     FuncQueueBased_FillNeighborValues(dst, src, mask, vp.point,
00259                                                       neighborCoordinates,
00260                                                       vecneighbors,
00261                                                       NeighborsT());
00262                     // CALCULATE put functor to work, might be removed by first call to getdata()
00263                     functor.Calculate(vecneighbors);
00264                 } //local scope
00265 
00266 
00267 
00268                 // read out phase, might have many values of different types
00269                 { // local scope
00270                     QAction action;
00271                     while ((action=functor.Result())!=STOP)
00272                     { 
00273                         switch (action)
00274                         {
00275                         case QUEUE:
00276                             { // local scope
00277                                 PointValueT vp;
00278                                 functor.GetItemToQueue(vp);
00279                                 theQueue.push(vp); 
00280                             } // local scope
00281                             break;
00282                         case REMOVE:
00283                             { // local scope
00284                                 PointValueT low, high;
00285                                 functor.GetItemToRemove(low, high);
00286                                 typename QT::iterator lowiter=theQueue.lower_bound(low);
00287                                 typename QT::iterator highiter=theQueue.after_upper_bound(high);
00288                                 for (typename QT::iterator iter=lowiter; iter!=highiter; iter++)
00289                                 {
00290                                     bool k=functor.KillThisOne(*iter);
00291                                     if (k)
00292                                     {
00293                                         theQueue.erase(iter);
00294                                         break;
00295                                     } 
00296                                 }
00297                             } // local scope
00298                             break;
00299                         case WRITE:
00300                             { // local scope
00301                                 Geometry::PointZ point; 
00302                                 DstArithT arith;
00303                                 functor.GetItemToWrite(point, arith);
00304                                 DstStorT* dPtr = ArrayCPB(dst, point.mX, point.mY);
00305                                 PtrWrite(dPtr, arith);
00306                             } // local scope
00307                             break;
00308                         default:
00309                             std::cerr << "ERROR switch (action) default:" << std::endl;
00310                         }; // switch (action)
00311                     } // while ((action=functor.Result())!=STOP) 
00312                 } // local scope
00313             } // while (!theQueue.empty()) 
00314         } // end local scope PROPAGATION
00315     }
00316     while (functor.WantAnotherLoop());
00317 }
00318 
00319 // version without mask
00320 template <class DstArrayT, class SrcArrayT, class FunctorT>
00321 void
00322 FuncQueueBasedDispatch(DstArrayT* dst, SrcArrayT* src,
00323                        FunctorT& functor, int connectivity, int radiusSqr)
00324 {
00325     typedef typename DstArrayT::StorType DstStorT;
00326     typedef typename DstArrayT::ArithType DstArithT;
00327     typedef typename SrcArrayT::StorType SrcStorT;
00328     typedef typename SrcArrayT::ArithType SrcArithT;
00329 
00330     typedef typename FunctorT::PointValueT PointValueT;
00331     typedef typename FunctorT::QT QT; 
00332     typedef typename FunctorT::NeighborsT NeighborsT;
00333     typedef typename FunctorT::VecNeighborsT VecNeighborsT;
00334 
00335     typedef Pattern::FcvArray<Geometry::PointZ> VecPointT;
00336 
00337     QT theQueue;
00338     int imgsizex = ArrayCW(dst);
00339     int imgsizey = ArrayCH(dst);
00340 
00341     // GLOBAL INIT
00342     { // local scope
00343         for (int y=0 ; y<imgsizey ; y++)
00344         {
00345             DstStorT* dPtr = ArrayCPB(dst, 0, y);
00346             SrcStorT* sPtr = ArrayCPB(src, 0, y);
00347             for (int x=0 ; x<imgsizex ; x++)
00348             {
00349                 PointValueT vp;
00350                 Geometry::PointZ p(x, y);
00351                 vp.point=p;
00352                 DstArithT d = PtrRead(dPtr, DstArithT());
00353                 SrcArithT s = PtrRead(sPtr, SrcArithT());
00354                 bool q = functor.GlobalPixelInit(vp, d, s);
00355                 if (q)
00356                     theQueue.push(vp); // NOTE: bool ok=queue.insert(vp).second is NEVER false
00357                 PtrWrite(dPtr, d);
00358                 dPtr += DstArrayT::ElemSize();
00359                 sPtr += SrcArrayT::ElemSize();
00360             }
00361         }
00362     } // end local scope
00363 
00364     // NEW: array of points to simplify loop 4/8/... connectivity, now skip (0,0,0)
00365     VecPointT neighborCoordinates;
00366     FuncQueueBased_ComputeNeighbors(neighborCoordinates, connectivity, radiusSqr);
00367 
00368     // clear speedup startpoint for localPixelInit() in large do while loop
00369     //__asm int 3
00370     Geometry::PointZ startpoint(0,0);
00371     VecNeighborsT vecneighbors;
00372 
00373     // LOOP until done with INIT local + PROPAGATE
00374     do
00375     {
00376         // INIT: FILL QUEUE
00377         { // local scope
00378             bool freshstart = functor.WantFreshStartLocalPixelInit();
00379             if (freshstart)
00380             {
00381                 startpoint.mX=0;
00382                 startpoint.mY=0;
00383             }
00384             bool continueloop=true;
00385             int x=startpoint.mX;
00386             int y=startpoint.mY;
00387             bool wenttonewpoint=false;
00388             if (wenttonewpoint)
00389                 y=0;
00390             for (; y<imgsizey; y++)
00391             {
00392                 if (wenttonewpoint)
00393                     x=0;
00394                 DstStorT* dPtr = ArrayCPB(dst, x, y);
00395                 SrcStorT* sPtr = ArrayCPB(src, x, y);
00396                 for (; x<imgsizex; x++)
00397                 {
00398                     if (!wenttonewpoint)
00399                     {
00400                         wenttonewpoint=true;
00401                     }
00402                     PointValueT vp;
00403                     vp.point.mX=x;
00404                     vp.point.mY=y;
00405                     DstArithT d = PtrRead(dPtr, DstArithT());
00406                     SrcArithT s = PtrRead(sPtr, SrcArithT());
00407                     bool q = functor.LocalPixelInit(vp, d, s, continueloop);
00408                     if (q)
00409                         theQueue.push(vp); // NOTE: bool ok=queue.insert(vp).second is NEVER false
00410                     PtrWrite(dPtr, d);
00411                     if (!continueloop)
00412                         break;
00413                     dPtr += DstArrayT::ElemSize();
00414                     sPtr += SrcArrayT::ElemSize();
00415                 }
00416                 if (!continueloop)
00417                     break;
00418             }
00419             // remember startpoint for next time
00420             startpoint.mX=x;
00421             startpoint.mY=y;
00422 
00423         } // end local scope
00424 
00425         // PROPAGATION
00426         { // local scope
00427             while (!theQueue.empty())
00428             { // line 4
00429                 PointValueT vp(theQueue.top());
00430                 theQueue.pop(); // line 5
00431 
00432                 // give functor first=this=center data
00433                 { // local scope
00434                     int tempx=vp.point.mX, tempy=vp.point.mY;
00435                     DstStorT* dPtr = ArrayCPB(dst, tempx, tempy);
00436                     SrcStorT* sPtr = ArrayCPB(src, tempx, tempy);
00437                     functor.First(vp, PtrRead(dPtr, DstArithT()),
00438                                   PtrRead(sPtr, SrcArithT()));
00439                 } // local scope
00440 
00441                 // give functor the neighbour pixels
00442                 // NOT yet optimized for iterator++ or LUT for coords
00443                 // NEW: use vector to pass neighbors, here be compatible with sequential code
00444                 { //local scope
00445                     FuncQueueBased_FillNeighborValues(dst, src, vp.point,
00446                                                       neighborCoordinates,
00447                                                       vecneighbors,
00448                                                       NeighborsT());
00449                     // CALCULATE put functor to work, might be removed by first call to getdata()
00450                     functor.Calculate(vecneighbors);
00451                 } //local scope
00452 
00453 
00454 
00455                 // read out phase, might have many values of different types
00456                 { // local scope
00457                     QAction action;
00458                     while ((action=functor.Result())!=STOP)
00459                     { 
00460                         switch (action)
00461                         {
00462                         case QUEUE:
00463                             { // local scope
00464                                 PointValueT vp;
00465                                 functor.GetItemToQueue(vp);
00466                                 theQueue.push(vp); 
00467                             } // local scope
00468                             break;
00469                         case REMOVE:
00470                             { // local scope
00471                                 PointValueT low, high;
00472                                 functor.GetItemToRemove(low, high);
00473                                 typename QT::iterator lowiter=theQueue.lower_bound(low);
00474                                 typename QT::iterator highiter=theQueue.after_upper_bound(high);
00475                                 for (typename QT::iterator iter=lowiter; iter!=highiter; iter++)
00476                                 {
00477                                     bool k=functor.KillThisOne(*iter);
00478                                     if (k)
00479                                     {
00480                                         theQueue.erase(iter);
00481                                         break;
00482                                     } 
00483                                 }
00484                             } // local scope
00485                             break;
00486                         case WRITE:
00487                             { // local scope
00488                                 Geometry::PointZ point; 
00489                                 DstArithT arith;
00490                                 functor.GetItemToWrite(point, arith);
00491                                 DstStorT* dPtr = ArrayCPB(dst, point.mX, point.mY);
00492                                 PtrWrite(dPtr, arith);
00493                             } // local scope
00494                             break;
00495                         default:
00496                             std::cerr << "ERROR switch (action) default:" << std::endl;
00497                         }; // switch (action)
00498                     } // while ((action=functor.Result())!=STOP) 
00499                 } // local scope
00500             } // while (!theQueue.empty()) 
00501         } // end local scope PROPAGATION
00502     }
00503     while (functor.WantAnotherLoop());
00504 }
00505 
00506 } // namespace Pattern
00507 } // namespace Array
00508 } // namespace Core
00509 } // namespace Impala
00510 
00511 #endif

Generated on Fri Mar 19 09:30:50 2010 for ImpalaSrc by  doxygen 1.5.1