A tiny bit of context: I'm using a TEM to take images of deposited metal on a surface. The images are in black and white. The deposited material forms little islands, and I want to use MM to figure out the surface concentration (i.e., the percent of the image covered by the islands). It's usually pretty clear from looking an one of the images by eye what should be counted as material and what shouldn't. Here's a typical, good picture:

enter image description here

And here's after naively doing Binarize[myimg,.5] (or some similar threshold):

enter image description here

That's an example of exactly what I want for every picture. However, some pictures I get are a little grainy, or have some background noise, or the contrast isn't as high, etc, but you can still definitely tell by eye what should and shouldn't be particles. Here are a few examples of the before picture and its corresponding Binarize[]'d image with a threshold of 0.65:

My main problem with most of those is that they're identifying the "islands" and making them sufficiently black, but are also shading in some black in the spots where there's nothing, which really throws off my data. So obviously changing the threshold to, say, 0.5, will fix some of these. But the problem is that it then starts messing up others that were fine with threshold = 0.65. For example, this one was fine at 0.65, but here's the before and after with 0.5:

So obviously 0.5 is no good for that image (and many others). This all stems from the fact that the machine's image collection is pretty basic, and I can't really control the contrast that exactly, as I take the images over the course of many days.

I can usually, if I'm looking at an image, "tune" the threshold so it's satisfactory. But obviously this is something I'd have to do for each image, which would take too much time. Is there a way I can make MM more "intelligent"? Maybe using some correlation between nearby spots as well?

Thank you!

  • 5
    $\begingroup$ LocalAdaptiveBinarize gives you a little more control over the binarization and helps a lot if you have a brightness gradient in you images. $\endgroup$
    – paw
    Nov 2, 2014 at 21:11
  • 1
    $\begingroup$ Also try BilateralFilter and MorphologicalBinarize $\endgroup$
    – shrx
    Nov 2, 2014 at 22:50
  • 1
    $\begingroup$ I wonder if adjusting the image histogram would allow you to make images obtained across multiple days a bit more consistent. $\endgroup$ Nov 3, 2014 at 1:22
  • $\begingroup$ Some denoising, using e.g. WienerFilter or TotalVariationFilter, will also help avoid the "shading in some black in the spots where there's nothing". $\endgroup$
    – user484
    Nov 3, 2014 at 6:04

1 Answer 1


As always in such cases, I would first try the most basic image processing approaches and see how far you come. Here, like in many other situations you can probably use a difference of Gaussian filters to get rid of the background variations and after this, you try to binarize your slightly smoothed images:

  With[{img = Import[url]},
      ImageAdjust[ImageSubtract[GaussianFilter[img, 5],GaussianFilter[img, 50]]], 
   ]] /@ {
  "http://i.imgur.com/hrKz2cc.png", "http://i.imgur.com/uaSeCaA.png", 
  "http://i.imgur.com/iL7CHC2.png", "http://i.imgur.com/nNruxOO.png"}

Looking at how different your images are regarding sizes of the structures, noise and brightness, the output looks promising as a first start:

Mathematica graphics Mathematica graphics Mathematica graphics Mathematica graphics Mathematica graphics


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.