We're Hiring!

Rendering images per channel

General and open developer discussion about using OMERO APIs from C++, Java, Python, Matlab and more! Please new questions at https://forum.image.sc/tags/omero
Please note:
Historical discussions about OMERO. Please look for and ask new questions at https://forum.image.sc/tags/omero

If you are having trouble with custom code, please provide a link to a public repository, ideally GitHub.

Rendering images per channel

Postby Charavay » Tue Jun 30, 2015 2:27 pm

Hi,

I'm developing a java application : it will display images from omero by using the BufferedImage class. The format of images can be jpeg, tiff, png, ome.tiff ... If a file contains several channels, I want to display one image per channel and an image with all channels.

I have developed the following code based on an example given on the Omero web site :
Code: Select all
                             // Read image
                            // See documentation at https://www.openmicroscopy.org/site/support/omero5.1/developers/Java.html
                            // https://www.openmicroscopy.org/community/viewtopic.php?f=6&t=7839
                           // Beans containing the bufferedImages to display
                            List<ImageBean> imageBeans = new ArrayList<>();
                            BufferedImage bufferedImage;
                            List<Image> images = containerPrx.getImages(Image.class.getName(), Arrays.asList(imageId), new ParametersI());

                            if (images.size() == 0) {
                                // Can not find image
                                bufferedImage = null;
                                ImageBean imageBean = new ImageBean(imageId, bufferedImage);
                                imageBeans.add(imageBean);
                            } else {

                                Image image = images.get(0);
                                ImageData imageData = new ImageData(image);
                                PixelsData pixelsData = imageData.getDefaultPixels();
                                // Number of z sections
                                int sizeZ = pixelsData.getSizeZ();
                                // Number of timepoints
                                int sizeT = pixelsData.getSizeT();
                                // Number of channels
                                int sizeC = pixelsData.getSizeC();

                                // Retrieve pixels
                                long pixelsId = pixelsData.getId();

                                RenderingEnginePrx proxy = serviceFactoryPrx.createRenderingEngine();
                                proxy.lookupPixels(pixelsId);
                                if (!(proxy.lookupRenderingDef(pixelsId))) {
                                    proxy.resetDefaultSettings(true);
                                    proxy.lookupRenderingDef(pixelsId);
                                }
                                proxy.load();

                                // Now can interact with the rendering engine.
                                // Render the image
                                PlaneDef pDef = new PlaneDef();
                                pDef.z = 0;
                                pDef.t = 0;
                                pDef.slice = omero.romio.XY.value;

                                // if the image contains several channels : create one bufferedimage for each channel
                                if (sizeC > 1) {
                                    for (int channelToActivate = 0; channelToActivate < sizeC; channelToActivate++) {
                                        for (int channel = 0; channel < sizeC; channel++) {
                                            if (channel == channelToActivate) {
                                                // Activate the channel
                                                proxy.setActive(channel, Boolean.valueOf(true));
                                            } else {
                                                // Desactivate the channel
                                                proxy.setActive(channel, Boolean.valueOf(false));
                                            }
                                        }
                                        // render the data compressed
                                        byte[] compressed = proxy.renderCompressed(pDef);
                                        //Create a buffered image
                                        ByteArrayInputStream stream = new ByteArrayInputStream(compressed);
                                        try {
                                            bufferedImage = ImageIO.read(stream);
                                            ImageBean imageBean = new ImageBean(imageId, bufferedImage);
                                            imageBeans.add(imageBean);

                                        } catch (IOException ex) {
                                            // Can not read the image (image not found or not supported format)
                                            bufferedImage = null;
                                            ImageBean imageBean = new ImageBean(omeroImageId, bufferedImage);
                                            imageBeans.add(imageBean);
                                        }
                                    }
                                }

                                // create a bufferedimage for all channels
                                for (int channel = 0; channel < sizeC; channel++) {
                                    // Activate the channel
                                    proxy.setActive(channel, Boolean.valueOf(true));
                                }
                                //render the data uncompressed.
                                //int[] uncompressed = proxy.renderAsPackedInt(pDef);
                                //render the data compressed
                                byte[] compressed = proxy.renderCompressed(pDef);

                                //Create a buffered image
                                ByteArrayInputStream stream = new ByteArrayInputStream(compressed);
                                try {
                                    bufferedImage = ImageIO.read(stream);
                                    ImageBean imageBean = new ImageBean(imageId, bufferedImage);
                                    imageBeans.add(imageBean);

                                } catch (IOException ex) {
                                    // Can not read the image (image not found or not supported format)
                                    bufferedImage = null;
                                    ImageBean imageBean = new ImageBean(imageId, bufferedImage);
                                    imageBeans.add(imageBean);
                                }

                                // Close
                                proxy.close();


With an ome.tiff file containg several channels, it works very well. But for a RGB tiff, the sizeC is equal to 3 and my application displays one image for the red channel, one for the green, one for the blue and one image with the three channels : in this case, I would like to display only one image with the three channels. How can I make it ?

Thank you in advance for your help

Céline
Charavay
 
Posts: 14
Joined: Fri Jun 19, 2015 1:49 pm

Re: Rendering images per channel

Postby rleigh » Tue Jun 30, 2015 10:20 pm

Can you special-case this with, for example:

Code: Select all
if (pixelsData.isRGB()) {
  // The image is RGB data; render a single image
  int nSubChannels = pixelsData.getRGBChannelCount();
} else {
  // The image is separate planes; render separately.
}
User avatar
rleigh
 
Posts: 217
Joined: Tue Mar 13, 2012 11:45 am

Re: Rendering images per channel

Postby Charavay » Wed Jul 01, 2015 6:57 am

Thank you for your answer.
But the PixelsData class that I use (pojos.PixelsData ; http://downloads.openmicroscopy.org/omero/5.1.2/api/pojos/PixelsData.html) don't have these methods. Is there another way to test this ?

Céline

PS : the classes I use are :
import omero.model.Image;
import omero.romio.PlaneDef;
import omero.sys.ParametersI;
import pojos.ImageData;
import pojos.PixelsData;
Charavay
 
Posts: 14
Joined: Fri Jun 19, 2015 1:49 pm

Re: Rendering images per channel

Postby jburel » Wed Jul 01, 2015 8:18 pm

Dear Celine
There is the getFormat() method on pojos.ImageData that could help you determining if the image is a graphics image or not
e.g. a jpg image will return JPEG

We could certainly add a isGraphics method to the imageData class.

Cheers

Jmarie
User avatar
jburel
Team Member
 
Posts: 348
Joined: Thu May 21, 2009 6:38 pm
Location: dundee

Re: Rendering images per channel

Postby Charavay » Thu Jul 02, 2015 7:14 am

Dear Jmarie

Thank you for your answer.
I have tried your solution but when I call the getFormat() on pojos.ImageData, the following exception is thrown :
omero.UnloadedEntityException: Object unloaded:omero.model.FormatI@5170bcf4

Do you have any idea ?

Thank you in advance for your help

Céline
Charavay
 
Posts: 14
Joined: Fri Jun 19, 2015 1:49 pm

Re: Rendering images per channel

Postby jburel » Thu Jul 02, 2015 8:10 am

This means that the call used to retrieve the information did not load that part of the graph.
Which method do you use to load the images?
If you access the image from the pixelsData object, the information about the image will most likely not be loaded.

Cheers
Jmarie
User avatar
jburel
Team Member
 
Posts: 348
Joined: Thu May 21, 2009 6:38 pm
Location: dundee

Re: Rendering images per channel

Postby Charavay » Thu Jul 02, 2015 8:32 am

I load the image like that :
Code: Select all
List<Image> images = containerPrx.getImages(Image.class.getName(), Arrays.asList(imageId), new ParametersI());
Image image = images.get(0);
ImageData imageData = new ImageData(image);
String format = imageData.getFormat();
PixelsData pixelsData = imageData.getDefaultPixels();


> If you access the image from the pixelsData object, the information about the image will most likely not be loaded

I'm not sure to understand your explanation : in my code, I retrieve the imageData from the image object. Do you think it could be another way to load my image in order to have the format ?

Best regards

Céline
Charavay
 
Posts: 14
Joined: Fri Jun 19, 2015 1:49 pm

Re: Rendering images per channel

Postby jburel » Thu Jul 02, 2015 3:11 pm

I had a look at the method you are using to retrieve the image.
The format is not loaded. I will open a PR to fix that.

How you get the imageID? by first browsing the data tree? i.e.
* load the dataset using the loadContainerHierarchy method and access the images in the dataset
the image returned using that method has the format object loaded.

Cheers
jmarie
User avatar
jburel
Team Member
 
Posts: 348
Joined: Thu May 21, 2009 6:38 pm
Location: dundee

Re: Rendering images per channel

Postby Charavay » Fri Jul 03, 2015 6:29 am

Hi Jmarie

> How you get the imageID? by first browsing the data tree?

The user of my java application gives the imageID thanks to a CSV file. So I don't browse the data tree.

> * load the dataset using the loadContainerHierarchy method and access the images in the dataset
> the image returned using that method has the format object loaded.

As I don't know the dataset id it is not possible for me to load it.

> I had a look at the method you are using to retrieve the image.
> The format is not loaded. I will open a PR to fix that.

Ok. Thank you.

Céline
Charavay
 
Posts: 14
Joined: Fri Jun 19, 2015 1:49 pm

Re: Rendering images per channel

Postby jburel » Fri Jul 03, 2015 9:35 am

Hi Celine

In that case, you can, for the time being, retrieve the value of the format via another call
Code: Select all
List<Image> images = containerPrx.getImages(Image.class.getName(), Arrays.asList(imageId), new ParametersI());
Image image = images.get(0);
//extra call
Format f = (Format) queryServicePrx.get(Format.class.getName(), img.getFormat().getId().getValue());
if (f.getValue() != null) {
  String v = f.getValue().getValue();
}
ImageData imageData = new ImageData(image);
PixelsData pixelsData = imageData.getDefaultPixels();


This should give you the format as a string and you can check if it is jpeg etc.

Cheers
jmarie
User avatar
jburel
Team Member
 
Posts: 348
Joined: Thu May 21, 2009 6:38 pm
Location: dundee

Next

Return to Developer Discussion

Who is online

Users browsing this forum: No registered users and 1 guest