Returning mean pixel value of ROI in pluginFilter

fiji
imagej
plugin
roi
java

#1

Hello,

I am working on a java plugin that returns a series of ROI lines parallel to a manually drawn line and should return the mean and mode pixel values for each of those lines. Right now I can generate the lines and add the lines to the ROI manager. I could either click measure and copy the results table, or get each pixel value along the line and calculate the average in the code, but it would be nice if there was an existing function to do this.

to show some code: I manually draw one line parallel to a feature of interest and then programmatically draw two guidelines perpendicular to this initial line, one at each end (guide1 and guide2). I then make these lines into polygons and use the points in the polygon guidelines as the endpoints for the new lines that I currently add to the ROI manager. The distance along one of the guidelines is reported in nm:

Roi guide1 = new PolygonRoi(guide1_iniX, guide1_iniY, 3, Roi.POLYGON);
Roi guide2 = new PolygonRoi(guide2_iniX, guide2_iniY, 3, Roi.POLYGON);
				
FloatPolygon guide1_f = guide1.getInterpolatedPolygon();
FloatPolygon guide2_f = guide2.getInterpolatedPolygon();
Point[] guide1_p = new Point[guide1_f.npoints];
Point[] guide2_p = new Point[guide2_f.npoints];
				
if (guide1_p.length == guide2_p.length) {
	for (int i=0; i<guide1_f.npoints; i++) {
		guide1_p[i] = new Point((int)Math.round(guide1_f.xpoints[i]), (int)Math.round(guide1_f.ypoints[i]));
		guide2_p[i] = new Point((int)Math.round(guide2_f.xpoints[i]), (int)Math.round(guide2_f.ypoints[i]));
		}	
	for (int i=0; i<guide1_f.npoints; i++) {
		int delX = guide1_p[i].x - guide1_p[0].x;
		int delY = guide1_p[i].y - guide1_p[0].y;
		double distancePxls = Math.sqrt(Math.pow(delX,2)+Math.pow(delY,2));
		double distance_nm = distancePxls/scaling;
		Roi tempLine = new Line(guide1_p[i].x, guide1_p[i].y, guide2_p[i].x, guide2_p[i].y);
		manager.addRoi(tempLine);
		IJ.log(String.valueOf(distance_nm)); 
		}
	}
 else {
        IJ.showMessage("number of guideline points did not match");
         }
			

is there a function I could call after making tempLine to get the pixel value mean and mode?

It’s my first time trying to write a plugin and I have almost no experience with java, so any general corrections or suggestions for code posted above are also appreciated!


#2

Hi Katydid,
Have you tried to use “summarize” from your results table of your ROI’s?
Should work,
Bob


#3

Bob,

please read carefully, the OP likes to see a plugin code in Java that gives him the mean and mode values from specific line selections.

Summarize doesn’t provide the mode value and in conjunction with the results table is in itself of considerable Java code complexity …

Regards

Herbie


#4

In order to get the modal value from a float-array you must first sort the array. For this purpose you may use the ArrayUtil. After you’ve sorted the array you must count the occurencies of every element.

HTH

Herbie


#5

@smithrobertj and @Herbie , thank you for taking the time to reply.

The suggestion to use ArrayUtil is very helpful, but I’ve run into a bit of a newbie problem. If I understand the API documentation correctly, I should generate the ArrayUtil with a float array. I tried to use the line method getPixels() to get a double of the pixel values along one of my line ROIs:

Roi tempLine = new Line(guide1_p[i].x, guide1_p[i].y, guide2_p[i].x, guide2_p[i].y);
double [] dPixels = tempLine.getPixels();
float[] fPixels = new float[dPixels.length];
for (i=0; i<= fPixels.length; i++) {
	fPixels[i]=(float)dPixels[i];
        }
ArrayUtil tempPixels= new ArrayUtil(fPixels);
double lineMean = tempPixels.getMean();

but I get the error that getPixels() is undefined for type Roi. Of course the data type of tempLine is Roi, but I thought that making an instance of Line would allow me to use the methods of the line class. Can anyone help explain my error?

Also, is there a reason getPixels() returns an array of doubles? I thought pixel values were typically integers. And I know it generally a bad idea to convert from doubles to floats, but I also do not see an alternative in this case.

Thank you again for the helpful suggestions!


#6

Good day,

these are a lot of questions from your side …
Therefore I ask myself, if you encounter so many problems, wouldn’t it be better to do the job with an ImageJ-macro?

Only one answer for now:

Also, is there a reason getPixels() returns an array of doubles?

Yes, e.g. if interpolation is required.

A question to you:
Are your lines arbitrarily oriented or only vertically and horizontally?

Regards

Herbie


#7

Greetings,

@Herbie , to be honest, this turned out to be more of a challenge than I expected :slight_smile: since one can easily draw a line and get the pixel values through the GUI I thought this would just be a few lines of code to generate the new lines relative to the single manually drawn guideline. My mistake.

The code is mostly working. If you think it is unreasonable to continue then I will return to the old working version and get the mean values manually through the ROI manager. I just thought I was missing something obvious with getPixels()

The lines are arbitrarily oriented.

Thank you for your help and best regards,
Katy


#8

Katy,

if you need some automatisation, try writing a macro. The macro-recoder may help!

If the lines are arbitrarily oriented, you need interpolation to get reasonable results!

If you think it is unreasonable to continue […]

It’s your time that is spent and testing is required as well …

Good luck

Herbie