summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 9f87175)
raw | patch | inline | side by side (parent: 9f87175)
author | ishmal <ishmal@users.sourceforge.net> | |
Thu, 30 Mar 2006 12:13:29 +0000 (12:13 +0000) | ||
committer | ishmal <ishmal@users.sourceforge.net> | |
Thu, 30 Mar 2006 12:13:29 +0000 (12:13 +0000) |
src/trace/siox.cpp | patch | blob | history | |
src/trace/siox.h | patch | blob | history | |
src/trace/trace.cpp | patch | blob | history |
diff --git a/src/trace/siox.cpp b/src/trace/siox.cpp
index be1dd399537fc3948771caf117d0171beafffb29..7975d940066516578d56c68f833d073ce2be5c42 100644 (file)
--- 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];
-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;
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)
// 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;
// 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 {
}
}
- 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;
-void SioxSegmentator::keepOnlyLargeComponents(float *cm, int cmSize,
+void SioxSegmentator::keepOnlyLargeComponents(float *cm,
float threshold,
double sizeFactorToKeep)
{
// 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++);
}
}
- 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)
-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
}
diff --git a/src/trace/siox.h b/src/trace/siox.h
index d6efbfba1de0c4195bfb2312731f5869ddb384dd..5d36a71f660e13540fdbe80fc84ca506d58f0266 100644 (file)
--- a/src/trace/siox.h
+++ b/src/trace/siox.h
*
* @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);
/**
* 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);
* @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:
/** 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 2e46dd854fba8789f826d11a197e4b1635796b5d..a0dbad9fdf3716454c43d98809e338f34a48b2b6 100644 (file)
--- a/src/trace/trace.cpp
+++ b/src/trace/trace.cpp
#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"
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;
+}
+*/
+
+
+
+
/**
*
*/
}
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))
{
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
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
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;
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;
}
//## 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);