From: makc on
On Mar 8, 11:49 pm, Nicolas Bonneel <nbonn...(a)cs.ubc.ca> wrote:
> makc wrote:
> [snip]
> > this blurring idea did not work, at least in its simplest form:
> >http://megaswf.com/view/dc3441f43c7f246ba433ac64def4955d.html
>
> > as you see, amount black pixels tend to "dominate" over time :(
>
> for int n=0 to Niterations
> for all pixels(i,j) [where you need values, ie. not on your boundaries]
>   newpixels[i,j] =
> 0.25*(pixel(i+1,j)+pixel(i-1,j)+pixel(i,j+1)+pixel(i,j-1))
> end for
> pixels = newpixels;
> end for.
>
> This should yield the right solution...

No, that gives the same result but converges slower than 9 pixels
blur:
http://megaswf.com/view/ff61ad3c9189dfd7709cdccd55b72ef0.html
From: Nicolas Bonneel on
makc wrote:
> On Mar 8, 11:49 pm, Nicolas Bonneel <nbonn...(a)cs.ubc.ca> wrote:
>> makc wrote:
>> [snip]
>>> this blurring idea did not work, at least in its simplest form:
>>> http://megaswf.com/view/dc3441f43c7f246ba433ac64def4955d.html
>>> as you see, amount black pixels tend to "dominate" over time :(
>> for int n=0 to Niterations
>> for all pixels(i,j) [where you need values, ie. not on your boundaries]
>> newpixels[i,j] =
>> 0.25*(pixel(i+1,j)+pixel(i-1,j)+pixel(i,j+1)+pixel(i,j-1))
>> end for
>> pixels = newpixels;
>> end for.
>>
>> This should yield the right solution...
>
> No, that gives the same result but converges slower than 9 pixels
> blur:
> http://megaswf.com/view/ff61ad3c9189dfd7709cdccd55b72ef0.html

Either the result still hasn't converged (which is possible with such a
method : the step size may be lower than the machine precision -
especially if you are dealing with 8 bit images) or you have a bug : in
any case, I just don't believe that the laplacian is 0 (ie., the
gradient is minimized) over the whole image.
The slope could be much smoother, ideally the slope would be constant in
most places, giving a linear falloff instead of a gaussian-like one.

Either try with floating point images (if this was not the case), or try
a faster converging scheme, for example with multigrid (do the same
thing with a coarser resolution of your image, then upsample and use
that as an initial guess for the next level of your pyramid).

If you want to convince yourself, type in matlab:
z=zeros(100,1);
z(50)=1;
y=[0.5 0 0.5];
for i=1:1000, z=conv(z,y); z=z(2:end-1);z(50)=1; plot(z); pause(0.05); end;
You'll end up with a perfect triangle - not a gaussian. But ok, in 1D
here it requires 1000 iterations.

--
Nicolas Bonneel
http://cs.ubc.ca/~nbonneel/
From: makc on
On Mar 9, 11:45 pm, Nicolas Bonneel <nbonn...(a)cs.ubc.ca> wrote:
> ...in 1D here it requires 1000 iterations.

the key here is "1D".
check it out: http://megaswf.com/view/9e4c222a11e92ed4378684a291965fa9.html
as you see, if we limit blur to 1D, it produces nice linear gradient
in that direction.
but that is because we have exactly 1 white pixel on one end, and 1
black pixel on another.
in 2D, we have lots of black pixels that simply outweight our poor
single white point.
From: Nicolas Bonneel on
makc wrote:
> On Mar 9, 11:45 pm, Nicolas Bonneel <nbonn...(a)cs.ubc.ca> wrote:
>> ...in 1D here it requires 1000 iterations.
>
> the key here is "1D".
> check it out: http://megaswf.com/view/9e4c222a11e92ed4378684a291965fa9.html
> as you see, if we limit blur to 1D, it produces nice linear gradient
> in that direction.
> but that is because we have exactly 1 white pixel on one end, and 1
> black pixel on another.
> in 2D, we have lots of black pixels that simply outweight our poor
> single white point.

There is no matter of outweighting : the "blurring" method *does*
converge to the true solution of the Poisson equation, and it thus
*should* give the right solution : ie. not a gaussian but a nice gradient.
And indeed, in 2D this may require much more iterations. Which is why
multigrid methods have been proposed (as well as domain decomposition
methods like Schwartz's alternate one, multipole methods...).

Fortunately, this blurring kernel is separable, so you may try applying
it twice in 1D in both directions. If you alternate the x and y
directions each time it should exactly lead to the solution which failed
in your 2D case (not converging quick enough I guess). But if you first
make the 1D solution converge in one direction and then continue it in
the other direction, you may get a correct solution... I don't know if
this is guaranteed.

--
Nicolas Bonneel
http://cs.ubc.ca/~nbonneel/
From: Andrew_M on


makc wrote:
> I have specified point inside polygon, and - well - polygon. I want to
> paint the point white, and polygon perimiter black, and then smooth
> gradient inbeween.
>
> For convex polygon, I would split it in a fan of triangles and
> gradient-fill them, but for concave polygons this will not work
> because of self-intersections. If I try to extend this algorithm by
> dropping lots of points inside and applying delaunay triangulation, it
> is not clear to me how to assign colors to vertices :(
>
> So, I was thinking maybe someone on the internet knows how to do it in
> general case? you know, just for the sake of solution' completeness?
> Everything goes - pathfinding, flood-fills, etc - as long as you have
> an idea how to come from particular known algorithm to this specific
> application, please post it.

Assume, you wanna paint the only point white, perimiter black and all
the rest of points inside your polygon with some intermediate
(actually gray) color. In that case I could you recommend to use an
analogue with e-field. One charged particle and perimeter, connected
with ground (it means, with potential equal to zero). You have to
solve Laplasian equation. Its solution is the sum of two components.
The first is logarithm of the distance to one point you want to paint
with white color. The second is to be added to reduce potential of a
border to zero. The only problem is to get the second component. There
are some methods to do it. For example, you may use the approach,
described at the article on "diffusion curves". Rough rectangular
mesh, few iterations, then add additional rows and columns to that
mesh and so on. After you have get this solution, you have to replace
it with another function, using solution of the Laplasian equation as
an argument. Is it clear what I mean? Look, at the first stage you'll
get something like y=log(r) what is not very smooth near your point.
But, if you replace y with Y=1-exp(y) it would be more smooth (and
limited at your point). You may use Y=(1-exp(y))*(1-exp(y)) as well or
anything you want. I think it is the best method. Go ahead.