On Tue, 6 Jan 2009 11:38:21 +1000
Anthony Thyssen <[email protected]> wrote:

| On Mon, 05 Jan 2009 11:49:42 +0100
| [email protected] wrote:
|
| | Hi,
| |
| | I have an image exported by inkscape to use in a 3d program, my problem
| | is that the border of the image is not really conveniant with the alpha
| | blending.
| | What i would like is to process the image to extend the border of the
| | rgb then the aplha will fade to the good color of border and not a
| | background flat white.
| | I thought to a filter that could detect the border of image then extend
| | it, but i did not success to do it. I am not really experienced in
| | filter processing, so advise will be welcome.
| |
| | here the picture to understand what i am explaining
| |
|
| ... previous response deleted ...
|

Looking again at your email....

One of the things you mentioned was..
| What i would like is to process the image to extend the border of the
| rgb...

This can be tricky, and is something that I have thought about a lot
over the last couple of years.


The following is a running experiment, so please bear with me.


So lets start with a test image...

  convert -size 100x100 xc:none \
          -draw "fill magenta path 'M 30,60  A 1,1 0 0,0 70,40 z'" \
          -draw "fill cyan    path 'M 30,60  A 1,1 0 1,1 70,40 z'" \
          -draw "fill blue    circle 50,50 37,37'" \
          circle_halves.png

Ok the problem here is that any pixel that his NOT fully-transparent
will have an undefined color.  Generally and mathematically algorithms
tend to set that undefined color to black.

(Scale the image larger to see it better...

  convert circle_halves.png  -scale 500%  show:

Note that there are properly defined semi-transparent pixels
around the edge.

For example...

   convert circle_halves.png  -alpha off  show:

What we want to do is define the hidden color of these pixels as
something other than black.  Some color that is a better representation
of the real colors of the visible object in the image.

There are a couple of methods that can be used for this, but the first
step is always the same.

First we need to figure out what pixel have a properly defined color
(anything which is opaque or semi-transparent) and what parts do not
have a properly defiend color.

First thing is to take the original image and threshold the alpha channel
so that any pixel that is NOT fully-transparent, becomes fully-opaque.
That is convert it to a boolean transparency, which gives us a mask
defining the pixels that we know has a 'good' color that we will not want
to change.

  convert circle_halves.png \
          -channel A -negate -threshold 0 -negate +channel \
          defined_color.png

Now we need to some how spread that good color to the other undefined
color pixels.

One method is to blur the 'mask of good colors' with a -channel RGBA setting.
This will make each pixel an average color of its neighbours, and the
color will spread into the undefined transparent areas.

Note that we don't want to change the properly defined colors
so we also overlay the good colors on top of the result, to resutl them
back to there correct values.

  convert defined_color.png \
          \( +clone -channel RGBA -blur 0x5 \
             -channel A -negate -threshold 0 -negate +channel \) \
             -compose DstOver -composite      blurred_color.png

Note that the above blur did manage to color most of the undefined
pixels, and the color were quite a reasonable result, at a distance from
the original image. however it fails close in to the original image,
producing a sharp discontinuity.  This is because it is average of all
the defined colors, especially the inside colors, rather that a
spreading of just the edge colors.

The better solution is a actually to blur the image using a radius of
only 1 to 2 pixels at most, so that new colors will only get a average
of the closest neighbours.

A mophological operation to average neighbours.

By repeating this small blur, and reseting the defined pixel colors
we can incrementally spread the objects edge color out to produce a
better result.

  convert circle_halves.png \
          -channel A -negate -threshold 0 -negate +channel \
          spreading_color.png
  for i in `seq 10`; do
    convert spreading_color.png \
            \( +clone -channel RGBA -blur 1x65000 \
               -channel A -negate -threshold 0 -negate +channel \) \
             -compose DstOver -composite     spreading_color.png
  done

  convert spreading_color.png  -scale 500%  show:

That worked but not very nicely. We got a 45 degree join, rather than
the original angle of the edges in the original image.  A different
mophological operation may have resulted in a horizontal or vertical
joint instead.

Repeating the above with a radius of 2 actually produces a better result
also not doing the thresholding also improves the result.

  convert circle_halves.png  tmp.png
  for i in `seq 35`; do
    convert tmp.png \( +clone -channel RGBA -blur 2x65000  \) \
             -compose DstOver -composite     tmp.png
  done
  convert tmp.png -channel A -negate -threshold 0 -negate spreading_color2.png

  convert spreading_color2.png  -scale 500%  show:

Now that you have your defined colors, all you need to do is re-add the
original images transparency, which is a very difficult thing to do.

All the normal Alpha Composition methods appear to fail.

The ONLY solutions I have found for this is either using the slow -fx
operator or to seperate and combine the image channels.

  convert spreading_color2.png circle_halves.png \
          -channel RGBA -separate -delete 3-6 -combine \
          circle_halves_restored.png

Of course that looks exactly like your original image, but then that is
the point.  You can verify that the transparent pixels have a nicely
defined color using, just as we did before...

  convert circle_halves_defined.png  -alpha off  show:

Be warned however that almost any typical IM operation will likely reset
those transparent colors back to the undefined state of black.

---

An alternative for all this is to pull out all the edge pixels of the image
and input them in the new   -sparse-colors  operator
  http://www.imagemagick.org/Usage/canvas/#sparse-color

As this operator is designed to deal with a very simular problem.

The question of course is how to extract a list of edge pixels and there
colors from an image.


  Anthony Thyssen ( System Programmer )    <[email protected]>
 -----------------------------------------------------------------------------
   Judith looked at the demons and shook her head.  "I'm glad we didn't
   build four processors.  I'm not sure I could take a barbershop
   quartet!"                      -- Rick Cook, "The Wizardry Compiled"
 -----------------------------------------------------------------------------
     Anthony's Home is his Castle     http://www.cit.gu.edu.au/~anthony/
_______________________________________________
Magick-users mailing list
[email protected]
http://studio.imagemagick.org/mailman/listinfo/magick-users

Reply via email to