How to preserve ROI property/color?

Hi all,

Macro Code

I am writing a macro to create ROIs from a list of coordinates, where each coordinate pair has a width, height, group label, and a property label. I store these values in a table by reading in a .csv file, then access each column of the table as follows (where the name of the table is "Coordinates", for example):

cname = "Coordinates";
X = Table.getColumn("X", cname);
Y = Table.getColumn("Y", cname);
width = Table.getColumn("Width", cname);
height = Table.getColumn("Height", cname);
group = Table.getColumn("Group", cname);
property = Table.getColumn("Property", cname);

I then iterate over the X coordinates and create the ROIs:

// set counter for specific groups
c = 0; d = 0; h = 0;

for (i = 0; i < X.length; i++) {
	makeRectangle(X[i], Y[i], width[i], height[i]);
	roiManager("add");
	roiManager("Select", i);
	// for loop continued below

Finally, based on the group variable, I define individual properties of the

    // for loop continued from above
    if(group[i] == "cat") {
        Roi.setGroup(1);
        Roi.setStrokeColor("ff2281");
        Roi.setProperty("Attribute", property[i]);
        roiManager("update");
        c = c + 1; roiManager("rename", "Cat" + c);
    }
                
    if(group[i] == "dog") {
        Roi.setGroup(2);
        Roi.setStrokeColor("09fbd3");
        Roi.setProperty("Attribute", property[i]);
        roiManager("update");
        d = d + 1; roiManager("rename", "Dog" + d);
    }
                
    if(group[i] == "hamster") {
        Roi.setGroup(3);
        Roi.setStrokeColor("fe5e41");
        Roi.setProperty("Attribute", property[i]);
        roiManager("update");
        h = h + 1; roiManager("rename", "Hamster" + h);
    }
}

Finally, I save the ROIs as follows:

roiManager("List");
saveAs("Results", "<directory>/ROI_Results.csv");

I would also like to measure each channel of the ROI (I am operating over a multi-channel TIFF), so do the following:

nROI = roiManager("Count");
roiManager("show all with labels");

for (k = 0; k < nROI; k++) {

    roiManager("Select", k);

    // ROIname is the name of each ROI
    run("Duplicate...", "title=" + ROIname + " duplicate");

    // measure each channel based on new ROI
    for (s = 1; s <= nSlices; s++) {
        setSlice(s);
        run("Measure");										
    }

    // close image window
    close();

}

// save results
saveAs("Results", "<directory>/ROI_Measurements.csv");

// save ROIs to ZIP file
roiManager("Save",  "<directory>/ROIs.zip");

Questions

I have three specific questions and would be grateful for any insight/guidance:

  1. Am I creating my ROIs in the most efficient manner? Or are there certain steps which are unnecessary?

  2. When I open "ROI_Results.csv", I see the below table, but the Property value seems to be missing. How do I preserve it in the ROI export?

image

  1. When I open the image file and load the ROIs again, the stroke color is lost. How can I set the stroke color per group?

Thanks for your help.

Dear Anoori,

Are you sure your property column “Attribute” is actually reported in the ImageJ table in the first place before saving it ? I dont think that the run("Measure") command with a ROI will actually add a table column for every property of a ROI.
However you could add a few lines of code to automatically add it to the table.

I think the stroke color is saved as a preference in the ImageJ installation. However Roi group are associated to predefined (and non changeable) colors. So you dont need to additionally specify a stroke color if the ROI already has a group attribute.
The first groups sometimes have similar colors but you can use any index between 1 and 255.

1 Like

Hi Laurent,

Thanks so much for your insightful response. Thanks also to @Bio7 for a very useful discussion over PM.

Yes, run("Measure") will not automatically add the column. Right now, I am using the following chunk as a stopgap measure. Is this what you would recommend? Hopefully this snippet will be useful for others who may like to solve this issue using IJM.

// get coordinates
roiManager("List");
rname = "Image ROIs";
Table.rename("Overlay Elements of Image", rname);

// create empty arrays
nROI = roiManager("Count");
property_type = newArray(nROI); 
property_quality = newArray(nROI); 

// get ROI properties
for (k = 0; k < nROI; k++) {
    roiManager("Select", k);
    property_type[k] = Roi.getProperty("Type");
    property_quality[k] = Roi.getProperty("Quality");
}

// add to Table
Table.setColumn("Type", property_type, rname);
Table.setColumn("Quality", property_quality, rname);

Regarding the latter point about stroke color - thank you so much! I wasn’t aware that ROI group was associated to non-changeable colors. Do you know where I can find a list of these color mappings for indices 1-255 (so I can choose the best indices)?

Best,

Ayush

It’s a good way to do it yes, you could try to directly populate this table in the first for loop of the original snippet, but then you have to deal with 2 different tables at a time which is not easy in the macro language, so I think your solution is best :slight_smile:

Sure, It follows the color of a Look Up Table, the “glasbey” LUT.
You can have a look with
Image > Color > Display LUTs
or
Open an image, change its LUT to Glasbey (Image > Lookup Tables) then
Image > Color > Show LUT
this will show a graph with this at the bottom,


Roi of group 0 will always be yellow due to backward compatibility but from group 1 it follows this palette (ie group 1 is blue…).

2 Likes

Perfect, thanks again Laurent! I appreciate your advice.

Following up w/ @LThomas’s advice RE: the glasbey LUT. I was able to find the mapping from index to RGB at fiji/glasbey.lut at master · fiji/fiji (github.com). Another helpful reference for those interested: Glasbey (imagej.github.io). It might be useful to publicize the former in case other users would like to set the group color of their ROIs more precisely?

OK - I have used a simple R script available at miscellaneous/lut.R at main · ayushnoori/miscellaneous (github.com) to generate the following plot of the glasbey LUT in hopes that it may be useful to other ImageJ users with ROI groups:

2 Likes