From: ishmal Date: Thu, 30 Mar 2006 12:13:29 +0000 (+0000) Subject: WIP. siox election progress. fix api a bit. X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=fc4b10dffe7746556a0e4177f90fbacc63a4923a;p=inkscape.git WIP. siox election progress. fix api a bit. --- diff --git a/src/trace/siox.cpp b/src/trace/siox.cpp index be1dd3995..7975d9400 100644 --- a/src/trace/siox.cpp +++ b/src/trace/siox.cpp @@ -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=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=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=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 labelSizes; - for (int i=0 ; i=threshold) { regionCount=depthFirstSearch(cm, i, threshold, curlabel++); @@ -1153,7 +1155,7 @@ void SioxSegmentator::keepOnlyLargeComponents(float *cm, int cmSize, } } - for (int i=0 ; i pixelsToVisit; - for (int i=0; isizeOfLargestComponent/sizeFactorToKeep. * @return true if the segmentation algorithm succeeded, * false 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 * sizeOfLargestComponent/sizeFactorToKeep. */ - 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; diff --git a/src/trace/trace.cpp b/src/trace/trace.cpp index 2e46dd854..a0dbad9fd 100644 --- a/src/trace/trace.cpp +++ b/src/trace/trace.cpp @@ -26,7 +26,9 @@ #include #include #include -#include //for intersection boolop + +#include +#include #include "siox.h" #include "imagemap-gdk.h" @@ -35,6 +37,100 @@ namespace Inkscape { namespace Trace { + + +/* +static PackedPixelMap * +renderToPackedPixelMap(SPDocument *doc, std::vector items) +{ + + double minX = 1.0e6; + double minY = 1.0e6; + double maxX = -1.0e6; + double maxY = -1.0e6; + for (int i=0 ; ibbox.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 image 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 arenaItems; + std::vector::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 ; rowheight ; 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::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::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::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);