dtype-next icon indicating copy to clipboard operation
dtype-next copied to clipboard

BufferedImage's .getRaster .getNumBands can be used in figuring out the shape

Open daslu opened this issue 4 weeks ago • 5 comments

The namespace tech.v3.libs.buffered-image extends BufferedImage with certain protocols, including the extraction of shape (tech.v3.datatype/shape): https://github.com/cnuernber/dtype-next/blob/9170e69/src/tech/v3/libs/buffered_image.clj#L160

In unknown image types, it is assumed only one band: https://github.com/cnuernber/dtype-next/blob/9170e69/src/tech/v3/libs/buffered_image.clj#L177

However, the number of bands can be extracted using .getRaster .getNumBands, as @larzeitlin does in an upcoming tutorial about Cloud Optimized GeoTiff: https://github.com/ClojureCivitas/clojurecivitas.github.io/blob/be26c88/src/gis/geotiff.clj#L135

Example test file: https://github.com/ClojureCivitas/clojurecivitas.github.io/blob/be26c887796258f9ae31756cc3da7b654cf8d11c/src/gis/resources/example_geotiff_medium.tif

You can download it, and use the following code from @larzeitlin's tutorial to read it and extract the number of bands:

(import '[java.awt.image BufferedImage]
        '[java.io File]
        '[javax.imageio ImageIO]
        '[javax.imageio.stream FileImageInputStream])

(defn tiff-reader []
  (let [readers (ImageIO/getImageReadersByFormatName "tiff")]
    (.next readers)))

(defn read-tiff [file-path]
  (let [file (File. file-path)
        reader (tiff-reader)]
    (with-open [stream (FileImageInputStream. file)]
      (.setInput reader stream)
      (let [images (doall
                    ;; A single TIFF can store multiple images.
                    ;; This will be significant when we come to
                    ;; GeoTIFFs because of resolution pyramids.
                    ;; See below.
                    (for [i (range (.getNumImages reader true))]
                      (let [metadata (.getImageMetadata reader i)
                            native-format (.getNativeMetadataFormatName metadata)]
                        {:index i
                         :native-format native-format
                         :width (.getWidth reader i)
                         :height (.getHeight reader i)
                         :image (.read reader i)
                         :metadata metadata})))]
        {:images images
         :reader-format (.getFormatName reader)}))))

(-> "example_geotiff_medium.tif"
    read-tiff
    :images
    first
    :image
    .getRaster
    .getNumBands)

This will also affect tech.v3.tensor/as-tensor and allow it to come up with the right shape of output, this allowing to turn any Raster image to a tensor -- quite important for working with multispectral images.

Zulip discussion with @harold: #tech.ml.dataset.dev > shape of an image

daslu avatar Nov 30 '25 08:11 daslu

Thanks @daslu - this is great.

The example_geotiff_medium.tif seems to be sort of big (80+MB), and not multi-image or multispectral.

Though it does load and shape returns [4999 5999 1]

I am working on a patch that makes shape return [4999 5999 3], which is an improvement, but I'd like to test it against additional files.

Do you know of any other test images? Perhaps smaller, and maybe w/ more than one image per file, or more than 3 bands per image?

harold avatar Dec 01 '25 16:12 harold

example geotiff: https://github.com/larzeitlin/example_small_ms_geotiff

larzeitlin avatar Dec 04 '25 00:12 larzeitlin

@larzeitlin - super 🆒, well done, we'll check it out.

harold avatar Dec 04 '25 05:12 harold

AFAIK this should support multiplex ome-tiff, too (open microscopy format). There's example data here. getRaster -> getNumBands appears to be used heavily in QuPath w/o much exception babying. [ ex ]

benkamphaus avatar Dec 07 '25 15:12 benkamphaus

AFAIK this should support multiplex ome-tiff, too (open microscopy format). There's example data here. getRaster -> getNumBands appears to be used heavily in QuPath w/o much exception babying. [ ex ]

Great to see you here, the whole buffered-image namespace has roots in our original conversations about multispectral images, so it's nice to see this progressing. This is on our list to look at, thanks for everyone's patience.

harold avatar Dec 08 '25 17:12 harold