Qeustion regarding labeling and regions of interest in imglib2

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

Qeustion regarding labeling and regions of interest in imglib2

Robert Haase
Hi All,

I'm quite new in developing imagej-plugins using imglib2. I ran in some
issues working with Labeling and Regions in imglib2. Hopefully, somebody
of you can help me. This is what I would like to do:

I have an image(Plus) where pixel values correspond to the desired
labeling. Thus, all pixels with value 1 belong to label 1, all pixels
with value 2 belong to label 2 and so on. Labelled regions cannot
overlap. Now, I would like to create an ImgLabeling from the given
ImagePlus to manage the corresponding regions of interest in imglib2 and
to do the analysis using this library.
I was able to create some functions which appear to do the
transformation, however, the results are not fully understandable for
me. On bottom of this email you find "minimal" example code (which runs
fine in eclipse set up for ImageJ-development) which creates a
labelmap-ImagePlus, transforms it into ImgLabeling and displays binary
images corresponding to the regions. However, when I input a label with
100 pixels, the corresponding output region may or may not have the same
number of pixels. So the output of the program is:

Number of input pixels in label 0: 9400
Number of input pixels in label 1: 100
Number of input pixels in label 2: 200
Number of input pixels in label 3: 300
Number of input pixels in label 4: 0
Number of out pixels in region: 10000
Number of out pixels in region: 600
Number of out pixels in region: 500
Number of out pixels in region: 300

As you can see, the number of read-in pixels is not equal to the number
of pixels which are positive afterwards in the corresponding region. The
program visualises the images as well. The mistake in the result is
obvious. My mistake in the code is not that obvious to me.

I guess, I interpret the meaning of regions and/or labels wrong.
Hopefully somebody of you may point me in the right direction to do the
above mentioned transformation properly.

Thanks a lot in advance!
Robert

LabelingExample.java ----------------------------


import ij.ImagePlus;
import ij.gui.NewImage;
import ij.process.ImageProcessor;

import java.awt.Rectangle;
import java.io.IOException;
import java.util.Set;

import net.imglib2.Cursor;
import net.imglib2.RandomAccess;
import net.imglib2.RandomAccessibleInterval;
import net.imglib2.img.Img;
import net.imglib2.img.array.ArrayImgs;
import net.imglib2.img.display.imagej.ImageJFunctions;
import net.imglib2.roi.labeling.ImgLabeling;
import net.imglib2.roi.labeling.LabelRegion;
import net.imglib2.roi.labeling.LabelRegionCursor;
import net.imglib2.roi.labeling.LabelRegions;
import net.imglib2.roi.labeling.LabelingType;
import net.imglib2.type.logic.BitType;
import net.imglib2.type.logic.BoolType;
import net.imglib2.type.numeric.integer.IntType;
import net.imglib2.type.numeric.real.FloatType;

public class LabelingExample {
     LabelingExample()
     {
         new ij.ImageJ();

         //Create and show a simple test image, 100x100
         ImagePlus imp = createTestImage();
         imp.show();

         //Create an ImgLabeling from the ImagePlus
         ImgLabeling<Integer, IntType> labeling =
getIntIntImgLabellingFromLabelMapImagePlus(imp);

         //Read out regions and labelNames
         LabelRegions<Integer> regions = new
LabelRegions<Integer>(labeling);
         Set<Integer> labelNames = labeling.getMapping().getLabels();

         //Visualise the labels as binary images.
         for (Integer labelName : labelNames )
         {
             LabelRegion<Integer> lr = regions.getLabelRegion(labelName);
             ImageJFunctions.show(labelRegionToBinaryImage(lr,
(Img<IntType>)labeling.getIndexImg()));
         }
     }

     //Create an image with three labels (+background)
     //The three labels have an area of 100, 200 and 300.
     private ImagePlus createTestImage()
     {
         ImagePlus imp = NewImage.createByteImage("Test iamge", 100,
100, 1, NewImage.FILL_BLACK);
         ImageProcessor ip = imp.getProcessor();
         ip.setRoi(new Rectangle(10, 10, 10, 10));
         ip.setColor(1);
         ip.fill();
         ip.setRoi(new Rectangle(20, 20, 10, 20));
         ip.setColor(2);
         ip.fill();
         ip.setRoi(new Rectangle(40, 40, 10, 30));
         ip.setColor(3);
         ip.fill();

         return imp;
     }

     //Transform an ImagePlus to a Labeling Imp. The original pixel
value should be the label afterwards.
     public static ImgLabeling<Integer, IntType>
getIntIntImgLabellingFromLabelMapImagePlus(ImagePlus labelMap)
     {
         final RandomAccessibleInterval< IntType > img =
ImageJFunctions.wrapNumeric(labelMap);
         Img< FloatType > img2 = ImageJFunctions.convertFloat(labelMap);
         final long[] dims = new long[ img.numDimensions() ];

         ImgLabeling< Integer, IntType > labeling = new ImgLabeling<
Integer, IntType >( img );

         Cursor<LabelingType<Integer>> labelCursor = labeling.cursor();
         RandomAccess<FloatType> imageRA = img2.randomAccess();

         // Go through the whole image again and again for every single
label, until no more label is found.
         // If you know a more efficient way to do this, tell me...
         int currentLabel = 0;
         boolean anythingFound = true;
         while (anythingFound)
         {
             anythingFound = false;
             labelCursor.reset();

             //Go through the whole image and add every pixel, that
belongs to the currently processed label
             int count = 0;
             while (labelCursor.hasNext())
             {
                 LabelingType<Integer> element = labelCursor.next();
                 imageRA.setPosition(labelCursor);

                 int i = (int)(imageRA.get().get());
                 if (i == currentLabel)
                 {
                     element.add(i);
                     anythingFound = true;
                     count ++;
                 }
             }
             System.out.println("Number of input pixels in label " +
currentLabel + ": " + count);
             currentLabel++;
         }
         ImageJFunctions.show(labeling.getIndexImg());
         return labeling;
     }

     //Transform a Region to a binary image, which can be displayed
     public static < T, F > Img<BitType>
labelRegionToBinaryImage(LabelRegion<T> region, Img<F> img)
     {
         final long[] pos = new long[ img.numDimensions() ];
         final long[] dims = new long[ img.numDimensions() ];
         img.dimensions( dims );

         final Img< BitType > newImage = ArrayImgs.bits( dims );

         RandomAccess<BitType> imageRA = newImage.randomAccess();
         LabelRegionCursor regionCursor = region.cursor();

         int count = 0;
         while (regionCursor.hasNext())
         {
             //Read yes/no from region
             BoolType regionElement = regionCursor.next();
             regionCursor.localize(pos);
             imageRA.setPosition(pos);
             BitType imageElement = imageRA.get();

             //Draw binary image pixel by pixel
             if (regionElement.get())
             {
                 count++;
                 imageElement.set(true);
             }
             else
             {
                 imageElement.set(false);
             }
         }
         System.out.println("Number of output pixels in region: " + count);
         return newImage;
     }



     //Just to run it
     public static void main(final String... args) throws IOException
     {
         new LabelingExample();
     }
}




--
Robert Haase
Bio-Image informatics, Scientific Computing Facility

Max Planck Institute CBG
Pfotenhauer Str. 108, 01307 Dresden
room: 106 (s)
phone: +49 351 210 2972
fax:   +49 351 210 1689


_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel
Reply | Threaded
Open this post in threaded view
|

Re: Qeustion regarding labeling and regions of interest in imglib2

Tobias Pietzsch
Hi Robert,

the problem is the following:
In the ImgLabeling constructor
public ImgLabeling( final RandomAccessibleInterval< I > img )
the img you pass is used to store the labels at each pixel.
(The way that works is that integers are mapped to sets of labels that occur. If you have labels of type String, i.e., a ImgLabeling<String,IntType>,
then depending on which labels and combinations of labels actually occur in your labeling, the mapping might be something like
 0 -> {}
 1 -> {"A"}
 2 -> {"B"}
 3 -> {"B","C"}
etc...
The mapping is build, as you add labels to pixels.)

The assumption is that initially the labeling is empty, that is all zeros in the backing image, and the mapping just comprising 0 -> {}.
In your example, you passed the labelMap as the backing image. This is not zeroed.

One way to make your example work is to simply use a new, empty backing image, and then set the labels from the labelMap like you did.
Replace this:
final RandomAccessibleInterval< IntType > img = ImageJFunctions.wrapNumeric( labelMap );
Img< FloatType > img2 = ImageJFunctions.convertFloat( labelMap );
final long[] dims = new longimg.numDimensions() ];
ImgLabeling< Integer, IntType > labeling = new ImgLabeling< Integer, IntType >( img );
by this:
final Img< FloatType > img2 = ImageJFunctions.convertFloat( labelMap );
final Dimensions dims = img2;
final IntType t = new IntType();
final RandomAccessibleInterval< IntType > img = Util.getArrayOrCellImgFactory( dimst ).create( dimst );
final ImgLabeling< Integer, IntType > labeling = new ImgLabeling< Integer, IntType >( img );
Then it works.


For transfering the labeling you do not have to loop over all the labels. you could just do this:
final Cursor< LabelingType< Integer > > labelCursor = Views.flatIterable( labeling ).cursor();
for ( final UnsignedByteType input : Views.flatIterable( ImageJFunctions.wrapByte( labelMap ) ) )
{
final LabelingType< Integer > element = labelCursor.next();
if ( input.get() != 0 )
element.add( input.get() );
}
(This assumes that in labelMap the value 0 means “no label”).


In principle, if your labelMap has values 0, 1, 2, ... without big gaps, and 0 means “no label” you could just use it directly as backing image and produce a fitting LabelingMapping, like
 0 -> {}
 1 -> {1}
 2 -> {2}
 3 -> {3}
etc yourself. But that involves diving much deeper into the details, basically reading through the code of ImgLabeling and LabelingMapping.
I would recommend above solution for now.

best regards,
Tobias

On 08 Sep 2015, at 09:11, Robert Haase <[hidden email]> wrote:

Hi All,

I'm quite new in developing imagej-plugins using imglib2. I ran in some issues working with Labeling and Regions in imglib2. Hopefully, somebody of you can help me. This is what I would like to do:

I have an image(Plus) where pixel values correspond to the desired labeling. Thus, all pixels with value 1 belong to label 1, all pixels with value 2 belong to label 2 and so on. Labelled regions cannot overlap. Now, I would like to create an ImgLabeling from the given ImagePlus to manage the corresponding regions of interest in imglib2 and to do the analysis using this library.
I was able to create some functions which appear to do the transformation, however, the results are not fully understandable for me. On bottom of this email you find "minimal" example code (which runs fine in eclipse set up for ImageJ-development) which creates a labelmap-ImagePlus, transforms it into ImgLabeling and displays binary images corresponding to the regions. However, when I input a label with 100 pixels, the corresponding output region may or may not have the same number of pixels. So the output of the program is:

Number of input pixels in label 0: 9400
Number of input pixels in label 1: 100
Number of input pixels in label 2: 200
Number of input pixels in label 3: 300
Number of input pixels in label 4: 0
Number of out pixels in region: 10000
Number of out pixels in region: 600
Number of out pixels in region: 500
Number of out pixels in region: 300

As you can see, the number of read-in pixels is not equal to the number of pixels which are positive afterwards in the corresponding region. The program visualises the images as well. The mistake in the result is obvious. My mistake in the code is not that obvious to me.

I guess, I interpret the meaning of regions and/or labels wrong. Hopefully somebody of you may point me in the right direction to do the above mentioned transformation properly.

Thanks a lot in advance!
Robert

LabelingExample.java ----------------------------


import ij.ImagePlus;
import ij.gui.NewImage;
import ij.process.ImageProcessor;

import java.awt.Rectangle;
import java.io.IOException;
import java.util.Set;

import net.imglib2.Cursor;
import net.imglib2.RandomAccess;
import net.imglib2.RandomAccessibleInterval;
import net.imglib2.img.Img;
import net.imglib2.img.array.ArrayImgs;
import net.imglib2.img.display.imagej.ImageJFunctions;
import net.imglib2.roi.labeling.ImgLabeling;
import net.imglib2.roi.labeling.LabelRegion;
import net.imglib2.roi.labeling.LabelRegionCursor;
import net.imglib2.roi.labeling.LabelRegions;
import net.imglib2.roi.labeling.LabelingType;
import net.imglib2.type.logic.BitType;
import net.imglib2.type.logic.BoolType;
import net.imglib2.type.numeric.integer.IntType;
import net.imglib2.type.numeric.real.FloatType;

public class LabelingExample {
   LabelingExample()
   {
       new ij.ImageJ();

       //Create and show a simple test image, 100x100
       ImagePlus imp = createTestImage();
       imp.show();

       //Create an ImgLabeling from the ImagePlus
       ImgLabeling<Integer, IntType> labeling = getIntIntImgLabellingFromLabelMapImagePlus(imp);

       //Read out regions and labelNames
       LabelRegions<Integer> regions = new LabelRegions<Integer>(labeling);
       Set<Integer> labelNames = labeling.getMapping().getLabels();

       //Visualise the labels as binary images.
       for (Integer labelName : labelNames )
       {
           LabelRegion<Integer> lr = regions.getLabelRegion(labelName);
           ImageJFunctions.show(labelRegionToBinaryImage(lr, (Img<IntType>)labeling.getIndexImg()));
       }
   }

   //Create an image with three labels (+background)
   //The three labels have an area of 100, 200 and 300.
   private ImagePlus createTestImage()
   {
       ImagePlus imp = NewImage.createByteImage("Test iamge", 100, 100, 1, NewImage.FILL_BLACK);
       ImageProcessor ip = imp.getProcessor();
       ip.setRoi(new Rectangle(10, 10, 10, 10));
       ip.setColor(1);
       ip.fill();
       ip.setRoi(new Rectangle(20, 20, 10, 20));
       ip.setColor(2);
       ip.fill();
       ip.setRoi(new Rectangle(40, 40, 10, 30));
       ip.setColor(3);
       ip.fill();

       return imp;
   }

   //Transform an ImagePlus to a Labeling Imp. The original pixel value should be the label afterwards.
   public static ImgLabeling<Integer, IntType> getIntIntImgLabellingFromLabelMapImagePlus(ImagePlus labelMap)
   {
       final RandomAccessibleInterval< IntType > img = ImageJFunctions.wrapNumeric(labelMap);
       Img< FloatType > img2 = ImageJFunctions.convertFloat(labelMap);
       final long[] dims = new long[ img.numDimensions() ];

       ImgLabeling< Integer, IntType > labeling = new ImgLabeling< Integer, IntType >( img );

       Cursor<LabelingType<Integer>> labelCursor = labeling.cursor();
       RandomAccess<FloatType> imageRA = img2.randomAccess();

       // Go through the whole image again and again for every single label, until no more label is found.
       // If you know a more efficient way to do this, tell me...
       int currentLabel = 0;
       boolean anythingFound = true;
       while (anythingFound)
       {
           anythingFound = false;
           labelCursor.reset();

           //Go through the whole image and add every pixel, that belongs to the currently processed label
           int count = 0;
           while (labelCursor.hasNext())
           {
               LabelingType<Integer> element = labelCursor.next();
               imageRA.setPosition(labelCursor);

               int i = (int)(imageRA.get().get());
               if (i == currentLabel)
               {
                   element.add(i);
                   anythingFound = true;
                   count ++;
               }
           }
           System.out.println("Number of input pixels in label " + currentLabel + ": " + count);
           currentLabel++;
       }
       ImageJFunctions.show(labeling.getIndexImg());
       return labeling;
   }

   //Transform a Region to a binary image, which can be displayed
   public static < T, F > Img<BitType> labelRegionToBinaryImage(LabelRegion<T> region, Img<F> img)
   {
       final long[] pos = new long[ img.numDimensions() ];
       final long[] dims = new long[ img.numDimensions() ];
       img.dimensions( dims );

       final Img< BitType > newImage = ArrayImgs.bits( dims );

       RandomAccess<BitType> imageRA = newImage.randomAccess();
       LabelRegionCursor regionCursor = region.cursor();

       int count = 0;
       while (regionCursor.hasNext())
       {
           //Read yes/no from region
           BoolType regionElement = regionCursor.next();
           regionCursor.localize(pos);
           imageRA.setPosition(pos);
           BitType imageElement = imageRA.get();

           //Draw binary image pixel by pixel
           if (regionElement.get())
           {
               count++;
               imageElement.set(true);
           }
           else
           {
               imageElement.set(false);
           }
       }
       System.out.println("Number of output pixels in region: " + count);
       return newImage;
   }



   //Just to run it
   public static void main(final String... args) throws IOException
   {
       new LabelingExample();
   }
}




--
Robert Haase
Bio-Image informatics, Scientific Computing Facility

Max Planck Institute CBG
Pfotenhauer Str. 108, 01307 Dresden
room: 106 (s)
phone: +49 351 210 2972
fax:   +49 351 210 1689


_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel


_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel

signature.asc (465 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Qeustion regarding labeling and regions of interest in imglib2

Robert Haase
Hi Tobias,

thanks a lot for the help. Actually, the presented for-loop only worked for byte images, but the needed change is not too complicated.

Just in case, somebody out there has a similar issue, the final solution is:

//Transform an ImagePlus to an ImpLabeling. The original pixel value should be the label afterwards.
    public static ImgLabeling<Integer, IntType> getIntIntImgLabellingFromLabelMapImagePlus(ImagePlus labelMap)
    {
        final Img< FloatType > img2 = ImageJFunctions.wrapFloat( labelMap );
        final Dimensions dims = img2;
        final IntType t = new IntType();
        final RandomAccessibleInterval< IntType > img = Util.getArrayOrCellImgFactory( dims, t ).create( dims, t );
        final ImgLabeling< Integer, IntType > labeling = new ImgLabeling< Integer, IntType >( img );
       
        final Cursor< LabelingType< Integer > > labelCursor = Views.flatIterable( labeling ).cursor();
       
        for ( final FloatType input : Views.flatIterable( img2 ) )
        {
            final LabelingType< Integer > element = labelCursor.next();
            if ( input.get() != 0 )
                element.add( (int)input.get() );
        }
       
        return labeling;
    }

So, thanks again!

Best,
Robert

Am 9/9/15 um 9:21 PM schrieb Tobias Pietzsch:
Hi Robert,

the problem is the following:
In the ImgLabeling constructor
public ImgLabeling( final RandomAccessibleInterval< I > img )
the img you pass is used to store the labels at each pixel.
(The way that works is that integers are mapped to sets of labels that occur. If you have labels of type String, i.e., a ImgLabeling<String,IntType>,
then depending on which labels and combinations of labels actually occur in your labeling, the mapping might be something like
 0 -> {}
 1 -> {"A"}
 2 -> {"B"}
 3 -> {"B","C"}
etc...
The mapping is build, as you add labels to pixels.)

The assumption is that initially the labeling is empty, that is all zeros in the backing image, and the mapping just comprising 0 -> {}.
In your example, you passed the labelMap as the backing image. This is not zeroed.

One way to make your example work is to simply use a new, empty backing image, and then set the labels from the labelMap like you did.
Replace this:
final RandomAccessibleInterval< IntType > img = ImageJFunctions.wrapNumeric( labelMap );
Img< FloatType > img2 = ImageJFunctions.convertFloat( labelMap );
final long[] dims = new longimg.numDimensions() ];
ImgLabeling< Integer, IntType > labeling = new ImgLabeling< Integer, IntType >( img );
by this:
final Img< FloatType > img2 = ImageJFunctions.convertFloat( labelMap );
final Dimensions dims = img2;
final IntType t = new IntType();
final RandomAccessibleInterval< IntType > img = Util.getArrayOrCellImgFactory( dimst ).create( dimst );
final ImgLabeling< Integer, IntType > labeling = new ImgLabeling< Integer, IntType >( img );
Then it works.


For transfering the labeling you do not have to loop over all the labels. you could just do this:
final Cursor< LabelingType< Integer > > labelCursor = Views.flatIterable( labeling ).cursor();
for ( final UnsignedByteType input : Views.flatIterable( ImageJFunctions.wrapByte( labelMap ) ) )
{
final LabelingType< Integer > element = labelCursor.next();
if ( input.get() != 0 )
element.add( input.get() );
}
(This assumes that in labelMap the value 0 means “no label”).


In principle, if your labelMap has values 0, 1, 2, ... without big gaps, and 0 means “no label” you could just use it directly as backing image and produce a fitting LabelingMapping, like
 0 -> {}
 1 -> {1}
 2 -> {2}
 3 -> {3}
etc yourself. But that involves diving much deeper into the details, basically reading through the code of ImgLabeling and LabelingMapping.
I would recommend above solution for now.

best regards,
Tobias

On 08 Sep 2015, at 09:11, Robert Haase <[hidden email]> wrote:

Hi All,

I'm quite new in developing imagej-plugins using imglib2. I ran in some issues working with Labeling and Regions in imglib2. Hopefully, somebody of you can help me. This is what I would like to do:

I have an image(Plus) where pixel values correspond to the desired labeling. Thus, all pixels with value 1 belong to label 1, all pixels with value 2 belong to label 2 and so on. Labelled regions cannot overlap. Now, I would like to create an ImgLabeling from the given ImagePlus to manage the corresponding regions of interest in imglib2 and to do the analysis using this library.
I was able to create some functions which appear to do the transformation, however, the results are not fully understandable for me. On bottom of this email you find "minimal" example code (which runs fine in eclipse set up for ImageJ-development) which creates a labelmap-ImagePlus, transforms it into ImgLabeling and displays binary images corresponding to the regions. However, when I input a label with 100 pixels, the corresponding output region may or may not have the same number of pixels. So the output of the program is:

Number of input pixels in label 0: 9400
Number of input pixels in label 1: 100
Number of input pixels in label 2: 200
Number of input pixels in label 3: 300
Number of input pixels in label 4: 0
Number of out pixels in region: 10000
Number of out pixels in region: 600
Number of out pixels in region: 500
Number of out pixels in region: 300

As you can see, the number of read-in pixels is not equal to the number of pixels which are positive afterwards in the corresponding region. The program visualises the images as well. The mistake in the result is obvious. My mistake in the code is not that obvious to me.

I guess, I interpret the meaning of regions and/or labels wrong. Hopefully somebody of you may point me in the right direction to do the above mentioned transformation properly.

Thanks a lot in advance!
Robert

LabelingExample.java ----------------------------


import ij.ImagePlus;
import ij.gui.NewImage;
import ij.process.ImageProcessor;

import java.awt.Rectangle;
import java.io.IOException;
import java.util.Set;

import net.imglib2.Cursor;
import net.imglib2.RandomAccess;
import net.imglib2.RandomAccessibleInterval;
import net.imglib2.img.Img;
import net.imglib2.img.array.ArrayImgs;
import net.imglib2.img.display.imagej.ImageJFunctions;
import net.imglib2.roi.labeling.ImgLabeling;
import net.imglib2.roi.labeling.LabelRegion;
import net.imglib2.roi.labeling.LabelRegionCursor;
import net.imglib2.roi.labeling.LabelRegions;
import net.imglib2.roi.labeling.LabelingType;
import net.imglib2.type.logic.BitType;
import net.imglib2.type.logic.BoolType;
import net.imglib2.type.numeric.integer.IntType;
import net.imglib2.type.numeric.real.FloatType;

public class LabelingExample {
   LabelingExample()
   {
       new ij.ImageJ();

       //Create and show a simple test image, 100x100
       ImagePlus imp = createTestImage();
       imp.show();

       //Create an ImgLabeling from the ImagePlus
       ImgLabeling<Integer, IntType> labeling = getIntIntImgLabellingFromLabelMapImagePlus(imp);

       //Read out regions and labelNames
       LabelRegions<Integer> regions = new LabelRegions<Integer>(labeling);
       Set<Integer> labelNames = labeling.getMapping().getLabels();

       //Visualise the labels as binary images.
       for (Integer labelName : labelNames )
       {
           LabelRegion<Integer> lr = regions.getLabelRegion(labelName);
           ImageJFunctions.show(labelRegionToBinaryImage(lr, (Img<IntType>)labeling.getIndexImg()));
       }
   }

   //Create an image with three labels (+background)
   //The three labels have an area of 100, 200 and 300.
   private ImagePlus createTestImage()
   {
       ImagePlus imp = NewImage.createByteImage("Test iamge", 100, 100, 1, NewImage.FILL_BLACK);
       ImageProcessor ip = imp.getProcessor();
       ip.setRoi(new Rectangle(10, 10, 10, 10));
       ip.setColor(1);
       ip.fill();
       ip.setRoi(new Rectangle(20, 20, 10, 20));
       ip.setColor(2);
       ip.fill();
       ip.setRoi(new Rectangle(40, 40, 10, 30));
       ip.setColor(3);
       ip.fill();

       return imp;
   }

   //Transform an ImagePlus to a Labeling Imp. The original pixel value should be the label afterwards.
   public static ImgLabeling<Integer, IntType> getIntIntImgLabellingFromLabelMapImagePlus(ImagePlus labelMap)
   {
       final RandomAccessibleInterval< IntType > img = ImageJFunctions.wrapNumeric(labelMap);
       Img< FloatType > img2 = ImageJFunctions.convertFloat(labelMap);
       final long[] dims = new long[ img.numDimensions() ];

       ImgLabeling< Integer, IntType > labeling = new ImgLabeling< Integer, IntType >( img );

       Cursor<LabelingType<Integer>> labelCursor = labeling.cursor();
       RandomAccess<FloatType> imageRA = img2.randomAccess();

       // Go through the whole image again and again for every single label, until no more label is found.
       // If you know a more efficient way to do this, tell me...
       int currentLabel = 0;
       boolean anythingFound = true;
       while (anythingFound)
       {
           anythingFound = false;
           labelCursor.reset();

           //Go through the whole image and add every pixel, that belongs to the currently processed label
           int count = 0;
           while (labelCursor.hasNext())
           {
               LabelingType<Integer> element = labelCursor.next();
               imageRA.setPosition(labelCursor);

               int i = (int)(imageRA.get().get());
               if (i == currentLabel)
               {
                   element.add(i);
                   anythingFound = true;
                   count ++;
               }
           }
           System.out.println("Number of input pixels in label " + currentLabel + ": " + count);
           currentLabel++;
       }
       ImageJFunctions.show(labeling.getIndexImg());
       return labeling;
   }

   //Transform a Region to a binary image, which can be displayed
   public static < T, F > Img<BitType> labelRegionToBinaryImage(LabelRegion<T> region, Img<F> img)
   {
       final long[] pos = new long[ img.numDimensions() ];
       final long[] dims = new long[ img.numDimensions() ];
       img.dimensions( dims );

       final Img< BitType > newImage = ArrayImgs.bits( dims );

       RandomAccess<BitType> imageRA = newImage.randomAccess();
       LabelRegionCursor regionCursor = region.cursor();

       int count = 0;
       while (regionCursor.hasNext())
       {
           //Read yes/no from region
           BoolType regionElement = regionCursor.next();
           regionCursor.localize(pos);
           imageRA.setPosition(pos);
           BitType imageElement = imageRA.get();

           //Draw binary image pixel by pixel
           if (regionElement.get())
           {
               count++;
               imageElement.set(true);
           }
           else
           {
               imageElement.set(false);
           }
       }
       System.out.println("Number of output pixels in region: " + count);
       return newImage;
   }



   //Just to run it
   public static void main(final String... args) throws IOException
   {
       new LabelingExample();
   }
}




--
Robert Haase
Bio-Image informatics, Scientific Computing Facility

Max Planck Institute CBG
Pfotenhauer Str. 108, 01307 Dresden
room: 106 (s)
phone: +49 351 210 2972
fax:   +49 351 210 1689


_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel


-- 
Robert Haase
Bio-Image informatics, Scientific Computing Facility

Max Planck Institute CBG
Pfotenhauer Str. 108, 01307 Dresden
room: 106 (s)
phone: +49 351 210 2972
fax:   +49 351 210 1689

_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel