📄 motionsearcher.hh
字号:
"%04d flood \r", frame, int (m_tnX), int (m_tnY), int (tnMatches), int (tnFlooded));#endif // That's more pixels found by flood-filling. if (tnMotionX == 0 && tnMotionY == 0) tnNotMovedFloodedPixels += tnFlooded; else tnFloodedPixels += tnFlooded; }#endif // USE_SEARCH_BORDERnextGroup: // Move to the next pixel-group. if (m_tnStepX == 1 && m_tnX == tnLastX || m_tnStepX == -1 && m_tnX == 0) { // We need to move down a line. If we're already on // the last line, we're done with the frame. if (m_tnY == tnLastY) break; // Move down a line. m_oSearchWindow.MoveDown();#ifdef USE_SEARCH_BORDER m_oSearchBorder.MoveDown (a_reStatus);#endif // USE_SEARCH_BORDER if (a_reStatus != g_kNoError) return; ++m_tnY; // HACK //fprintf (stderr, "Now on line %d\r", int (m_tnY)); // Now move across the frame in the other direction, // i.e. zigzag. m_tnStepX = -m_tnStepX; } else if (m_tnStepX == 1) { // Move right one pixel. m_oSearchWindow.MoveRight();#ifdef USE_SEARCH_BORDER m_oSearchBorder.MoveRight (a_reStatus);#endif // USE_SEARCH_BORDER if (a_reStatus != g_kNoError) return; ++m_tnX; } else { // Move left one pixel. assert (m_tnStepX == -1); m_oSearchWindow.MoveLeft();#ifdef USE_SEARCH_BORDER m_oSearchBorder.MoveLeft (a_reStatus);#endif // USE_SEARCH_BORDER if (a_reStatus != g_kNoError) return; --m_tnX; } }#ifdef USE_SEARCH_BORDER m_oSearchBorder.FinishFrame (a_reStatus);#endif // USE_SEARCH_BORDER if (a_reStatus != g_kNoError) return; // We've found all the possible moved regions between the // new frame and the reference frame. // Loop through the moved regions found by motion-detection, // apply each one to the new frame. //fprintf (stderr, "Applied extents:"); // HACK while (m_setRegions.Size() > 0) { typename MovedRegionSet::Iterator itRegion; MovedRegion *pRegion; // The moved region to apply next. PIXELINDEX tnMotionX, tnMotionY; // The region's motion vector. // Get the moved region to apply next. itRegion = m_setRegions.Begin(); pRegion = *itRegion; m_setRegions.Erase (itRegion); pRegion->GetMotionVector (tnMotionX, tnMotionY); // Flood-fill the candidate region, re-testing all the // extents. This removes parts that have been resolved // already, plus it expands the region to its fullest // extent. m_oMatchThrottleFloodFillControl.SetupForFloodFill (tnMotionX, tnMotionY); pRegion->FloodFill (a_reStatus, m_oMatchThrottleFloodFillControl, true); if (a_reStatus != g_kNoError) return; // If that makes it smaller than the next highest- // priority region we found, put it back in & try again. itRegion = m_setRegions.Begin(); if (itRegion != m_setRegions.End() && pRegion->NumberOfPoints() < (*itRegion)->NumberOfPoints()) { // Are there enough points left in this region for // us to bother with it? if (pRegion->NumberOfPoints() <= 2 * PGW * PGH) { // No. Just get rid of it. delete pRegion; } else { // Yes. Put the region back into our set, to be // tried later.#ifndef NDEBUG typename MovedRegionSet::InsertResult oInsertResult =#endif // NDEBUG m_setRegions.Insert (a_reStatus, pRegion); if (a_reStatus != g_kNoError) { delete pRegion; return; } assert (oInsertResult.m_bInserted); } // Try the region that's now the highest priority. continue; } // Apply this region to the new frame. ApplyRegionToNewFrame (a_reStatus, *pRegion); if (a_reStatus != g_kNoError) { delete pRegion; return; } // That's more moved pixels. tnMovedPixels += pRegion->NumberOfPoints(); // We're done with this region. delete pRegion; } } // Prepare for searching the next frame. m_oSearchWindow.FinishFrame(); } // Motion-searching is done. Loop through the reference frame's // pixels, find any unresolved pixels, and create a new pixel for // them, using the data in the new frame. for (i = 0; i < m_tnPixels; ++i) { ReferencePixel_t *pNewPixel; // If this pixel is still unresolved, give it the value of // the corresponding pixel in the new frame. pNewPixel = m_pNewFrame->GetPixel (i); if (pNewPixel == NULL) { // Allocate a new reference pixel. ReferencePixel_t *pNewPixel = m_oPixelPool.Allocate(); // Store the new pixel in the reference frame. m_pNewFrame->SetPixel (i, pNewPixel); // Give it the value from the new frame. pNewPixel->AddSample (a_pPixels[i]); // That's one more new pixel. ++tnNewPixels; } else if (pNewPixel != NULL && pNewPixel->GetFrameReferences() == 1) { // Count up the earlier-found new pixel. ++tnNoMatchNewPixels; } } // Make sure all pixels were accounted for. assert (tnNotMovedPixels + tnMovedPixels + tnNotMovedFloodedPixels + tnFloodedPixels + tnNoMatchNewPixels + tnNewPixels == m_tnPixels); // All done. Remember that the data in the new frame is now valid. ++m_nLastFrame;#ifndef NDEBUG // Make sure none of the pixels have more references than we have // frames. (Sanity check.) for (i = 0; i < m_tnPixels; ++i) { int16_t nRefs = m_pNewFrame->GetPixel (i)->GetFrameReferences(); assert (nRefs > 0); assert (nRefs <= m_nFrames); }#endif // NDEBUG // We'll have a new reference-frame and new-frame in the next pass. m_pReferenceFrame = m_pNewFrame = NULL; m_pNewFramePixels = NULL; // HACK: print the pixel statistics. if (verbose >= 1) fprintf (stderr, "Frame %d: %.1f%% not-moved, " //"%.1f%%+%.1f%% flood, %.1f%% moved, %.1f%%+%.1f%% new\n", "%.1f%%+%.1f%% moved, %.1f%%+%.1f%% new\n", frame, (float (tnNotMovedPixels) * 100.0f / float (m_tnPixels)), (float (tnNotMovedFloodedPixels) * 100.0f / float (m_tnPixels)), (float (tnFloodedPixels) * 100.0f / float (m_tnPixels)), //(float (tnMovedPixels) * 100.0f / float (m_tnPixels)), (float (tnNoMatchNewPixels) * 100.0f / float (m_tnPixels)), (float (tnNewPixels) * 100.0f / float (m_tnPixels))); #ifndef NDEBUG // Print the allocation totals. fprintf (stderr, "%lu regions, %lu pixel-sorters, "#ifdef USE_SEARCH_BORDER "%lu RUCs"#endif // USE_SEARCH_BORDER "\n", MovedRegion::GetInstances(), m_oSearchWindow.GetPixelSorterNodeCount()#ifdef USE_SEARCH_BORDER , m_oSearchBorder.GetRegionUnderConstructionCount()#endif // USE_SEARCH_BORDER );#endif // NDEBUG}// Once there is no more input, call this repeatedly to get the// details of the remaining frames, until it returns 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>::GetRemainingFrames (void){ ReferenceFrame_t *pFrame; // The frame to return to the caller. // If there are no frames left, let our caller know. if (m_nFirstFrame == m_nLastFrame) return NULL; // Get the frame to return to the caller. pFrame = m_ppFrames[m_nFirstFrame]; // Remember not to hand it to the caller ever again. ++m_nFirstFrame; // Finally, return the frame to our caller. return pFrame;}// Purge ourselves of temporary structures.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>::Purge (void){ // Clear out the pixel-sorter. m_oSearchWindow.PurgePixelSorter();}#ifdef THROTTLE_PIXELSORTER_WITH_SAD// 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>::MatchedPixelGroup::MatchedPixelGroup(){ // No match yet. m_tnSAD = 0; m_pGroup = NULL;}// Initializing 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>::MatchedPixelGroup::MatchedPixelGroup (Tolerance_t a_tnSAD, const typename SearchWindow_t::PixelGroup *a_pGroup): m_tnSAD (a_tnSAD), m_pGroup (a_pGroup){ // Nothing else to do.}// 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>::MatchedPixelGroup::~MatchedPixelGroup(){ // Nothing to do.}// A comparison operator, suitable for Set<>.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>inline boolMotionSearcher<PIXEL_NUM,DIM,PIXEL_TOL,PIXELINDEX,FRAMESIZE, PGW,PGH,SORTERBITMASK,PIXEL,REFERENCEPIXEL, REFERENCEFRAME>::MatchedPixelGroup::SortBySAD::operator() (const MatchedPixelGroup &a_rLeft, const MatchedPixelGroup &a_rRight) const{ // Easy enough. return (a_rLeft.m_tnSAD < a_rRight.m_tnSAD);}#endif // THROTTLE_PIXELSORTER_WITH_SAD// Apply this region to the new frame.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> ::ApplyRegionToNewFrame (Status_t &a_reStatus, const MovedRegion &a_rRegion){ PIXELINDEX tnMotionX, tnMotionY; // The region's motion vector, i.e. the offset between // the new-frame pixel and the corresponding // reference-frame pixel. typename MovedRegion::ConstIterator itExtent; // An extent to apply to the new frame. PIXELINDEX x; // Used to loop through pixels. // Make sure they didn't start us off with an error. assert (a_reStatus == g_kNoError); // Get this region's motion vector. a_rRegion.GetMotionVector (tnMotionX, tnMotionY); // Loop through the region's extents, locate every pixel it // describes, and set it to the corresponding pixel in the // reference-frame representation of the new frame. for (itExtent = a_rRegion.Begin(); itExtent != a_rRegion.End(); ++itExtent) { // Get the next extent. const typename MovedRegion::Extent &rExtent = *itExtent; // Loop through the pixels it represents, set each // new-frame pixel to the corresponding reference-frame // pixel. for (x = rExtent.m_tnXStart; x < rExtent.m_tnXEnd; ++x) {#ifdef PRINT_SEARCHBORDER if (m_pNewFrame->GetPixel (x, rExtent.m_tnY) != NULL && m_pNewFrame->GetPixel (x, rExtent.m_tnY) ->GetFrameReferences() != 1) { fprintf (stderr, "Pixel (%d,%d) already resolved\n", int (x), int (rExtent.m_tnY)); }#endif // PRINT_SEARCHBORDER // Make sure this new-frame pixel hasn't been // resolved yet. assert (m_pNewFrame->GetPixel (x, rExtent.m_tnY) == NULL || m_pNewFrame->GetPixel (x, rExtent.m_tnY) ->GetFrameReferences() == 1); // Get the corresponding reference-frame pixel. ReferencePixel_t *pReferencePixel = m_pReferenceFrame->GetPixel
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -