How to draw the result of "Analyze Particles" on the original image?

I need to count the number of particles found in the following image:

But before analyzing it using “Analyze > Analyze Particles”, I have to perform some pre-processing tasks on it like “Subtract Background” or converting it to binary. Therefore, the resulting circles of “Analyze Particles” will be drawn on the binary image. I need to show the found circles on the original image though. I guess I have to do that with ROI Manager, but don’t know how. Any advice would be appreciated.

Hi meysam,

in the Particle analyser, you can select “Add to manager” and after analysis, all ROIs will be shown in the list of the ROI manager. If you then switch to your original image and select “Show all” in the ROI manager, the ROI manager will show all ROIs on the original image. For visualisation purposes, it may make sense to select the “Labels” checkbox as well. :slightly_smiling:

Cheers,
Robert

1 Like

Thank you, it worked!
Some questions:

  1. How can I save the original image with circles shown on it? When I save it, the circles drawn on it do not get saved.
  2. I need to do this in a custom java application I am developing. So I load the input image in an ImagePlus object, convert it to binary, and analyze particles on it. Do you know how I can programmatically add/draw the found circles to/on the original ImagePlus object?

Use the ij.gui.Overlay class.

See how it’s done in RoiManager.java:

2 Likes

ImageJ is definitely tailored toward doing exactly that. The process is described on the Segmentation page of the ImageJ wiki. See in particular Transferring Selections.

As @haesleinhuepf describes, it’s pretty automatic, since the ROI Manager is a global (i.e.: image independent) window. Any ROIs you add to the ROI Manager using the T key can be visualized on any open image by:

  1. Clicking the image; then
  2. Toggling the “Show All” option in the ROI Manager
3 Likes

Check out “Flatten” in ROI manager (after, of course, reading Segmentation as indicated by earlier posts).

Just remember, if you can do it manually, the macro recorder can convert your steps into programmatic code. Start with that idea.

1 Like

Thank you for the advice. But I guess the generated java code by the macro recorder, is only suitable for developing plugins. Since I am developing my own java application, I can only get general ideas from the generated macro and may not be able to directly use it.

Are you generating macro code? Or Java code? The recorder can do either.

The Java code generated will work from your own application, with the caveat that it might rely on the ImageJ 1.x user interface being visible to work properly, depending on the circumstances.

Yes I generated the java code. I don’t want the ImageJ user interface to be visible in my application.

You will find various limitations in what you can do using the ImageJ 1.x API without its interface being visible.

In general, consider using the ImageJ2 APIs instead for maximum flexibility.

If you describe specifically what you are trying to do, we can comment further.

1 Like

Thank you for your prompt reply @ctrueden. I am specifically trying to deal with the problem I’ve already described here on StackOverflow. I am going to develop a software for a hair transplant company which allows them count the number of hairs they transplant for each patient. I may ask specifically about this on a separate question, but that’s all I am trying to achieve.

I am trying to count the number of white dots in that scalp picture using a combination of several methods and filters including: “Subtract Background”, “FFT > Bandpass Filter” (to correct uneven illumination), “Adjust > Threshold”, Posterizing (which seems not to be available in ImageJ), “Binary > Fill Holes”, “Filters > Median”, “Process > Binary > Erode, Dilate, Open, Close, Watershed”, “Analyze > Analyze Particles” and finally use the “ROI Manager” to show the found dots and count them. I may also need to use some filters from “Plugins > Fast Morphology > Morphological Filters”.

That’s all the features I think I need to use of ImageJ library behind the scenes in the application I am developing.

I also came across Cell Profiler which seems very promising. Do you think I can use it for my purpose?

And thank you for pointing out ImageJ2 APIs. Currently I am using the libraries shipped with ImageJ 1.49. Is it fine if I download https://github.com/imagej/imagej to work with ImageJ2 API? What about testing its functionality before using the API? Should I use Fiji instead of ImageJ?

Hi Meysam

If you are interested in ImageJ2 I suggest starting with the ImageJ2 tutorials on github

I have actually been working on projects similar to yours over the last couple years, processing images from dermatology, looking for spots, porphyrins etc…

I put some code on github that shows how you might attack scalp analysis in an ImageJ2ish fashion… by no means polished or optimized for your application, however it shows how you might build an application out of ImageJ2 commands and ops.

Scalp analysis example(s)

2 Likes

Thank you @bnorthan :slightly_smiling: I really appreciate the code you shared on github. Could you please share the file this example application is working with? (aR5VYcropped.tif) (Is it the scalp image I posted myself?)

And your sample application opens the ImageJ as well, right? Is it possible to avoid it?

It’s easy to avoid opening up the ImageJ. I just updated it on github.

this code starts imagej and shows the GUI

 final ImageJ ij = net.imagej.Main.launch(args);

this code creates a new ImageJ instance… but doesn’t show the GUI

final ImageJ ij = new ImageJ();
2 Likes

I just cropped a version of the ‘truecolor’ image you shared on stack overflow. It was cropped closer to the patient’s head, just to make the program run faster.

2 Likes

@meysam I updated the Scalp Analysis so that it can find Fiji plugins. Previously the routine based on “Auto Threshold” didn’t run correctly. If you want to try running the program on your machine you will have to edit ScalpAnalysisMain.java so that the directory locations are correct for your system.

Do you use maven?? To start my example project, from the command line with maven try

mvn exec:java -Dexec.mainClass=“com.truenorth.ScalpAnalysisMain”

For ImageJ2 development it is useful to know a little bit about maven. Maven in 5 minutes.

Maven can be used within an IDE. I use eclipse, I think you mentioned you use NetBeans?? If so search for “NetBeans Maven” or ask other netbeands users about this.

1 Like

Hi @bnorthan
Thank you for the update. Indeed, I’ve never used maven before, but it seems easy to get my hands on it. I can work both on Windows and Linux, but currently I am on Windows and cannot execute the mvn exec:java command you mentioned. Fortunately, I am using NetBeans to open your sample project and it apparently automatically takes care of the maven stuff. After opening the project in NetBeans, it resolves all the ImageJ dependencies using the pom.xml file. I could run your application and got two different output images (which to me seems that you have tested two different approaches on the image):

So it gives me a good start on using ImageJ and its plugins behind the scenes. I will take a look at your code and will try to fine tune it to get more accurate results. I greatly appreciate your help and will keep you posted. :smile:

2 Likes

Awesome that you got it running so fast.

Here is a quick explanation of the various parts of the program

The program is made of 4 Commands and a main

Main -> starts up headless imagej, loads the data, calls ScalpAnalysisCommand

ScalpAnalysisCommand -> high level command

OpsLogFilterThresholdCommand -> This uses the IJ2 ops library to perform the segmentation

IJ1LocalAutoThresholdAndOpenCommand -> Uses IJ1 function(s) to perform the segmentation

CountParticlesDrawOverlay -> Uses IJ1 to count particles and draw the overlay.

This example is really a hybrid ImageJ2/IJ1 program. If you have several IJ1 processing steps, that produce nice results for your example, it should be feasible for you to wrap them in your own command(s).

2 Likes

Dear @bnorthan,

I’ve been working on another project and just got the chance to get back to this…
I created a simple Maven-based JavaFx application in Netbeans, and added only ImageJ ij = new ImageJ(); to my code. But when the application starts, the UI of ImageJ is loaded separately and shown as well. Do you know why?

package com.meysam.hello;

import ij.ImageJ;

import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;

public class FXMLController implements Initializable {

    @FXML
    private Label label;

    @FXML
    private void handleButtonAction(ActionEvent event) {
        System.out.println("You clicked me!");
        label.setText("Hello World!");
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // create the ImageJ application context with all available services
        final ImageJ ij = new ImageJ();// net.imagej.Main.launch(args);

    }
}

I’ve also added these lines to the pom.xml file:

<repositories>
    <repository>
        <id>imagej.public</id>
        <url>http://maven.imagej.net/content/groups/public</url>
    </repository>
</repositories>
   
<dependencies>
    <dependency>
        <groupId>net.imagej</groupId>
        <artifactId>ij</artifactId>
        <version>1.50e</version>
    </dependency>
    <dependency>
        <groupId>net.imagej</groupId>
        <artifactId>imagej-common</artifactId>
        <version>0.19.0</version>
        <type>jar</type>
    </dependency>
</dependencies>

Hi @meysam, it looks like you are importing ij.ImageJ which is actually ij 1.50. in my imagej2 projects I import net.imagej.ImageJ

And add these lines to the pom.xml.

<parent>
		<groupId>net.imagej</groupId>
		<artifactId>pom-imagej</artifactId>
		<version>14.4.0</version>
		<relativePath />
</parent>

<dependencies>
		<dependency>
			<groupId>net.imagej</groupId>
			<artifactId>imagej</artifactId>
		</dependency>
</dependencies>
2 Likes