Surface of contact between 2 colors

Tags: #<Tag:0x00007fd5422a4620> #<Tag:0x00007fd5422a44e0> #<Tag:0x00007fd5422a4378>


Hello everybody,

I would like to know if it’s possible to calculate on this picture the surface of contact between 2 colors. In this case i’m interested in the surface of contact between the green (biomaterial) and the red (bone).

Thank you

How to do a Binary image for a specific color

Hi @bcarv28,

I don’t think this is necessarily the best way to go, but it was fast for me to record a macro that does it (see below).


What I did:

  1. Get binary mask for red and green regions
  2. Dilate both
  3. Multiply the dilated masks to get a mask of the “contact region”
  4. Compute the “area” -> should correspond to contact surface

There are some compression artifacts in the image you posted

Cleaner images should give a better result.

I also dilated 3 times for each images, I think it may be wise to go with less than that, but the result “looks prettier” with more dilations, and is suggestive of what this approach can and can’t do well.


run("Split Channels");
selectWindow("surfContact.jpg (red)");
setMinAndMax(232, 255);
run("Apply LUT");
run("Make Binary");
selectWindow("surfContact.jpg (green)");
setMinAndMax(233, 255);
run("Apply LUT");
run("Make Binary");
selectWindow("surfContact.jpg (red)");
imageCalculator("Multiply create 32-bit", "surfContact.jpg (red)","surfContact.jpg (green)");
selectWindow("Result of surfContact.jpg (red)");


@bcarv28, I assumed that by “surface of contact” you mean something like the surface area of the boundary between the biomaterial (G) and bone ® objects If this is wrong please correct me.

To elaborate on the above:

  • That black and white “edgy” image is white for pixels that are near the boundary between the objects whose surface of contact we want to estimate. Counting the number of white pixels gives an estimate of the “perimeter” of that surface.
  • In the “Results” window in the first screenshot, the number under “Area” is the count of white pixels in that image.
  • The attached macro automatically generates both of these.

Reiteration of my critique of the above approach

  • I’m not crazy about counting pixels as a measure of perimeter, but it’s easy to do, and is likely to be closely related to “the right thing”. If someone knows how to fit curves to boundaries, I’m all ears!


Ok, now i understood.

But how do i arrive to the black image ? Should I paste that code somewhere ?


Plugins > New > Macro or pressing [ will bring up a window where you can paste that code.
Then there’s “Run” button near the bottom left.



Hi bogovicj,
I agree with you with counting the number of pixels at the interface. It is a quick way to get a rough approximation of the boundary length, even if it may be difficult to relate it to a physical quantity.

Just from a “theoretical” point of view, I see two ways for trying to measure it in a better way:

  • Measuring the length of a curve can be made by counting the number of intersections with a set of parallel lines. A useful ref is that of Moran (1966). Here, considering horizontal and vertical lines can be easy, but I do not know direct implementation for ImageJ.
  • Other approaches are related to Digital geometry, for example the works of Klette and Yip (Klette, R.; Kovalesky, V. & Yip, B. Length Estimation of Digital Curves Vision Geometry VIII-SPIE, 1999, 117-129). Again, the 2D case is not too complicated, but to my knowledge there is no plugin…

We have implemented methods for perimeter estimation within MorphoLibJ. I think I can adapt it to the measurement of boundary length between two regions. I’ll let you know if I find time.



I can only arrive to this step (first image). So i put the code, and 3 images was generated. At this images I will make them binary and then i dilate. But then i can’t compute the areas. When i click on Analyze > Compute curvatures i got the grey image.

Sorry, can you guide me?


Oh, the issue is likely that the code I posted assumes that the image of interest is called ‘surfContact.jpg’.


oh ok, now he generates only one image. So after binary and dilate i get like this. What’s the step missing ?


You should not have to do any steps by hand. If the macro does not produce a results window as in my screenshot, then something went wrong… were there any error windows?


yes, only this one.


Ah! The above macro also assumes the input is an RGB image - perhaps that is not the case?

Try taking your image and getting two binary images containing your objects of interest, then running
this modified macro:
Make sure there are only two images open, otherwise this may not do the right thing!

list = getList("image.titles")
imageCalculator("Multiply create 32-bit", list[0], list[1]);


well, no error but still not your result.

What should i change to get your exactly result ?


That’s looks like what I would expect from using the purple and green objects in your original image. I used the green and red ( isn’t that what you want?)


yes I want the green and red surface of contact. So what have i done wrong ?


What images were open when you ran that new macro?

There should be only two images open when you run it:

  1. A mask corresponding to the red object
  2. A mask corresponding to the green object

If these two images are not present, or if there are more than two images open, the macro will not produce the right output.


I open the original colored picture 2 times and I make it binary, with no differences between images. Then i apply the code.


A mask for an object means that it should be ‘white’ where that object is present and ‘black’ elsewhere, ie, the two should look something like this:


I’m sorry Bogovicj, but can you tell me how do I create a binary mask for red and a binary mask for gree ? :confused:

How to do a Binary image for a specific color