📄 motionsearcher.hh
字号:
#endif // ZERO_MOTION_FLOOD_FILL_WITH_BITMAP_REGIONS void Init (Status_t &a_reStatus, MotionSearcher *a_pMotionSearcher); // Initializer. // Redefined FloodFillControl methods. bool ShouldUseExtent (typename ZeroMotionFloodFillControl::BaseClass::Extent &a_rExtent); // Return true if the flood-fill should examine the given // extent. bool IsPointInRegion (PIXELINDEX a_tnX, PIXELINDEX a_tnY); // Returns true if the given point should be included in the // flood-fill. }; friend class ZeroMotionFloodFillControl; // Allow the zero-motion flood-fill-control class direct access. ZeroMotionFloodFillControl m_oZeroMotionFloodFillControl; // Used to implement flood-filling the result of the // zero-motion search. // A class that helps implement the match-throttle flood-fill. class MatchThrottleFloodFillControl#ifdef MATCH_THROTTLE_FLOOD_FILL_WITH_BITMAP_REGIONS : public BitmapRegion_t::FloodFillControl#else // MATCH_THROTTLE_FLOOD_FILL_WITH_BITMAP_REGIONS : public Region_t::FloodFillControl#endif // MATCH_THROTTLE_FLOOD_FILL_WITH_BITMAP_REGIONS { private:#ifdef MATCH_THROTTLE_FLOOD_FILL_WITH_BITMAP_REGIONS typedef typename BitmapRegion_t::FloodFillControl BaseClass; // Keep track of who our base class is.#else // MATCH_THROTTLE_FLOOD_FILL_WITH_BITMAP_REGIONS typedef typename Region_t::FloodFillControl BaseClass; // Keep track of who our base class is.#endif // MATCH_THROTTLE_FLOOD_FILL_WITH_BITMAP_REGIONS public:#ifdef MATCH_THROTTLE_FLOOD_FILL_WITH_BITMAP_REGIONS MatchThrottleFloodFillControl(); // Default constructor. Must be followed by Init().#else // MATCH_THROTTLE_FLOOD_FILL_WITH_BITMAP_REGIONS MatchThrottleFloodFillControl (typename BaseClass::Allocator &a_rAllocator = Region_t::Extents::Imp::sm_oNodeAllocator); // Partially-initializing constructor. // Must be followed by Init().#endif // MATCH_THROTTLE_FLOOD_FILL_WITH_BITMAP_REGIONS void Init (Status_t &a_reStatus, MotionSearcher *a_pMotionSearcher); // Initializer. void SetupForFloodFill (PIXELINDEX a_tnMotionX, PIXELINDEX a_tnMotionY); // Set up to to a flood-fill. Provide the motion vector. // Call this before doing a flood-fill with this control // object. // Redefined FloodFillControl methods. bool ShouldUseExtent (typename Region_t::Extent &a_rExtent); // Return true if the flood-fill should examine the given // extent. bool IsPointInRegion (PIXELINDEX a_tnX, PIXELINDEX a_tnY); // Returns true if the given point should be included in the // flood-fill. private: MotionSearcher *m_pMotionSearcher; // The motion-searcher we're working for. PIXELINDEX m_tnMotionX, m_tnMotionY; // The motion vector to be used for this flood-fill. }; friend class MatchThrottleFloodFillControl; // Allow the zero-motion flood-fill-control class direct access. MatchThrottleFloodFillControl m_oMatchThrottleFloodFillControl; // Used to implement flood-filling a region before // motion-searching is done.};// Default constructor.template <class PIXEL_NUM, int DIM, class PIXEL_TOL, class PIXELINDEX, class FRAMESIZE, PIXELINDEX PGW, PIXELINDEX PGH, class SORTERBITMASK, class PIXEL, class REFERENCEPIXEL, class REFERENCEFRAME>MotionSearcher<PIXEL_NUM,DIM,PIXEL_TOL,PIXELINDEX,FRAMESIZE, PGW,PGH,SORTERBITMASK,PIXEL,REFERENCEPIXEL, REFERENCEFRAME>::MotionSearcher() :#ifdef USE_SEARCH_BORDER m_oSearchBorder (m_setRegions),#endif // USE_SEARCH_BORDER m_oRegionAllocator (1048576), m_oMatchThrottleRegion (m_oRegionAllocator)#ifndef ZERO_MOTION_FLOOD_FILL_WITH_BITMAP_REGIONS , m_oZeroMotionFloodFillControl (m_oRegionAllocator)#endif // ZERO_MOTION_FLOOD_FILL_WITH_BITMAP_REGIONS#ifndef MATCH_THROTTLE_FLOOD_FILL_WITH_BITMAP_REGIONS , m_oMatchThrottleFloodFillControl (m_oRegionAllocator)#endif // MATCH_THROTTLE_FLOOD_FILL_WITH_BITMAP_REGIONS{ // No frames yet. m_nFrames = 0; m_ppFrames = NULL; m_nFirstFrame = m_nLastFrame = 0; m_tnWidth = m_tnHeight = PIXELINDEX (0); m_tnPixels = FRAMESIZE (0); // No information on the sort of search to do yet. m_tnSearchRadiusX = m_tnSearchRadiusY = PIXELINDEX (0); m_tnZeroTolerance = m_tnTolerance = m_tnTwiceTolerance = PIXEL_TOL (0); m_nMatchCountThrottle = 0; m_nMatchSizeThrottle = 0; // No active search yet. m_tnX = m_tnY = m_tnStepX = PIXELINDEX (0); m_pNewFrame = NULL; m_pReferenceFrame = NULL; m_pNewFramePixels = NULL;}// Destructor.template <class PIXEL_NUM, int DIM, class PIXEL_TOL, class PIXELINDEX, class FRAMESIZE, PIXELINDEX PGW, PIXELINDEX PGH, class SORTERBITMASK, class PIXEL, class REFERENCEPIXEL, class REFERENCEFRAME>MotionSearcher<PIXEL_NUM,DIM,PIXEL_TOL,PIXELINDEX,FRAMESIZE, PGW,PGH,SORTERBITMASK,PIXEL,REFERENCEPIXEL, REFERENCEFRAME>::~MotionSearcher(){ // Free up any remaining moved regions. (Testing for a non-zero // size is defined to be safe even if the set hasn't been // initialized, i.e. if we get destroyed before our Init() has been // called.) if (m_setRegions.Size() > 0) { typename MovedRegionSet::Iterator itHere; // The location of the next region to destroy. // Loop through the moved-regions set, remove each item, // destroy it. while (itHere = m_setRegions.Begin(), itHere != m_setRegions.End()) { // Get the moved-region to destroy. MovedRegion *pRegion = *itHere; // Remove it from the set. m_setRegions.Erase (itHere); // Destroy the region. delete pRegion; } } // Destroy the reference frames. for (int i = 0; i < m_nFrames; i++) { m_ppFrames[i]->Reset(); delete m_ppFrames[i]; } delete[] m_ppFrames;}// Initializer.template <class PIXEL_NUM, int DIM, class PIXEL_TOL, class PIXELINDEX, class FRAMESIZE, PIXELINDEX PGW, PIXELINDEX PGH, class SORTERBITMASK, class PIXEL, class REFERENCEPIXEL, class REFERENCEFRAME>voidMotionSearcher<PIXEL_NUM,DIM,PIXEL_TOL,PIXELINDEX,FRAMESIZE, PGW,PGH,SORTERBITMASK,PIXEL,REFERENCEPIXEL,REFERENCEFRAME>::Init (Status_t &a_reStatus, int a_nFrames, PIXELINDEX a_tnWidth, PIXELINDEX a_tnHeight, PIXELINDEX a_tnSearchRadiusX, PIXELINDEX a_tnSearchRadiusY, PixelValue_t a_tnZeroTolerance, PixelValue_t a_tnTolerance, int a_nMatchCountThrottle, int a_nMatchSizeThrottle){ int i; // Used to loop through things. FRAMESIZE tnPixels; // The number of pixels in each frame. // Make sure they didn't start us off with an error. assert (a_reStatus == g_kNoError); // Make sure they gave us a reasonable number of frames. assert (a_nFrames >= 2); // Make sure the width & height are reasonable. assert (a_tnWidth > PIXELINDEX (0)); assert (a_tnHeight > PIXELINDEX (0)); // Make sure the search radius is reasonable. assert (a_tnSearchRadiusX > PIXELINDEX (0) && a_tnSearchRadiusY > PIXELINDEX (0) && a_tnSearchRadiusX <= a_tnWidth && a_tnSearchRadiusY <= a_tnHeight); // Make sure the match throttles are reasonable. assert (a_nMatchCountThrottle >= 0 && a_nMatchCountThrottle <= a_tnSearchRadiusX * a_tnSearchRadiusY); assert (a_nMatchSizeThrottle > 0); // Calculate the number of pixels in each frame. tnPixels = FRAMESIZE (a_tnWidth) * FRAMESIZE (a_tnHeight); // Initialize our pixel pool. m_oPixelPool.Initialize (a_reStatus, tnPixels * FRAMESIZE (a_nFrames)); if (a_reStatus != g_kNoError) return; // Allocate space for our pointers to frames. m_ppFrames = new ReferenceFrame_t * [a_nFrames]; if (m_ppFrames == NULL) { a_reStatus = g_kOutOfMemory; return; } // (Initialize each one to NULL, in case we run out of memory while // trying to allocate frames -- if we don't do this, we'll end up // trying to delete garbage pointers.) for (i = 0; i < a_nFrames; ++i) m_ppFrames[i] = NULL; // (Save this parameter now, to make it possible to destroy an // incompletely-initialized object.) m_nFrames = a_nFrames; // Allocate our reference frames. for (i = 0; i < a_nFrames; ++i) { // Allocate the next reference frame. m_ppFrames[i] = new ReferenceFrame_t (a_reStatus, a_tnWidth, a_tnHeight); if (m_ppFrames[i] == NULL) { a_reStatus = g_kOutOfMemory; return; } if (a_reStatus != g_kNoError) return; } // Initialize the search-window. m_oSearchWindow.Init (a_reStatus, a_tnWidth, a_tnHeight, a_tnSearchRadiusX, a_tnSearchRadiusY, a_tnTolerance); if (a_reStatus != g_kNoError) return;#ifdef THROTTLE_PIXELSORTER_WITH_SAD // Initialize our set of matches. (We'll use this to sort the // incoming matches by how closely it matches the current // pixel-group, and we'll throw away bad matches.) m_setMatches.Init (a_reStatus, true); if (a_reStatus != g_kNoError) return;#endif // THROTTLE_PIXELSORTER_WITH_SAD // Initialize our moved-regions set. m_setRegions.Init (a_reStatus, true); if (a_reStatus != g_kNoError) return; // Initialize our used reference-pixels container.#ifdef USED_REFERENCE_PIXELS_REGION_IS_BITMAP m_oUsedReferencePixels.Init (a_reStatus, a_tnWidth, a_tnHeight);#else // USED_REFERENCE_PIXELS_REGION_IS_BITMAP m_oUsedReferencePixels.Init (a_reStatus, m_oRegionAllocator);#endif // USED_REFERENCE_PIXELS_REGION_IS_BITMAP if (a_reStatus != g_kNoError) return;#if defined (USED_REFERENCE_PIXELS_REGION_IS_BITMAP) && defined (DEBUG_REGION2D) // HACK: too expensive, test region class elsewhere. m_oUsedReferencePixels.SetDebug (false);#endif // USED_REFERENCE_PIXELS_REGION_IS_BITMAP && DEBUG_REGION2D // Initialize our match-throttle region. m_oMatchThrottleRegion.Init (a_reStatus); if (a_reStatus != g_kNoError) return;#ifdef USE_SEARCH_BORDER // Initialize the search-border. m_oSearchBorder.Init (a_reStatus, a_tnWidth, a_tnHeight, PGW, PGH); if (a_reStatus != g_kNoError) return;#endif // USE_SEARCH_BORDER // Finally, store our parameters. (Convert the tolerance value to // the format used internally.) //m_nFrames = a_nFrames; (Stored above) m_tnWidth = a_tnWidth; m_tnHeight = a_tnHeight; m_tnPixels = tnPixels; m_tnSearchRadiusX = a_tnSearchRadiusX; m_tnSearchRadiusY = a_tnSearchRadiusY; m_tnZeroTolerance = Pixel_t::MakeTolerance (a_tnZeroTolerance); m_tnTolerance = Pixel_t::MakeTolerance (a_tnTolerance); m_tnTwiceTolerance = Pixel_t::MakeTolerance (2 * a_tnTolerance); m_nMatchCountThrottle = a_nMatchCountThrottle; m_nMatchSizeThrottle = a_nMatchSizeThrottle; // Initialize our flood-fill controllers. (This happens after we // store our parameters, because these methods may need those // values.) m_oZeroMotionFloodFillControl.Init (a_reStatus, this); if (a_reStatus != g_kNoError) return; m_oMatchThrottleFloodFillControl.Init (a_reStatus, this); if (a_reStatus != g_kNoError) return;}// If a frame is ready to be output, return it, otherwise return// NULL.template <class PIXEL_NUM, int DIM, class PIXEL_TOL, class PIXELINDEX, class FRAMESIZE, PIXELINDEX PGW, PIXELINDEX PGH, class SORTERBITMASK, class PIXEL, class REFERENCEPIXEL, class REFERENCEFRAME>const typename MotionSearcher<PIXEL_NUM,DIM,PIXEL_TOL,PIXELINDEX, FRAMESIZE, PGW,PGH,SORTERBITMASK,PIXEL,REFERENCEPIXEL, REFERENCEFRAME>::ReferenceFrame_t *MotionSearcher<PIXEL_NUM,DIM,PIXEL_TOL,PIXELINDEX,FRAMESIZE, PGW,PGH,SORTERBITMASK,PIXEL,REFERENCEPIXEL, REFERENCEFRAME>::GetFrameReadyForOutput (void){ ReferenceFrame_t *pFrame; // The frame to return to the caller. int i; // Used to loop through things. // If we have space for the new frame in our reference frames, then // it's not time to emit a frame yet. (We delay emitting frames for // as long as possible, in order to calculate the most accurate // pixel values.) if (m_nFirstFrame != 0 || m_nLastFrame != m_nFrames) return NULL; // Get the frame to return to the caller. pFrame = m_ppFrames[0]; // Shift the remaining frames down. (This is technically bad for // performance, but we don't expect our callers to use enough // reference frames to make this a problem, and if they do, well, // I guess I'll fix the code. Call this one of the very few // shortcuts taken in this project. :-) for (i = 1; i < m_nFrames; ++i) m_ppFrames[i - 1] = m_ppFrames[i]; // Our caller will read the data in the frame. By the time the // caller calls AddFrame(), we'll need to use this frame again. // So put it at the end of the list. --m_nLastFrame; m_ppFrames[m_nLastFrame] = pFrame; // Finally, return the frame to our caller. return pFrame;}// HACK: developer debugging output.extern "C" { extern int frame, verbose; };// Add another frame to be analyzed into the system.template <class PIXEL_NUM, int DIM, class PIXEL_TOL, class PIXELINDEX, class FRAMESIZE, PIXELINDEX PGW, PIXELINDEX PGH, class SORTERBITMASK, class PIXEL, class REFERENCEPIXEL, class REFERENCEFRAME>voidMotionSearcher<PIXEL_NUM,DIM,PIXEL_TOL,PIXELINDEX,FRAMESIZE, PGW,PGH,SORTERBITMASK,PIXEL,REFERENCEPIXEL,REFERENCEFRAME>::AddFrame (Status_t &a_reStatus, const Pixel_t *a_pPixels){ FRAMESIZE i, x, y; // Used to loop through pixels. FRAMESIZE tnNotMovedPixels, tnMovedPixels, tnNotMovedFloodedPixels, tnFloodedPixels, tnNoMatchNewPixels, tnNewPixels; // Statistics on the result of our analysis -- the number of // pixels that didn't move, the number that moved, the number // found by flood-filling, and the number of new pixels. // Make sure they didn't start us off with an error. assert (a_reStatus == g_kNoError); // Make sure we can accept a new frame. assert (m_nFirstFrame == 0 && m_nLastFrame < m_nFrames); // Get the reference frame that will become the new frame. m_pNewFrame = m_ppFrames[m_nLastFrame]; m_pNewFramePixels = a_pPixels; // Reset the new frame, so that it doesn't refer to any pixels. // (This frame was previously returned by GetFrameReadyForOutput(), // so we can't reset it until now.) m_pNewFrame->Reset(); // Reset our statistics.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -