эффективное извлечение тайлов TIFF C ++ - PullRequest
8 голосов
/ 30 октября 2009

Я работаю с 1-гигабайтными изображениями большого размера размером около 20000 x 20000 пикселей. Мне нужно извлечь несколько изображений (размером около 300x300 пикселей) из изображений в случайном порядке.

Я пробовал следующие решения:

  • Libtiff (единственная библиотека нижнего уровня, которую я смог найти) предлагает TIFFReadline (), но это означает чтение примерно 19700 ненужных пикселей.

  • Я реализовал свой собственный TIFF-ридер, который извлекает плитку из изображения, не считывая ненужные пиксели. Я ожидал, что это будет быстрее, но выполнение поиска для каждой строки плитки делает его очень медленным. Я также попытался прочитать в буфер все строки файла, которые содержат мою плитку, а затем извлечь плитку из буфера, но результаты более или менее совпадают.

Я бы хотел получать предложения по улучшению инструмента извлечения плитки!

Все приветствуется, может быть, вы можете предложить более эффективную библиотеку, которую я мог бы использовать, несколько советов по вводу / выводу C / C ++, стратегии более высокого уровня для моих нужд и т. Д.

С уважением, Juan

Ответы [ 5 ]

3 голосов
/ 04 января 2010

[Major edit 14 января 10]

Меня немного смутило упоминание о плитках, когда tiff не выложен плиткой.

Я использую мозаичные / пирамидальные изображения TIFF. Я создал их с VIPS

vips im_vips2tiff source_image output_image.tif:none,tile:256x256,pyramid

Я думаю, что вы можете сделать это с:

vips im_vips2tiff source_image output_image.tif:none,tile:256x256,flat

Вы можете поэкспериментировать с размером плитки. Затем вы можете читать, используя TIFFReadEncodedTile.

Хранение в нескольких разрешениях с использованием пирамидальных символов намного быстрее, если вам нужно увеличить / уменьшить масштаб. Вы также можете использовать это, чтобы почти сразу же получить грубое изображение, а затем детальное изображение.

После переключения на мозаичное хранилище (подходящего размера) (которое принесет вам ОГРОМНОЕ улучшение производительности для произвольного доступа!), Вашим узким местом станет диск io. Чтение файлов происходит намного быстрее, если читать последовательно. Здесь mmapping может быть решением.

Некоторые полезные ссылки:

ВИПС IIPImage Перемещение в стеке LibTiff.NET VIPS - это библиотека обработки изображений, которая может делать гораздо больше, чем просто читать / писать. У него есть собственный, очень эффективный внутренний формат. Имеет хорошую документацию по алгоритмам. Во-первых, он отделяет обработку от файловой системы, позволяя кэшировать тайлы.

IIPImage - это веб-сервер / библиотека браузера с несколькими зумами. Я нашел документацию очень хорошим источником информации по изображениям с несколькими разрешениями (например, карты Google)

Другое решение на этой странице, использующее mmap, эффективно только для «маленьких» файлов. Я часто сталкиваюсь с 32-битными границами. Как правило, выделение фрагмента памяти объемом 1 ГБ завершится неудачно на 32-разрядной ОС (с установленной 4 ГБ ОЗУ) из-за того, что даже виртуальная память разрушается после запуска одного или двух приложений. Тем не менее, достаточно памяти для кэширования частей или всего изображения. Больше памяти = больше производительности.

2 голосов
/ 21 апреля 2010

Спасибо всем за ответы.

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

Прирост эффективности был огромным. В противном случае, если вам нужен произвольный доступ к файлу, mmap - хорошая сделка.

С уважением, Juan

2 голосов
/ 31 октября 2009

Просто отобразите свой файл.

http://www.kernel.org/doc/man-pages/online/pages/man2/mmap.2.html

0 голосов
/ 08 ноября 2010

Вы получили конкретное сообщение об ошибке? В зависимости от того, как вы использовали эту командную строку, вы могли наступить на свой собственный файл.

Если это не проблема, попробуйте использовать imagemagick вместо vips, если это возможно.

0 голосов
/ 04 января 2010

Я сделал нечто подобное, чтобы обработать файл формата TARGA (TGA) произвольно большого размера. Для такого файла стало проще то, что изображение не сжимается. Вы можете рассчитать положение любого произвольного пикселя на изображении и найти его простым поиском. Вы можете рассмотреть формат targa, если у вас есть возможность указать кодировку изображения.

Если нет, существует много разновидностей форматов TIFF. Возможно, вы захотите использовать библиотеку, если они уже прошли через поддержку поддержки всех различных форматов.

...