Area filters
This discussion is connected to the gegl-developer-list.gnome.org mailing list which is provided by the GIMP developers and not related to gimpusers.com.
This is a read-only list on gimpusers.com so this discussion thread is read-only, too.
Area filters | Øyvind Kolås | 26 Jun 11:18 |
Area filters | Øyvind Kolås | 26 Jun 14:31 |
Area filters | David Gowers | 27 Jun 06:11 |
Area filters | Daniel Rogers | 27 Jun 06:48 |
Area filters | Kurt Pruenner | 27 Jun 09:35 |
Area filters | David Gowers | 27 Jun 10:43 |
Area filters | Øyvind Kolås | 27 Jun 11:14 |
Area filters | yahvuu | 27 Jun 11:16 |
Area filters | yahvuu | 27 Jun 11:31 |
Area filters | Øyvind Kolås | 27 Jun 11:43 |
Area filters | Kurt Pruenner | 27 Jun 11:52 |
Area filters | yahvuu | 27 Jun 12:06 |
Area filters | Joao S. O. Bueno | 28 Jun 02:56 |
486351EA.1000402@gmail.com | 07 Oct 20:29 | |
48637807.3090403@gmail.com | 07 Oct 20:29 |
Area filters
On Thu, Jun 26, 2008 at 9:23 AM, yahvuu wrote:
Hi all,
if i read gegl-operation-area-filter.c correctly, both the bounding box and the invalidate_by_change region grow by the amount specified in prepare(). Assuming all area operations are by type similar to blur, i had expected that only the input region (required_for_output) grows. Are there other types of area filters which require this behaviour?
How are area filters supposed to handle the source node's bounding box? For correctly handling border pixels, a filter probably has to differentiate between the borders of the currently rendered tile and the borders of the source's bounding box. The current blur implementations don't handle this, is there a reference filter which does?
There currently isn't any filters giving such a behavior. Making the
blur filter assume the
buffer abyss (the region outside the defined image) to be transparent
and extend the defined region by the kernel radius gives what I expect
as the result from blurring it, a rectangle with a fuzzy edge.
All the information to deal with this in different ways should be available, I do not remember if any of the operations currently shipping with GEGL does so though.
/Øyvind K.
Area filters
On Thu, Jun 26, 2008 at 12:05 PM, yahvuu wrote:
Øyvind Kolås schrieb:
Making the blur filter assume the buffer abyss (the region outside the defined image) to be transparent and extend the defined region by the kernel radius gives what I expect as the result from blurring it, a rectangle with a fuzzy edge.
GIMP allows to blur a layer without getting fuzzy edges. How will GEGL serve this use case?
Formulated like that, this is GIMPs problem not GEGLs problem, one way to achieve this is to crop the resulting image to the pre-extended extents, I suspect that the result on the edges by doing this, will be roughly equivalent to what you get in GIMP when blurring a layer/rectangular selection etc.
Another option is to define a new operation that doesn't grow, that also encodes the edge/abyss behavior (I hve written som GEGL operations based on random sampling of the neighbourhood that discards the random sample if it falls outside the defined area and does another random one instead).
Another option that hasn't been fully explored that might prove more fruitful is allowing GeglBuffers to define the abyss/edge behavior. Whether the abyss is transparent blank (or opaque black for no alpha) like it is now or it mirrors/extends pixel data.
/Øyvind K.
Area filters
Hi Øyvind,
On Thu, Jun 26, 2008 at 10:01 PM, Øyvind Kolås wrote:
On Thu, Jun 26, 2008 at 12:05 PM, yahvuu wrote:
Øyvind Kolås schrieb:
Making the blur filter assume the buffer abyss (the region outside the defined image) to be transparent and extend the defined region by the kernel radius gives what I expect as the result from blurring it, a rectangle with a fuzzy edge.
GIMP allows to blur a layer without getting fuzzy edges. How will GEGL serve this use case?
Formulated like that, this is GIMPs problem not GEGLs problem, one way to achieve this is to crop the resulting image to the pre-extended extents, I suspect that the result on the edges by doing this, will be roughly equivalent to what you get in GIMP when blurring a layer/rectangular selection etc.
Another option is to define a new operation that doesn't grow, that also encodes the edge/abyss behavior (I hve written som GEGL operations based on random sampling of the neighbourhood that discards the random sample if it falls outside the defined area and does another random one instead).
Another option that hasn't been fully explored that might prove more fruitful is allowing GeglBuffers to define the abyss/edge behavior. Whether the abyss is transparent blank (or opaque black for no alpha) like it is now or it mirrors/extends pixel data.
I believe tiling/wrapping would be more useful than mirroring. Right now, I know two applications, tiling and texturing, where tiled edge behaviour would help; Offhand, I cannot think of any way to employ mirroring abyss behaviour at all. Are there any?
David
Area filters
On Jun 26, 2008, at 9:11 PM, David Gowers wrote:
I believe tiling/wrapping would be more useful than mirroring. Right now, I know two applications, tiling and texturing, where tiled edge behaviour would help; Offhand, I cannot think of any way to employ mirroring abyss behaviour at all. Are there any?
Mirroring (or replicating the edge pixels) is the best approximation to what exists beyond the boundary in a photograph of a real object.
When convolving an image of a real object, the best results on the boundary are achieved by mirroring the edge.
Area filters
David Gowers wrote:
Offhand, I cannot think of any way to employ mirroring abyss behaviour at all. Are there any?
When coloring stuff I often create a black/white layer using the paintbrush and smear tools to add shading, and then blur it to smooth it out even more.
If there's one thing I don't want in this case is for the edges to become transparent or change their value much. In that case, mirroring probably would be the best option...
Area filters
Hi Kurt,
On Fri, Jun 27, 2008 at 5:05 PM, Kurt Pruenner wrote:
David Gowers wrote:
Offhand, I cannot think of any way to employ mirroring abyss behaviour at all. Are there any?
When coloring stuff I often create a black/white layer using the paintbrush and smear tools to add shading, and then blur it to smooth it out even more.
If there's one thing I don't want in this case is for the edges to become transparent or change their value much. In that case, mirroring probably would be the best option...
For your usage, I'd like to know why you think mirroring is better
than extending (GIMP calls it smearing -- pixels beyond the border are
treated as the nearest pixel on the border.).
With mirroring, supposing that you have pixels like:
(B = Black, G = Grey, W = White)
BBBGGWW on the right border of the image,
the result of blurring would be like BBBGGWG (hello weird-colored pixel!)
whereas with extending,
the result would be like BBBGGWW.
Incidentally, looking at the above, I realize why Daniel says mirroring is good for photos; it treats texture on and near the edges better, which would be good in nearly every case (the major exception being when you're trying to make a texture out of part of a photo -- extend or tile make more sense then!)
David
Area filters
On Thu, Jun 26, 2008 at 4:33 PM, yahvuu wrote:
On Thu, Jun 26, 2008 at 2:31 PM, Øyvind Kolås wrote: Anyhow, implementing these filters as new operations solves the problem for now. Having two kinds of gaussian blur seems awkward at first, but it is a user choice which edges to blur and not GEGL's. The filter pairs can be merged later on by implementing one as a meta operation of the other or simply by an option property like "preserve bounding box".
I'll derive the new filters from GeglOperationEdgedAreaFilter if no better naming comes up. For the filters probably: gaussian-blur-edged,
box-blur-edged
It is much better to extend GeglBuffer to have an abyss policy, this means that requests for pixels outside the define area gets read back as if they were smeared/mirrored (or like now all 0). After this the gaussian blur could be changed to not expand it's result rectangle beyond the original input, and still use the current easily managable code paths for the actual filtering.
/Øyvind K.
Area filters
[reposting]
On Thu, Jun 26, 2008 at 2:31 PM, Øyvind Kolås wrote:
Formulated like that, this is GIMPs problem not GEGLs problem, one way to achieve this is to crop the resulting image to the pre-extended extents, I suspect that the result on the edges by doing this, will be roughly equivalent to what you get in GIMP when blurring a layer/rectangular selection etc.
i doubt that. Consider a box-blur with radius = 1. A corner pixel will be the average of 4 image pixels and 5 abyss pixels. With larger radii the result gets deteriorated worse by larger fractions of abyss.
Another option is to define a new operation that doesn't grow, that also encodes the edge/abyss behavior (I hve written som GEGL operations based on random sampling of the neighbourhood that discards the random sample if it falls outside the defined area and does another random one instead).
yes, that's what i'm thinking about. The only way to achieve high quality results for border pixels is to implement the edge handling in the filter itself. The current "blur to abyss"-behaviour will be supported by specifying an accordingly bigger bounding box (some additional copying might be involved).
Sadly, this requires more complicated bounding box handling as this somehow infiltrates GEGL with the layer concept in disguise. Just limiting the filter to the source's bounding box might yield unexpected results if the source is a composition. For example, an overlay of two smaller nodes might look like this:
*--*--------*
| | |
*--* *--*
| | |
*--------*--*
(where the outer rectangle is the bounding box of the resulting composition and the smaller inner rectangles denote the source bounding boxes) Blurring this composition will fuzzy the inner edges while the outer edges stay crisp.
If this result is undesired, some superordinate instance must enlarge the composition's bounding box prior to blurring. Down that path probably lies madness.
Anyhow, implementing these filters as new operations solves the problem for now. Having two kinds of gaussian blur seems awkward at first, but it is a user choice which edges to blur and not GEGL's. The filter pairs can be merged later on by implementing one as a meta operation of the other or simply by an option property like "preserve bounding box".
I'll derive the new filters from GeglOperationEdgedAreaFilter if
no better naming comes up. For the filters probably:
gaussian-blur-edged,
box-blur-edged
greetings,
peter
Area filters
On Fri, Jun 27, 2008 at 11:14 AM, Øyvind Kolås wrote:
It is much better to extend GeglBuffer to have an abyss policy, this means that requests for pixels outside the define area gets read back as if they were smeared/mirrored (or like now all 0). After this the gaussian blur could be changed to not expand it's result rectangle beyond the original input, and still use the current easily managable code paths for the actual filtering.
handling the bounding box inside the filter is kind of a PITA, yes. But anything else will be a rough approximation (at least for blur filters). I feel it somewhat contradicting to utilize floating point arithmetic for the calculation of low quality results.
But OK, if these filters won't make it into GEGL, there's no need to mess with the details.
peter
Area filters
On Fri, Jun 27, 2008 at 10:31 AM, yahvuu wrote:
handling the bounding box inside the filter is kind of a PITA, yes. But anything else will be a rough approximation (at least for blur filters). I feel it somewhat contradicting to utilize floating point arithmetic for the calculation of low quality results.
I do not see how allowing to specify that pixels outside the defined
rectangle for a buffer by
definition is for instance the smeared out values (or the mirrored
values) of the defined content
would yield a different result from handling this inside the operation itself.
Doing it this way keeps the blur operations clean and simple and moves the complexity down in the abstraction layers.
/Øyvind K.
Area filters
David Gowers wrote:
For your usage, I'd like to know why you think mirroring is better than extending (GIMP calls it smearing -- pixels beyond the border are treated as the nearest pixel on the border.).
Yeah, I hadn't thought of smearing - the choices I was thinking of was either transparent, black or mirroring.
Mirroring did work fine when I implemented it in my version of the AviSynth KernelDeinterlacer, though - but that's just two lines at the top and bottom of each field.
I wonder - what does GIMP (or rather, GEGL) do when there's a gap (abyss?) of n pixels from an edge pixel to the adjacent next one and I do a blur of radius m > n?
Ideally, it should just smear the edge pixel(s) indefinitely, but does it do that?
Area filters
On Fri, Jun 27, 2008 at 11:43 AM, Øyvind Kolås wrote:
I do not see how allowing to specify that pixels outside the defined rectangle for a buffer by
definition is for instance the smeared out values (or the mirrored values) of the defined content
would yield a different result from handling this inside the operation itself.
the best definition of border pixels i'm aware of is to 'mask' the kernel with the bounding box. So for a box blur with radius=1 this means that the corner pixels are defined as average of 4 image pixels, and for each edge pixel 6 image pixels get averaged.
At first glance it think it is possible to implement this by creating suitable pixels outside the bounding box and keep the normal 3x3 kernel. But calculating the exact values for these 'helper pixels' is probably more effort than to truncate the kernel somehow. At least simple mirroring doesn't give exact results. Am i missing something here?
peter
Area filters
On Friday 27 June 2008, Øyvind Kolås wrote:
On Thu, Jun 26, 2008 at 4:33 PM, yahvuu wrote:
On Thu, Jun 26, 2008 at 2:31 PM, Øyvind Kolås wrote: Anyhow, implementing these filters as new operations solves the problem for now. Having two kinds of gaussian blur seems awkward at first, but it is a user choice which edges to blur and not GEGL's.
The filter pairs can be merged later on by implementing one as a meta operation of the other or simply by an option property like "preserve bounding box".I'll derive the new filters from GeglOperationEdgedAreaFilter if no better naming comes up. For the filters probably: gaussian-blur-edged,
box-blur-edgedIt is much better to extend GeglBuffer to have an abyss policy, this means that requests for pixels outside the define area gets read back as if they were smeared/mirrored (or like now all 0). After this the gaussian blur could be changed to not expand it's result rectangle beyond the original input, and still use the current easily managable code paths for the actual filtering.
This looks plainly as the right thing to do. Just to formalize the behavior. The most natural way of doing it would be if the filter should have a way to "tell" the buffer what it wants from the abyss. Note that this is different than setting the behavior as a property in the source buffer - it sounds more like a "temporary property" defined by whoever is consuming the buffer.
If that is too weird, or would make the code too insane, plain object properties to set the buffer behavior would be fine.
So, far I think the desired behaviors for the abyss could be:
- solid color (any, including transparent colors)
- stretch (smear)
- wrap (tile)
- mirror
and maybe:
- offset buffer
where offset buffer would be another buffer linked to the source one, just like a larger background layer. This would allow one to implement any desired behavior by creating the other buffer prior to applying the filter - (gradients, scaled mirroring, relief effects, etc... )
js
->
/Øyvind K.