app: create a simple priority map for line art selection flooding.
We actually don't need to compute distance map. I just make the simplest
priority map, with 1 any line art pixel and 0 any other pixel (in mask
or not), lowest priority being propagated first.
And let the flooding begin!
(cherry picked from commit 410c747509)
This commit is contained in:
@ -226,7 +226,7 @@ gimp_pickable_contiguous_region_by_seed (GimpPickable *pickable,
|
||||
* unknown pixels be labelled by flooding through watershed.
|
||||
*/
|
||||
GeglBufferIterator *gi;
|
||||
GeglBuffer *distmap;
|
||||
GeglBuffer *priomap;
|
||||
GeglBuffer *tmp;
|
||||
GeglNode *graph;
|
||||
GeglNode *input;
|
||||
@ -236,73 +236,41 @@ gimp_pickable_contiguous_region_by_seed (GimpPickable *pickable,
|
||||
|
||||
GIMP_TIMER_START();
|
||||
|
||||
/* Compute a distance map for the labels. */
|
||||
graph = gegl_node_new ();
|
||||
input = gegl_node_new_child (graph,
|
||||
"operation", "gegl:buffer-source",
|
||||
"buffer", mask_buffer,
|
||||
NULL);
|
||||
op = gegl_node_new_child (graph,
|
||||
"operation", "gegl:distance-transform",
|
||||
"metric", GEGL_DISTANCE_METRIC_EUCLIDEAN,
|
||||
"normalize", FALSE,
|
||||
NULL);
|
||||
sink = gegl_node_new_child (graph,
|
||||
"operation", "gegl:buffer-sink",
|
||||
"buffer", &distmap,
|
||||
NULL);
|
||||
gegl_node_connect_to (input, "output",
|
||||
op, "input");
|
||||
gegl_node_connect_to (op, "output",
|
||||
sink, "input");
|
||||
gegl_node_process (sink);
|
||||
g_object_unref (graph);
|
||||
/* Flag the mask on the line art and create a priority map. */
|
||||
priomap = gegl_buffer_new (gegl_buffer_get_extent (mask_buffer),
|
||||
babl_format ("Y u8"));
|
||||
|
||||
/* gegl:distance-transform returns distances as float. I want them as
|
||||
* unsigned ints without converting (i.e. not assuming pixel values).
|
||||
* Let's just loop through the map).
|
||||
*/
|
||||
tmp = gegl_buffer_new (gegl_buffer_get_extent (distmap),
|
||||
babl_format ("Y u8"));
|
||||
gi = gegl_buffer_iterator_new (distmap, NULL, 0, NULL,
|
||||
GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 2);
|
||||
gegl_buffer_iterator_add (gi, tmp, NULL, 0, NULL,
|
||||
GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);
|
||||
while (gegl_buffer_iterator_next (gi))
|
||||
{
|
||||
float *data = (float*) gi->items[0].data;
|
||||
guint8 *out = (guint8*) gi->items[1].data;
|
||||
gint k;
|
||||
|
||||
for (k = 0; k < gi->length; k++)
|
||||
{
|
||||
*out = (guint8) G_MAXUINT32 - MIN (round (*data), G_MAXUINT8);
|
||||
data++;
|
||||
out++;
|
||||
}
|
||||
}
|
||||
g_object_unref (distmap);
|
||||
distmap = tmp;
|
||||
|
||||
/* Flag the mask on the line art. */
|
||||
gi = gegl_buffer_iterator_new (src_buffer, NULL, 0, NULL,
|
||||
GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 2);
|
||||
GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 3);
|
||||
gegl_buffer_iterator_add (gi, mask_buffer, NULL, 0,
|
||||
babl_format ("Y float"),
|
||||
GEGL_ACCESS_READWRITE, GEGL_ABYSS_NONE);
|
||||
gegl_buffer_iterator_add (gi, priomap, NULL, 0,
|
||||
babl_format ("Y u8"),
|
||||
GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);
|
||||
|
||||
while (gegl_buffer_iterator_next (gi))
|
||||
{
|
||||
guchar *lineart = (guchar*) gi->items[0].data;
|
||||
gfloat *mask = (gfloat*) gi->items[1].data;
|
||||
guchar *lineart = (guchar*) gi->items[0].data;
|
||||
gfloat *mask = (gfloat*) gi->items[1].data;
|
||||
guint8 *prio = (guint8*) gi->items[2].data;
|
||||
gint k;
|
||||
|
||||
for (k = 0; k < gi->length; k++)
|
||||
{
|
||||
if (*lineart && ! *mask)
|
||||
*mask = flag;
|
||||
if (*lineart)
|
||||
{
|
||||
*prio = 1;
|
||||
if (! *mask)
|
||||
*mask = flag;
|
||||
}
|
||||
else
|
||||
{
|
||||
*prio = 0;
|
||||
}
|
||||
lineart++;
|
||||
mask++;
|
||||
prio++;
|
||||
}
|
||||
}
|
||||
g_object_unref (src_buffer);
|
||||
@ -315,7 +283,7 @@ gimp_pickable_contiguous_region_by_seed (GimpPickable *pickable,
|
||||
NULL);
|
||||
aux = gegl_node_new_child (graph,
|
||||
"operation", "gegl:buffer-source",
|
||||
"buffer", distmap,
|
||||
"buffer", priomap,
|
||||
NULL);
|
||||
op = gegl_node_new_child (graph,
|
||||
"operation", "gegl:watershed-transform",
|
||||
@ -334,7 +302,7 @@ gimp_pickable_contiguous_region_by_seed (GimpPickable *pickable,
|
||||
sink, "input");
|
||||
gegl_node_process (sink);
|
||||
g_object_unref (graph);
|
||||
g_object_unref (distmap);
|
||||
g_object_unref (priomap);
|
||||
|
||||
gegl_buffer_copy (tmp, NULL, GEGL_ABYSS_NONE, mask_buffer, NULL);
|
||||
g_object_unref (tmp);
|
||||
|
||||
Reference in New Issue
Block a user