32-разрядное изображение в формате TIFF выглядит белым и отличается от RAW

#c #tiff #imagej #libtiff

#c #tiff #imagej #libtiff

Вопрос:

У меня проблема с сохранением изображения с использованием библиотеки LibTIFF.

В моем коде у меня есть массив с плавающей точкой, представляющий значения пикселей изображения. Когда я сохраняю эти значения в файл RAW, все выглядит нормально. Однако, когда я пытаюсь сохранить его как TIFF-файл с помощью библиотеки LibTIFF, изображение выглядит совершенно нормально, когда я открываю его в ImageJ, однако, когда я открываю его в Photoshop или Windows, это выглядит странно (смотрите ниже), а Gimp показывает полностью прозрачное изображение (как будто на изображении вообще не было данных).

Я использую ImageJ для открытия файла RAW, тип изображения установлен в 32 бита — порядок байтов в реальном и младшем разрядах отмечен галочкой.

RAW слева, TIFF справа

Вот код, который я использую для сохранения изображения в формате TIFF:

 TIFF *tif= TIFFOpen(name, "w");

TIFFSetField (tif, TIFFTAG_IMAGEWIDTH, width);
TIFFSetField (tif, TIFFTAG_IMAGELENGTH, height);
TIFFSetField (tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField (tif, TIFFTAG_SAMPLESPERPIXEL, 1);
TIFFSetField (tif, TIFFTAG_ROWSPERSTRIP, 1);
TIFFSetField (tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
TIFFSetField (tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
TIFFSetField (tif, TIFFTAG_BITSPERSAMPLE, 32);
TIFFSetField (tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);

tsize_t strip_size = TIFFStripSize (tif);
tstrip_t strips_num = TIFFNumberOfStrips (tif); 

float* strip_buf=(float*)_TIFFmalloc(strip_size);
for (unsigned int s=0; s<strips_num; s  ) {
    for (unsigned int col=0; col<width; col  ) {
        strip_buf[col]=image[s][col];
    }
    TIFFWriteEncodedStrip (tif, s, strip_buf, strip_size);

}
_TIFFfree(strip_buf);
TIFFClose(tif);
  

Я почти уверен, что что-то не так с тем, как я сохраняю файл, но я понятия не имею, что. Большое спасибо за вашу помощь!

Ответ №1:

Возможно, вам потребуется добавить следующую строку, чтобы указать, что изображение имеет плавающий 32-разрядный формат.

     TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
  

И тогда у вас не должно возникнуть никаких проблем с программой, которая может считывать плавающее изображение.

Комментарии:

1. Ты спас меня! В общедоступных libtiff-руководствах нет такого ценного намека.

Ответ №2:

Я сомневаюсь, что что-то не так в том, как вы его сохраняете — просто средство просмотра изображений Windows не может должным образом обрабатывать TIFF-файлы с 32-разрядной версией. Ничего не зная о LibTIFF, я бы предположил, что вы могли бы изменить bitdepth созданного TIFF, установив соответствующую строку в вашем коде на 8 вместо 32 , чтобы она читалась следующим образом:

 TIFFSetField (tif, TIFFTAG_BITSPERSAMPLE, 8);
  

Однако, пожалуйста, имейте в виду, что это приведет к потере информации, если ваши исходные данные имели больше значений интенсивности, чем то, что может быть представлено 8 битами. И я понятия не имею, как LibTIFF выполняет там масштабирование.

Но только потому, что Windows / Gimp / Photoshop не отображают их корректно, не означает, что файлы TIFF повреждены.

Комментарии:

1. Глядя на правильное изображение на вашем скриншоте, я бы предположил, что это всего лишь младшие 8 бит из 32-разрядного файла TIFF. Вероятно, это то, что делает программа просмотра изображений Windows, когда сталкивается с чем-то, что она понимает лишь частично 😉