How can i binarize an image in image J

I use image j software for the first time. I use the Bezier curve to evaluate eyelid contour.
First, how can I select the color of the Bezier line?
Second, how can i binarize this human face image using color threshold tool so that the only the pixels forming the contour are displayed in black and the remaining pixels are converted to white.

Thank you very much in advance

Hi @Mostafa_Diab,

Welcome to the forum. The most given reply in the forum is ‘please post a representative image’, followed by ‘post an annotated image of what you want to achieve’.

Do you manually put in the Bezier?If you have the Bezier Region of Interest, there is a simple macro command to retrieve the pixel coordinates of pixels that make up the Bezier line.

A further good practice is to record (Plugins>Macro>Record) what you do and use that as a basis for a macro (or a discussion on what you did). When posting code, copy the code, in the editor of the forum press the </> tool and paste. This way code remains copy-pastabe for us to use

Thank you.

I do the Bezier Manually. as in the image.

What I want to achieve this black curve
All best

This is the protocol , I want to apply
Lid contour extraction
Using the Bézier icon of the software, the user clicked
on the lateral canthus and on the end of the ciliated
portion of the upper lid to create a straight line defined
by two control points (Figure 1 top). Then, the user was
able to freely modify the straight line to adjust it to the
lid contour by clicking on any of the two control points
and dragging them around (Figure 1 middle). The resultant
Bezier line was draw with a preselected line color
(Figure 1 bottom). We used a yellow hue, but any color
that has no correspondence with the spectrum of human
facial hues might be employed. Finally, the image was
binarized (color threshold tool) in such way that only
the pixels forming the contour were displayed in black.
The remaining pixels were converted to white and not
shown (Figure 2).
The numerical coordinates of the line representing
the contour were saved and transferred to a statistical
software for graphical analysis (Matlab 8.5, The MathWorks Inc., Natick, MA). The line expressing the lid contour
was resampled to contain 1000 points (a spatial resolution
of approximately 0.03 mm) and smoothed using
a Savitzky-Golay filter. The final contour line relative to
the pupil center is displayed in figure 3.



type or paste code here
``` open("C:/Users/DR.MOSTAFA/Desktop/008.jpg");
run("Color Threshold...");

Hi @Mostafa_Diab,

Thanks for the precise description of the method used. It does make me wonder about a few things.
It is just the coordinates of the points on the contour are desired?
Why there was a color thresholding tool necessary?
To what effect the interpolation to 1000 points was performed (more precise? normalisation?)
The whole image, of which the Bezier covers only half, only has 727 pixels.
The spatial calibration also depends on the distance between the camera and the subject.

Especially the sentence “the image was binarized (color threshold tool) in such way that only the pixels forming the contour were displayed in black.” puzzels me. Was the colour threshold iteratively changed so all the pixels of the contour became black? Was that excluding them or including them? Foreground is usually white…

Four coordinates (the bezier points) would suffice to extract all information, isn’t it? That would result in awesome (simple, elegant) problem space!

Finally to answer your very first question: you can use the ROI manager or the Overlays, in particular Overlay.addSelection(strokeColor) to set the overlay and colour of the selection as desired.

Thank you very much for your reply.
I am sorry, I can’t cope up with all comments !
Please, I am an oculoplastic surgeon, i have very little knowledge regarding the use of image J
I wonder if there’s any step by step guide to achieve my goal?


All the best


To retrieve the coordinates of the points, you can change the line tool (5th tool in the toolbar) with the right mouse button; change it to Segmented Line. Then set three points in the image. The first point in the corner of the eye, the second in the middle of the eyebow, for the third and last point, use a double click, near the other corner of the eye. Then use Edit > Selection > Fit Spline

You can now move the middle point to precisely follow the contour (edge) of the eye lid. If this curvature is not sufficient, you can perform this procedure with four points.

Once you have created the curved line to your liking, you can harvest the coordinates of the points that make up the curve with a small macro. The main component of this macro is an interpolation command, to make sure every pixel under the ROI is used, and a Roi.getCoordinates(xpoints, ypoints) to harvest the coordinates in two arrays.

Depending on your needs you can then process these coordinates, get the accompanying pixel values (ie. colours) and/or save these to file.


run("Fit Spline");
run("Install...", "install=C:/Users/DR.MOSTAFA/Downloads/Compressed/ImageJ/macros/RoiManagerMacros.ijm");

What is the next step

Hi @Mostafa_Diab,

Do note, that AFTER you have performed the run("Fit Spline"); command on three or more points of the polyLine, the points now behave as a spline, that is, you can manipulate them to change the shape and the shape will graciously follow the moving point.

OK, since you haven’t posted the original image to this selection we cannot reproduce exactly, still the following macro will get you the coordinates of every pixel covered by the yellow line.
Copy the text, use Plugins>New>Macro (in ImageJ1; Fiji is ImageJ2), paste the text, then from the Macro menu, choose Run. Adapt the spline, click OK and voillá, there is your data.


run("Fit Spline");
waitForUser("Move the points to the desired locations, then press OK");
run("Interpolate", "interval=1"); //use every pixel under the ROI
Roi.getCoordinates(xpoints, ypoints); //get their coordinates;//can be saved as text;
for(pixel=0;pixel < xpoints.length; pixel++){//display the location and the colour values
	x = floor(xpoints[pixel]);
	y = floor(ypoints[pixel]);
	pv = getPixel(x, y);
	red = (pv>>16)&0xff;  // extract red byte (bits 23-17)
	green = (pv>>8)&0xff; // extract green byte (bits 15-8)
	blue = pv&0xff;       // extract blue byte (bits 7-0)
	print("("+x+","+y+") = "+red+","+green+","+blue);	//print to the log window
saveAs("Text", getDirectory("temp")+"results.txt");//save as text in the temp folder of the computer

Thank you very much @eljonco

run("Fit Spline");
saveAs("Text", "C:/Users/DR.MOSTAFA/Desktop/Log.txt");
saveAs("Results", "C:/Users/DR.MOSTAFA/Desktop/ypoints.csv");

This what I’ve done

This is the picture i’m working on.

Thanks for posting the image. Has your question been answered to your satisfaction?

When I paste the text in the macro, there is a distortion in the line on the image.
another point is that, when i save the two columns of data, one y points are saved in excel sheet and x points in note?

Finally, How can I get the final Graph

I’m not sure what you mean with the distortion. If three points are not sufficient to accurately describe the eyebrow, you can add coordinates of a fourth point, e.g.


The two arrays (x coordinates and y coordinates) are shown in their own windows. You can copy-paste or SaveAs each of them.
Alternatively, to get each result in a separate column which can be imported into a spreadsheet as tab separated text, change the print statement to


and change the last line to

selectWindow("Log");saveAs("Text", getDirectory("temp")+"results.txt");

The spline appears like in the picture once I run the macro

The cure is inverted upside down


Image processing happens in a grid where (0,0) is the top left coordinate, bigger y values going downward.
In spreadsheets (0,0) is in the bottom left, with bigger y values going upward
Suppose 600 is the maximum value of column B then the solution is a function that corrects for this:
then plot the resulting columns C as x, D as y in a scatter plot.

More involved solutions would calculate the max value of column B, put the result in, say, D1 and then your correction would be

Thank you very much dear @eljonco for your effort and precious time

All the best


Hello @eljonco,
I used Data in excel sheet to sort y values from smallest to largest to correct the problem of inverted curve, is it okay?

Regarding the segmented line, is it as accurate as Bezier curve?
Do you think that the number or the location of the points have an effect on the values, or the fitting of the curve?

  • How can the final curve displayed relative to the pupil?

All the best

Hi @Mostafa_Diab,

As an answer to your first question: Just sorting the y values doesn’t seem to correct any problem. It swaps y coordinates that belong to different x coordinates.

About the second question: The data (numbers, coordinates of the points on the curve) is generated from three points and a formula. Any point in between is just an interpolation of these three points and does not add information, just a bit of visual fluff. Fitting a curve to it does not add information either; all information is already in the three (four?) points that define the curve. As each pixel on the segmented is generated from the Bezier function, the set of pixels is just as accurate as the function that generated them, subpixel resolution set aside.

You apparently are after a distance of something to the pupil relative to something else. The two somethings are unknown to me. Try to put these to words, please as there might very well be a much simpler way to answer your scientific question (which is still unclear to me).

How can the final curve displayed relative to the pupil?

What final curve do you mean? The Bezier shaped line selection is already there. Do you mean another measure?

The dashed line in Figure 3. indicates something; what measure does it indicate? Relative to what? What is the meaning of the dashed line. Why is there an arrow on the curve? Why is it in that location? Would that location change if the right side of the curve would be 0 too? Would the curve change if the patient tilted her/his head? How was that vertical line determinated?

And on the pupil: it is very hard to detect when the image is taken with one flash which reflects on the eye at the location of the pupil. Have you tried to make a photo using a ring illumination? This image from Google shows why optimising source material for image processing is paramount: eye ring lit.tif (313.0 KB)
In this image, finding the key locations including the pupil is a whim. Maybe a diffusor would make the quality of the recording even better.