https://kotlinlang.org logo
Title
a

Alexandre Brown

05/06/2022, 6:15 PM
Is there a nice kotlin/java package that exists to tile a large orthomosaic image without loading the entire orthomoasaic (13GB) in memory?
Ok I got it working, this is pretty handy for performing inference on large images, will share code snippet tomorrow morning for others
👍 1
Here is the prototype I ended up with for people interested in using this for CNN or exploratory data analysis on images. In this prototype, I load a big tiff (3.6GB), by reading only tiles (regions) of it so that it only loads this part in memory and not the entire tiff so that RAM usage stays pretty low during reading. Here I defined a 512x512 tile but you can change it to whatever you want.
import java.awt.Rectangle
import java.awt.image.BufferedImage
import java.io.File
import java.io.RandomAccessFile
import javax.imageio.ImageIO
import javax.imageio.ImageReadParam
import javax.imageio.ImageReader
import kotlin.system.measureTimeMillis
import kotlin.time.TimeSource
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking


fun main() {

	println("Extracting tile...")

	val totalTime = measureTimeMillis {
		runBlocking(<http://Dispatchers.IO|Dispatchers.IO>) {
			val openTiffTime = TimeSource.Monotonic.markNow()
			RandomAccessFile(File("FN1_jpeg_compression.tif"), "r").use {
				ImageIO.createImageInputStream(it).use { imageInputStream ->
					val imageReader: ImageReader = ImageIO.getImageReaders(imageInputStream)
						.next()
						.apply {
							input = imageInputStream
						}

					val width = imageReader.getWidth(0)
					val height = imageReader.getHeight(0)
					println("Initial open of tiff took ${openTiffTime.elapsedNow().inWholeMilliseconds}ms")
					println("Tiff Height $width")
					println("Tiff Width $height")

					val tilesTime = measureTimeMillis {
						for (x in 0 until 15) {
							for (y in 0 until 15) {
								val tileTime = measureTimeMillis {
									println("Reading tile...")
									val param: ImageReadParam = imageReader.defaultReadParam.apply {
										sourceRegion = Rectangle(x, y, 512, 512)
									}

									val imageTile: BufferedImage = imageReader.read(0, param)
								}
								println("Read a tile in ${tileTime}ms!")
							}
						}
					}

					println("Read all tiles in ${tilesTime}ms")
				}
			}
		}
	}

	println("Total execution time : ${totalTime}ms")
}
Dependencies :
implementation("com.twelvemonkeys.imageio:imageio-jpeg:3.8.2")
implementation("com.twelvemonkeys.imageio:imageio-tiff:3.8.2")
❤️ 2
a

asad.awadia

05/12/2022, 1:13 AM
Damn you a solid dev
🤘 1