Simple image filters using convolution matrix
Monkey Forums/Monkey Code/Simple image filters using convolution matrix
| ||
Here is some nice code that can apply realtime (but sometimes slow) filters to images. Including blur, sharpen, emboss, edge detect, median blur, gaussian blur etc. The Median function is particularly slow. See an example here: Example Enjoy. If you make any improvements, please post them here. example.monkey convmatrix.monkey |
| ||
I forgot to mention that it currently doesn't handle image edges very elegantly. I will probably fix this at some point. |
| ||
Nice ! |
| ||
2x Nice ! |
| ||
What should one do with edges? I'm thinking two options: average the colour near an edge and treat outside pixels as being that colour, or wrap around (useful for tiled graphics). |
| ||
gimp offers a choice for tiled/nontiled this opens the possibility for monkey to do an elite style game with procedurally generated planet images ^_^ |
| ||
I've done a little tweaking to improve performance a bit. The speed-up ranges from a little to a lot depending on target and build settings. I only tried HTML5, Flash, XNA and GLFW but the techniques are mostly transferable. Going native with this sort of thing would be the natural end-game though. The output may not be exactly the same as the original but it looks visually equivalent. |
| ||
The only problem (and a quite major one) that I can see with your nice optimised code is that it will be much harder (if not impossible) to adjust it to handle image edges. Or am I missing something? |
| ||
You're missing a description of how you would handle edges. |
| ||
Like this: |
| ||
What's that meant to be doing? It looks like it wraps the pixel values to the right and bottom and repeats the border values to the left and top. |
| ||
It doesn't wrap them, instead it clamps the edges, which works great. |
| ||
[monkeycode] For Local x2:Int = -halfSize To halfSize Local newx:Int = (x+x2) Mod image.Width() If newx < 0 newx = 0 For Local y2:Int = -halfSize To halfSize Local newy:Int = (y+y2) Mod image.Height() If newy < 0 newy = 0 [/monkeycode] If you put (x+x2) = width and (y+y2) = height into that you get 0,0 out. It wraps. If you put (x+x2) = -1 and (y+y2) = -1 into that you get 0,0 out. It clamps. |
| ||
Anyway, I believe this does what you intend: |
| ||
Oops. Sorry, I'm an idiot. In my defense it's been a very long day. How about this: |
| ||
muddy_shoes - looks great. |
| ||
thank you for posting this, I have never heard of convolution matrices before, very interesting reading up on them and their uses. I saw this as an interesting programming challenge and decided to try writing my own now. After a few hours I managed to get mine working correctly, It's always easier implementing something when there is reference code to help! I believe I have a working Sobel edge filter although I need to read up on it some more to make sure, the output seems to match but it was a weird one. Is there a list or website showing kernel values or filter names that can be used with this method? I have about 14 so far, would be good to get a complete collection. |