app/base/Makefile.am renamed to siox.[ch].

2005-07-13  Sven Neumann  <sven@gimp.org>

	* app/base/Makefile.am
	* app/base/segmentator.[ch]: renamed to siox.[ch].

	* app/base/siox.[ch]: added API docs and a link to the algorithm's
	new homepage. Removed unused code.

	* app/core/gimpdrawable-foreground-extract.c: changed accordingly.
This commit is contained in:
Sven Neumann 2005-07-13 19:30:25 +00:00 committed by Sven Neumann
parent 65e26d5b30
commit 70aa10cef7
7 changed files with 47 additions and 1628 deletions

View File

@ -1,3 +1,13 @@
2005-07-13 Sven Neumann <sven@gimp.org>
* app/base/Makefile.am
* app/base/segmentator.[ch]: renamed to siox.[ch].
* app/base/siox.[ch]: added API docs and a link to the algorithm's
new homepage. Removed unused code.
* app/core/gimpdrawable-foreground-extract.c: changed accordingly.
2005-07-13 Michael Natterer <mitch@gimp.org>
* app/core/gimppalette.c (gimp_palette_add_entry): actually return

View File

@ -36,8 +36,8 @@ libappbase_a_SOURCES = \
pixel-region.h \
pixel-surround.c \
pixel-surround.h \
segmentator.c \
segmentator.h \
siox.c \
siox.h \
temp-buf.c \
temp-buf.h \
threshold.c \

File diff suppressed because it is too large Load Diff

View File

@ -1,49 +0,0 @@
/*
* The GIMP Foreground Extraction Utility
* segmentator.c - main algorithm.
*
* For algorithm documentation refer to:
* G. Friedland, K. Jantz, L. Knipping, R. Rojas:
* "Image Segmentation by Uniform Color Clustering
* -- Approach and Benchmark Results",
* Technical Report B-05-07, Department of Computer Science,
* Freie Universitaet Berlin, June 2005.
* http://www.inf.fu-berlin.de/inst/pubs/tr-b-05-07.pdf
*
* Algorithm idea by Gerald Friedland.
* This implementation is Copyright (C) 2005
* by Gerald Friedland <fland@inf.fu-berlin.de>
* and Kristian Jantz <jantz@inf.fu-berlin.de>.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#ifndef __SEGMENTATOR_H__
#define __SEGMENTATOR_H__
/* Amount of color dimensions in one point */
#define DIMS 3
void foreground_extract (TileManager *tiles,
TileManager *trimap,
gfloat limits[DIMS],
gint smoothness);
#endif /* __SEGMENTATOR_H__ */

View File

@ -10,6 +10,8 @@
* Freie Universitaet Berlin, June 2005.
* http://www.inf.fu-berlin.de/inst/pubs/tr-b-05-07.pdf
*
* See http://www.siox.org/ for more information.
*
* Algorithm idea by Gerald Friedland.
* This implementation is Copyright (C) 2005
* by Gerald Friedland <fland@inf.fu-berlin.de>
@ -42,7 +44,7 @@
#include "paint-funcs/paint-funcs.h"
#include "pixel-region.h"
#include "segmentator.h"
#include "siox.h"
#include "tile-manager.h"
@ -214,7 +216,7 @@ stageone (lab *points,
int dims,
int depth,
ArrayList *clusters,
float limits[DIMS],
float limits[SIOX_DIMS],
int length)
{
int curdim = depth % dims;
@ -329,7 +331,7 @@ stagetwo (lab *points,
int dims,
int depth,
ArrayList *clusters,
float limits[DIMS],
float limits[SIOX_DIMS],
int length,
int total,
float threshold)
@ -483,7 +485,7 @@ euklid (const lab p,
static lab *
create_signature (lab *input,
int length,
float limits[DIMS],
float limits[SIOX_DIMS],
int *returnlength)
{
ArrayList *clusters1;
@ -504,7 +506,7 @@ create_signature (lab *input,
clusters1 = g_new0 (ArrayList, 1);
stageone (input, DIMS, 0, clusters1, limits, length);
stageone (input, SIOX_DIMS, 0, clusters1, limits, length);
clusters1size = list_size (clusters1);
centroids = g_new (lab, clusters1size);
curelem = clusters1;
@ -536,7 +538,7 @@ create_signature (lab *input,
clusters2 = g_new0 (ArrayList, 1);
stagetwo (centroids, DIMS, 0, clusters2, limits, clusters1size, length, 0.1);
stagetwo (centroids, SIOX_DIMS, 0, clusters2, limits, clusters1size, length, 0.1);
/* see paper by tomasi */
rval = list_to_array (clusters2, returnlength);
@ -776,7 +778,7 @@ find_max_blob (TileManager *mask,
/* Returns squared clustersize */
static gfloat
getclustersize (const float limits[DIMS])
getclustersize (const float limits[SIOX_DIMS])
{
float sum = (limits[0] - (-limits[0])) * (limits[0] - (-limits[0]));
@ -787,24 +789,21 @@ getclustersize (const float limits[DIMS])
}
/*
* Call this method:
* rgbs - the picture
* confidencematrix - a confidencematrix with values <=0.1 is sure background,
* >=0.9 is sure foreground, rest unknown
* xres, yres - the dimensions of the picture and the confidencematrix
* limits - a three dimensional float array specifing the accuracy
/**
* siox_foreground_extract:
* @pixels: the tiles to extract the foreground from
* @mask: a trimap indicating sure foreground, sure background and
* undecided regions
* @limits: a three dimensional float array specifing the accuracy,
* a good value is: { 0.66, 1.25, 2.5 }
* int smoothness - specifies how smooth the boundaries of a picture should
* be made (value greater or equal to 0).
* More smooth = fault tolerant,
* less smooth = exact boundaries - try 3 for a first guess.
* returns and writes into the confidencematrix the resulting segmentation
* @smoothness: boundary smoothness (a good value is 3)
*
* Writes the resulting segmentation into @mask.
*/
void
foreground_extract (TileManager *pixels,
siox_foreground_extract (TileManager *pixels,
TileManager *mask,
gfloat limits[DIMS],
gfloat limits[SIOX_DIMS],
gint smoothness)
{
gfloat clustersize = getclustersize (limits);
@ -1013,267 +1012,3 @@ foreground_extract (TileManager *pixels,
/* Now dilate, to fill up boundary pixels killed by erode */
dilate_mask (mask, 0, 0, width, height);
}
/************ Unused functions, for reference ***************/
/* calculates alpha \times Confidencematrix */
static void
premultiply_matrix (float alpha,
float *cm,
int length)
{
int i;
for (i = 0; i < length; i++)
cm[i] = alpha * cm[i];
}
/* Normalizes a confidencematrix */
static void
normalize_matrix (float *cm,
int length)
{
float max = 0.0;
float alpha = 0.0;
int i;
for (i = 0; i < length; i++)
{
if (max < cm[i])
max = cm[i];
}
if (max <= 0.0)
return;
if (max == 1.00)
return;
alpha = 1.00f / max;
premultiply_matrix (alpha, cm, length);
}
/* A confidence matrix eroder */
static void
erode2 (float *cm,
int xres,
int yres)
{
int idx, x, y;
/* From right */
for (y = 0; y < yres; y++)
{
for (x = 0; x < xres - 1; x++)
{
idx = (y * xres) + x;
cm[idx] = MIN (cm[idx], cm[idx + 1]);
}
}
/* From left */
for (y = 0; y < yres; y++)
{
for (x = xres - 1; x >= 1; x--)
{
idx = (y * xres) + x;
cm[idx] = MIN (cm[idx - 1], cm[idx]);
}
}
/* From down */
for (y = 0; y < yres - 1; y++)
{
for (x = 0; x < xres; x++)
{
idx = (y * xres) + x;
cm[idx] = MIN (cm[idx], cm[((y + 1) * xres) + x]);
}
}
/* From up */
for (y = yres - 1; y >= 1; y--)
{
for (x = 0; x < xres; x++)
{
idx = (y * xres) + x;
cm[idx] = MIN (cm[((y - 1) * xres) + x], cm[idx]);
}
}
}
/* A confidence matrix dilater */
static void
dilate2 (float *cm,
int xres,
int yres)
{
int x, y, idx;
/* From right */
for (y = 0; y < yres; y++)
{
for (x = 0; x < xres - 1; x++) {
idx = (y * xres) + x;
cm[idx] = MAX (cm[idx], cm[idx + 1]);
}
}
/* From left */
for (y = 0; y < yres; y++)
{
for (x = xres - 1; x >= 1; x--)
{
idx = (y * xres) + x;
cm[idx] = MAX (cm[idx - 1], cm[idx]);
}
}
/* From down */
for (y = 0; y < yres - 1; y++)
{
for (x = 0; x < xres; x++)
{
idx = (y * xres) + x;
cm[idx] = MAX (cm[idx], cm[((y + 1) * xres) + x]);
}
}
/* From up */
for (y = yres - 1; y >= 1; y--)
{
for (x = 0; x < xres; x++)
{
idx = (y * xres) + x;
cm[idx] = MAX (cm[((y - 1) * xres) + x], cm[idx]);
}
}
}
/* Smoothes the confidence matrix */
static void
smoothcm (float *cm,
int xres,
int yres,
float f1,
float f2,
float f3)
{
int y, x, idx;
/* Smoothright */
for (y = 0; y < yres; y++)
{
for (x = 0; x < xres - 2; x++)
{
idx = (y * xres) + x;
cm[idx] =
f1 * cm[idx] +
f2 * cm[idx + 1] +
f3 * cm[idx + 2];
}
}
/* Smoothleft */
for (y = 0; y < yres; y++)
{
for (x = xres - 1; x >= 2; x--)
{
idx = (y * xres) + x;
cm[idx] =
f3 * cm[idx - 2] +
f2 * cm[idx - 1] +
f1 * cm[idx];
}
}
/* Smoothdown */
for (y = 0; y < yres - 2; y++)
{
for (x = 0; x < xres; x++)
{
idx = (y * xres) + x;
cm[idx] =
f1 * cm[idx] +
f2 * cm[((y + 1) * xres) + x] +
f3 * cm[((y + 2) * xres) + x];
}
}
/* Smoothup */
for (y = yres - 1; y >= 2; y--)
{
for (x = 0; x < xres; x++)
{
idx = (y * xres) + x;
cm[idx] =
f3 * cm[((y - 2) * xres) + x] +
f2 * cm[((y - 1) * xres) + x] +
f1 * cm[idx];
}
}
}
/* region growing */
static void
findmaxblob (float *cm,
guint *image,
int xres,
int yres)
{
int i;
int curlabel = 1;
int maxregion = 0;
int maxblob = 0;
int regioncount = 0;
int pos = 0;
int length = xres * yres;
int *labelfield = g_new0 (int, length);
GQueue *q = g_queue_new ();
for (i = 0; i < length; i++)
{
regioncount = 0;
if (labelfield[i] == 0 && cm[i] >= 0.5)
g_queue_push_tail (q, GINT_TO_POINTER (i));
while (! g_queue_is_empty (q))
{
pos = GPOINTER_TO_INT (g_queue_pop_head (q));
if (pos < 0 || pos >= length)
continue;
if (labelfield[pos] == 0 && cm[pos] >= 0.5f)
{
labelfield[pos] = curlabel;
regioncount++;
g_queue_push_tail (q, GINT_TO_POINTER (pos + 1));
g_queue_push_tail (q, GINT_TO_POINTER (pos - 1));
g_queue_push_tail (q, GINT_TO_POINTER (pos + xres));
g_queue_push_tail (q, GINT_TO_POINTER (pos - xres));
}
}
if (regioncount > maxregion)
{
maxregion = regioncount;
maxblob = curlabel;
}
curlabel++;
}
for (i = 0; i < length; i++)
{
/* Kill everything that is not biggest blob! */
if (labelfield[i] != 0 && labelfield[i] != maxblob)
cm[i] = 0.0;
}
g_queue_free (q);
g_free (labelfield);
}

View File

@ -10,6 +10,8 @@
* Freie Universitaet Berlin, June 2005.
* http://www.inf.fu-berlin.de/inst/pubs/tr-b-05-07.pdf
*
* See http://www.siox.org/ for more information.
*
* Algorithm idea by Gerald Friedland.
* This implementation is Copyright (C) 2005
* by Gerald Friedland <fland@inf.fu-berlin.de>
@ -37,12 +39,12 @@
/* Amount of color dimensions in one point */
#define DIMS 3
#define SIOX_DIMS 3
void foreground_extract (TileManager *tiles,
void siox_foreground_extract (TileManager *tiles,
TileManager *trimap,
gfloat limits[DIMS],
gfloat limits[SIOX_DIMS],
gint smoothness);

View File

@ -23,7 +23,7 @@
#include "core-types.h"
#include "base/pixel-region.h"
#include "base/segmentator.h"
#include "base/siox.h"
#include "base/tile-manager.h"
#include "gimpchannel.h"
@ -39,7 +39,7 @@ gimp_drawable_foreground_extract (GimpDrawable *drawable,
GimpDrawable *mask)
{
GimpImage *gimage;
gfloat limits[DIMS] = { 0.66, 1.25, 2.5 };
gfloat limits[SIOX_DIMS] = { 0.66, 1.25, 2.5 };
g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)));
@ -49,7 +49,7 @@ gimp_drawable_foreground_extract (GimpDrawable *drawable,
gimage = gimp_item_get_image (GIMP_ITEM (drawable));
foreground_extract (gimp_drawable_data (drawable),
siox_foreground_extract (gimp_drawable_data (drawable),
gimp_drawable_data (mask),
limits, 3);