Сохранение многоканальных (n › 3) изображений со сжатием JPEG (python)

Я работаю с некоторыми биомедицинскими изображениями с более чем 3 каналами. Изображения довольно большие, поэтому я бы предпочел хранить их в виде пирамидальных файлов TIFF со сжатием JPEG. Это дает коэффициент сжатия порядка величины по сравнению с другими схемами сжатия (например, LZW, Deflate).

В настоящее время я использую функцию tiffsave pyvips для сохранения этих изображений. С другими схемами сжатия я могу сохранять изображения с произвольным количеством каналов. Однако со сжатием JPEG я понял, что сохраненные изображения могут иметь только 1 или 3 канала.

Если алгоритм JPEG может сжимать 1 канал, наверняка должны быть способы упаковать несколько сжатых JPEG одноканальных изображений в один файл?

Кто-нибудь знает способ сохранить n> 3-канальные изображения в один файл со следующими критериями?

  • Сжатие JPEG (или алгоритм с сопоставимой производительностью)
  • Легко просматривается с помощью программного обеспечения для просмотра изображений с графическим интерфейсом (например, ImageJ)
  • Я действительно не хочу хранить каждый канал в виде отдельного файла.
  • Изображения, хранящиеся в пирамидальном формате
  • Питон 3

person matohak    schedule 11.04.2020    source источник


Ответы (1)


вышла версия libvips 8.10 и поддерживает создание пирамид OME-TIFF.

Эти файлы TIFF хранят каждый канал на отдельной странице файла, при этом каждая страница имеет собственную пирамиду, хранящуюся в TIFF SUBIFD. Я ожидаю, что ImageJ сможет их прочитать, хотя вам, возможно, понадобится плагин.

Вы можете сгенерировать их в pyvips следующим образом:

#!/usr/bin/python3

import sys
import pyvips

def load(filename):
    return pyvips.Image.new_from_file(filename)

# load a couple of eg. three-band images to make a 6-band image
image = load(sys.argv[2]).bandjoin(load(sys.argv[3]))

# to convert to OME, we need a tall, thin mono image with page-height set to
# indicate where the joins are
ome = pyvips.Image.arrayjoin(image.bandsplit(), across=1)

# you must make a private copy before modifying image metadata
ome = ome.copy()
ome.set_type(pyvips.GValue.gint_type, 'page-height', image.height)

# now we can write as a pyramid
# libvips 8.10+ will put the pyramid layers into SUBIFDs
ome.tiffsave(sys.argv[1], pyramid=True, compression="jpeg", Q=90)

Выполнить так:

$ ./gen_ome.py x.tif ~/pics/1.tiff ~/pics/2.tiff 
$ tiffinfo x.tif 
TIFF Directory at offset 0x173f02 (1523458)
  Subfile Type: multi-page document (2 = 0x2)
  Image Width: 6048 Image Length: 4032
  Tile Width: 128 Tile Length: 128
  Resolution: 300, 300 pixels/inch
  Bits/Sample: 8
  Sample Format: unsigned integer
  Compression Scheme: JPEG
  Photometric Interpretation: min-is-black
  Orientation: row 0 top, col 0 lhs
  Samples/Pixel: 1
  Planar Configuration: single image plane
  Page Number: 0-6
  SubIFD Offsets: 2153288 2339670 2396406 2415400 2422262 2424960
  JPEG Tables: (73 bytes)
TIFF Directory at offset 0x3c3b2c (3947308)
  Subfile Type: multi-page document (2 = 0x2)
  Image Width: 6048 Image Length: 4032
  Tile Width: 128 Tile Length: 128
...

Итак, вы можете видеть, что есть шесть страниц для шести каналов, и каждая страница имеет набор SUBIFD, содержащих слои пирамиды.

person jcupitt    schedule 18.08.2020