// Title of the tool: Sort Selections in Overlays // First version: 06/02/2013 // Description: get overlays elements from any kind of selection (line, freehand etc...) with the options of // inclusion, exclusion and intersection (using exclusion removes selected overlays). // Allows sorting of the selected overlays elements from their colors. Compatible with composite images. // Author : Gilles Carpentier // Faculte des Sciences et Technologie, // Universite Paris Est Creteil Val de Marne, France. // Demo image: neuron cells culture. labeling: psd-95 post-synaptic element (red), V-Glut (green) pre-synaptic element, // http://imagej.nih.gov/ij/macros/images/demo-overlay-multicolor.tif // Image courtesy of Pr.O. Stettler. Experiment author: Asma Soltani. Image acquisition and processing: Gilles Carpentier // Laser confocal microscope Olympus IX81 FV 1000. var selectionMaskID, unlabeledColor="#0076ff"; var inclu = 1, inter = 1, exclu = 0; macro "Sort Selections in Overlays [o]" { requires("1.47j"); var listOfOverlayColors = newArray; if (selectionType() == -1) exit ("This function requires a selection. \"Select All\" to treat the full image."); if (Overlay.size == 0) exit ("No overlay found in this image."); setSelectionName("User defined selection"); Overlay.addSelection(unlabeledColor); run("Select None"); UserSelectionIndex= Overlay.size-1; setBatchMode(true); nomdimage=getTitle(); overlayedImageID=getImageID(); listOfOverlayColors=listOfOverlayColor (overlayedImageID, listOfOverlayColors, unlabeledColor); listOfOverlayColors=userSettings (listOfOverlayColors); sufix= "."; if (lastIndexOf(nomdimage, sufix) > 1) { workingima = substring (nomdimage,0,lastIndexOf(nomdimage, sufix)); } else {workingima=nomdimage;} selectImage (overlayedImageID); run("Select None"); titre=workingima+"-sort"; if (is("composite")) { Overlay.copy; Stack.getDimensions(widthS, heightS, channelsS, slicesS, framesS); stringChannel="1-"+channelsS; stringSlices="1-"+slicesS; run("Duplicate...", "title=["+titre+"] duplicate channels=&stringChannel slices=&stringSlices"); Overlay.paste; } if (!is("composite")) run("Duplicate...", "title=&titre"); sortingImageID = getImageID(); rename (titre); titre=workingima+"-temp"; if (is("composite")) { Overlay.copy; Stack.getDimensions(widthS, heightS, channelsS, slicesS, framesS); stringChannel="1-"+channelsS; stringSlices="1-"+slicesS; run("Duplicate...", "title=["+titre+"] duplicate channels=&stringChannel slices=&stringSlices"); Overlay.paste; } if (!is("composite")) run("Duplicate...", "title=&titre"); archiveOverlay=getImageID(); selectImage(sortingImageID); Overlay.remove; selectionMaskID=getSelectionBinaryMask (archiveOverlay,UserSelectionIndex,"user-selection-Mask") ; for (j=0; j<(listOfOverlayColors.length); j++) { if (listOfOverlayColors[j] != "none") { colorMapID= getOverlayColor (archiveOverlay,listOfOverlayColors[j]); colorMaskID=getOverlayBinaryMask (colorMapID,listOfOverlayColors[j]); sortingOverlayID = getUnionOverlay (colorMapID, colorMaskID, selectionMaskID, sortingImageID, inclu,inter,exclu, listOfOverlayColors[j]); if (isOpen (sortingOverlayID)) { selectImage (sortingOverlayID); nOverlay= Overlay.size; if (Overlay.size > 0) { for (k=0; k<(nOverlay); k++) { selectImage (sortingOverlayID); Overlay.activateSelection(k); selectImage (sortingImageID); run("Restore Selection"); Overlay.addSelection(); } } } if (isOpen(colorMapID)) {selectImage(colorMapID); close();} if (isOpen(colorMaskID)) {selectImage(colorMaskID); close();} if (isOpen(sortingOverlayID)) {selectImage(sortingOverlayID); close();} } } if (isOpen(selectionMaskID)) {selectImage(selectionMaskID); close();} selectImage(archiveOverlay); Overlay.activateSelection(UserSelectionIndex); colorTest=getInfo("selection.color"); selectImage(sortingImageID); if (colorTest ==unlabeledColor) run("Restore Selection"); selectImage(overlayedImageID); Overlay.activateSelection(UserSelectionIndex); colorTest=getInfo("selection.color"); if (colorTest ==unlabeledColor) Overlay.removeSelection(UserSelectionIndex); if (isOpen(archiveOverlay)) {selectImage(archiveOverlay); close();} setBatchMode("exit and display"); } macro "-" {} macro "Hide overlay [h]" { run("Hide Overlay"); } macro "Show overlay [s]" { run("Show Overlay"); } macro "-" {} macro "Open Sample Image" { run("URL...", "url=http://imagej.nih.gov/ij/macros/images/demo-overlay-multicolor.tif"); run("Make Composite", "display=Composite"); } function getUnionOverlay (source1ID, binaryMapID, userSelectionBinaryID, destinationID, inclu,inter,exclu, currentOverlayColor) { imageCalculator("or create", binaryMapID, userSelectionBinaryID); getStatistics(area, mean, min, max, std, histogram); binORMapID=getImageID(); selectImage (source1ID); Overlay.copy; selectImage (binaryMapID); Overlay.paste; nOverlay=Overlay.size; for (j=0; j<(nOverlay); j++) { selectImage (binaryMapID); Overlay.activateSelection(j); selectImage (binORMapID); run("Restore Selection"); getStatistics(area, mean, min, max, std, histogram); Array.getStatistics(histogram, min, max, mean, stdDev); if (histogram[255] == 0) { // excluded overlay selectImage (binORMapID); if (exclu == 1) { nom=getInfo("selection.name"); selectionOverlayName = nom +"-excl"; setSelectionName(selectionOverlayName); Overlay.addSelection(currentOverlayColor, 0); } } if (histogram[255] > 0) { // intersection between overlays if (max != area) { if (inter == 1) { nom=getInfo("selection.name"); selectionOverlayName = nom +"-inter"; setSelectionName(selectionOverlayName); Overlay.addSelection(currentOverlayColor, 0); } } } if (histogram[255] > 0) { // included overlay if (max == area) { if (inclu == 1) { nom=getInfo("selection.name"); selectionOverlayName = nom +"-inclu"; setSelectionName(selectionOverlayName); Overlay.addSelection(currentOverlayColor, 0); } } } run("Select None"); } return binORMapID; } // returns the overlays which color is "colorOverlay" function getOverlayColor (sourceID,colorOverlay) { if (isOpen(sourceID)) selectImage (sourceID); titre=colorOverlay+"-map"; run("Select None"); run("Duplicate...", "title=&titre"); colorOverlayID = getImageID(); run("Remove Overlay"); selectImage (sourceID); nOverlay=Overlay.size; for (j=0; j<(nOverlay); j++) { selectImage (sourceID); Overlay.activateSelection(j); colorSelection = getInfo("selection.color"); selectionOverlayName = colorOverlay +"-thing"; selectImage (colorOverlayID); run("Restore Selection"); if (colorSelection==colorOverlay) {setSelectionName(selectionOverlayName); Overlay.addSelection;} run("Select None"); } return colorOverlayID; } // returns the binary mask of the overlay contained in image "sourceID " with the result title has the prefix "title" function getOverlayBinaryMask (sourceID,titre) { titre=titre+"-mask"; setColor(0, 0, 0); if (isOpen(sourceID)) selectImage (sourceID); getDimensions(width, height, channels, slices, frames); newImage(titre, "8-bit", width, height, 1); maskID=getImageID(); if (isOpen(sourceID)) selectImage (sourceID); nOverlay=Overlay.size; for (j=0; j<(nOverlay); j++) { selectImage (sourceID); Overlay.activateSelection(j); selectImage (maskID); run("Restore Selection"); fill(); } return maskID; } // returns a binary mask of the selections contained in the image "sourceID" with the result title has the prefix "title" function getSelectionBinaryMask (source1ID,indexOfUserelection,titre) { setColor(0, 0, 0); selectImage (source1ID); getDimensions(width, height, channels, slices, frames); newImage(titre, "8-bit", width, height, 1); maskID=getImageID(); selectImage (source1ID); Overlay.activateSelection(indexOfUserelection); colorTest=getInfo("selection.color"); if (colorTest !=unlabeledColor) exit "no user selection detected"; selectImage (maskID); run("Restore Selection"); if (selectionType() == 4 ||selectionType() == 5 || selectionType() == 6 || selectionType() == 7 ) { setForegroundColor(0, 0, 0); run("Draw"); } else { if (selectionType() == 9) run("Draw"); fill(); } run("Make Binary"); selectImage (source1ID); run("Select None"); return maskID; } function listOfOverlayColor (sourceID, listOfColors, exeptColor) { setOption("ExpandableArrays", true); selectImage (sourceID); nbOverlays=Overlay.size; if (nbOverlays > 0) { for (i=0; i<(nbOverlays); i++) { Overlay.activateSelection(i); colorSelection = getInfo("selection.color"); testOfColor=0; for (j=0; j<(listOfColors.length); j++) { if (colorSelection == listOfColors[j] || colorSelection==exeptColor ) testOfColor = 1; } if (testOfColor==0) { listOfColors [listOfColors.length]=colorSelection; } } } run("Restore Selection"); return listOfColors; } function userSettings (colorList) { Dialog.create("Color and Belonging"); Dialog.addCheckbox("Included", inclu); Dialog.addCheckbox("Excluded", exclu); Dialog.addCheckbox("at intersection", inter); Dialog.addMessage("\nColor Sorting"); for (j=0; j<(colorList.length); j++) { if (colorList[j] != unlabeledColor) Dialog.addCheckbox(colorList[j], 1); } Dialog.show(); inclu=Dialog.getCheckbox(); exclu=Dialog.getCheckbox(); inter=Dialog.getCheckbox(); for (j=0; j<(colorList.length); j++) { if (colorList[j] !=unlabeledColor) { checkColor=Dialog.getCheckbox(); if (checkColor == 0) colorList[j]="none"; } } return colorList; }