Jump to content
  • Advertisement
Sign in to follow this  
Endemoniada

Convolution Filters - Corners and Edges

This topic is 4788 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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
Advertisement
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
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!