Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    Curtis Rueden
    @ctrueden
    I second the suggestion to use Maven. You could look at https://github.com/fiji/fiji for an example of including Bio-Formats. You need the formats-gpl component in particular.
    wongmac
    @wongmac
    How can I set the current file so I can uses the svs reader of the bioformats library? https://downloads.openmicroscopy.org/bio-formats/5.1.0/api/loci/formats/IFormatReader.html#getCurrentFile()
    Curtis Rueden
    @ctrueden
    @wongmac OK, here we are! Let me dig up the example for you.
    Here is where it reads bytes from one plane at a time in a loop.
    And here is where it assigns the filename to the reader, using the setId method. The file format is autodetected from the contents of the file.
    wongmac
    @wongmac
    @ctrueden No I haven't, thank you!
    Curtis Rueden
    @ctrueden
    That example is pretty comprehensive. In fact, it is the code for the showinf command line tool.
    If anything is not clear in there, let us know here, and we will explain. Good luck. :-)
    Note that that example does a lot of extra stuff you probably don't need for your use case, like wrapping up the reader in some layers.
    For you, it is likely enough to just do:
    ImageReader r = new ImageReader();
    r.setId("/path/to/my.svs");
    for (int s=0; s<r.getSeriesCount(); r++) {
      r.setSeries(s);
      for (int i=0; i<r.getImageCount(); i++) {
        byte[] plane = r.openBytes(i);
      }
    }
    And if you need to extract metadata, there are various ways of doing that; see this page for a primer.
    wongmac
    @wongmac
    @ctrueden thank you so much! that's exactly what I needed :)
    Curtis Rueden
    @ctrueden
    @wongmac You're welcome. :-)
    wongmac
    @wongmac
    @ctrueden it works perfectly, but as you said the array of bytes cannot hold the files that large of the svs. Is there anyway to gather the data into say a matrix of the values or something that could hold it all?
    Curtis Rueden
    @ctrueden
    @wongmac You can use SCIFIO to read an ImageJ2 Dataset object. This API is not yet stable but it is working.
    wongmac
    @wongmac
    How can I decode the byte array returned by openBytes into the RGB values of each pixel inside of the given sub image. How do the byte arrays store the data?
    Curtis Rueden
    @ctrueden
    @wongmac You probably want loci.common.DataTools.makeDataArray and loci.common.DataTools.makeDataArray2D!
    You need to ask the reader for the bits per pixel, type, etc., unfortunately. But it is doable.
    wongmac
    @wongmac
    does the make2DDataArray function given by the DataTools class allow me to retrieve the RGB values somehow? (what data type is stored inside of the array) and how can I retrieve the rgb or hsi values from the byte array returned by open bytes? (Sorry for the noob questions, I'm extremely new to this, and have never worked with complex image types)
    Curtis Rueden
    @ctrueden
    It's been a long time since I have looked at that code, but my guess is it will come back as packed RGBA ints. Or else three separate byte channels. You can check via instanceof.
    Maybe someone else can clarify further; sleepy time for me.
    David Gault
    @dgault
    Hi, just following up on the suggestions that Curtis had made, if you are using the make2DDataArray function then you will receive back a 2d array. The function requires the following parameters: makeDataArray2D(byte[] b, int bpp, boolean fp, boolean little, int height)
    bpp is the bytes per pixel, fp is a boolean representing if the data is floating point or not. The return type of values in the array received back is based on these 2 values
    If the bytes per pixel == 1 then your return array will be a byte[][]
    If the bytes per pixel == 2 then your return array will be a short[][]
    If the bytes per pixel == 4 and floating point then your return array will be a double[][]
    If the bytes per pixel == 4 and not floating point then your return array will be a int[][]
    If the bytes per pixel == 8 and floating point then your return array will be a float[][]
    If the bytes per pixel == 8 and not floating point then your return array will be a long[][]
    You can read these values from the reader using the following :
    boolean floatingPoint = (pixelType == FormatTools.FLOAT || pixelType == FormatTools.DOUBLE);
    int bytesPerPixel = FormatTools.getBytesPerPixel(pixelType);
    David Gault
    @dgault
    If your data is split in separate RGB channels (which can be read with int channels = r.getSizeC();) then you will still receive back a single 2d array. The array however will be of size [channels * width] [height]
    A simple example of this might be:
    SVSReader r = new SVSReader();
    r.setId("/path/to/myfile.svs");
    
    int pixelType = r.getPixelType();
    boolean floatingPoint = (pixelType == FormatTools.FLOAT || pixelType == FormatTools.DOUBLE);
    int bytesPerPixel = FormatTools.getBytesPerPixel(pixelType);
    boolean litteEndian = r.isLittleEndian();
    
    for (int s=0; s<r.getSeriesCount(); s++) {
      r.setSeries(s);
      int width = r.getSizeX();
      int height = r.getSizeY();
      int z = r.getSizeZ();
      int timePoints = r.getSizeT();
      int channels = r.getSizeC();
      for (int i=0; i<r.getImageCount(); i++) {
        byte[] plane = r.openBytes(i);
        Object pixelData = DataTools.makeDataArray2D(plane, bytesPerPixel, floatingPoint, litteEndian, height);
        byte[][] pixels = (byte[][]) pixelData;
        for (int c =0; c < channels; c++) {
          for (int x =0; x < width; x++) {
            for (int y =0; y < height; y++) {
              System.out.println("Pixel Value at channel:" + c +" coordinates x: " + x + " y: " + y + " is: " + pixels[(c*x)+x][y]);
            }
          }
        }
      }
    }
    r.close();
    Note in the example above I am casting to byte[][] but the type of your array may differ based on the bytes per pixel etc as mentioned above
    Curtis Rueden
    @ctrueden
    @dgault The other potential complication, which I believe @wongmac might be hitting, is the case where getSizeC > getEffectiveC. This will be the case for RGB data for example, unless ChannelSeparator is used. It is maybe the case that makeDataArray2D does not actually support this situation.
    @wongmac The quick solution is to use ChannelSeparator.
    (Caveat emptor: this is all from memory so note that my knowledge may now be out of date or wrong.)
    David Gault
    @dgault
    In which case the ChannelSeperator can be used as a Reader Wrapper to automatically handle the splitting of the channels. To use the ChannelSeperator you can simply wrap your reader with it and then use it as you would the original reader
    reader = new ChannelSeparator(reader);
    Christian Dietz
    @dietzc
    hi @/all. Quick question: shouldn't the public static methods in DataTools https://github.com/openmicroscopy/bioformats/blob/develop/components/formats-common/src/loci/common/DataTools.java be synchronized? because for example https://github.com/openmicroscopy/bioformats/blob/develop/components/formats-gpl/src/loci/formats/in/ZeissCZIReader.java#L2499 accesses these DataTools for parsing the String. However, if you have multiple CZIReaders open in multiple threads, this causes race conditions as DecimalFormat.parse(...) and all other NumberFormat things in java are not thread-safe.
    Curtis Rueden
    @ctrueden
    I would suggest making the nf field into a ThreadLocal. Should be more performant than synchronizing, yeah?
    Christian Dietz
    @dietzc
    yep
    Christian Dietz
    @dietzc
    I think the problem comes with openmicroscopy/bioformats@87730bd
    S├ębastien Besson
    @sbesson
    @dietzc: many thanks for catching up these issues, could you raise it either as a Bio-Formats issue, a forum thread or an email to ome-devel?
    Christian Dietz
    @dietzc
    It seems I've chosen the worst channel to communicate this issue :-P I'll open an issue
    is openmicroscopy/bioformats#2551 enough?