Sign in to follow this  
Endemoniada

Convolution Filters - Corners and Edges

Recommended Posts

Hi guys, From what I've gathered there are four (five ?) ways to handle corners and edges when applying a box filter. 1) don't process them 2) treat the non-existent pixels as zero 3) invent values for the non-existent pixels 4) crop the result 5) see below Well, (1) is lame, (2) will mess up a simple mean filter because it's like the pixels are black, (3) may work alright but I don't know what to make the pixels, I don't want to wrap them to the other side because I'm not making tilable images, maybe I can make them the same as the edges, (4) is a pain because the destination is smaller than the source. And maybe (5) which would work something like this: simple 3x3 filter, divisor=8 -1 -2 -1 -2 20 -2 -1 -2 -1 ...now if I'm at the top left pixel, I would use: 20 -2 -2 -1 ...with the 20 on the top-left pixel. Do I change the divisor ? Maybe I use different weights ? How do I make it so it's esentially the same operation as a 'regular' pixel using the full box ? Besides the extra coding this method to me seems the best, certainly the most 'complete'. All the ugly code will be tucked away in a function I never see so I don't care how it looks. What do you guys think ? I want to make this thing the right way, I don't mind if it takes an extra day to do. I've read many articles on convolution and they all gloss over the corners and edges, I've yet to see a good explanation of available options. Any advice would be appreciated.

Share this post


Link to post
Share on other sites
I have personally done similar filtering and have found that duplicating an edge from its nearest interior pixel gives good results. i was using a 4x4 Bartlett filter to perform supersampling so i had wider base, thus, more interior pixels than you do.

I was limited to keeping the same divisor in my project so i had no choice but to replicate values.

If you are simply box filtering on a software project you could just alter the divisor, this would give the correct result, so for

20 -2
-2 -1

you just divide by 6.25 rather than 8. I worked this out using

32(total weight) / 8(divisor) = 4

4 / 25(total weights of small filter) = 6.25(divisor)

unless for performance you were using shifts to divide by 8. This was my requirement for my project, since this is friendlier for implementation in hardware, rather than using a full divider. Best thing is to try a few different ways and see which gives you the smallest error, or best appearance, a large amount of graphical work is subjective anyhow, a simplification versus an almost imperceptable change is usually a wise trade off unless you require complete accuracy

Share this post


Link to post
Share on other sites
The two options I've actually seen are:

1) replicate edge pixels out to infinity

2) wrap around

Both are implementations of "invent pixel values". Both are correct, from a signal processing point of view; the first is correct if you want to use your texture without tiling (with texture clamping); the second is correct if you are tiling your texture coordinates (i e, use range outside 0-1).

Share this post


Link to post
Share on other sites
Yeah, that works too! thats essentially what i was doing, didnt make it clear that 'interior pixels' meant the ones that are under the centre of the filter. So, yeah, I meant you just repeat pixels.

Im an awkward git who didnt think of the simple way of explaining it! lol, though thats partly because i was used to a few complications in the system i was working on where I couldn't directly replicate some pixels...

My bad! :-D

Share this post


Link to post
Share on other sites
Hi guys,

Thanks for that information, it's nice to see people working on the same stuff I am.

I really have no requirements, I'm doing this in straight C(++) and don't really mind if it's not the fastest way possible (the naive approch I'm using now is fast enough, and I'm using floats.)

I like the replicating idea, it's nice and clean, and now that I know it's correct I feel satisfied with it. I will get to work on that now.

aleks, about that new divisor method you explained, you used 32 as the total weight to get the ratio, so that means I ignore the signs of the weights when I compute the new divisor ?

I'll try both methods. Right now I'm just applying mean, median, and sharpening filters so it's hard to see any difference between the methods, even if I don't process the edges at all I can't notice anything in the final result; that's why I'm looking for a 'correct' method.

Thanks again.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this