Я работаю с очень большими изображениями tif, которые я составляю в одно большое изображение. У меня есть библиотека, созданная моим коллегой, которая генерирует пирамиду изображений и предоставляет очень удобный инструмент для визуализации пирамиды изображений. Этот визуализатор отлично подходит для получения пикового изображения на большом изображении и визуального определения точек интереса, но клиенты больше заинтересованы в анализе изображений на этих больших изображениях.
Таким образом, необходимо экспортировать очень большое изображение в один файл. Я считаю, что это проблематично, учитывая, что эти образы могут иметь размер от 800 МБ до нескольких ГБ. И сама задача загрузки этого единственного изображения в память является сложной задачей, особенно когда выполняется анализ изображения.
Мне было интересно, можно ли в java написать это большое изображение в формате tiff в виде блока или строки за строкой. В настоящее время моему приложению не хватает памяти на небольших (8 ГБ ОЗУ) машинах.
Текущий метод составления этих изображений:
Сохраните значения пикселей в
BufferedImage
с помощьюWritableRaster
short[][]pixels = ... BufferedImage image = new BufferedImage(width, height, type); WritableRaster = image.getRaster(); for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { raster.setSample(col, row, 0, pixel[row][col]); } }
А затем записать буферизованное изображение на диск. В этой части я использую
ImageJ
для записи изображения в формате tif. Если есть лучшие способы поддержки 16-битных изображений tif в оттенках серого, я буду рад взглянуть// BufferedImage image; from above ... ImagePlus img = new ImagePlus(); img.setImage(image); FileSaver fs = new FileSaver(img); fs.saveAsTiff(file.getAbsolutePath());
Проблема с этим методом заключается в том, что он занимает слишком много памяти для машины с 8 ГБ ОЗУ.
В идеале я хотел бы иметь только один short[][]pixels
. Это в основном потому, что мне нужно вычислить среднюю функцию смешивания, поэтому там будет некоторый объем памяти. Также в будущем я добавлю линейный бленд. short[][]pixels
должен занимать только ~765 МБ ОЗУ для данных размером 20k x 20k пикселей, что, как мне кажется, в настоящее время неизбежно, поэтому для больших изображений, например, 100k x 100k пикселей, я надеюсь, что биологи не захотят экспортировать это изображение как это займет 18 ГБ ОЗУ.
Позже я изменю код для поддержки экспорта очень больших изображений, таких как 100k x 100k. На данный момент я согласен с тем, что для хранения начальных значений пикселей используется один фрагмент памяти.
Итак, каков хороший метод записи частей изображения tif на диск, чтобы я мог поддерживать запись основных изображений, таких как изображения 100k x 100k.
Я видел это сообщение: Напишите мозаичный вывод TIFF, используя ImageIO на Java
Но это просто обсуждает спецификацию TIFF 6.0. Но я посмотрю на ImageOutputStreams
. Однако Тиф — зверь, поэтому я мог бы просто стиснуть зубы и призвать биологов экспортировать только интересующие области.
EDIT: найдено жизнеспособное решение:
и
Основная страница группы: https://github.com/openmicrooscopy/bioformats