July 01, 2009
Automated Threshold & Edge Detection

It's a tiny bit late maybe, but here are two image processing techniques that deal with automated thresholding and edge detection that I showed in my "2d or not 2d" talk in 2007 and in "The Pixel Whisperer" in 2008.

I've had a look at my presentation demos and repackaged their code into a single class called ThresholdBitmap. This is a BitmapData class with a few extras that help you if you plan to extract blobs or edges from a camera stream or some other bitmap.

The general problem when you do camera based experiments is that you have unnown lighting conditions. Using a simple fixed threshold might work at your development machine but might fail completely on a user's computer that has a different camera model or a different backdrop.

In image processing there are several automated thresholding methods, that are supposed to help with this problem, by looking at an image's histogram and adjusting the threshold to a level that separates the foreground from the background in an optimum way: Moment-Preservation, Maximum Entropy, Discriminant and Otsu. Those are quite capable in finding the optimum threshold level if you have relatively uniform lighting over the whole scene.

As an (better) alternative I included an adaptive threshold method which is implemented in PixelBender and which works very well also with uneven lighting, especially if you try to detect QR codes or other markers.

Furthermore the class includes a very fast edge detection (based on the thresholded image) which gives you nice 1 pixel wide edges in most cases.

Here is a demo that allows you to play around (you'll need a webcam)

Sourceview and code can be found here

Credits: the demo uses the super useful Minimal Components by Keith Peters and the Hi.RES! Stats by Mr. Doob.

Posted at July 01, 2009 08:27 PM | Further reading

Thanks for the hint. Strange - I can see the google link just fine - maybe one has to be logged in. I will think of a different way to link to it.

What FLARToolKit demo are you referring to? The rectangle tracking demo I showed in my talk was my own creation and did not use any external libraries. Yes you are right, I should post that stuff as well.

Posted by: Mario Klingemann on July 3, 2009 12:13 PM

Hi Mario,

this looks quite cool, and performs really nice. I did not had the time to look at the code yet, but could this be used for blob detection as well? Other blob detection methods i have seen so far are really a cpu killer..


Posted by: Balazs on July 3, 2009 03:17 PM

Indeed I have used the threshold method as a base for my "floodFill + getColorBoundsRect" blob detection method. Another one of those things I've only showed during my talks but never published here.

Posted by: Mario Klingemann on July 3, 2009 03:51 PM

Hi Mario,

thanks for this great article! As you already mentioned these techniques are very important for marker detection. Saqoosha (author of FLARToolKit) also did some experimental stuff http://blog.jactionscripters.com/2009/05/18/adaptive-thresholding-experiment/ and since there are many problems with AR at low illuminated webcam images this will be a great extension to the library.

Posted by: Erik Lembke on July 6, 2009 12:11 PM

I'm blown away by this performance and the quality of the threshholding. You continue to amaze Mario.

Posted by: Adriaan on July 14, 2009 10:58 AM

Hi there.
I get the source code and everything works fine, except the adaptative threshold, that gives me a very different output compared to the demo in the link.
Any ideia of what could go wrong?

Thank you.
Really nice work. Congratulations.

Posted by: Pedro Silva on October 13, 2009 06:26 PM

Did you try to change the parameters? The default settings might not be the right ones for your use case.

Posted by: Mario Klingemann on October 13, 2009 06:52 PM

Thank you for your fast reply.

The problem is that i can get very nice values in demo that in the link that you release, but when running in flash, i get an error with the following output :

ArgumentError: Error #2164: The Shader input src1 is missing or an unsupported type.
at flash.display::BitmapData/applyFilter()
at com.quasimondo.bitmapdata::ThresholdBitmap/render()
at MultiExhibit/render()
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at com.quasimondo.bitmapdata::CameraBitmap/paint()
at flash.utils::Timer/_timerDispatch()
at flash.utils::Timer/tick()

I think that the problem is the .pbj or .pbk files formats.

I'm running it on mac. I'm giving you all this information, maybe it can help you to help me :)

Thank you.

Posted by: Pedro Silva on October 13, 2009 07:09 PM


I found what was going on. I updated my CS4 Flash Player to the lastest version and voilá, its working with adaptative threshold.



Posted by: Pedro Silva on October 14, 2009 05:03 PM

Ah, great that you could find it yourself and thanks for posting the solution here!

Posted by: Mario Klingemann on October 14, 2009 07:07 PM

No problem. Is the less i can do.

Can you update the source code with the blobs detection?

Ok, maybe i'm asking to much. :)


Posted by: Pedro Silva on October 14, 2009 09:48 PM

Very nice article. I thought to let you know that you website isn't getting displayed properly on opera mini browser on my pda.

I wish that increasingly number of webmasters would consider the fact that there is an ever growing number of users browsing webpages on the mobile.

Posted by: on November 4, 2009 05:24 PM

Can anyone provide guidance on how to get this demo working in Flash Builder 4 beta 2? I can successfully import, compile, and run the code in Flex Builder 3 (Eclipse plug-in version), but when I follow the same steps in Flash Builder 4 (Eclipse plug-in version) I get runtime errors telling me it can't find built-in player classes like flash.filters::ShaderFilter. My project is pointing to a valid FP 10 playerglobal.swc so I'm stumped.

Posted by: Kristopher Schultz on December 9, 2009 07:19 PM

Found my answer...changing the project's "Flex SDK version" setting from Flex 3.4 to Flex 4.0 fixed the runtime problems.

Posted by: Kristopher Schultz on December 9, 2009 09:17 PM
Post a comment

Email Address:



Remember info?

Thank you!

Most Visited Entries
Sketches, Works & Source Code
In Love with
Powered by
Movable Type 2.661

© Copyright Mario Klingemann

Syndicate this site:
RSS 1.0 - RSS 2.0

Quasimondo @ flickr
Quasimondo @ LinkedIn
Quasimondo @ Twitter
Quasimondo @ Facebook
Quasimondo @ MySpace
Quasimondo is a Bright
Citizen of the TRansnational Republic
My other blog in german

My family name is written Klingemann,
not Klingelmann, Klingeman, Klingaman, Kingemann,
Kindermann, Killingaman, Klingman, Klingmann, Klingonman
Klingemman, Cleangerman, Klingerman or Kleangerman

profile for Quasimondo at Stack Overflow, Q&A for professional and enthusiast programmers