ImageJ: Analyze particles in different ROI at the same time - imagej

I am measuring vessel area in different annual rings (trees; dendrochronology). I captured high quality pictures with approximatelly 20 annual rings. Each annual ring is my ROI.
I croped my image into 20 smaller images, each annual ring is one image. I open each image, I treshold it and use function: analyze particles.
However, it would be much less time consuming, if I could use my original image with 20 rings; I would separate each annual ring by defining ROI and I would label each ROI by 2012, 2011, 2010... After I would treshold the image and use function analyze particles. In my result table I would get area of vessel lumen for each vessel, separately for each annual ring.
The question is: is it possible to use ROI Manager and to set more ROIs and to analyze particles in them.
Thank you very much for your time.
Jernej

Use the ROI Manager to store your ROIs. Then use the ImageJ macro language and its built-in roiManager functions to loop over all ROIs. Record your analysis via Plugins > Macros > Record... to get the relevant macro commands.
Here's an example:
id = getImageID();
setAutoThreshold("Default");
for (i=0 ; i<roiManager("count"); i++) {
selectImage(id);
roiManager("select", i);
run("Analyze Particles...", "size=0-Infinity circularity=0.00-1.00 show=Masks clear");
}
To answer the additional questions you posted in another answer:
You get the name of the current ROI using Roi.getName() that you can use to name the results file:
current = Roi.getName();
saveAs("Results", "/path/to/results/Results_" + current + ".txt");
Alternatively, you can include the current ROI name in each line of your results by checking Display label in the Analyze > Set Measurements... dialog, resulting in a macro command similar to this:
run("Set Measurements...", "area display redirect=None decimal=3");
Please see the macro language documentation and the ImageJ mailing list archives before posting any new questions related to ImageJ macros.

Related

image preprocessing methods that can be used for identification of industrial parts name (stuck or engraved) on the surface?

I am working on a project where my task is to identify machine part by its part number written on label attached to it or engraved on its surface. One such example of label and engraved part is shown in below figures.
My task is to recognise 9 or 10 alphanumerical number (03C 997 032 D in 1st image and 357 955 531 in 2nd image). This seems to be easy task however I am facing problem in distinguishing between useful information in the image and rest of the part i.e. there are many other numbers and characters in both image and I want to focus on only mentioned numbers. I tried many things but no success as of now. Does anyone know the image pre processing methods or any ML/DL model which I should apply to get desired result?
Thanks in advance!
JD
You can use OCR to the get all characters from the image and then use regular expressions to extract the desired patterns.
You can use OCR method, like Tesseract.
Maybe, you want to clean the images before running the text-recognition system, by performing some filtering to remove noise / remove extra information, such as:
Convert to gray scale (colors are not relevant, aren't them?)
Crop to region of interest
Canny Filter
A good start can be one of this tutorial:
OpenCV OCR with Tesseract (Python API)
Recognizing text/number with OpenCV (C++ API)

setting threshold and batch processing in ImageJ (FIJI) macro

I know this has been posted elsewhere and that this is no means a difficult problem but I'm very new to writing macros in FIJI and am having a hard time even understanding the solutions described in various online resources.
I have a series of images all in the same folder and want to apply the same operations to them all and save the resultant excel files and images in an output folder. Specifically, I'd like to open, smooth the image, do a Max intensity Z projection, then threshold the images to the same relative value.
This thresholding is one step causing a problem. By relative value I mean that I would like to set the threshold so that the same % of the intensity histogram is included. Currently, in FIJI if you go to image>adjust>threshold you can move the sliders such that a certain percentage of the image is thresholded and it will display that value for you in the open window. In my case 98% is what I am trying to achieve, eg thresholding all but the top 2% of the data.
Once the threshold is applied to the MIP, I convert it to binary and do particle analysis and save the results (summary table, results, image overlay.
My approach has been to try and automate all the steps/ do batch processing but I have been having a hard time adapting what I have written to work based on instructions found online. Instead I've been just opening every image in the directory one by one and applying the macro that I wrote, then saving the results manually. Obviously this is a tedious approach so any help would be much appreciated!
What I have been using for my simple macro:
run("Smooth", "stack");
run("Z Project...", "projection=[Max Intensity]");
setAutoThreshold("Default");
//run("Threshold...");
run("Convert to Mask");
run("Make Binary");
run("Analyze Particles...", " show=[Overlay Masks] display exclude clear include summarize in_situ");
You can use the Process ▶ Batch ▶ Macro... command for this.
For further details, see the Batch Processing page of the ImageJ wiki.

Mathematical Operations on an Image Stack in ImageJ (Fiji)

I am writing an imageJ/Fiji plugin in Jython using the pydev plugin in eclipse.The plugin will be the ImageJ version of an already existing denoising software called CANDLE written as a matlab program. Changing the value of every pixel(voxel) of an image in matlab is trivial:
InputImage = 2 * sqrt(InputImage + (3/8));
Median3DFilteredImage = 2 * sqrt(Median3DFiltered + (3/8));
Here "InputImage" and "Median3DFilteredImage" are 3D Matrices, with the last dimension being time (slices). To reproduced the following operation on an ImageJ image, I had to employ two for loops, one to iterate through the image slices (3rd dimension) and the other loop to iterate over all the pixels in a particular slice:
medFiltStack = medianFilteredImage.getStack()
newMedFiltStack = ImageStack(medianFilteredImage.width, medianFilteredImage.height)
InputStack = InputImage.getStack()
newInputStack = ImageStack(InputImage.width, InputImage.height)
for i in xrange(1 , medianFilteredImage.getNSlices() + 1):
ip = medFiltStack.getProcessor(i).convertToFloat()
ip2 = InputStack.getProcessor(i).convertToFloat()
pixels = ip.getPixels()
pixels2 = ip2.getPixels()
for j in xrange (len(pixels)):
pixels[j] = 2 * javaMath.sqrt(pixels[j] + (3.0/8.0) )
pixels2[j] = 2 * javaMath.sqrt(pixels2[j] + (3.0/8.0) )
newMedFiltStack.addSlice(ip)
newInputStack.addSlice(ip2)
medianFilteredImage = ImagePlus("MedianFiltered-Image", newMedFiltStack)
InputImage = ImagePlus("Input-Image", newInputStack)
My question is as follows: Is there a way to perform mathematical operations on an image Stack, i.e. on every pixel (voxel) in the image stack, without having to write code that explicitly visits every pixel in every slice of the image, i.e. for loops. It just seems to be a very primitive way of going about it and I am wondering if there isn't an optimal way of doing this operation. I also had to work with copies and then gave the new images the same names as before as opposed to working with the original images and editing them directly. So is there a way to edit the pixel values of the original images rather than copies of the images? Any help would be appreciated as there are plenty of more math operations that I have to perform. It would be super useful to find a way to do mathematical operations on images in an optimal way both in terms of the amount of code and if possible, in terms of speed.
In pure ImageJ 1.x, the answer is: no, there's no other way than to visit every slice and get its ImageProcessor. That's the way how ImageJ1 deals with its limited number of dimensions (z, time, channel), you always have a (Hyper-)Stack of 2D planes.
There is however a more powerful way of dealing with n-dimensional images called ImgLib, which is included into Fiji together with ImageJ2.
To avoid re-inventing the wheel, you should have a look a Jean-Yves Tinevez's great plugin Image Expression Parser. Use it headlessly with Fiji, or just have look at its source code (it uses a previous version though, ImgLib1, but the idea is the same: you avoid hard-coding the dimensions by using Java generics), see e.g. for the sqrt function:
public final <R extends RealType<R>> float evaluate(final R alpha) {
return (float) Math.sqrt(alpha.getRealDouble());
}

Difficulty counting cells due to clustering and pixel value cut off

EDIT:
I have continued working on my problem among other things and have made significant process. Using one Dr. Ashby's macro provided on ImageJwiki, and using some of my own makeshift code I can now do batch processing of images taken of Hoescht, Calcein AM, and Ethidium Homodimer stains and get decent recognition of objects. Reducing exposure time and levels of stain used (specifically calcein AM) has helped with the pixel value cut offs I was dealing with earlier. The macro still has problems with distinguishing clumped cells from one another though. To address this issue I want to implement a command in my macro that divides clusters of cells that it identifies as one cell based on the average size of our cells. The only problem is that in all my reading I haven't seen anything that mentions this. Does anyone have any thoughts on how I could implement this code? I have copied the macro below.
//get appropriate directories from user
dir1 = getDirectory("Choose Source Directory ");
dir2 = getDirectory("Choose Destination directory");
list = getFileList(dir1);
//give user an opportunity to adjust default parameters to better fit their application
Dialog.create("Adjust for objective magnification");
Dialog.addNumber("Objective Magnification (use 10 if unknown)", 10);
Dialog.addMessage("\tIf needed particle size limits can be adjusted below \nLeave mag. at 10 if customizing particle size limits\n");
Dialog.addNumber("Minimum particle size (pixels^2)",420);
Dialog.addNumber("Maximum particle size (pixels^2)",1600);
Dialog.addMessage("\tIn the following dialogs select \n first the Source Directory, \nthen a Destinaion directory for Results");
Dialog.show();
//Assigning the entered values to variables
magnification=Dialog.getNumber();
userMin=Dialog.getNumber();
userMax=Dialog.getNumber();
sMin=magnification*magnification/100*userMin;
sMax=magnification*magnification/100*userMax;
setBatchMode(true);
for (i=0; i<list.length; i++){
//print (list[i]);
open(dir1+list[i]);
name=File.nameWithoutExtension;
//Prepare the image by removing any scale and making 8-bit
run("Set Scale...", "distance=0 known=0 pixel=1 unit=pixel");
run("8-bit");
saveAs("Tiff", dir2+i+" Original "+name);//Saving with this naming scheme is required for the MeLast macro to function
//run("Brightness/Contrast...");
setMinAndMax(50, 255);
setOption("BlackBackground", false);
run("Make Binary", "method=Yen background=Light calculate black");
run("Watershed", "stack");
//Analyze particles
run("Analyze Particles...", "size="+sMin+"-"+sMax+" circularity=0.50-1.00 show=[Count Masks] display exclude include summarize");
//Save the masks file
saveAs("Tiff", dir2+i+" CountMask "+name);//Saving with this naming scheme is required for the MeLast macro to function
close();
//Save the thresholded image
saveAs("Tiff", dir2+i+" Thresholded "+name);//Saving with this naming scheme is required for the MeLast macro to function
}
//Save the results
selectWindow("Results");
saveAs("Results", dir2+"ZZ Results.xls");
//Save the summary
selectWindow("Summary");
saveAs("Text", dir2+"Z Summary.txt");
You need to find those clusters and analyze each to guess how many cells might belong to that cluster, using spatial information of the cells and other specific information in your problem domain. I believe that's an usual image analysis task.
As for cut-off pixel values, I guess you can consider the cut-off pixels as censored data. But I am not sure how meaningful it would be for 8 bit depth images.
There is another free, open-source program called CellProfiler (http://www.cellprofiler.org) that has some more specialized methods for separating cells -- more advanced than the standard watershed. See, for example, part of the manual here: http://www.cellprofiler.org/CPmanual/IdentifyPrimaryObjects.html.
Perhaps CellProfiler can do the job, or point you to the right algorithms to bring into the ImageJ macro.

Compare Scanned Images and detect very small visible changes

I need a solution to compare two scanned images.
I have an image of an application form (unfilled), I need to compare that against other images of the same form, and want to detect whether there is any totally unfilled application form.
I just tried with Emgu CV AbsDiff, MatchTemplate etc, but none of them give me a 100 % match, even if I scanned the same form twice in the same scanner, could be because of the noise in the scanning, I can apply a tolerance but the problem is that I need to find out whether the user has filled anything in it. If I apply a tolerance then small changes in the form will not be detected.
I also had a look at the Python Image Libray, Accord.Net etc but couldn't find an approach for comparing this type of image.
Any suggestions on how to do this type of image comparison ?
Is there any free or paid library available for this ?
Only inspect the form fields. Without distractions it's easier to detect small changes. You also don't have to inspect each pixel. Use the histogram or mean color. I used SimpleCV:
from SimpleCV import *
form = Image("form.png")
form_field = form.crop(34, 44, 200, 30)
mean_color = form_field.meanColor()[0] # For simplicity only red channel.
if mean_color < 253:
print "Field is filled"
else:
print "Field is empty"
Alternatively look for features. E.g. corners, blobs or key points. Key points will ignore noise and will work better with poor scans:
key_points = form_field.findKeypoints()
if key_points:
print "Field is filled"
key_points.show(autocolor=True)
else:
print "Field is empty"

Resources