Quantifying RNAScope spots and nuclei



I want to quantify red spots (in situ hybridization signal) and count the purple nuclei. I will have 12 samples and several images per sample. I can optimize images better. So far I have saved this positive control image as a tiff. I think I defined the red spots fairly well with the following method. Please advise if you have other suggestions. I am wondering how to (1) apply the classifier I created in the Trainable Weka Segmentation tool to other images. (2) count nuclei on same images (3) write a macro to automate. I am a new ImageJ user, so any suggestions are appreciated. I’ll upload the original image (PPIB 40x), the background subtracted image and a thresholded image.
After watching a Fiji training video, I tried the following:
Import Image using Bio-formats. Select Grayscale & split channels.

  1. Pre-Process
    Apply Gaussian Blur to Background image with Sigma 150
    Use Image Calculator to subtract Background from Original image
    Image 1 Original; Operation Subtract; Image 2 Background
    Check the “Create New Window” and “32-bit (float) result
    Rename Original - Bkgd; and Duplicate it.
    Process > Enhance Contrast > Default is saturated pixels: 0.3% > OK
  2. Threshold
    Plugins > Segmentation> Trainable Weka Segmentation
    Zoom in using the “+” key
    Create New Class
    Settings > Name Class 1 “Spots” > Name Class 2 nuclei > Name Class 3 Background
    Using line tool, draw across about 3 or 4 spots > Add to Spots
    Then draw across about 3 or 4 cells > Add to Nuclei
    Then hit “Train classifier”. This takes a minute or so.
    Re-adjust and re-train if necessary until you think the spots, nuclei and background are properly defined. Use the “Toggle overlay” button to check how the program did at labeling.
    Save Classifier.
    Create Result. Duplicate
    Image > Type > 8 Bit
    Image > Adjust > Threshold > Default > Red > Apply
    Create Mask
  3. Clean-up:
    Process > Binary > Watershed
  4. Analyze:
    Analyze > Analyze Particles > Size (micron squared) 1000000-Infinity > Display results > > Clear Results > summarize > Exclude on edgesPPIB-Background
    Thank you, Diane


Dear @diane,

sorry that your post has been sitting unanswered for so long!

I fear something went wrong during the upload. At least I can only see an empty image in your post. Could you try to upload those images again?

You can use the Apply button in the Trainable Weka Segmentation interface. See https://imagej.net/Trainable_Weka_Segmentation#Apply_classifier for more details.

That’s hard to say without looking at an example. Have you tried applying a similar method to the one for spot identification? The Trainable Weka Segmentation is a versatile tool (although it might be overkill in your case) that you can also use for nuclei detection. You’d end up with two classifiers that you can apply to the individual channels (Image > Color > Split Channels might be useful in that context) of your images.

You can start by using the Macro Recorder to record the steps that you are taking in the user interface. We also have an amazing presentation on the Wiki: https://imagej.github.io/presentations/fiji-scripting/#/



Thanks for the reply. I’ve been learning more about ImageJ in the last couple weeks, so hopefully I’m at a better starting point for help. I’ll upload an image with high expression of the signal (red spots) (#10383) and one with low expression (#9345). These are 8bit 2000dpi tiff images.

(1) I have figured out how to apply a classifier to other images. Would it be helpful for me to send the process I’ve been using for image classification or would you prefer to start from scratch? I think my classifier is working pretty well, but I’m sure it could be improved with more knowledge. I think I’m over-counting the signal in some cases. I’m trying to increase contrast between the signal and the nuclei to better count both, especially the signal. (I’ll just add my sequence to the bottom of this reply. You can ignore it if you don’t need it.)
(2) I’ve been able to count signal and nuclei on the same image by using the trainable weka and then thresholding at different levels for the 2 sized objects.
(3) I have tried recording a macro but am confused about how to remove the title dependency of the original image.

  1. Open Image in BioFormats selecting Grayscale and Split Channels.
    This opens 3 images: C=0, C=1, C=2
    C=1 shows both the nuclei and spots I want to measure. Close other 2 images.
  2. Duplicate C=1. Perform a Gaussian Blur with Sigma Radius 150 on duplicate & name it background.
  3. Image Calculator to subtract Background image from C=1 (create new window & 32-bit float result checked)
  4. Process > Filter > Minimum 1 pixel > Sharpen (I’m not sure I like how this makes the spots larger.)
  5. Plugins > Segmentation > Trainable Weka Segmentation.
    Create new class (background)
    Settings: Use default settings of Training Features: Gaussian blur, Hessian, Membrane projections, Sobel filter, Difference of Gaussians. Membrane thickness 1. Membrane patch size 19. Minimum sigma 1. Max sigma 16. Filter option FastRandomForest.
    Class names: 1 spots, 2 nuclei, 3 bkgd
    Result overlay opacity 33.
  6. Define spots, nuclei and bkgd. Train classifier. This will take a couple of minutes. Toggle overlay to check correctness of labeling.
  7. Create result. Image > Type > 8 bit and threshold in Image > Adjust >Threshold
    The default 0-130 range labels the spots well.
  8. Create mask
  9. Analyze > Analyze Particles > size 5-100 pixels squared. Circularity 0-1. Show Nothing. Display Results. Clear Results. Summarize. Add to Manager. Exclude on edges.
  10. Go back to Trainable Weka Segmentation and Create Result again. It should pop right up. Image > Type > 8 bit and threshold in Image > Adjust >Threshold. This time threshold on the nuclei. 0-155 works well.
  11. Create mask
  12. Watershed split > Analyze > Analyze Particles > size 500-15000 pixels squared. To check the accuracy of the labeling, Image > Overlay > Add Image > select the starting image – bkgd and Opacity 50%.

Thank you,


I would suggest that you open one image via File > Open (I don’t see a necessity for using Bio-Formats but might be mistaken) and subsequently start the Macro Recorder. Your next step should be to use Image > Color > Split Channels and close the unwanted images. Then continue with your described procedure but instead of training a classifier, use Load classifier and Create result. Afterward, continue with your procedure and copy your resulting macro in here s.t. we can help with generalizing.

The general idea is to record a macro that can be applied to other images and this does not include re-training of a classifier (hopefully).


Thanks for the reply on the macros. I think I’ve got it now. Did you have any advice on optimizing the segmentation of the images I sent? Thanks


Do you observe any issues in your downstream processing with your current segmentation approach? If so, what exactly is the issue and could you upload the output of the Trainable Weka Segmentation for the two images that you have posted? Thanks!


I have a couple questions about the Set Scale function in ImageJ.

  1. My first question is that a known scale bar and the automatic set scale from the meta data produce very different set scale conversions. The automatic from the meta-data seems more accurate, but I’m confused as to why my embedded scale bar would produce incorrect conversion.

I am opening an 8bit 2000dpi tiff in the Bio-Formats function as a split channel, grayscale image. I have a 20x image with an embedded scale bar of 5 microns on the image. If I go to Analyze > Set Scale, I get the following Set Scale data which I think is calculated from the meta-data embedded in the image file:

If I measure the 5 micron scale bar on the image using the freehand straight line tool and go to Analyze > Set Scale I get this data which is the same ratio as the Set Scale above.

However, I know that the known distance is not 3920 microns, but 5 microns! If I change the known distance, the conversion is now Scale: 61.733 pixels/micron. The 2 conversions are so vastly different I don’t know what I’m doing wrong.

  1. My second question is what units is the Average Size in in my results. I know this depends on whether I’ve used a conversion. But this relates to the question above.

I am counting particles (spots) and nuclei on the image. Again, I open an 8-bit 2000dpi tiff in Bio-Formats using split channel and grayscale. I close the C=0 and C=2 images and preprocess the C=1 image to increase contrast of the features of interest using this macro:

Then I in the Trainable weka Segmentation function I trained a classifier to identify spots and nuclei. After that I used the following macro to get counts of spots and nuclei and the sizes of both.

I gated the spots for either 5-100 pixel^2 or 10-100 pixel^2 and the nuclei for 500-5000pixel^2. Even though I am defining the feature size in pixel^2 I think the system is using the default set scale conversion of 0.787 pixels/micron and reporting is the Average Size in micron^2. In the in the Summary chart below, row 3 reports 289 nuclei counted with an average nuclei size of 281135. If this unit is in micron^2 then using area = pi(r^2) then the radius of the nuclei would be 299um, diameter = 600um. I think these nuclei should have a diameter in the range of 80-500um so that is close to the upper end of the scale.
If I were to use the conversion measured off the scale bar on the image, I get an average size of 0.456micron^2 which calculates to a radius of 0.38um and a diameter of 0.76microns. So this seems incorrect. Can you see what I am doing wrong?
Thanks you so much for all your help!!