Login  Register

Re: find all locations of the same pixel value

Posted by Michael Schmid on Aug 14, 2012; 10:26am
URL: http://imagej.273.s1.nabble.com/calculating-DF-F-and-movement-correction-tp4999726p4999758.html

Hi Xin,

if you have thousands of pixels of the same value, you will create thousands of new int[] objects.  The Garbage Collector will have a lot of work to find out whether each of them is still needed, and eventually to remove them.

If your image size is not too large, simply create two arrays, say, xPixel, and yPixel, each of them the same size as the number of pixels, and write into them as much data as you need.

int width = iproc.getWidth();
int height = iproc.getHeight();
int[] xPixel = new int[width*height];
int[] yPixel = new int[width*height];

int nEqual = 0; // number of pixels with a value equal to the given one.
for (int x=0; x<width; x++) {
  for(int y=0; y<height; y++) {
    if (iproc.getPixel(x, y) == pixelValue) {
      xPixel[nEqual] = x;
      yPixel[nEqual] = y;
      nEqual++;
    }
  }
}

If you don't need the sequence as in your program, it would be faster to reverse the x and y loops (y in the outer loop). This addresses the pixels in the same sequence as they are stored in memory.

As a return value, you may then create a new 2-dimensional array,
  int[][] locations = int[2][nEqual],
and use System.arraycopy to copy nEqual items from xPixel into locations[0]; same for yPixel to locations[1].


If your image is very large and you run out of memory, you have a a few options:
- use short instead of int for x & y (unless any image is larger than 32767 pixels in width or height)
- encode x & y in a single int; see the built-in MaximumFinder for how to do this (intEncodeXMask, intEncodeYMask and intEncodeShift) - this works also with width or height > 32767)
- if the expected number of pixels with the given value is low, use smaller xPixel, yPixel arrays.  If you run over the array size, create new arrays of larger size (e.g. twice the size), copy the contents, and discard the old arrays.  See xstack, ystack in ij.process.FloodFiller.java for an example.


Michael
________________________________________________________________
On Aug 14, 2012, at 08:09, 周鑫 wrote:

> Dear all,
>
> I want to find in one image all the locations which have the same pixel value.
>
> currently I wrote a function for that:
>
> =======================================
>
> ArrayList<int[]> locations = new ArrayList<int[]>();
>  for (int x=0; x<iproc.getWidth(); x++)
>  {
>   for(int y=0; y<iproc.getHeight(); y++)
>   {
>    if (iproc.getPixel(x, y) == pixelValue)
>    {
>     locations.add(new int[]{x,y});
>    }
>   }
>  }
>  return locations;
>
> =======================================
>
> but I wonder if there is something more smart, or build-in functions that can do the job quicker.
>
> This is for me a basic operation, which will be done again and again. There must be more intelligent ways.
>
> Many thanks, Xin
>
>
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html