Contouring area percentage using a binary image

I have a binary image with distributed black areas on white background:

I want to create an equivalent map of pixel values which have the black area percentage of surrounding pixels of 10x10 pixels. I will then take these values and create an image coloured by area percentage in Matlab.

Can anyone suggest how the area percentage can be easily calculated over a gridded area?

Good day,

as I understand the desired processing, it is relatively easy to achieve and it looks like you don’t even need MathLab.

However, some details are not perfectly clear from your description:

  1. Your image isn’t actually binary-valued. This may be due to the fact that it is JPG-compressed which generally doesn’t keep binary-valued images binary. Please post images either as PNG- or TIF-files.
  2. "black area percentage of surrounding pixels of 10x10 pixels"
    This poses two problems:
    a) Should the center pixel be included? If yes, one should assume an odd-sized area, e.g. 9x9.
    b) It sounds as if this percentage is to be computed for all positions, resulting in an image of essentially the same size (boundary positions need a special treatment).
  3. "calculated over a gridded area"
    Here you tell us something that is in opposition to point 2b, because in this case the resulting image would consist of roughly only (2048/9)x(213/9) pixels.

It would be very helpful, if you could clarify these issues.



From your posted image, after binarization

the computed result image according to points “2ab” of my previous post becomes:

As you can see from its histogram
the values in this result image run from 0 to 100 and give the percentage of black in a 9x9 running window.

You may apply a LUT of your liking to indicate the percentages in color.

Here are two examples of the result image in false color:



Hi, thanks for your questions.

  1. will do
  2. a) yes, though I dont understand why the area will be a big factor
    b) yes, correct
  3. Lets stick with your understanding from 2ab

This is exactly what I am after. I plan to use this and apply it to a larger image, and test a few zone areas (9x9 vs 90x90 etc) until I get what I am after.

Can you tell me how you have performed this magnificent work?

Good day!

the core operation is one of the most basic operations in image processing: Running mean.

The running mean is computed by first specifying the kernel function (in your case a square window with odd sized side length) that is applied at every position of an image. The underlying mathematical operation is a convolution integral that means a linear filter operation.

With ImageJ you go to “Process >> Filters >> Convolve…”, define the kernel function with all (e.g. 9x9) values having value 1, check Normalize Kernel and click OK. Please note that this approach requires kernels with odd-sized side length!

Before the filtering you need to invert your image, because you are interested in the black areas of your binary image.

The remaining operations are simple normalizations of the resulting image in order to get values from 0 to 100.





good to see that my approach is to the point!

Here is an ImageJ macro that performs the necessary steps:

// ImageJ macro code
nme = getTitle();
setOption( "BlackBackground", true );
run( "Make Binary") ;
n = getNumber( "Kernel Side Length", 9 );
if ( n % 2 == 0 ) n--;
if ( n < 3 ) exit( "Use an odd-sized kernel side length greater than one!" );
kernel = createKernel( n-1 );
run( "Convolve...", "text1=[" + kernel + "] normalize" );
run( "Multiply...", "value=" + d2s( 100/255, 9 ) );
nme = split( nme, "_" );
rename( nme[0] + "_kernel-" + n );
function createKernel( sz ) {
	str = "";
	for ( i = 0; i < sz; i++ ) { str += "1 "; }
	str += "1\n";
	k = str;
	for ( i = 0; i < sz; i++ ) { k += str; }
	return k;
// Paste the above macro code to an empty macro window (Plugins >> New >> Macro) and run it.

Here are two false color versions of the result obtained with a 89x89 kernel: