ROI post processing help: split in two equal surfaces

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

ROI post processing help: split in two equal surfaces

julcanada
hey all

so i am analyzing particles and after using the particle analyzer module to identify the boundaries, i can create nice ROI. now im trying to extract intensity (integrated density actually) for the two halves of these particles. a macro was written to automate the process and it's at the end of this message. it finds the center of mass (generally its pretty much the same as the centroid), then split the ROI vertically through it, leaving me with a left and a right ROI that i can use for my calculations.

my main problem is that the particles are not perfectly spherical, so when this macro is run, the ROIs have a different surface, and hence the integrated density measurement is biased. What i would like to do, is adjust the position of the division axis so that the surfaces are equal. any idea on how i would code this?

thanks for your help!


run("Set Measurements...", "area mean standard modal min centroid center perimeter bounding fit shape feret's integrated median skewness kurtosis area_fraction stack limit display scientific redirect=None decimal=9"); //Ensure that all properties are met in the results table
imgw = getWidth();

org = roiManager("Count");

srcDir = File.directory(); //Stores the directory path of the file.
srcNam = File.name(); //Stores the name of the file with the extension.

setFont("Cambria",20," italic antialiased"); //Set font properties for the particle labeler function.
drwCol = 255; //Set font colour of the particle labeler function.

doit();

function doit()
{
 for (i=org;i>0;i--)
 {

n = roiManager("Count") - 1; //this is the number of rois in the list, then -1 accounts for the select list with 0 being the first number

//Left Side

roiManager("Select", n);
roiManager("Rename", "Cell " + n);
run("Measure");
makeRectangle(round(getResult("XM",0)), 0, imgw - round(getResult("XM",0)), imgw);

roiManager("Add");
roiManager("Select", n);
run("Make Inverse");
roiManager("Add");

roiManager("Select", n+1);
setKeyDown("shift");
roiManager("Select", n+2);
setKeyDown("none");

run("Make Inverse");
roiManager("Add");

roiManager("Select", n+3);
roiManager("Rename", "Partition Left " + n);

//Right Side

roiManager("Select", n+1);
run("Make Inverse");
roiManager("Add");

roiManager("Select", n+2);
roiManager("Add");

roiManager("Select", n+4);
setKeyDown("shift");
roiManager("Select", n+5);
setKeyDown("none");

run("Make Inverse");
roiManager("Add");

roiManager("Select", n+6);
roiManager("Rename", "Partition Right " + n);

//Clean up

roiManager("Select", n+1);
roiManager("Delete");
roiManager("Select", n+1);
roiManager("Delete");
roiManager("Select", n+2);
roiManager("Delete");
roiManager("Select", n+2);
roiManager("Delete");

//Save

//roiManager("Save",srcDir+srcNam+i+".zip");


saveAs("Measurements",srcDir+i+".xls");

print("Cell: "+i+" Intensity: "+getResult("IntDen", 2)/getResult("IntDen", 1));
//drawString(i, getResult("XM",0), getResult("YM",0));
run("Clear Results");


Reply | Threaded
Open this post in threaded view
|

Re: ROI post processing help: split in two equal surfaces

Nathaniel Ryckman
You could iteratively split the particle, measure the areas of the two new particles, and then save the results if the ratio between the two areas is ~1. You could do a binary search for the correct axis, using the left and right boundary of the original particle as limits.

A couple things to note:
1) I think you are only using vertical axis to split the particle? If you rotate the axis, you would have more opportunities to find a good axis, although, I wouldn't think that would be worth the trouble.
2) Why is dividing the particle so essential if you don't mind changing where the particle is split? Choosing an axis that would give the 2 new particles roughly equal area would essentially be changing their shapes, right?
3) I'm not really understanding the nature of the problem that well, but, if I understand correctly, I would just use Mean Gray Value instead of Integrated Density. I think that's maybe what you really are interested in.

Here is more information about what each of the measurement commands do:
http://rsb.info.nih.gov/ij/docs/menus/analyze.html
Reply | Threaded
Open this post in threaded view
|

Re: ROI post processing help: split in two equal surfaces

vischer
In reply to this post by julcanada
Hi julien,

when you temporarily fill the roi with a uniform value, then center of mass can be used to divide the irregular particle in two parts of equal area (horizontally or vertically).

Norbert Vischer
Reply | Threaded
Open this post in threaded view
|

Re: ROI post processing help: split in two equal surfaces

vischer
Hi julien (and Wayne)

I have to make a correction to my previous mail where I suggested to fill the roi with a constant value- this would only give you the centroid, not divide the roi into equal parts.
Below is a demo how to divide a roi into two parts:

- The first macro creates a demo roi
- The second divides it into halves.

Wayne, there is a strange behavior, which I only cold work-around by inserting a "Copy" command. Roi operations shouldn't change the image, but if I omit the "Copy" work around, a part of the contour is painted into the image.


Norbert Vischer



macro "Create a roi [F1]"{
        run("Leaf (36K)");
        run("8-bit");
        setThreshold(229, 255);
        doWand(26, 223);
        resetThreshold();
}


//divides current roi into left and right half
macro "divide roi [F2]"{
        run("Clear Results");
        roiManager("Reset");
        run("Add to Manager");
        roiManager("Select", 0);
        getSelectionBounds(x, y, width, height)
        getRawStatistics(totalArea);
        minOff = 1e9;
        for (w=1; w < width; w++){
                roiManager("Select", 0);
                setKeyDown("alt");
                makeRectangle(x, y, w, height);
                getRawStatistics(rightArea);
                off = abs(2*rightArea - totalArea);
                if (off < minOff){
                        minOff = off;
                        xHalf = x + w;
                        wHalf = w;
                        halfArea = rightArea;
                }
        }

        //Display result:
        roiManager("Select", 0);
        setKeyDown("alt");
        makeRectangle(x, y, wHalf, height);
        run("Copy");//work around
        run("Add to Manager");
        run("Measure");
        wait(500);
        roiManager("Select", 0);
        setKeyDown("alt");
        makeRectangle(x+wHalf, y, width - wHalf, height);
        run("Copy");//work around
        run("Add to Manager");
        run("Measure");
}