#ifndef IPTEMPORALAVERAGE_HEADER #define IPTEMPORALAVERAGE_HEADER 1 ////////////////////////////////////////////////////////// //! rcsid="$Id: TemporalAverage.hh,v 1.3 2000/07/07 12:57:58 ees1cg Exp $" //! file="amma/Image/IPStream/IPLinear/TemporalAverage.hh" //! lib=IPLinear //! docentry="default.Charles Galambos" //! author="Charles Galambos" //! date="04/07/2000" #include "amma/DP/Process.hh" #include "amma/Ring.hh" #include "amma/Image.hh" #include "amma/Image4Iter.hh" #include //! userlevel=Develop //: Temporal Average of images. template class IPTemporalAverageBodyC : public DPProcessBodyC,ImageC > { public: IPTemporalAverageBodyC(IntT len = 5) : buffLen(len), sr(len), full(false) { assert(len > 1); } //: Constructor. virtual ImageC Apply (const ImageC &im); //: Apply to image. // NB. The first 'len' applications will not be fully filtered. protected: IntT buffLen; RingBuffC > sr; ImageC sum; BooleanT full; }; //! userlevel=Normal //: Temporal Average of images. template class IPTemporalAverageC : public DPProcessC,ImageC > { public: IPTemporalAverageC() {} //: Default constructor. // Creates an invalid handle. IPTemporalAverageC(IntT len) : DPProcessC,ImageC >(*new IPTemporalAverageBodyC(len)) {} //: Constructor. }; ////////////////////////////////////////////////////////////////////////////////////////// template ImageC IPTemporalAverageBodyC::Apply (const ImageC &im) { if(full) { // Normal running buffer... if(im.Rectangle() != sum.Rectangle()) { cerr << "IPTemporalAverageBodyC::Apply (), Size mismatch. \n"; return im; } ImageC ret(sum.Rectangle()); ImageC old = sr.GetLast(); for(Image4IterC it(ret,sum,im,old);it.IsElm();it.Next()) { it.Data2() += it.Data3() - it.Data4(); it.Data1() = it.Data2() / buffLen; } sr.Insert(im); return ret; } sr.Insert(im); if(sr.Items() == 1) { // Initalise sum ? sum = ImageC(im.Rectangle()); // Setup sum. for(Image2IterC it(sum,im);it.IsElm();it.Next()) it.Data1() = it.Data2(); return im; } // Fill buffer. if(im.Rectangle() != sum.Rectangle()) { cerr << "IPTemporalAverageBodyC::Apply (), Size mismatch. \n"; return im; } ImageC ret(im.Rectangle()); TypeT curBuffSize = (TypeT) sr.Items(); for(Image3IterC it(ret,sum,im);it.IsElm();it.Next()) { it.Data2() += it.Data3(); it.Data1() = it.Data2() / curBuffSize; } if(sr.Items() == buffLen) full = true; return ret; } #endif