pythonjythonimage-segmentationimagejroi

Get the pixels in an ROI only, how?


Trying my hand at scripting and so far I have a function that returns an ROI derived through thresholding.

PA.setRoiManager(roim)
paOpt = PA.CLEAR_WORKSHEET +PA.SHOW_NONE +PA.INCLUDE_HOLES +PA.EXCLUDE_EDGE_PARTICLES + PA.ADD_TO_MANAGER 
# measurement options: clear the results, show nothing, include holes, exclude particles on edges and add ROIs to manager
measOpt = PA.AREA + PA.MEAN + PA.MIN_MAX # measure the minimum, maximum, mean and area of particles          
pa = PA(paOpt, measOpt, rt, minSize, maxSize)
pa.analyze(imp)
roi_list = roim.getRoisAsArray()
print roi_list[0] 

This gives an output to the console: Roi[Traced, x= , y=, width=, height= ] so I am confident that I am finding an ROI. roim is an instance of RoiManager.

Now the problem is when I go to look at the pixels within the ROI.

def pixelStats(roiPatch, imp):
  '''
  get the pixel value distribution for the patch ROI 
  return the number of Lo pixels and the number of Ld pixels 
  roi_Patch returns handle to the patch ROI and imp is the 
  instance of current ImagePlus to be measured
  '''
  mask = roiPatch.getMask() # mask of roiPatch, do you need this?
  ip = imp.getProcessor() 
  ip.setRoi(roiPatch)
  cal = imp.getCalibration()
  # options = IS.MEAN | IS.STD_DEV | IS.MODE
  stats = IS.getStatistics(ip, M.MEAN | M.MODE | M.STD_DEV, cal) # what does getCalibration do??? stats for ROI only applied to imp, why?
  # see the following --> http://fiji.sc/Jython_Scripting#Obtain.2FView_histogram_and_measurements_from_an_image
  domThreshold = stats.mode - stats.STD_DEV 
  backGround = stats.MEAN - stats.STD_DEV 
  # define the threshold for Lo/Ld phase 
  pixels = ip.getPixels() 
  above = filter(lambda i: pixels[i] > backGround, xrange(len(pixels)))
  below = filter(lambda i: above[i] < domThreshold, xrange(len(above)))
  # calculate the length of the arrays containing pixels of Lo/Ld phase 
  return len(above), len(below), len(pixels)

Looking at the measurements this returns, I am sure that that ip.getPixels() is just returning the pixels from the original image processor and not the ROI only. In other words I simply get the number of pixels in the original "rectangular" image.

Can anyone provide the reason as to why this is? Or suggest a better way of doing the same thing.


Solution

  • I am familiar with the Java API but not the python so my answer has not been tested.

    The method

    ip.getPixels() 
    

    is doing what I expect and returning all the pixels. Having a ROI or not does not affect this. Your measurements take account of the ROI so the mean and the mode are calculated on the ROI you have set.

    To solve this I would crop the ip. There should be a

    ip.crop() 
    

    method that will return an ip having taken the ROI into account that you could then call

    ip.getPixels()
    

    to only get the pixels in the ROI.