Code

WIP. siox election progress. fix api a bit.
authorishmal <ishmal@users.sourceforge.net>
Thu, 30 Mar 2006 12:13:29 +0000 (12:13 +0000)
committerishmal <ishmal@users.sourceforge.net>
Thu, 30 Mar 2006 12:13:29 +0000 (12:13 +0000)
src/trace/siox.cpp
src/trace/siox.h
src/trace/trace.cpp

index be1dd399537fc3948771caf117d0171beafffb29..7975d940066516578d56c68f833d073ce2be5c42 100644 (file)
@@ -949,7 +949,9 @@ SioxSegmentator::SioxSegmentator(int w, int h, float *limitsArg, int limitsSize)
 
     imgWidth   = w;
     imgHeight  = h;
-    labelField = new int[imgWidth*imgHeight];
+    pixelCount = imgWidth * imgHeight;
+
+    labelField = new int[pixelCount];
 
     if (!limitsArg) {
         limits = new float[3];
@@ -1009,8 +1011,8 @@ void SioxSegmentator::trace(char *fmt, ...)
 
 
 
-bool SioxSegmentator::segmentate(unsigned long *image, int imageSize,
-                                 float *cm, int cmSize,
+bool SioxSegmentator::segmentate(unsigned long *image,
+                                 float *cm,
                                  int smoothness, double sizeFactorToKeep)
 {
     segmentated=false;
@@ -1018,12 +1020,12 @@ bool SioxSegmentator::segmentate(unsigned long *image, int imageSize,
     hs.clear();
 
     // save image for drb
-    origImage=new long[imageSize];
-    for (int i=0 ; i<imageSize ; i++)
+    origImage=new long[pixelCount];
+    for (int i=0 ; i<pixelCount ; i++)
         origImage[i] = image[i];
 
     // create color signatures
-    for (int i=0; i<cmSize; i++) {
+    for (int i=0; i<pixelCount; i++) {
         if (cm[i]<=BACKGROUND_CONFIDENCE)
             knownBg.push_back(rgbToClab(image[i]));
         else if (cm[i]>=FOREGROUND_CONFIDENCE)
@@ -1040,7 +1042,7 @@ bool SioxSegmentator::segmentate(unsigned long *image, int imageSize,
 
     // classify using color signatures,
     // classification cached in hashmap for drb and speedup purposes
-    for (int i=0; i<cmSize; i++) {
+    for (int i=0; i<pixelCount; i++) {
         if (cm[i]>=FOREGROUND_CONFIDENCE) {
             cm[i]=CERTAIN_FOREGROUND_CONFIDENCE;
             continue;
@@ -1097,17 +1099,17 @@ bool SioxSegmentator::segmentate(unsigned long *image, int imageSize,
 
     // postprocessing
     smoothcm(cm, imgWidth, imgHeight, 0.33f, 0.33f, 0.33f); // average
-    normalizeMatrix(cm, cmSize);
+    normalizeMatrix(cm, pixelCount);
     erode(cm, imgWidth, imgHeight);
-    keepOnlyLargeComponents(cm, cmSize, UNKNOWN_REGION_CONFIDENCE, sizeFactorToKeep);
+    keepOnlyLargeComponents(cm, UNKNOWN_REGION_CONFIDENCE, sizeFactorToKeep);
 
     for (int i=0; i<smoothness; i++) {
         smoothcm(cm, imgWidth, imgHeight, 0.33f, 0.33f, 0.33f); // average
     }
 
-    normalizeMatrix(cm, cmSize);
+    normalizeMatrix(cm, pixelCount);
 
-    for (int i=0; i<cmSize; i++) {
+    for (int i=0; i<pixelCount; i++) {
         if (cm[i]>=UNKNOWN_REGION_CONFIDENCE) {
             cm[i]=CERTAIN_FOREGROUND_CONFIDENCE;
         } else {
@@ -1115,8 +1117,8 @@ bool SioxSegmentator::segmentate(unsigned long *image, int imageSize,
         }
     }
 
-    keepOnlyLargeComponents(cm, cmSize, UNKNOWN_REGION_CONFIDENCE, sizeFactorToKeep);
-    fillColorRegions(cm, cmSize, image);
+    keepOnlyLargeComponents(cm, UNKNOWN_REGION_CONFIDENCE, sizeFactorToKeep);
+    fillColorRegions(cm, image);
     dilate(cm, imgWidth, imgHeight);
 
     segmentated=true;
@@ -1125,7 +1127,7 @@ bool SioxSegmentator::segmentate(unsigned long *image, int imageSize,
 
 
 
-void SioxSegmentator::keepOnlyLargeComponents(float *cm, int cmSize,
+void SioxSegmentator::keepOnlyLargeComponents(float *cm,
                                               float threshold,
                                               double sizeFactorToKeep)
 {
@@ -1140,7 +1142,7 @@ void SioxSegmentator::keepOnlyLargeComponents(float *cm, int cmSize,
 
     // slow but easy to understand:
     std::vector<int> labelSizes;
-    for (int i=0 ; i<cmSize ; i++) {
+    for (int i=0 ; i<pixelCount ; i++) {
         regionCount=0;
         if (labelField[i]==-1 && cm[i]>=threshold) {
             regionCount=depthFirstSearch(cm, i, threshold, curlabel++);
@@ -1153,7 +1155,7 @@ void SioxSegmentator::keepOnlyLargeComponents(float *cm, int cmSize,
         }
     }
 
-    for (int i=0 ; i<cmSize ; i++) {
+    for (int i=0 ; i<pixelCount ; i++) {
         if (labelField[i]!=-1) {
             // remove if the component is to small
             if (labelSizes[labelField[i]]*sizeFactorToKeep < maxregion)
@@ -1301,7 +1303,7 @@ bool SioxSegmentator::subpixelRefine(int xa, int ya, int dx, int dy,
 
 
 
-void SioxSegmentator::fillColorRegions(float *cm, int cmSize, unsigned long *image)
+void SioxSegmentator::fillColorRegions(float *cm, unsigned long *image)
 {
     int idx = 0;
     for (int i=0 ; i<imgHeight ; i++)
@@ -1310,7 +1312,7 @@ void SioxSegmentator::fillColorRegions(float *cm, int cmSize, unsigned long *ima
 
     //int maxRegion=0; // unused now
     std::vector<int> pixelsToVisit;
-    for (int i=0; i<cmSize; i++) { // for all pixels
+    for (int i=0; i<pixelCount; i++) { // for all pixels
         if (labelField[i]!=-1 || cm[i]<UNKNOWN_REGION_CONFIDENCE) {
             continue; // already visited or bg
         }
index d6efbfba1de0c4195bfb2312731f5869ddb384dd..5d36a71f660e13540fdbe80fc84ca506d58f0266 100644 (file)
@@ -205,18 +205,17 @@ public:
      *
      * @param image Pixel data of the image to be segmentated.
      *        Every integer represents one ARGB-value.
-     * @param imageSize number of values in image
      * @param cm Confidence matrix specifying the probability of an image
      *        belonging to the foreground before and after the segmentation.
      * @param smoothness Number of smoothing steps in the post processing.
+     *        Both arrays should be width * height in size.
      * @param sizeFactorToKeep Segmentation retains the largest connected
      *        foreground component plus any component with size at least
      *        <CODE>sizeOfLargestComponent/sizeFactorToKeep</CODE>.
      * @return <CODE>true</CODE> if the segmentation algorithm succeeded,
      *         <CODE>false</CODE> if segmentation is impossible
      */
-    bool segmentate(unsigned long *image, int imageSize,
-                    float *cm, int cmSize,
+    bool segmentate(unsigned long *image, float *cm,
                     int smoothness, double sizeFactorToKeep);
 
     /**
@@ -232,7 +231,7 @@ public:
      *        component plus any component with size at least
      *        <CODE>sizeOfLargestComponent/sizeFactorToKeep</CODE>.
      */
-    void keepOnlyLargeComponents(float *cm, int cmSize,
+    void keepOnlyLargeComponents(float *cm,
                                  float threshold,
                                  double sizeFactorToKeep);
 
@@ -316,7 +315,7 @@ public:
      * @param cm confidence matrix to be searched
      * @param image image to be searched
      */
-    void fillColorRegions(float *cm, int cmSize, unsigned long *image);
+    void fillColorRegions(float *cm, unsigned long *image);
 
 private:
 
@@ -345,6 +344,11 @@ private:
     /** Vertical resolution of the image to be segmentated. */
     int imgHeight;
 
+    /** Number of pixels and/or confidence matrix values to process.
+        equal to imgWidth * imgHeight
+    */
+    long pixelCount;
+
     /** Stores component label (index) by pixel it belongs to. */
     int *labelField;
 
index 2e46dd854fba8789f826d11a197e4b1635796b5d..a0dbad9fdf3716454c43d98809e338f34a48b2b6 100644 (file)
@@ -26,7 +26,9 @@
 #include <sp-item.h>
 #include <sp-shape.h>
 #include <sp-image.h>
-#include <splivarot.h> //for intersection boolop
+
+#include <display/nr-arena.h>
+#include <display/nr-arena-shape.h>
 
 #include "siox.h"
 #include "imagemap-gdk.h"
@@ -35,6 +37,100 @@ namespace Inkscape {
 
 namespace Trace {
 
+
+
+/*
+static PackedPixelMap *
+renderToPackedPixelMap(SPDocument *doc, std::vector<SPItem *> items)
+{
+
+    double minX =  1.0e6;
+    double minY =  1.0e6;
+    double maxX = -1.0e6;
+    double maxY = -1.0e6;
+    for (int i=0 ; i<items.size() ; i++)
+        {
+        SPItem *item = items[i];
+        if (item->bbox.x0 < minX)
+            minX = item->bbox.x0;
+        if (item->bbox.y0 < minY)
+            minY = item->bbox.y0;
+        if (item->bbox.x1 > maxX)
+            maxX = item->bbox.x1;
+        if (item->bbox.y1 > maxY)
+            maxY = item->bbox.x1;
+        }
+
+    double dwidth  = maxX - minX;
+    double dheight = maxY - minY;
+
+    NRRectL bbox;
+    bbox.x0 = 0;
+    bbox.y0 = 0;
+    bbox.x1 = 256;
+    bbox.y1 = (int) ( 256.0 * dwidth / dheight );
+
+
+    NRArena *arena = NRArena::create();
+    unsigned dkey = sp_item_display_key_new(1);
+
+    // Create ArenaItems and set transform
+    NRArenaItem *root = sp_item_invoke_show(SP_ITEM(sp_document_root(doc)),
+            arena, dkey, SP_ITEM_SHOW_DISPLAY);
+    nr_arena_item_set_transform(root, NR::Matrix(&affine));
+
+    NRPixBlock pb;
+    nr_pixblock_setup(&pb, NR_PIXBLOCK_MODE_R8G8B8A8N,
+                      minX, minY, maxX, maxY, true);
+
+    //fill in background
+    for (int row = 0; row < bbox.y1; row++)
+        {
+        guchar *p = NR_PIXBLOCK_PX(&pb) + row * bbox.x1;
+        for (int col = 0; col < bbox.x1; col++)
+            {
+            *p++ = ebp->r;
+            *p++ = ebp->g;
+            *p++ = ebp->b;
+            *p++ = ebp->a;
+            }
+        }
+
+    // Render
+    nr_arena_item_invoke_render(root, &bbox, &pb, 0);
+
+    for (int r = 0; r < num_rows; r++) {
+        rows[r] = NR_PIXBLOCK_PX(&pb) + r * pb.rs;
+    }
+
+    //## Make an packed pixel map
+    PackedPixelMap *ppMap = PackedPixelMapCreate(bbox.x1, bbox.y1);
+    for (int row = 0; row < bbox.y1; row++)
+        {
+        guchar *p = NR_PIXBLOCK_PX(&pb) + row * bbox.x1;
+        for (int col = 0; col < bbox.x1; col++)
+            {
+            int r = *p++;
+            int g = *p++;
+            int b = *p++;
+            int a = *p++;
+            ppMap->setPixelValue(ppMap, col, row, r, g, b);
+            }
+        }
+
+    //## Free allocated things
+    nr_pixblock_release(&pb);
+    nr_arena_item_unref(root);
+    nr_object_unref((NRObject *) arena);
+
+
+    return ppMap;
+}
+*/
+
+
+
+
 /**
  *
  */
@@ -92,7 +188,7 @@ Tracer::getSelectedSPImage()
                     }
                 img = SP_IMAGE(item);
                 }
-            else if (img) //# items -after- the image in tree (above it in Z)
+            else // if (img) //# items -after- the image in tree (above it in Z)
                 {
                 if (SP_IS_SHAPE(item))
                     {
@@ -160,6 +256,8 @@ GdkPixbuf *
 Tracer::sioxProcessImage(SPImage *img, GdkPixbuf *origPixbuf)
 {
 
+    //Convert from gdk, so a format we know.  By design, the pixel
+    //format in PackedPixelMap is identical to what is needed by SIOX
     PackedPixelMap *ppMap = gdkPixbufToPackedPixelMap(origPixbuf);
     //We need to create two things:
     //  1.  An array of long pixel values of ARGB
@@ -167,6 +265,22 @@ Tracer::sioxProcessImage(SPImage *img, GdkPixbuf *origPixbuf)
     unsigned long *imgBuf = ppMap->pixels;
     float *confidenceMatrix = new float[ppMap->width * ppMap->height];
 
+    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+    if (!desktop)
+        {
+        g_warning("Trace: No active desktop\n");
+        return NULL;
+        }
+
+    Inkscape::Selection *sel = SP_DT_SELECTION(desktop);
+    if (!sel)
+        {
+        char *msg = _("Select an <b>image</b> to trace");
+        SP_DT_MSGSTACK(desktop)->flash(Inkscape::ERROR_MESSAGE, msg);
+        //g_warning(msg);
+        return NULL;
+        }
+
     Inkscape::XML::Node *imgRepr = SP_OBJECT(img)->repr;
     /*
     //## Make a Rect overlaying the image
@@ -209,9 +323,26 @@ Tracer::sioxProcessImage(SPImage *img, GdkPixbuf *origPixbuf)
     double iwscale = width  / iwidth;
     double ihscale = height / iheight;
 
-    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
-
     unsigned long cmIndex = 0;
+
+    /* Create new arena */
+    NRArena *arena = NRArena::create();
+    unsigned dkey = sp_item_display_key_new(1);
+
+    std::vector<NRArenaItem *> arenaItems;
+    std::vector<SPShape *>::iterator iter;
+    for (iter = sioxShapes.begin() ; iter!=sioxShapes.end() ; iter++)
+        {
+        /* Create ArenaItems and set transform */
+        NRArenaItem *aItem =
+            sp_item_invoke_show(*iter,
+                 arena, dkey, SP_ITEM_SHOW_DISPLAY);
+        nr_arena_item_set_transform(aItem, img->transform);
+        arenaItems.push_back(aItem);
+        }
+
+    PackedPixelMap *dumpMap = PackedPixelMapCreate(ppMap->width, ppMap->height);
+
     for (int row=0 ; row<ppMap->height ; row++)
         {
         double ypos = y + ihscale * (double) row;
@@ -223,30 +354,35 @@ Tracer::sioxProcessImage(SPImage *img, GdkPixbuf *origPixbuf)
             point *= img->transform;
             point = desktop->doc2dt(point);
             std::vector<SPShape *>::iterator iter;
-            g_message("x:%f    y:%f\n", point[0], point[1]);
-            SPItem *itemOverPoint = desktop->item_at_point(point, false, NULL);
-            int weHaveAHit = false;
-            if (itemOverPoint)
+            //g_message("x:%f    y:%f\n", point[0], point[1]);
+            bool weHaveAHit = false;
+            std::vector<NRArenaItem *>::iterator aIter;
+            for (aIter = arenaItems.begin() ; aIter!=arenaItems.end() ; aIter++)
                 {
-                printf("searching\n");
-                for (iter = sioxShapes.begin() ; iter!=sioxShapes.end() ; iter++)
+                NRArenaItem *arenaItem = *aIter;
+                NRArenaItemClass *arenaClass =
+                    (NRArenaItemClass *) NR_OBJECT_GET_CLASS (arenaItem);
+                if (arenaClass && arenaClass->pick)
                     {
-                    SPShape *shape = *iter;
-                    if (shape == itemOverPoint)
+                    if (arenaClass->pick(arenaItem, point, 0.0f, 0))
                         {
                         weHaveAHit = true;
                         break;
                         }
                     }
                 }
+
             if (weHaveAHit)
                 {
-                g_message("hit!\n");
+                //g_message("hit!\n");
+                dumpMap->setPixelLong(dumpMap, col, row, 0L);
                 confidenceMatrix[cmIndex] =
                         org::siox::SioxSegmentator::CERTAIN_FOREGROUND_CONFIDENCE;
                 }
             else
                 {
+                dumpMap->setPixelLong(dumpMap, col, row,
+                        ppMap->getPixel(ppMap, col, row));
                 confidenceMatrix[cmIndex] =
                         org::siox::SioxSegmentator::CERTAIN_BACKGROUND_CONFIDENCE;
                 }
@@ -256,10 +392,19 @@ Tracer::sioxProcessImage(SPImage *img, GdkPixbuf *origPixbuf)
 
     //## ok we have our pixel buf
     org::siox::SioxSegmentator ss(ppMap->width, ppMap->height, NULL, 0);
-    ss.segmentate(imgBuf, ppMap->width * ppMap->height,
-                  confidenceMatrix, ppMap->width * ppMap->height,
-                  0, 0.0);
-
+    ss.segmentate(imgBuf, confidenceMatrix, 0, 0.0);
+
+    dumpMap->writePPM(dumpMap, "siox.ppm");
+    dumpMap->destroy(dumpMap);
+
+    /* Free Arena and ArenaItem */
+    std::vector<NRArenaItem *>::iterator aIter;
+    for (aIter = arenaItems.begin() ; aIter!=arenaItems.end() ; aIter++)
+       {
+       NRArenaItem *arenaItem = *aIter;
+       nr_arena_item_unref(arenaItem);
+       }
+    nr_object_unref((NRObject *) arena);
 
 
     GdkPixbuf *newPixbuf = packedPixelMapToGdkPixbuf(ppMap);