📄 referenceframe.hh
字号:
#ifndef __REFERENCE_FRAME_H__#define __REFERENCE_FRAME_H__// This file (C) 2004 Steven Boswell. All rights reserved.// Released to the public under the GNU General Public License.// See the file COPYING for more information.#include "config.h"#include <assert.h>#include "mjpeg_types.h"#include "Status_t.h"#include "TemplateLib.hh"// Definitions for pixels, reference pixels, pixel allocators, and// reference frames.// A generic pixel.// Provide the numeric type used to store pixel values, the dimension of// the pixel type, and the numeric type to use in tolerance// calculations.template <class NUM, int DIM, class TOL>class Pixel{public: typedef NUM Num_t; // The numeric type used to store pixel values. Pixel() {} // Default constructor. Pixel (const NUM a_atnVal[DIM]); // Initializing constructor. Pixel (const Pixel<NUM,DIM,TOL> &a_rOther); // Copy constructor. void MakeInvalid (void); // Make the pixel invalid. bool IsPixelInvalid (void) const; // Return whether the pixel is invalid. NUM &operator[] (int a_nDim) { return m_atnVal[a_nDim]; } NUM operator[] (int a_nDim) const { return m_atnVal[a_nDim]; } // Get the value of this pixel. static TOL MakeTolerance (NUM a_tnTolerance); // Turn an integer tolerance value into what's appropriate for // the pixel type. bool IsWithinTolerance (const Pixel<NUM,DIM,TOL> &a_rOther, TOL a_tnTolerance) const; // Return true if the two pixels are within the specified // tolerance. // a_tnTolerance must have been previously retrieved from // MakeTolerance(). bool IsWithinTolerance (const Pixel<NUM,DIM,TOL> &a_rOther, TOL a_tnTolerance, TOL &a_rtnSAD) const; // Return true if the two pixels are within the specified // tolerance, and backpatch the sample-array-difference. // a_tnTolerance must have been previously retrieved from // MakeTolerance().private: NUM m_atnVal[DIM]; // The pixel value.};// Pixel types we use.typedef Pixel<uint8_t,1,int32_t> PixelY;typedef Pixel<uint8_t,2,int32_t> PixelCbCr;// A reference pixel. Used to accumulate values across several frames// for any pixel deemed, via motion detection, to actually be the same// pixel.// Provide the numeric type for accumulated pixels (and tolerance// calculations), the numeric type for pixels, the dimension of the// pixel, and the class used to implement pixels.template <class ACCUM_NUM, class PIXEL_NUM, int DIM, class PIXEL = Pixel<PIXEL_NUM,DIM,ACCUM_NUM> >class ReferencePixel{public: typedef PIXEL Pixel_t; // Our pixel type. typedef ACCUM_NUM Tolerance_t; // Our tolerance value type. ReferencePixel(); // Default constructor. ~ReferencePixel(); // Destructor. void Reset (void); // Reset ourselves, so that we may refer to a new pixel. void AddSample (const PIXEL &a_rPixel); // Incorporate another sample. const PIXEL &GetValue (void); // Return this pixel's value. void AddFrameReference (void) { ++m_nFrameReferences; } // Add another reference from a frame. void RemoveFrameReference (void) { --m_nFrameReferences; } // Remove an existing reference from a frame. // (Once all references are removed, the pixel is implicitly // unallocated.) int16_t GetFrameReferences (void) const { return m_nFrameReferences; } // Return the number of frames that refer to this pixel.private: ACCUM_NUM m_atSum[DIM]; // The sum of the values of all pixels we've incorporated. ACCUM_NUM m_tCount; // The number of pixels we've incorporated. int16_t m_nFrameReferences; // The number of reference-frames that make use of this pixel. // A value of 0 means the pixel is not in use & therefore can // be allocated. PIXEL m_oPixel; // The value of this pixel, i.e. m_nSumY / m_nYCount. // Calculated on demand.};// Reference-pixel types we use.typedef ReferencePixel<uint16_t,uint8_t,1,PixelY> ReferencePixelY;typedef ReferencePixel<uint16_t,uint8_t,2,PixelCbCr> ReferencePixelCbCr;// A class to allocate reference pixels.// Parameterized by the type of reference pixel, and a numeric type that// can hold the largest number of reference pixels to be allocated (i.e.// big enough to hold the product of the frame's width & height).template <class REFERENCEPIXEL, class FRAMESIZE>class PixelAllocator{public: PixelAllocator(); // Default constructor. ~PixelAllocator(); // Destructor. void Initialize (Status_t &a_reStatus, FRAMESIZE a_tnCount); // Initialize the pool to contain the given number of pixels. // This must be greater than or equal to the number of pixels // that can ever be in use at one time. REFERENCEPIXEL *Allocate (void); // Allocate another pixel. // (Note that not having a free pixel to allocate indicates // that the a_nCount parameter to Initialize() needed to be // bigger.)private: FRAMESIZE m_tnCount; // The number of reference pixels in our pool. FRAMESIZE m_tnNext; // The index of the next pixel to try to allocate. // A pixel is considered unallocated if it has a zero // reference count. REFERENCEPIXEL *m_pPixels; // The pool of pixels.};// A reference frame. Points to reference pixels, which may be shared// across several reference frames, depending on what motion-detection// determines about the pixel's lifetime. Parameterized by the type of// reference pixels to use, the numeric type to use for pixel indices,// and a numeric type big enough to hold the product of the largest// expected width & height.template <class REFERENCEPIXEL, class PIXELINDEX, class FRAMESIZE>class ReferenceFrame{public: ReferenceFrame (Status_t &a_reStatus, PIXELINDEX a_tnWidth, PIXELINDEX a_tnHeight); // Initializing constructor. REFERENCEPIXEL *GetPixel (PIXELINDEX a_tnX, PIXELINDEX a_tnY) const; // Get the pixel at this index (which may be NULL). REFERENCEPIXEL *GetPixel (FRAMESIZE a_tnI) const; // Get the pixel at this offset (which may be NULL). void SetPixel (PIXELINDEX a_tnX, PIXELINDEX a_tnY, REFERENCEPIXEL *a_pPixel); // Set the pixel at this index. a_pPixel may be NULL. void SetPixel (FRAMESIZE a_tnI, REFERENCEPIXEL *a_pPixel); // Set the pixel at this offset. a_pPixel may be NULL. void Reset (void); // Reset the frame, i.e. set all the pixels to NULL.private: PIXELINDEX m_tnWidth, m_tnHeight; // The dimensions of the frame. REFERENCEPIXEL **m_ppPixels; // The reference pixels that make up this frame. // The contained pointers may be NULL, to mark pixels that still // need to be resolved.};// Reference-frame types we use.typedef ReferenceFrame<ReferencePixelY, int16_t, int32_t> ReferenceFrameY;typedef ReferenceFrame<ReferencePixelCbCr, int16_t, int32_t> ReferenceFrameCbCr;// Initializing constructor.template <class NUM, int DIM, class TOL>Pixel<NUM,DIM,TOL>::Pixel (const NUM a_atnVal[DIM]){ // Store the values. for (int i = 0; i < DIM; ++i) m_atnVal[i] = a_atnVal[i];}// Copy constructor.template <class NUM, int DIM, class TOL>Pixel<NUM,DIM,TOL>::Pixel (const Pixel<NUM,DIM,TOL> &a_rOther){ // Copy the values. for (int i = 0; i < DIM; ++i) m_atnVal[i] = a_rOther.m_atnVal[i];}// Make the pixel invalid.template <class NUM, int DIM, class TOL>voidPixel<NUM,DIM,TOL>::MakeInvalid (void){ // 0 isn't a valid value for pixels. m_atnVal[0] = 0;}// Return whether the pixel is invalid.template <class NUM, int DIM, class TOL>inline boolPixel<NUM,DIM,TOL>::IsPixelInvalid (void) const{ // Return whether the first pixel value is invalid. return m_atnVal[0] == 0;}// Turn an integer tolerance value into what's appropriate for// the pixel type.template <class NUM, int DIM, class TOL>TOLPixel<NUM,DIM,TOL>::MakeTolerance (NUM a_tnTolerance){ // The default is to just use the given number. return TOL (a_tnTolerance);}#if 0// This is what I mean, but C++ templates can't do this.// Turn an integer tolerance value into what's appropriate for// the pixel type.template <class NUM, class TOL>TOLPixel<NUM,1,TOL>::MakeTolerance (NUM a_tnTolerance){ // For a one-dimensional pixel, just use the given number. return TOL (a_tnTolerance);}#endif// Turn an integer tolerance value into what's appropriate for// the pixel type.template <>int32_tPixelY::MakeTolerance (uint8_t a_tnTolerance){ // For a one-dimensional pixel, just use the given number. return int32_t (a_tnTolerance);}#if 0// This is what I mean, but C++ templates can't do this.// Turn an integer tolerance value into what's appropriate for// the pixel type.template <class NUM, class TOL>TOLPixel<NUM,2,TOL>::MakeTolerance (NUM a_tnTolerance){ // For a two-dimensional pixel, use the square of the given number. return TOL (a_tnTolerance) * TOL (a_tnTolerance);}#endif// Turn an integer tolerance value into what's appropriate for// the pixel type.template <>int32_tPixelCbCr::MakeTolerance (uint8_t a_tnTolerance){ // For a two-dimensional pixel, use the square of the given number. return int32_t (a_tnTolerance) * int32_t (a_tnTolerance);} #if 0// This is what I mean, but C++ templates can't do this.// Return true if the two pixels are within the specified tolerance.template <class NUM, class TOL>boolPixel<NUM,1,TOL>::IsWithinTolerance (const Pixel<NUM,1,TOL> &a_rOther, TOL a_tnTolerance) const{ // Check to see if the absolute value of the difference between // the two pixels is within our tolerance value. return AbsoluteValue (TOL (m_atnVal[0]) - TOL (a_rOther.m_atnVal[0])) <= a_tnTolerance;}#endif// Return true if the two pixels are within the specified tolerance.template <>boolPixelY::IsWithinTolerance (const PixelY &a_rOther, int32_t a_tnTolerance) const{ // Check to see if the absolute value of the difference between // the two pixels is within our tolerance value. return AbsoluteValue (int32_t (m_atnVal[0]) - int32_t (a_rOther.m_atnVal[0])) <= a_tnTolerance;}// Return true if the two pixels are within the specified tolerance.template <>boolPixelY::IsWithinTolerance (const PixelY &a_rOther, int32_t a_tnTolerance, int32_t &a_rtnSAD) const{ // Check to see if the absolute value of the difference between // the two pixels is within our tolerance value. a_rtnSAD = AbsoluteValue (int32_t (m_atnVal[0]) - int32_t (a_rOther.m_atnVal[0])); return a_rtnSAD <= a_tnTolerance;}#if 0// This is what I mean, but C++ templates can't do this.// Return true if the two pixels are within the specified tolerance.template <class NUM, class TOL>boolPixel<NUM,2,TOL>::IsWithinTolerance (const Pixel<NUM,2,TOL> &a_rOther, TOL a_tnTolerance) const{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -