searchwindow.hh
来自「Motion JPEG编解码器源代码」· HH 代码 · 共 1,997 行 · 第 1/5 页
HH
1,997 行
// later time.public: // A class to keep track of our progress during a search inside the // pixel sorter. (This has to be public, in order to allow clients // to create one, but the definition is hidden down here because the // details of it aren't public.) class PixelSorterIterator { public: const PixelGroup *m_pSearch; // The pixel group being searched for. const PixelSorterBranchNode *m_pBranch; // The branch being examined. // Initialized to &m_oPixelSorter. // If NULL, means the search is over. const SearchWindowCell *m_pCell; // The last cell examined. // If equal to m_pBranch->m_oSplitValue, means that the // branch hasn't been examined yet. };};// 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>SearchWindow<PIXEL_NUM,DIM,PIXEL_TOL,PIXELINDEX,FRAMESIZE, PGW,PGH,SORTERBITMASK,PIXEL,REFERENCEPIXEL, REFERENCEFRAME>::SearchWindow(){ // No frames yet. m_tnWidth = m_tnHeight = PIXELINDEX (0); // No information on the sort of search to do yet. m_tnSearchRadiusX = m_tnSearchRadiusY = PIXELINDEX (0); m_tnTolerance = m_tnTwiceTolerance = PIXEL_TOL (0); // No active search yet. m_tnX = m_tnY = PIXELINDEX (0); m_pReferenceFrame = NULL; // No search window yet. m_ppSearchWindow = NULL; m_pSearchWindowStorage = NULL; m_tnSearchWindowPixelLeft = m_tnSearchWindowPixelRight = m_tnSearchWindowPixelTop = m_tnSearchWindowPixelBottom = m_tnSearchWindowSortLeft = m_tnSearchWindowSortRight = m_tnSearchWindowSortTop = m_tnSearchWindowSortBottom = PIXELINDEX (0);}// 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>SearchWindow<PIXEL_NUM,DIM,PIXEL_TOL,PIXELINDEX,FRAMESIZE, PGW,PGH,SORTERBITMASK,PIXEL,REFERENCEPIXEL, REFERENCEFRAME>::~SearchWindow(){ // Destroy the search window. delete[] m_ppSearchWindow; delete[] m_pSearchWindowStorage;}// 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>voidSearchWindow<PIXEL_NUM,DIM,PIXEL_TOL,PIXELINDEX,FRAMESIZE, PGW,PGH,SORTERBITMASK,PIXEL,REFERENCEPIXEL,REFERENCEFRAME>::Init (Status_t &a_reStatus, PIXELINDEX a_tnWidth, PIXELINDEX a_tnHeight, PIXELINDEX a_tnSearchRadiusX, PIXELINDEX a_tnSearchRadiusY, PixelValue_t a_tnTolerance){ 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 the sorter bit-mask type is big enough to hold // pixel-sorter branch-node child indices. (Note that this is // technically a compile-time assertion.) assert (sizeof (SORTERBITMASK) * g_knBitsPerByte > PGH * PGW * DIM); // 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 tolerance is reasonable. (A zero tolerance can // be used for MPEG-encoding-style motion detection.) assert (a_tnTolerance >= 0); // Calculate the number of pixels in each frame. tnPixels = FRAMESIZE (a_tnWidth) * FRAMESIZE (a_tnHeight); // Allocate enough cells for our search window. m_pSearchWindowStorage = new SearchWindowCell [(a_tnHeight - PGH + 1) * (a_tnWidth - PGW + 1)]; if (m_pSearchWindowStorage == NULL) { a_reStatus = g_kOutOfMemory; return; } // Allocate enough space for our line-based index into the // search window storage. m_ppSearchWindow = new SearchWindowCell * [a_tnHeight - PGH + 1]; if (m_ppSearchWindow == NULL) { a_reStatus = g_kOutOfMemory; return; } // Generate pointers to the beginning of each line in the search // window. SearchWindowCell *pNextLine = m_pSearchWindowStorage; for (i = 0; i < (a_tnHeight - PGH + 1); ++i) { m_ppSearchWindow[i] = pNextLine; pNextLine += (a_tnWidth - PGW + 1); } // Initialize the root of the pixel-sorter tree to split the // available range in half. Also generate search-window cells // that represent the minimum/maximum values for pixels. { PIXELINDEX x, y; // Used to loop through pixels. PixelValue_t atnMin[DIM], atnHalf[DIM], atnMax[DIM]; // What we initialize each pixel to. // Generate a pixel value that represents half the available // range in each dimension, plus the minimums & maximums. for (i = 0; i < DIM; i++) { atnMin[i] = Limits<PixelValue_t>::Min; atnHalf[i] = (Limits<PixelValue_t>::Min + Limits<PixelValue_t>::Max) / 2; atnMax[i] = Limits<PixelValue_t>::Max; } // Loop through all pixels in the root of the pixel-sorter tree, // initialize them to half the maximum value. Set up our // search-window minimum/maximum too. for (y = 0; y < PGH; ++y) { for (x = 0; x < PGW; ++x) { m_oPixelSorterMin.m_atPixels[y][x] = Pixel_t (atnMin); m_oPixelSorter.m_oSplitValue.m_atPixels[y][x] = Pixel_t (atnHalf); m_oPixelSorterMax.m_atPixels[y][x] = Pixel_t (atnMax); } } } // Finally, store our parameters. m_tnWidth = a_tnWidth; m_tnHeight = a_tnHeight; m_tnSearchRadiusX = a_tnSearchRadiusX; m_tnSearchRadiusY = a_tnSearchRadiusY; m_tnTolerance = Pixel_t::MakeTolerance (a_tnTolerance); m_tnTwiceTolerance = Pixel_t::MakeTolerance (2 * a_tnTolerance);}// Purge the pixel sorter.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>voidSearchWindow<PIXEL_NUM,DIM,PIXEL_TOL,PIXELINDEX,FRAMESIZE, PGW,PGH,SORTERBITMASK,PIXEL,REFERENCEPIXEL, REFERENCEFRAME>::PurgePixelSorter (void){ // Clear out the pixel-sorter. for (SORTERBITMASK i = 0; i < m_oPixelSorter.m_knBranches; ++i) { if (m_oPixelSorter.m_apBranches[i] != NULL) { delete m_oPixelSorter.m_apBranches[i]; m_oPixelSorter.m_apBranches[i] = NULL; } }}// 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>SearchWindow<PIXEL_NUM,DIM,PIXEL_TOL,PIXELINDEX,FRAMESIZE, PGW,PGH,SORTERBITMASK,PIXEL,REFERENCEPIXEL,REFERENCEFRAME> ::PixelGroup::PixelGroup(){ // No location yet. m_tnX = m_tnY = PIXELINDEX (0);}// 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>SearchWindow<PIXEL_NUM,DIM,PIXEL_TOL,PIXELINDEX,FRAMESIZE, PGW,PGH,SORTERBITMASK,PIXEL,REFERENCEPIXEL,REFERENCEFRAME> ::PixelGroup::~PixelGroup(){ // Nothing to do.}// Returns true if the two pixels groups are equal, within// the given tolerance.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>boolSearchWindow<PIXEL_NUM,DIM,PIXEL_TOL,PIXELINDEX,FRAMESIZE, PGW,PGH,SORTERBITMASK,PIXEL,REFERENCEPIXEL,REFERENCEFRAME> ::PixelGroup::IsWithinTolerance (const PixelGroup &a_rOther, Tolerance_t a_tnTolerance#ifdef CALCULATE_SAD , Tolerance_t &a_rtnSAD#endif // CALCULATE_SAD ) const{ PIXELINDEX tnX, tnY; // Used to loop through pixels. // Compare the two pixel groups, pixel by pixel.#ifdef CALCULATE_SAD a_rtnSAD = 0;#endif // CALCULATE_SAD for (tnY = 0; tnY < PGH; ++tnY) { for (tnX = 0; tnX < PGW; ++tnX) {#ifdef CALCULATE_SAD Tolerance_t tnSAD; // The sum-of-absolute-differences between these two // pixels.#endif // CALCULATE_SAD // Get the two pixels of interest. const Pixel_t &rThisPixel = m_atPixels[tnY][tnX]; const Pixel_t &rOtherPixel = a_rOther.m_atPixels[tnY][tnX]; // If this pixel value is not within the tolerance of // the corresponding pixel in the other group, exit now. if (!rThisPixel.IsWithinTolerance (rOtherPixel, a_tnTolerance#ifdef CALCULATE_SAD , tnSAD#endif // CALCULATE_SAD )) { return false; }#ifdef CALCULATE_SAD // Sum up the sum-of-absolute-differences. a_rtnSAD += tnSAD;#endif // CALCULATE_SAD } } // The pixel groups are equal, within the given tolerance. return true;}// 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>SearchWindow<PIXEL_NUM,DIM,PIXEL_TOL,PIXELINDEX,FRAMESIZE, PGW,PGH,SORTERBITMASK,PIXEL,REFERENCEPIXEL,REFERENCEFRAME> ::SearchWindowCell::SearchWindowCell(){ // We haven't been put into the pixel-sorter yet. m_pSorter = NULL; m_eDoneSorting = m_knNotDone;}// 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>SearchWindow<PIXEL_NUM,DIM,PIXEL_TOL,PIXELINDEX,FRAMESIZE, PGW,PGH,SORTERBITMASK,PIXEL,REFERENCEPIXEL,REFERENCEFRAME> ::SearchWindowCell::~SearchWindowCell(){ // Nothing to do.}// Begin searching through a frame.// Provide the frame to search through.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>voidSearchWindow<PIXEL_NUM,DIM,PIXEL_TOL,PIXELINDEX,FRAMESIZE, PGW,PGH,SORTERBITMASK,PIXEL,REFERENCEPIXEL, REFERENCEFRAME>::StartFrame (ReferenceFrame_t *a_pReferenceFrame){ // Make sure they gave us a frame. assert (a_pReferenceFrame != NULL); // Remember the frame we're operating on this pass. m_pReferenceFrame = a_pReferenceFrame; // We'll be checking the upper-left corner first. m_tnX = m_tnY = PIXELINDEX (0);}// Prepare for searching, i.e. find all search-window cells within the// search radius of the current pixel-group that aren't in the// pixel-sorter already, and put them there.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>voidSearchWindow<PIXEL_NUM,DIM,PIXEL_TOL,PIXELINDEX,FRAMESIZE, PGW,PGH,SORTERBITMASK,PIXEL,REFERENCEPIXEL, REFERENCEFRAME>::PrepareForSearch (Status_t &a_reStatus, bool a_bSortPixels){ PIXELINDEX tnSearchWindowPixelLeft, tnSearchWindowPixelRight, tnSearchWindowPixelTop, tnSearchWindowPixelBottom; // What the search window should look like when we're done. PIXELINDEX tnX, tnY; // Used to loop through pixel groups. PIXELINDEX tnSearchLeft, tnSearchRight, tnSearchTop, tnSearchBottom; // The part of the search window that we actually loop through. SearchWindowCell *pCell; // The search-window cell corresponding to the pixel group being // manipulated. // Make sure they didn't start us off with an error. assert (a_reStatus == g_kNoError);#ifndef OPTIONALLY_SORT_PIXEL_GROUPS // (If we're not doing the expanding-regions variant, make sure // they always want to add search-window cells to the pixel-sorter.) assert (a_bSortPixels);#endif // OPTIONALLY_SORT_PIXEL_GROUPS // Make sure we have a new frame & reference frame to work with. assert (m_pReferenceFrame != NULL); // The search window starts in a radius around the index of the // current pixel group. tnSearchWindowPixelLeft = m_tnX - m_tnSearchRadiusX; tnSearchWindowPixelRight = m_tnX + m_tnSearchRadiusX + PIXELINDEX (1);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?