Hello -
Does anyone have experience with anaylzing a grid of square ROIs according to mean gray values? Basically, I am trying to quantify how sorted or patchy a given field of cells (half of which are stained for GFP) is, using nearest-neighbor analysis. The method is described in more detail in this paper (http://www.ncbi.nlm.nih.gov/pubmed/9520108?dopt=Abstract), but basically what we want to do is: 1. divide the image into a grid of squares with height and width approximately equal to cell diameter 2. find the mean gray value of the whole image and set it as the threshold 3. count each square as above or below the threshold 4. count how many of each "above threshold" square's nearest neighbor squares (above, below, left, and right) are above threshold I can do step (1) using a variant of the macro found here (http://imagej.1557.x6.nabble.com/How-to-create-a-regular-grid-of-rectangular-ROI-s-td3685056.html), and step (2) is fairly trivial, but I am totally lost when it comes to steps (3) and (4). Thanks very much! Audrey Postdoc, Bush lab Cell and Tissue Biology UCSF School of Dentistry -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Dear Audrey,
I had a play around with some code yesterday evening starting with the reference code you referred to and came up with: macro analyse_grid{ connected = 0; width = 4; height = 4; spacing = 0; Dialog.create("ROI"); Dialog.addNumber("ROI width in pixels", width); Dialog.addNumber("ROI height in pixels", height); Dialog.addNumber("Spacing between ROIs", spacing); Dialog.show(); width = Dialog.getNumber(); height = Dialog.getNumber(); spacing = Dialog.getNumber(); run("Select None"); setBatchMode(true); title=getTitle(); H = getHeight(); W = getWidth(); run("Set Measurements...", " mean redirect=None decimal=3"); getRawStatistics(nPixels, mean, min, max, std, histogram); numRow = floor((H+spacing)/(height+spacing)); numCol = floor((W+spacing)/(width+spacing)); x = ((W+spacing)-(numCol*(width+spacing)))/2; y = ((H+spacing)-(numRow*(height+spacing)))/2; for(i = 0; i < numRow; i++){ for(j = 0; j < numCol; j++){ xOffset = j * (width + spacing); yOffset = i * (height + spacing); makeRectangle(x + xOffset, y + yOffset, width, height); roiManager("Add"); } } n = roiManager("count"); newImage("Mean", "RGB Black", W, H, 1); for(i=0;i<n;i++){ selectWindow(title); roiManager("select", i); getRawStatistics(nPixels, meanROI, min, max, std, histogram); meanROI=mean/meanROI; selectWindow("Mean"); if(meanROI>1){ setForegroundColor(0, 0, 255); roiManager("select", i); roiManager("Fill"); } if(meanROI<1){ setForegroundColor(255, 0, 0); roiManager("select", i); roiManager("Fill"); } } //find way to select only red and compare neighbours selectWindow("Mean"); run("Duplicate...", "title=Mean-1"); run("Split Channels"); selectWindow("Mean-1 (green)"); close(); selectWindow("Mean-1 (blue)"); close(); selectWindow("Mean-1 (red)"); run("Select None"); run("Duplicate...", "title=connected"); run("RGB Color"); setForegroundColor(255, 0, 0); for (i=2; i<=numRow-1;i++){ for(j=2; j<=numCol-1;j++){ selectWindow("Mean-1 (red)"); run("Select None"); c = (i-1)*numCol+j; roiManager("select", c); getRawStatistics(nPixels, meanROI, min, max, std, histogram); if(meanROI == 255) { roiManager("select", c-1); getRawStatistics(nPixels, meanROIa, min, max, std, histogram); if(meanROIa == 255){ roiManager("select", c+1); getRawStatistics(nPixels, meanROIb, min, max, std, histogram); if(meanROIb == 255){ roiManager("select", c-numCol); getRawStatistics(nPixels, meanROIc, min, max, std, histogram); if(meanROIc == 255){ roiManager("select", c+numCol); getRawStatistics(nPixels, meanROId, min, max, std, histogram); if(meanROId == 255){ connected = connected + 1; selectWindow("connected"); roiManager("select", c); roiManager("Fill"); } } } } } //print(numCol, c); } } selectWindow("Mean-1 (red)"); close(); setBatchMode("exit and display"); print("number of connected ="+connected); } The macro allows you to set the square size as well as the spacing. It will give you two images with one showing grid squares above (red) and below (blue) the mean of the image, and an image showing the grid squares above mean (white) with the "above threshold" square's nearest neighbour squares marked in red + a log file with the total number. Obviously, additional information can be extracted from the data. You have to open an image and run the macro but I guess speed can be increased if you let the macro open the file in Batch mode. BE AWARE that I have not fully tested the code but have a look if it is useful. Best wishes Kees Dr Ir K.R. Straatman Senior Experimental Officer Centre for Core Biotechnology Services University of Leicester http://www.le.ac.uk/biochem/microscopy/home.html ImageJ workshops 29 and 30 July 2013 visit: http://www.le.ac.uk/biochem/microscopy/ImageJ2013.html -----Original Message----- From: ImageJ Interest Group [mailto:[hidden email]] On Behalf Of Audrey O'Neill Sent: 07 May 2013 19:18 To: [hidden email] Subject: Analyzing a grid of ROIs Hello - Does anyone have experience with anaylzing a grid of square ROIs according to mean gray values? Basically, I am trying to quantify how sorted or patchy a given field of cells (half of which are stained for GFP) is, using nearest-neighbor analysis. The method is described in more detail in this paper (http://www.ncbi.nlm.nih.gov/pubmed/9520108?dopt=Abstract), but basically what we want to do is: 1. divide the image into a grid of squares with height and width approximately equal to cell diameter 2. find the mean gray value of the whole image and set it as the threshold 3. count each square as above or below the threshold 4. count how many of each "above threshold" square's nearest neighbor squares (above, below, left, and right) are above threshold I can do step (1) using a variant of the macro found here (http://imagej.1557.x6.nabble.com/How-to-create-a-regular-grid-of-rectangular-ROI-s-td3685056.html), and step (2) is fairly trivial, but I am totally lost when it comes to steps (3) and (4). Thanks very much! Audrey Postdoc, Bush lab Cell and Tissue Biology UCSF School of Dentistry -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Audrey O'Neill
Hi,
On May 7, 2013, at 2:18 PM, Audrey O'Neill wrote: > Hello - > > Does anyone have experience with anaylzing a grid of square ROIs according to mean gray values? > > Basically, I am trying to quantify how sorted or patchy a given field of cells (half of which are stained for GFP) is, using nearest-neighbor analysis. > > The method is described in more detail in this paper (http://www.ncbi.nlm.nih.gov/pubmed/9520108?dopt=Abstract), but basically what we want to do is: > > 1. divide the image into a grid of squares with height and width approximately equal to cell diameter > 2. find the mean gray value of the whole image and set it as the threshold > 3. count each square as above or below the threshold > 4. count how many of each "above threshold" square's nearest neighbor squares (above, below, left, and right) are above threshold > > I can do step (1) using a variant of the macro found here (http://imagej.1557.x6.nabble.com/How-to-create-a-regular-grid-of-rectangular-ROI-s-td3685056.html), and step (2) is fairly trivial, but I am totally lost when it comes to steps (3) and (4). > You might be able to adapt the RATSQuadtree class in the RATS_ plugin - see http://rsb.info.nih.gov/ij/plugins/rats/index.html Once the quadtree is set up, you can query any 'leaf' to compute stats about the companion image within each 'leaf'. My memory of it is fuzzy enough that I don't recall if it will require a lot of tweaking to enforce square leaves - I think it is set up now to subdivide based upon a suggested minimum leaf size so you may end up with rectangles rather than squares. Cheers, Ben > Thanks very much! > > Audrey > Postdoc, Bush lab > Cell and Tissue Biology > UCSF School of Dentistry > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Hi Ben,
If you need an example of a macro that can iterate though a grid of ROIs and measure/do stuff to each then this may help: http://imagejdocu.tudor.lu/doku.php?id=macro:tiled_autofocus_hyperstack Cheers Rich On 09/05/13 18:20, Ben Tupper wrote: > Hi, > > On May 7, 2013, at 2:18 PM, Audrey O'Neill wrote: > >> Hello - >> >> Does anyone have experience with anaylzing a grid of square ROIs according to mean gray values? >> >> Basically, I am trying to quantify how sorted or patchy a given field of cells (half of which are stained for GFP) is, using nearest-neighbor analysis. >> >> The method is described in more detail in this paper (http://www.ncbi.nlm.nih.gov/pubmed/9520108?dopt=Abstract), but basically what we want to do is: >> >> 1. divide the image into a grid of squares with height and width approximately equal to cell diameter >> 2. find the mean gray value of the whole image and set it as the threshold >> 3. count each square as above or below the threshold >> 4. count how many of each "above threshold" square's nearest neighbor squares (above, below, left, and right) are above threshold >> >> I can do step (1) using a variant of the macro found here (http://imagej.1557.x6.nabble.com/How-to-create-a-regular-grid-of-rectangular-ROI-s-td3685056.html), and step (2) is fairly trivial, but I am totally lost when it comes to steps (3) and (4). >> > You might be able to adapt the RATSQuadtree class in the RATS_ plugin - see http://rsb.info.nih.gov/ij/plugins/rats/index.html Once the quadtree is set up, you can query any 'leaf' to compute stats about the companion image within each 'leaf'. My memory of it is fuzzy enough that I don't recall if it will require a lot of tweaking to enforce square leaves - I think it is set up now to subdivide based upon a suggested minimum leaf size so you may end up with rectangles rather than squares. > > Cheers, > Ben > > > > > >> Thanks very much! >> >> Audrey >> Postdoc, Bush lab >> Cell and Tissue Biology >> UCSF School of Dentistry >> >> -- >> ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- Dr Richard Mort MRC Human Genetics Unit MRC IGMM University of Edinburgh Western General Hospital Crewe Road Edinburgh. EH4 2XU, UK Tel: +44 (0)131 332 2471 Fax: +44 (0)131 467 8456 -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html The University of Edinburgh is a charitable body, registered in Scotland, with registration number SC005336. -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Audrey O'Neill
Thanks for working on this! Your output is a really nice visual representation (though I think it has some problems near the edges).
I was working on making up a macro myself, and I came up with something that is similar to yours but has slightly different outputs. I wanted to get the number of stained (white) neighbors of each stained square, not the number of stained squares that have 4 stained neighbors. Also, I decided that I will not need spacing between the squares and to convert all the images to 8-bit, so that simplifies matters. This is a macro where I set the threshold manually, but I have another one where I set it based on the median of the means of the ROIs. Thanks for your help! Audrey /* convert to 8-bit */ run("8-bit"); /* set desired variables */ imageName = getInfo("image.filename"); x = 0; y = 0; cellDiam = 80; // set according to average cell diameter in pixels in your image threshold = 20; // set threshold according to dimmest positive cell imageWidth = getWidth(); imageHeight = getHeight(); numRow = floor(imageHeight / cellDiam); numCol = floor(imageWidth / cellDiam); countSquares = numRow * numCol; countStainedSquares = 0; countStainedNeighbors = 0; /* crop image to a multiple of the cell diameter */ makeRectangle(x, y, (numCol * cellDiam), (numRow * cellDiam)); roiManager("Add"); run("Crop"); /* first for loop: convert each square to black or white depending on whether its mean is above the threshold */ for(i = 0; i < numRow; i++) { for(j = 0; j < numCol; j++) { xOffset = j * cellDiam; yOffset = i * cellDiam; makeRectangle(x + xOffset, y + yOffset, cellDiam, cellDiam); roiManager("Add"); getRawStatistics(dummy, mean, dummy, dummy, dummy, dummy2); if (mean >= threshold) { // set cells above threshold to white and count them setColor(255); fillRect(x + xOffset, y + yOffset, cellDiam, cellDiam); countStainedSquares++; } else { // end of if statement to set color to white and test nearest neighbors setColor(0); fillRect(x + xOffset, y + yOffset, cellDiam, cellDiam); } // end of else statement to set color to black } //end of j for loop } // end of i for loop /* end of first for loop */ /* second for loop: test and count neighbors of stained squares */ for(i = 0; i < numRow; i++) { for(j = 0; j < numCol; j++) { xOffset = j * cellDiam; yOffset = i * cellDiam; testSquare=getPixel((x + xOffset + (0.5 * cellDiam)), (y + yOffset + (0.5 * cellDiam))); if (testSquare == 255) { // for stained squares, score neighbors /* test square to the right and count if stained */ if (j < numCol) { testRight = getPixel((x + xOffset + (1.5 * cellDiam)),(y + yOffset + (0.5 * cellDiam))); if (testRight == 255) { countStainedNeighbors++; } } /* test square to the left and count if stained */ if (j > 0) { testLeft = getPixel((x + xOffset - (0.5 * cellDiam)),(y + yOffset + (0.5 * cellDiam))); if (testLeft == 255) { countStainedNeighbors++; } } /* test square above and count if stained */ if (i > 0) { testAbove = getPixel((x + xOffset + (0.5 * cellDiam)),(y + yOffset - (0.5 * cellDiam))); if (testAbove == 255) { countStainedNeighbors++; } } /* test square below and count if stained */ if (i < numRow) { testBelow = getPixel((x + xOffset + (0.5 * cellDiam)),(y + yOffset + (1.5 * cellDiam))); if (testBelow == 255) { countStainedNeighbors++; } } } // end of if statement to test nearest neighbors } //end of j for loop } // end of i for loop /* end of second for loop */ /* calculate and display sorting scores */ stainedSortingScore = countStainedNeighbors / (countStainedSquares * 4); randomSortingScore = (0.95 * (countStainedSquares / countSquares) - 0.0213) print(imageName + ", " + threshold + ", " + countSquares + ", " + countStainedSquares + ", " + (countStainedSquares * 100 / countSquares) + ", " + stainedSortingScore + ", " + randomSortingScore); rename(imageName + "binary"); run("Tiff..."); -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Audrey O'Neill
I'm looking to make a macro for wax valve spreading. The problem is the lack of uniformity with the wax valve spread. The spread is further on the corners than in the center of the rectangular block. I'd like to see the furtherest distance that the wax traveled, but also see the distribution of the wax spread. Assuming my image is black and white, I'd like to create a grid of .1mm X .1 mm squares along the area of the photo. If the squares have any black color, I'd like to store them in a recursive counter. I'd like to plot a histogram of the stored values along each row of the grid being one bin. |
Free forum by Nabble | Edit this page |