Code

Applied patch #1501375
authorjoncruz <joncruz@users.sourceforge.net>
Tue, 6 Jun 2006 04:37:22 +0000 (04:37 +0000)
committerjoncruz <joncruz@users.sourceforge.net>
Tue, 6 Jun 2006 04:37:22 +0000 (04:37 +0000)
ChangeLog
src/trace/siox.cpp
src/trace/siox.h
src/trace/trace.cpp
src/ui/dialog/tracedialog.cpp

index f2db872f48d2476143d1973d9180099fff8ada78..c2622d5e4b867982e6e49d82a17eb438a2e90773 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2006-06-05  Jon A. Cruz  <jon@joncruz.org>
+
+       * trace/siox.cpp, trace/siox.h, trace/trace.cpp,
+         src/ui/dialog/tracedialog.cpp:
+
+         Applied patch #1501375.
+
 2006-06-05  Jon A. Cruz  <jon@joncruz.org>
 
        * trace/siox.cpp, trace/trace.cpp:
index 752a14460d5d5578ab3d49f02b369d31522a6f53..b0632567cfc65c4aaecdff4f8d2d31deee9a9e55 100644 (file)
@@ -655,9 +655,19 @@ const float Siox::CERTAIN_BACKGROUND_CONFIDENCE=0.0f;
  */
 Siox::Siox()
 {
+    sioxObserver = NULL;
     init();
 }
 
+/**
+ *  Construct a Siox engine
+ */
+Siox::Siox(SioxObserver *observer)
+{
+    init();
+    sioxObserver = observer;
+}
+
 
 /**
  *
@@ -704,6 +714,27 @@ void Siox::trace(char *fmt, ...)
 
 
 
+/**
+ * Progress reporting
+ */
+bool Siox::progressReport(float percentCompleted)
+{
+    if (!sioxObserver)
+        return true;
+
+    bool ret = sioxObserver->progress(percentCompleted);
+
+    if (!ret)
+      {
+      trace("User selected abort");
+      keepGoing = false;
+      }
+
+    return ret;
+}
+
+
+
 
 /**
  *  Extract the foreground of the original image, according
@@ -713,6 +744,7 @@ SioxImage Siox::extractForeground(const SioxImage &originalImage,
                                   unsigned int backgroundFillColor)
 {
     init();
+    keepGoing = true;
 
     SioxImage workImage = originalImage;
 
@@ -729,17 +761,28 @@ SioxImage Siox::extractForeground(const SioxImage &originalImage,
     //#### create color signatures
     std::vector<CLAB> knownBg;
     std::vector<CLAB> knownFg;
-    for (int x = 0 ; x < workImage.getWidth() ; x++)
-        for (int y = 0 ; y < workImage.getHeight() ; y++)
+    std::vector<CLAB> imageClab;
+    for (int y = 0 ; y < workImage.getHeight() ; y++)
+        for (int x = 0 ; x < workImage.getWidth() ; x++)
             {
             float cm = workImage.getConfidence(x, y);
             unsigned int pix = workImage.getPixel(x, y);
+            CLAB lab(pix);
+            imageClab.push_back(lab);
             if (cm <= BACKGROUND_CONFIDENCE)
-                knownBg.push_back(pix); //note: uses CLAB(rgb)
+                knownBg.push_back(lab); //note: uses CLAB(rgb)
             else if (cm >= FOREGROUND_CONFIDENCE)
-                knownFg.push_back(pix);
+                knownFg.push_back(lab);
             }
 
+    if (!progressReport(10.0))
+        {
+        error("User aborted");
+        workImage.setValid(false);
+        delete[] labelField;
+        return workImage;
+        }
+
     trace("knownBg:%d knownFg:%d", knownBg.size(), knownFg.size());
 
 
@@ -748,14 +791,25 @@ SioxImage Siox::extractForeground(const SioxImage &originalImage,
         {
         error("Could not create background signature");
         workImage.setValid(false);
+        delete[] labelField;
+        return workImage;
+        }
+
+    if (!progressReport(30.0))
+        {
+        error("User aborted");
+        workImage.setValid(false);
+        delete[] labelField;
         return workImage;
         }
+
+
     std::vector<CLAB> fgSignature ;
     if (!colorSignature(knownFg, fgSignature, 3))
         {
         error("Could not create foreground signature");
-        delete[] labelField;
         workImage.setValid(false);
+        delete[] labelField;
         return workImage;
         }
 
@@ -765,17 +819,41 @@ SioxImage Siox::extractForeground(const SioxImage &originalImage,
         {
         // segmentation impossible
         error("Signature size is < 1.  Segmentation is impossible");
+        workImage.setValid(false);
         delete[] labelField;
+        return workImage;
+        }
+
+    if (!progressReport(30.0))
+        {
+        error("User aborted");
         workImage.setValid(false);
+        delete[] labelField;
         return workImage;
         }
 
+
     // classify using color signatures,
     // classification cached in hashmap for drb and speedup purposes
     std::map<unsigned int, Tupel> hs;
+    
+    unsigned int progressResolution = pixelCount / 10;
 
     for (unsigned int i=0; i<pixelCount; i++)
         {
+        if (i % progressResolution == 0)
+            {
+            float progress = 
+                30.0 + 60.0 * (float)i / (float)progressResolution;
+            if (!progressReport(progress))
+                {
+                error("User aborted");
+                delete[] labelField;
+                workImage.setValid(false);
+                return workImage;
+                }
+            }
+
         if (cm[i] >= FOREGROUND_CONFIDENCE)
             {
             cm[i] = CERTAIN_FOREGROUND_CONFIDENCE;
@@ -795,7 +873,7 @@ SioxImage Siox::extractForeground(const SioxImage &originalImage,
                 }
             else
                 {
-                CLAB lab(image[i]);
+                CLAB lab = imageClab[i];
                 float minBg = sqrEuclidianDist(lab, bgSignature[0]);
                 int minIndex=0;
                 for (unsigned int j=1; j<bgSignature.size() ; j++)
@@ -846,8 +924,11 @@ SioxImage Siox::extractForeground(const SioxImage &originalImage,
             }
         }
 
+
+
     trace("### postProcessing");
 
+
     //## postprocessing
     smooth(cm, width, height, 0.33f, 0.33f, 0.33f); // average
     normalizeMatrix(cm, pixelCount);
@@ -871,7 +952,14 @@ SioxImage Siox::extractForeground(const SioxImage &originalImage,
     fillColorRegions();
     dilate(cm, width, height);
 
-    delete[] labelField;
+    if (!progressReport(100.0))
+        {
+        error("User aborted");
+        delete[] labelField;
+        workImage.setValid(false);
+        return workImage;
+        }
+
 
     //#### Yaay.  We are done.  Now clear everything but the background
     for (unsigned int y = 0 ; y < height ; y++)
@@ -884,7 +972,10 @@ SioxImage Siox::extractForeground(const SioxImage &originalImage,
                 }
             }
 
+    delete[] labelField;
+
     trace("### Done");
+    keepGoing = false;
     return workImage;
 }
 
index ba85f0fa63be9c62e99f27b3c7491c1cab598f4b..0dbf76a8e0e187b8ea28bc0c5e49b70535519595 100644 (file)
@@ -341,6 +341,56 @@ private:
 
 
 
+//########################################################################
+//#  S I O X    O B S E R V E R
+//########################################################################
+class Siox;
+
+/**
+ *  This is a class for observing the progress of a Siox engine.  Overload
+ *  the methods in your subclass to get the desired behaviour.
+ */
+class SioxObserver
+{
+public:
+
+    /**
+     *  Constructor.  Context can point to anything, and is usually
+     *  used to point to a C++ object or C state object, to delegate
+     *  callback processing to something else.  Use NULL to ignore.
+     */
+    SioxObserver(void *contextArg) : context(NULL)
+        { context = contextArg; }
+
+    /**
+     *  Destructor
+     */
+    virtual ~SioxObserver()
+        { }
+
+    /**
+     *  Informs the observer how much has been completed.
+     *  Return false if the processing should be aborted.
+     */
+    virtual bool progress(float percentCompleted)
+        {
+        return true;
+        }
+
+    /**
+     *  Send an error string to the Observer.  Processing will
+     *  be halted.
+     */
+    virtual void error(const std::string &msg)
+        {
+        }
+
+protected:
+
+    void *context;
+
+};
+
 
 
 //########################################################################
@@ -384,6 +434,11 @@ public:
      */
     Siox();
 
+    /**
+     *  Construct a Siox engine.  Use null to ignore
+     */
+    Siox(SioxObserver *observer);
+
     /**
      *
      */
@@ -401,6 +456,18 @@ public:
 
 private:
 
+    SioxObserver *sioxObserver;
+
+    /**
+     * Progress reporting
+     */
+    bool progressReport(float percentCompleted);
+
+    /**
+     * Flag this as false during processing to abort
+     */
+    bool keepGoing;
+
     /**
      * Our signature limits
      */
index 408f5c5c3b988ef4e640817750a974240367da38..8e31265013f011b2b4f7634b3cb614d01df673e8 100644 (file)
@@ -19,6 +19,7 @@
 #include <desktop-handles.h>
 #include <document.h>
 #include <message-stack.h>
+#include <gtkmm.h>
 #include <glibmm/i18n.h>
 #include <selection.h>
 #include <xml/repr.h>
@@ -57,7 +58,7 @@ Tracer::getSelectedSPImage()
     SPDesktop *desktop = SP_ACTIVE_DESKTOP;
     if (!desktop)
         {
-        g_warning("Trace: No active desktop\n");
+        g_warning("Trace: No active desktop");
         return NULL;
         }
 
@@ -155,8 +156,61 @@ Tracer::getSelectedSPImage()
 
 
 typedef org::siox::SioxImage SioxImage;
+typedef org::siox::SioxObserver SioxObserver;
 typedef org::siox::Siox Siox;
 
+
+class TraceSioxObserver : public SioxObserver
+{
+public:
+
+    /**
+     *
+     */
+    TraceSioxObserver (void *contextArg) :
+                     SioxObserver(contextArg)
+        {}
+
+    /**
+     *
+     */
+    virtual ~TraceSioxObserver ()
+        { }
+
+    /**
+     *  Informs the observer how much has been completed.
+     *  Return false if the processing should be aborted.
+     */
+    virtual bool progress(float percentCompleted)
+        {
+        //Tracer *tracer = (Tracer *)context;
+        //## Allow the GUI to update
+        Gtk::Main::iteration(false); //at least once, non-blocking
+        while( Gtk::Main::events_pending() )
+            Gtk::Main::iteration();
+        return true;
+        }
+
+    /**
+     *  Send an error string to the Observer.  Processing will
+     *  be halted.
+     */
+    virtual void error(const std::string &msg)
+        {
+        //Tracer *tracer = (Tracer *)context;
+        }
+
+
+};
+
+
+
+
+
+/**
+ * Process a GdkPixbuf, according to which areas have been
+ * obscured in the GUI.
+ */
 GdkPixbuf *
 Tracer::sioxProcessImage(SPImage *img, GdkPixbuf *origPixbuf)
 {
@@ -213,8 +267,8 @@ Tracer::sioxProcessImage(SPImage *img, GdkPixbuf *origPixbuf)
         }
     //g_message("%d arena items\n", arenaItems.size());
 
-    PackedPixelMap *dumpMap = PackedPixelMapCreate(
-                    simage.getWidth(), simage.getHeight());
+    //PackedPixelMap *dumpMap = PackedPixelMapCreate(
+    //                simage.getWidth(), simage.getHeight());
 
     for (int row=0 ; row<simage.getHeight() ; row++)
         {
@@ -246,14 +300,14 @@ Tracer::sioxProcessImage(SPImage *img, GdkPixbuf *origPixbuf)
             if (weHaveAHit)
                 {
                 //g_message("hit!\n");
-                dumpMap->setPixelLong(dumpMap, col, row, 0L);
+                //dumpMap->setPixelLong(dumpMap, col, row, 0L);
                 simage.setConfidence(col, row, 
                         Siox::UNKNOWN_REGION_CONFIDENCE);
                 }
             else
                 {
-                dumpMap->setPixelLong(dumpMap, col, row,
-                        simage.getPixel(col, row));
+                //dumpMap->setPixelLong(dumpMap, col, row,
+                //        simage.getPixel(col, row));
                 simage.setConfidence(col, row,
                         Siox::CERTAIN_BACKGROUND_CONFIDENCE);
                 }
@@ -261,7 +315,7 @@ Tracer::sioxProcessImage(SPImage *img, GdkPixbuf *origPixbuf)
         }
 
     //dumpMap->writePPM(dumpMap, "siox1.ppm");
-    dumpMap->destroy(dumpMap);
+    //dumpMap->destroy(dumpMap);
 
     //## ok we have our pixel buf
     org::siox::Siox sengine;
index 4bfb66f3dfdced3de13ac9201c66a39e2420b0c5..b79d0f0e6241625578572902fd555e0567f5e211 100644 (file)
@@ -343,7 +343,7 @@ TraceDialogImpl::TraceDialogImpl()
 
     /*#### SIOX ####*/
     //# for now, put at the top of the potrace box.  something better later
-    sioxButton.set_label(_("SIOX foreground selection"));
+    sioxButton.set_label(_("SIOX foreground selection (experimental)"));
     sioxBox.pack_start(sioxButton, false, false, MARGIN);
     tips.set_tip(sioxButton, 
         _("Cover the area you want to select as the foreground"));