Sunday, April 19, 2009

Cartoonize Image by AS3.0 - Cartoon Filter

Using Photoshop or Gimp, you can create lots of artistic pictures from photos like water painting, oil painting, sketch ..., by powerful filters there.

Actionscript provides some filters such as BlurFilter, DisplacementMapFilter... and two basic but useful filter ColorMatrixFilter and ConvolutionFilter. We can do many things using those two filter. Here are two tutorials explaining them:
Once I want to convert a photo into a Chinese painting style pic but failed.
What inspired me recently is this free online app based on flash -Befunky Cartoonizer http://www.befunky.com/, which can convert your photo into a cartoon style pic.
I searched the Internet and found some tutorials on how to cartoonize your photo into cartoon
using some image processing software.
(Now we have a cartoon filter in GIMP: http://docs.gimp.org/en/plug-in-cartoon.html)
I found that the only trick is to find edges of image, extract outline of shapes and set BelndMode to multiply! I think Actionscript can handle that, so did this little experiment.

Firstly, ConvolutionFilter can do edge detection. Secondly, we can use BitmapData.draw()
+BlendMode to set blend mode.
However, in my test, simple edge detection using ConvolutionFilter with 3*3 array
[ 0, -1, 0, -1, 4, -1, 0, -1, 0 ] or [1, 2, 1, 0 ,0, 0, -1, -2, -1] or [1, 0, -1, 2, 0, -2, 1, 0, -1]
wouldn't result a nice effect.

But thanks to this post:
I get a better way to extract outlines.

If you wants to know more about edge detection using AS3.0, here are two tutorials with source:

And I found BlendMode.OVERLAY seems better than BlendMode.MULTIPLY.
This is the final result:
original picture:
edge detection:
BlendMode.MULTIPLY+Blur :
BlendMode.OVERLAY :
It doesn't look like a cartoon very much and may produce ugly things when using photos of human face but that's all I can do now.

In my test this is not suitable for real time rendering. 6*applyFilter()+3*draw()+2*threshold() eats too much CPU. I hope to find some better ways to do this. Hope some one could write a shader to do that work. If anyone knows a faster way to trace edges, please tell me. I do hope to make it run on the fly!
Source Code:

================================================
UPDATE 2009_7_09
another cartoon filter (version B) using Image binarization and edge tracing:
http://bruce-lab.blogspot.com/2009/05/image-binarization-and-edge-tracing-in.html

5 comments:

  1. I'm working on something similar... i think i am going to use the Laplace convolution method. http://www.pages.drexel.edu/~weg22/edge.html Basically instead of 2 3x3 filters you can use a single 5x5... that works about as good

    ReplyDelete
  2. Hi can u please help me how u find the edge in above example , i want to decrease the outline thickness please guide.

    ReplyDelete
  3. @chandni: You can use threshold to find the edge: http://www.kirupa.com/forum/showthread.php?p=2205469
    There is a threshold parameter controls the thickness of the outline.

    And here is another example of how to detect edge using pixel manipulation:
    http://bruce-lab.blogspot.com/2009/05/image-binarization-and-edge-tracing-in.html

    ReplyDelete
  4. Will you help me convert this into timeline code so that I can play with it?

    ReplyDelete
    Replies
    1. Try this: http://actionsnippet.com/timeline_to_doc.php

      Delete

Sponsors