# Connect neighbouring contours

#1

Hello
I would like to measure the leaf area over the time.
I did a macro to segment arabidopsis plants, it work relatively well but i am facing an issue.
During the segmentation i am loosing parts of the leaves.
So it’s difficult to acces to the totale leaf area.
I used the excellent biovoxxel plugins tool (Extended particules analyser) to remove small particles and unwanted background (that i could not remove during my segmentation).

is it possible to connect and/or merge differents particules according proximity criteria automatically?
For example in this image i wouls like to have the area, convexhull of the particles 2 + 4 without taking in account particle 1 , 3 & 5…

Kill borders is not working because in some case the main particle could touch one of thèses unwanted particles.

I hope someone could help me.

Best
another example image

#2

Good day,

how do you expect a machine to do this?

How can a machine know that particle 4 belongs to object 2.

If you have an idea and if you can express this idea in mathematical terms, then we could try to find a way.

Regards

Herbie

#3

Hello Herbie,
I am not a good mathematician but i would go for something telling me :
1- detect the biggest object closest to the centre of the image
2- find the contours
3- calculate distances between particules ( border to border and/or centre to border or another one in don’t know)
4- “agrregate” particules into the biggest one with a max distance parameter
5- look for another one iteratively

Another way could be
1- to create a ROI with the tool make a circle = define the region where the final object is supposed to be inclosed
2- Don’t take in account particles if there centroid/ centre of mass are not into this area
3- find a way to combine others particles into a biggest one (recursively or iteratively?) …

I guess programmers are able to find better way to do this king of task iteratively or recursivly

I hope i a clear enough?

#4

Well something along these lines can be tried but, as you describe it, there are

1. several parameters that need to be defined by you a priori, such as “max distance parameter” and
2. fuzzy terms must be formalized, such as “find a way to combine others particles” or “aggregate” particules into the biggest one”

I guess programmers are able to find better way […]

Programming and conceptualization are completely different things and at the moment you need the latter.
(If you have a satisfying concept, you can start programming.)

I am not a good mathematician […]

This will permanently pose problems in our increasingly formalized world …

I hope that someone on the Forum will find time and provide an approximate solution that satisfies your needs.

Regards

Herbie

#5

You’re right i have to conceptualize first !
Sorry to be fuzzy, it’s not easy to explain.

I would be able to define parameter such as max distance in fact the plants are in pots of 7.2 cm. and the space between pot is constant. But sometime when the plants becomes older they are growing outside the pots and neighbours enter in the field of view of the centered plant.
Young plant

Older plant ( a leave at the bottom right is “appearing”)

I would like to be able to create a unique “object” corresponding to the plant in the middle in order to have the right area , convex hull et so on.

Is it less fuzzy?

#6

You will have to work along various lines to get what you want.

First image acquistion must be optimized:
The light is suboptimum and causing shadows.
The best would be to use a ringlight around the camera optics with a strong diffusor.
Camera position appears ok.

Second I would …
… try to detect the border of the pot, which appears rather easy.
… look at leaves that leave (nice!) the pot.
(Then you know what belongs to the very pot and you can ignore everything outside.)

Now you need someone to program this. An ImageJ-macro appears suited.

Good luck

Herbie

IMPORTANT:
Don’t use JPG-compressed images because they suffer from compression artifacts. Use raw camera images in TIFF- or PNG-format.
(Converting a JPG-compressed image to TIFF- or PNG-format doesn’t make sense.)

#7

For the final area measurements I would use the Yellow color excerpt after RGB -> CMYK conversion. Here is the result obtained with the automatic Default threshold. (Don’t use hand-set thresholds because they introduce a subjective component which means bad science.)

Obviously the binary image needs some post-processing and a suitable choice of the “Analyze Particles”-parameters.

Finding the pot border is a different issue …

HTH

Herbie

#8

I used to post here Jpeg because my Tiff are 30 Mb big.
Unfortunaty, the pots are not always as clean as in this picture…
For the lightning we will try to find a solution to have something more homogeneous
Thank you for help.
I’ll try to improve my segmentation and do what you sugested.

#9

I eventually managed to write an ImageJ macro that works as expected with your sample images. Here are the results:

Total Area: 42405 pixel

Total Area: 348635 pixel

Here is the macro code:

``````setBatchMode(true);
orig = getImageID();
run("RGB to CMYK");
run("Split Channels");
close();
bin = getImageID();
resetMinAndMax();
run("16-bit");
selectImage(orig);
run("Invert");
hh = getHeight()*0.5;
makeRectangle(0,hh,getWidth(),1);
p = getProfile();
strt = -1;
end = -1;
i = 0;
do {
if (p[i]==0 && strt<0) strt = i*0.5;
if (p[i]>0 && strt>=0) end = i*0.5;
i++;
} while (end<0);
doWand(strt+end, hh, 10.0, "Legacy");
run("Convex Hull");
run("Fit Circle");
selectImage(bin);
run("Restore Selection");
getSelectionBounds(x, y, w, h);
wh = w*0.5;
run("Polar Transformer", "method=Polar degrees=360 number=720 center_x="+(x+wh)+" center_y="+(y+h*0.5));
pol = getImageID();
setAutoThreshold("Default dark");
setOption("BlackBackground", false);
run("Set Measurements...", "bounding redirect=None decimal=3");
selectWindow("Results");
p = Table.getColumn("BX");
n = p.length;
a = newArray(n);
j = 0;
for ( i=0; i<n; i++ ) {
if (p[i]<wh-2) { a[j] = i; j++; }
}
close("Results");
roiManager("Select", a);
roiManager("Combine");
run("Make Inverse");
run("Clear", "slice");
roiManager("Show None");
run("Select None");
run("Polar Transformer", "method=Cartesian degrees=360 default_center");
run("8-bit");
setOption("BlackBackground", false);
run("Create Selection");
List.setMeasurements;
area = List.getValue("Area");
run("Crop");
run("Invert LUT");
run("Select None");
setBatchMode("show");
print( "Total Area: "+ area+" pixel" );
selectImage(orig);
run("Select None");
run("Revert");
setBatchMode(false);
exit();
``````

Paste the above macro code to an empty macro window (Plugins >> New >> Macro), open the desired image, and run the code.

HTH

Herbie

PS:
You must have two ImageJ-plugins installed;

1. “Polar Transformer”
2. “RGB to CMYK”

I think both come installed with the FIji-distribution of ImageJ.

#10

Hi Herbie,
Unfortunatly your code don’t work for others images.
I tryed to understand what your code is doing but for away from my knowledge.
I used a part of your code in a macro and i tryed it on more pictures

hh = getHeight()0.5;
makeRectangle(0,hh,getWidth(),1);
p = getProfile();
strt = -1;
end = -1;
i = 0;
do {
if (p[i]==0 && strt<0) strt = i
0.5;
if (p[i]>0 && strt>=0) end = i*0.5;
i++;
} while (end<0);
doWand(strt+end, hh, 10.0, “Legacy”);

followed by few steps of selection and “clear” (i will paste the code later) and this can remove some big blobs at the edges but not all of them.

I have one question maybe you could guive me some advices.

1- create a selection of all blobs in binary
2- identify the biggest one and store it centroid in a variable
3- check for intersection points between blobs boundaries
4- check the distance between centroid of the biggest particle and this crossing points
a- if it’s less than the distance between the biggest centroid and the image width minus 1cm combines particles

3b- if not then enlarge the selection by a factor ( 0.5 cm for example ) and check again for intersections

4- stop when no more particles can be combined