ImageJ macro has loop error during ROI analysis - imagej

I am trying to analyze confocal microscopy image for cFos analysis.
From maxstacked image, I took ROI of DAPI and enlarged the ROI to detect the degree of expression of transgene marker.
So I can find whether expression of transgene Piezo1 is related to increase of cFof level.
Here's the problem, when I took ROI twice by processing DAPI image differently worked well, but this has a consideration that the sequence of both ROI groups might be not same.
So I tried to enlarge the ROI from DAPI image, but then I am having trouble in loop analysis.
The macro runs for ever, but seems like to be saving same file names again and again, even with skipping some of the files in array.
Thank you for reading.
//The one is in trouble
dir1 = getDirectory("Choose Source Directory ");
dir2 = getDirectory("Choose Destination Directory ");
list = getFileList(dir1);
Array.sort(list);
run("Clear Results");
setBatchMode(true);
for (i=0; i<list.length; i++) {
if (endsWith(list[i],"tif")) {
showProgress(i+1, list.length);
open(dir1+list[i]);
title = getTitle();
saveFilename = replace(list[i], "_Maxstacked.tif","");
selectWindow(title);
run("Duplicate...", "title=DAPI duplicate channels=4");;
selectWindow("DAPI");
run("Subtract Background...", "rolling=80");
run("Gaussian Blur...", "sigma=1");
run("8-bit");
run("Auto Threshold", "method=Li white");
run("Convert to Mask");
run("Minimum...", "radius=8");
run("Maximum...", "radius=9");
run("Watershed");
run("Analyze Particles...", "size=20-1000 display exclude clear include overlay add");
roiN = roiManager("count");
if (roiN > 0) {
roiManager("Save", dir2+saveFilename+"_DAPI+_RoiSet.zip");
for(i=0; i<roiN; i++) {
roiManager("Select", i);
run("Enlarge...", "enlarge=2.7");
roiManager("Update");
}
roiManager("Save", dir2+saveFilename+"_DAPI+_for_Piezo1_RoiSet.zip");
roiManager("Delete");
roiManager("Delete");
}
close("*");
}
}
//The one worked
dir1 = getDirectory("Choose Source Directory ");
dir2 = getDirectory("Choose Destination Directory ");
list = getFileList(dir1);
Array.sort(list);
run("Clear Results");
setBatchMode(true);
for (i=0; i<list.length; i++) {
if (endsWith(list[i],"tif")) {
showProgress(i+1, list.length);
open(dir1+list[i]);
title = getTitle();
saveFilename = replace(list[i], "_Maxstacked.tif","");
selectWindow(title);
run("Duplicate...", "title=DAPI duplicate channels=4");
selectWindow(title);
run("Duplicate...", "title=DAPI_for_Piezo1 duplicate channels=4");
selectWindow("DAPI");
run("Subtract Background...", "rolling=80");
run("Gaussian Blur...", "sigma=1");
run("8-bit");
run("Auto Threshold", "method=Li white");
run("Convert to Mask");
run("Minimum...", "radius=8");
run("Maximum...", "radius=9");
run("Watershed");
run("Analyze Particles...", "size=20-1000 display exclude clear include overlay add");
roiN = roiManager("count");
if (roiN > 0) {
roiManager("Save", dir2+saveFilename+"_DAPI+_RoiSet.zip");
roiManager("Delete");
}
selectWindow("DAPI");
run("Subtract Background...", "rolling=80");
run("Gaussian Blur...", "sigma=1");
run("8-bit");
run("Auto Threshold", "method=Li white");
run("Convert to Mask");
run("Minimum...", "radius=8");
run("Maximum...", "radius=16");
run("Watershed");
run("Analyze Particles...", "size=20-1000 display exclude clear include overlay add");
roiN = roiManager("count");
if (roiN > 0) {
roiManager("Save", dir2+saveFilename+"_DAPI+_for_Piezo1_RoiSet.zip");
roiManager("Delete");
}
close("*");
}
}

I think you created an endless loop, because you use i both times. So in the second for loop the i is set back to 0. Just try changing it in the second one (you can choose whatever letter or word).
...
for(n=0; n<roiN; n++) {
roiManager("Select", n);
run("Enlarge...", "enlarge=2.7");
roiManager("Update");
}
...

Related

ImageJ batch processing: saving results of each image separately in the csv format

I have around 30 images and use ImageJ macros to analyse the particles (area, circularity, etc.) in the batch. From the macros script that I'm using, I'm not able to save the results separately, I mean one results.csv file per image.
Script:
fileName = getTitle();
run("Set Scale...", "distance=231 known=200 unit=um");
//setTool("rectangle");
run("Select All");
makeRectangle(0, 0, 2560, 1856);
run("Crop");
run("8-bit");
setAutoThreshold("Default");
run("Threshold...");
setThreshold(0, 116);
setOption("BlackBackground", false);
run("Convert to Mask");
//run("Close");
run("Analyze Particles...", "size=80-Infinity display exclude summarize add");
selectWindow("Results"); //activate results table
saveAs("Results", "C:/folder/Results.csv");
In the final line, your script will save a file called Results.csv and then overwrite it when you save the next image. So you need to construct a unique path for the Results for each image.
fileName = getTitle();
run("Set Scale...", "distance=231 known=200 unit=um");
//setTool("rectangle");
run("Select All");
makeRectangle(0, 0, 2560, 1856);
run("Crop");
run("8-bit");
setAutoThreshold("Default");
run("Threshold...");
setThreshold(0, 116);
setOption("BlackBackground", false);
run("Convert to Mask");
//run("Close");
run("Analyze Particles...", "size=80-Infinity display exclude summarize add");
selectWindow("Results"); //activate results table
// construct unique path here using fileName
path = "C:/folder/" + fileName + ".csv";
saveAs("Results", path);

Operations in a for loop only apply to the last file in imageJ

I have a folder of images that I want to subtract a background file from them. I store the background file in another folder. I wrote the macro below but it only operates on the last file:
setBatchMode(true);
input_to_files = "C:/Users/user/Desktop/FL_20191115_40540 PM/";
input_to_BG = "C:/Users/user/Desktop/BG/";
output = "C:/Users/user/Desktop/SumZ/";
function action(input_file, filename, inputBG, bg, output) {
open(input_file + filename);
open(inputBG + bg);
imageCalculator("Subtract create stack", filename, bg);
saveAs("tif", output + filename);
close();
}
list = getFileList(input_to_files);
background = getFileList(input_to_BG);
for (i = 0; i < list.length; i++)
filename = list[i];
bg = background[0];
action(input_to_files, filename, input_to_BG, bg, output)
setBatchMode(false);
Your for-loop should be in braces and the final line of the loop needs a terminating semi-colon:
for (i = 0; i < list.length; i++) {
filename = list[i];
print(filename);
bg = background[0];
action(input_to_files, filename, input_to_BG, bg, output);
}

Imagej macro to save data generated by results and log pages into the same end excel file

I have created a macro that generates results both in the log and results pages. I need a macro that saves both the results and log files into one big excel file and is organized by image name.
input=getDirectory("Choose Source Directory ");
list = getFileList(input);
for (i = 0; i < list.length; i++)
rootangle(input, list[i]);
function angle (input,filename){
open (input + filename);
setTool("angle");
for (i = 0; i < 5; i++){
waitForUser("Select Angle Points");
run("Set Measurements...", " display redirect=None decimal=3");
//run("Measure");
}
setTool("multipoint");
waitForUser("Count");
run("Set Measurements...", " display redirect=None decimal=3");
run("Measure");
}
setTool("line");
waitForUser("Measure");
run("Set Measurements...", " display redirect=None decimal=3");
run("Measure");
}
setTool("freehand");
waitForUser("Distance");
run("Set Measurements...", " display redirect=None decimal=3");
run("Measure");
}
setTool("polyline");
waitForUser("Draw");
run("Fit Spline", "straighten");
getSelectionCoordinates(x, y);
for (i=0; i<x.length; i++)
print(i+" "+x[i]+" "+y[i]);
}
dir=getDirectory("image");
name = "Results";
index = lastIndexOf(name, "\\");
if (index!=-1) name = substring(name, 0, index);
name = name + ".xls"; ///can change xls to csv, txt, etc.
saveAs("Measurements", dir+name);
close();
}
run("Clear Results");
In this macro the polyline generates many many x,y coordinates for each image that may be bulky for the excel file. These coordinates can be listed on one line in the results excel file.
Is there a way you can add manual annotation to the label in the results page?
Also, is there a way you can add pose measurement functions? Like divide the numbers by 2, etc before creating the excel file?
I wrote a macro which saves results of ROI multimeasures to the log window. Since I only wanted specific results (the highest three Raw Integrated Densities), I had my code use getResult("Column Label", row) to get the results out, manipulate them, and then print to the log using print("stuff to print"). At the end, I saved the log as a csv, which one can open in excel. Just use commas to separate

Getting vector which holding certain point

I've a vector of points from a grey section of an image and written like this:
std::vector<Point> vectorg;
for(i = 0; i <= hei - 1; i++) {
for(j = 0; j <= wid - 1; j++) {
if(mask(i,j) == 128) {
vectorg.push_back(Point(j,i));
}
}
}
Knowing what coordinates stored in certain cell is possible by:
cout << vectorg[0].x;
cout << vectorg[0].y;
The question is now the other way around, is it possible to know which cell holds certain coordinates?
Thanks a lot, I'm new here also with opencv programming, I'll be in your care.
Just do the following:
#include <algorithm>
// ...
Point p(searchedX, searchedY);
std::vector<Point>::iterator element = std::find(vectorg.begin(), vectorg.end(), p);
if (element != vectorg.end()) {
cout << (*element).x << endl;
cout << (*element).y << endl;
} else {
cout << "The point is not in the vector" << endl;
}
It may be overkill, but a way to do it (without doing a greedy exhaustive search) would be to build a FLANN index that will store the position of your points.
The feature matrix is made of the coordinates of your points.
Since OpenCV knows how to convert a vector to a matrix, you should be able to use your current vector as is.
Then, if you want only one point, just ask for the 1 nearest neighbour in the query (k parameter).
The bonus is, if you decide later that you need to have also the closest points in the neighborhood, just raise the value of k.
Sorry for the late response, and thanks for the answers, they inspired me indirectly.
I found an easy way to do it. This is by making another Mat which holds the numbers where the coordinates were saved.
std::vector<Point> vectorg;
cv::Mat_<int> Index =Mat_<int>::zeros(hei,wid);
for(i = 0; i <= hei - 1; i++) {
for(j = 0; j <= wid - 1; j++) {
if(mask(i,j) == 128) {
vectorg.push_back(Point(j,i));
Index(vector[count])=count;
count++;
}
}
}
This way I can know which cell holds certain coordinates by simply:
cout<<Index(36,362); //as example
Thanks a lot, I'll be in your care next time.

How to get threshold value used by auto threshold Plugin

I have the following code, where I read images from directory and use ImageJ Auto Threshold plugin to segment my images.
dir = getDirectory("path");
list = getFileList(dir);
for (i=0; i<list.length; i++)
{
if (endsWith(list[i], ".tif"))
{
open(dir + list[i]);
run("8-bit");
run("Gaussian Blur...", "sigma=2");
setAutoThreshold("Otsu dark");
run("Convert to Mask");
saveAs("TIFF", dir+list[i]);
close();
}
}
I would like to get the threshold value using "Otsu dark" method, and modify that value (e.g. scale it by a factor) and apply it to my images for segmentation.
In an ImageJ macro, use the getThreshold(lower,upper) and setThreshold(lower,upper) methods (here's the documentation).
Your code would look like this then:
dir = getDirectory("path");
list = getFileList(dir);
factor = 1.5;
for (i=0; i<list.length; i++)
{
if (endsWith(list[i], ".tif"))
{
open(dir + list[i]);
run("8-bit");
run("Gaussian Blur...", "sigma=2");
setAutoThreshold("Otsu dark");
getThreshold(lower,upper);
setThreshold(lower,upper*factor);
run("Convert to Mask");
saveAs("TIFF", dir+list[i]);
close();
}
}
If you plan to do more complicated things, consider using another scripting language like the ones provided by Fiji.

Resources