iorodeo avatar iorodeo committed 4cccd84

Modified histogram and backgound median to recycle memory for histogram data
as allocating this large chunk of memory is expensive.

Comments (0)

Files changed (8)

src/gui/background_data_ufmf.cpp

     {
         unsigned int bin;
         unsigned int binValue;
+        unsigned int *binPtr = binPtr_.get();
+
         unsigned long cntTotal;
         unsigned long cntHalf;
         unsigned long cntCurrent;
-        unsigned int  *binPtr = binPtr_.get();
         unsigned long *cntPtr = cntPtr_.get();
+
+        float medianScale = float(binSize_);
+        float medianShift = (medianScale - 1.0)/2.0;
+        float medianTmp;
+
         std::shared_ptr<float> medianPtr = std::shared_ptr<float>(
                 new float[numRows_*numCols_],
                 std::default_delete<float[]>()
                 );
+
         float *medianPtrTmp = medianPtr.get();  
-        float medianTmp;
-
 
         for (unsigned int i=0; i<numRows_; i++)
         {
                     binValue = *(binPtr + j+ numCols_*i + (numRows_*numCols_)*bin);  
                     cntCurrent += binValue;
                 }
-                if ((cntTotal%2!=0) || (binValue > 1))
+
+                if ((cntTotal%2!=0) || ((cntHalf-(cntCurrent-binValue)) > 1))
                 {
                     medianTmp = float(bin);
 
                 }
+
                 else
                 {
-                    medianTmp = float(bin)-0.5;
+                    medianTmp = (float(bin)-0.5);
                 }
 
+                medianTmp = medianScale*medianTmp + medianShift;
                 *(medianPtrTmp + j + numCols_*i) = medianTmp;
 
-            }
-        }
+            } // for j
+
+        } // for i
 
         return medianPtr;
     }

src/gui/background_histogram_ufmf.cpp

 {
 
     // Temporary
-    // ---------------------------------------
+    // ------------------------------------------------
     const unsigned int DEFAULT_NUM_BINS = 256;
     const unsigned int DEFAULT_BIN_SIZE = 1;
-    // ---------------------------------------
+    const unsigned int DEFAULT_MIN_UPDATE_COUNT = 50;
+    // -------------------------------------------------
 
 
     BackgroundHistogram_ufmf::BackgroundHistogram_ufmf(QObject *parent) 
         : QObject(parent) 
     {
-        initialize(NULL,NULL);
+        initialize(NULL,NULL,NULL);
     }
 
 
     BackgroundHistogram_ufmf::BackgroundHistogram_ufmf (
             std::shared_ptr<LockableQueue<StampedImage>> bgImageQueuePtr, 
-            std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgDataQueuePtr,
+            std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgNewDataQueuePtr,
+            std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgOldDataQueuePtr,
             QObject *parent
             ) 
         : QObject(parent)
     {
-        initialize(bgImageQueuePtr, bgDataQueuePtr);
+        initialize(bgImageQueuePtr, bgNewDataQueuePtr, bgOldDataQueuePtr);
     }
 
 
     void BackgroundHistogram_ufmf::initialize( 
             std::shared_ptr<LockableQueue<StampedImage>> bgImageQueuePtr,
-            std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgDataQueuePtr
+            std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgNewDataQueuePtr,
+            std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgOldDataQueuePtr
             ) 
     {
         ready_ = false;
         stopped_ = true;
         bgImageQueuePtr_ = bgImageQueuePtr;
-        bgDataQueuePtr_ = bgDataQueuePtr;
-        if ((bgImageQueuePtr_ != NULL) && (bgDataQueuePtr_ != NULL))
+        bgNewDataQueuePtr_ = bgNewDataQueuePtr;
+        bgOldDataQueuePtr_ = bgOldDataQueuePtr;
+
+        // Make sure none of the data queue pointers are null
+        bool notNull = true;
+        notNull &= (bgImageQueuePtr_   != NULL);
+        notNull &= (bgNewDataQueuePtr_ != NULL);
+        notNull &= (bgOldDataQueuePtr_ != NULL);
+
+        if (notNull) 
         {
             ready_ = true;
         }
     { 
         bool done = false;
         bool isFirst = true;
-        unsigned long frameCount = 0;
+        unsigned long count = 0;
         BackgroundData_ufmf backgroundData;
 
         StampedImage newStampedImg;
             bgImageQueuePtr_ -> pop();
             bgImageQueuePtr_ -> releaseLock();
 
-            std::cout << "have new image" << std::endl;
+            std::cout << "* new bg image, count = " << count << std::endl;
             if (isFirst)
             {
-                // Create new Background data object
-                backgroundData = BackgroundData_ufmf(
-                        newStampedImg,
-                        DEFAULT_NUM_BINS,
-                        DEFAULT_BIN_SIZE
-                        );
+                // Create two new background data objects - put one in old data queue.
+                for (int i=0; i<2; i++) 
+                {
+                    backgroundData = BackgroundData_ufmf(
+                            newStampedImg,
+                            DEFAULT_NUM_BINS,
+                            DEFAULT_BIN_SIZE
+                            );
+                    if (i==0)
+                    {
+                        bgOldDataQueuePtr_ -> acquireLock();
+                        bgOldDataQueuePtr_ -> push(backgroundData);
+                        bgOldDataQueuePtr_ -> releaseLock();
+                    }
+                }
+
                 isFirst = false;
             }
 
             // Add image to background data
             backgroundData.addImage(newStampedImg);
+            count++;
+
+            // Check to see if median computation is done if so swap the buffers
+            if (count > DEFAULT_MIN_UPDATE_COUNT)
+            {
+                bool swapDataFlag = false;
+                BackgroundData_ufmf backgroundDataTmp;
+
+                bgOldDataQueuePtr_ -> acquireLock();
+                if (!(bgOldDataQueuePtr_ -> empty()))
+                {
+                    backgroundDataTmp = bgOldDataQueuePtr_ -> front();
+                    bgOldDataQueuePtr_ -> pop();
+                    swapDataFlag = true;
+                }
+                bgOldDataQueuePtr_ -> releaseLock();
+
+                if (swapDataFlag)
+                {
+                    bgNewDataQueuePtr_ -> acquireLock();
+                    bgNewDataQueuePtr_ -> push(backgroundData);
+                    bgNewDataQueuePtr_ -> signalNotEmpty();
+                    bgNewDataQueuePtr_ -> releaseLock();
+                    backgroundData = backgroundDataTmp;
+                    count = 0;
+                }
+            }
 
             acquireLock();
             done = stopped_;

src/gui/background_histogram_ufmf.hpp

             BackgroundHistogram_ufmf(QObject *parent=0);
             BackgroundHistogram_ufmf(
                     std::shared_ptr<LockableQueue<StampedImage>> bgImageQueuePtr, 
-                    std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgDataQueuePtr,
+                    std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgNewDataQueuePtr,
+                    std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgOldDataQueuePtr,
                     QObject *parent=0
                     );
             void initialize(
                     std::shared_ptr<LockableQueue<StampedImage>> bgImageQueuePtr,
-                    std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgDataQueuePtr
+                    std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgNewDataQueuePtr,
+                    std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgOldDataQueuePtr
                     );
             void stop();
 
         private:
+
             bool ready_;
             bool stopped_;
 
             // Queue of incoming images for background model
             std::shared_ptr<LockableQueue<StampedImage>> bgImageQueuePtr_;       
 
-            // Queue of outgoing background data for median calculation
-            std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgDataQueuePtr_;
+            // Queue of outgoing and incoming background data for median calculations
+            std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgNewDataQueuePtr_;
+            std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgOldDataQueuePtr_;
 
             void run();
     };

src/gui/background_median_ufmf.cpp

     BackgroundMedian_ufmf::BackgroundMedian_ufmf(QObject *parent)
         : QObject(parent)
     { 
-        initialize(NULL);
+        initialize(NULL,NULL);
     }
 
 
     BackgroundMedian_ufmf::BackgroundMedian_ufmf( 
-            std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgDataQueuePtr,
+            std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgNewDataQueuePtr,
+            std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgOldDataQueuePtr,
             QObject *parent
             ) 
         : QObject(parent)
     {
-        initialize(bgDataQueuePtr);
+        initialize(bgNewDataQueuePtr,bgOldDataQueuePtr);
     }
 
 
     void BackgroundMedian_ufmf::initialize(
-            std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgDataQueuePtr
+            std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgNewDataQueuePtr,
+            std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgOldDataQueuePtr
             )
     {
         ready_ = false;
         stopped_ = true;
-        bgDataQueuePtr_ = bgDataQueuePtr;
-        if (bgDataQueuePtr_ != NULL)
+        bgNewDataQueuePtr_ = bgNewDataQueuePtr;
+        bgOldDataQueuePtr_ = bgOldDataQueuePtr;
+        if ((bgNewDataQueuePtr_ != NULL) && (bgOldDataQueuePtr_))
         {
             ready_ = true;
         }
         bool done = false;
         bool isFirst = true;
         BackgroundData_ufmf backgroundData;
+        std::shared_ptr<float> medianData;
 
         if (!ready_) 
         { 
         while(!done)
         {
             // Grab background data from queue
-            bgDataQueuePtr_ -> acquireLock();
-            bgDataQueuePtr_ -> waitIfEmpty();
-            if (bgDataQueuePtr_ -> empty())
+            bgNewDataQueuePtr_ -> acquireLock();
+            bgNewDataQueuePtr_ -> waitIfEmpty();
+            if (bgNewDataQueuePtr_ -> empty())
             {
-                bgDataQueuePtr_ -> releaseLock();
+                bgNewDataQueuePtr_ -> releaseLock();
                 break;
             }
-            backgroundData = bgDataQueuePtr_ -> front();
-            bgDataQueuePtr_ -> pop();
-            bgDataQueuePtr_ -> releaseLock();
+            backgroundData = bgNewDataQueuePtr_ -> front();
+            bgNewDataQueuePtr_ -> pop();
+            bgNewDataQueuePtr_ -> releaseLock();
 
-            std::cout << "background median - have new data" << std::endl;
+            std::cout << "*** new median data" << std::endl;
+
+            // Compute median
+            medianData = backgroundData.getMedians();
+
+
+            // Put data back into outgoing queue 
+            bgOldDataQueuePtr_ -> acquireLock();
+            bgOldDataQueuePtr_ -> push(backgroundData);
+            bgOldDataQueuePtr_ -> releaseLock();
+
 
             acquireLock();
             done = stopped_;

src/gui/background_median_ufmf.hpp

         public:
             BackgroundMedian_ufmf(QObject *parent=0);
             BackgroundMedian_ufmf( 
-                    std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgDataQueuePtr,
+                    std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgNewDataQueuePtr,
+                    std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgOldDataQueuePtr,
                     QObject *parent=0
                     );
             void initialize(
-                    std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgDataQueuePtr
+                    std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgNewDataQueuePtr,
+                    std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgOldDataQueuePtr
                     );
             void stop();
 
         private:
             bool ready_;
             bool stopped_;
-            // Queue of incoming background data for median calculation
-            std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgDataQueuePtr_;
+            // Queues of incoming and outgoing background data for median calculation
+            std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgNewDataQueuePtr_;
+            std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgOldDataQueuePtr_;
 
             void run();
 

src/gui/image_logger.cpp

             logImageQueuePtr_ -> releaseLock();
 
             frameCount_++;
+            //std::cout << "logger frame count = " << frameCount_ << std::endl;
 
             if (!errorFlag) 
             {
                     emit imageLoggingError(errorId, errorMsg);
                     errorFlag = true;
                 }
-                std::cout << "queue size: " << logQueueSize << std::endl;
+                //std::cout << "queue size: " << logQueueSize << std::endl;
 
                 // Add frame to video writer
                 try 

src/gui/video_writer_ufmf.cpp

 
         // Create queue for images sent to background modeler
         bgImageQueuePtr_ = std::make_shared<LockableQueue<StampedImage>>();
-        bgDataQueuePtr_ = std::make_shared<LockableQueue<BackgroundData_ufmf>>();
+        bgNewDataQueuePtr_ = std::make_shared<LockableQueue<BackgroundData_ufmf>>();
+        bgOldDataQueuePtr_ = std::make_shared<LockableQueue<BackgroundData_ufmf>>();
     }
 
 
         // Process frame on every frame count divisible by the frame skip parameter
         if (frameCount_%frameSkip_==0)
         {
-
-            //std::cout << "video writer processing frame" << std::endl;
-
             // Add frame to background image queue if it is empty 
             bgImageQueuePtr_ -> acquireLock();
             if (bgImageQueuePtr_ -> empty())
 
     void VideoWriter_ufmf::checkImageFormat(StampedImage stampedImg)
     {
-        std::cout << __PRETTY_FUNCTION__ <<  std::endl;
-        // Check that  image format is suitable
         if (stampedImg.image.channels() != 1)
         {
             unsigned int errorId = ERROR_VIDEO_WRITER_INITIALIZE;
 
     void VideoWriter_ufmf::setupOutput(StampedImage stampedImg) 
     {
-        std::cout << __PRETTY_FUNCTION__ <<  std::endl;
         size_ = stampedImg.image.size();
     }
 
 
     void VideoWriter_ufmf::startBackgroundModeling()
     {
-        std::cout << __PRETTY_FUNCTION__ <<  std::endl;
-
         bgImageQueuePtr_ -> clear();
-        bgDataQueuePtr_ -> clear();
+        bgNewDataQueuePtr_ -> clear();
+        bgOldDataQueuePtr_ -> clear();
 
         bgHistogramPtr_ = new BackgroundHistogram_ufmf(
                 bgImageQueuePtr_,
-                bgDataQueuePtr_
+                bgNewDataQueuePtr_,
+                bgOldDataQueuePtr_
                 );
 
         bgMedianPtr_ = new BackgroundMedian_ufmf(
-                bgDataQueuePtr_
+                bgNewDataQueuePtr_,
+                bgOldDataQueuePtr_
                 );
 
         threadPoolPtr_ -> start(bgHistogramPtr_);
 
     void VideoWriter_ufmf::stopBackgroundModeling()
     {
-        std::cout << __PRETTY_FUNCTION__ << std::endl;
-
         // Signal for background modeling threads to stop
         if (!bgMedianPtr_.isNull())
         {
             bgMedianPtr_ -> stop();
             bgMedianPtr_ -> releaseLock();
 
-            // Not sure is this is right
-            bgDataQueuePtr_ -> acquireLock();
-            bgDataQueuePtr_ -> signalNotEmpty();
-            bgDataQueuePtr_ -> releaseLock();
+            bgNewDataQueuePtr_ -> acquireLock();
+            bgNewDataQueuePtr_ -> signalNotEmpty();
+            bgNewDataQueuePtr_ -> releaseLock();
         }
 
         if (!bgHistogramPtr_.isNull()) 
             bgHistogramPtr_ -> stop();
             bgHistogramPtr_ -> releaseLock();
 
-            // Not sure if ths is right
             bgImageQueuePtr_ -> acquireLock();
             bgImageQueuePtr_ -> signalNotEmpty();
             bgImageQueuePtr_ -> releaseLock();

src/gui/video_writer_ufmf.hpp

             QPointer<BackgroundHistogram_ufmf> bgHistogramPtr_;
             QPointer<BackgroundMedian_ufmf> bgMedianPtr_;
             std::shared_ptr<LockableQueue<StampedImage>> bgImageQueuePtr_;
-            std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgDataQueuePtr_;
+            std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgNewDataQueuePtr_;
+            std::shared_ptr<LockableQueue<BackgroundData_ufmf>> bgOldDataQueuePtr_;
 
             void checkImageFormat(StampedImage stampedImg);
             void setupOutput(StampedImage stampedImg);
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.