Блочная обработка больших изображений

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

Чтобы избежать этих проблем, можно пошагово обрабатывать большие изображения: чтение, обработка и, наконец, запись результатов обратно на диск, по одной области за раз. The blockproc функция помогает вам в этом процессе. Использование blockproc, задайте изображение, размер блока и указатель на функцию. blockproc затем делит входное изображение на блоки заданного размера, обрабатывает их с помощью указателя на функцию по одному блоку за раз, а затем собирает результаты в выходное изображение. blockproc возвращает выход в память или в новый файл на диске.

Сначала рассмотрим результаты выполнения обнаружения ребра без обработки блоков. Этот пример использует небольшое изображение, cameraman.tif, чтобы проиллюстрировать концепции, но обработка блоков часто более полезна для больших изображений.

file_name = 'cameraman.tif';
I = imread(file_name);
normal_edges = edge(I,'canny');

imshow(I)
title('Original Image')

Figure contains an axes. The axes with title Original Image contains an object of type image.

imshow(normal_edges)
title('Conventional Edge Detection')

Figure contains an axes. The axes with title Conventional Edge Detection contains an object of type image.

Теперь попробуйте ту же задачу с помощью обработки блока. The blockproc функция имеет встроенную поддержку TIFF изображений, поэтому вы не должны полностью читать файл в память с помощью imread. Вместо этого вызовите функцию, используя строковое имя файла как вход. blockproc читает в одном блоке за раз, делая этот рабочий процесс идеальным для очень больших изображений.

При работе с большими изображениями вы часто будете использовать параметр 'Destination', чтобы задать файл, в который blockproc запишет выходное изображение. Однако в этом примере вы вернете результаты к переменной, в памяти.

Этот пример использует размер блока [50 50]. В целом выбор больших размеров блоков приводит к лучшей эффективности для blockproc. Это особенно верно для рабочих процессов «файл-файл», где доступ к диску будет иметь значительные затраты на эффективность. Соответствующие размеры блоков варьируются в зависимости от доступных ресурсов машины, но, вероятно, должны быть в области значений тысяч пикселей на размерность.

% You can use an anonymous function to define the function handle. The
% function is passed a structure as input, a "block struct", with several
% fields containing the block data as well as other relevant information.
% The function should return the processed block data.
edgeFun = @(block_struct) edge(block_struct.data,'canny');

block_size = [50 50];
block_edges = blockproc(file_name,block_size,edgeFun);

imshow(block_edges)
title('Block Processing - Simplest Syntax')

Figure contains an axes. The axes with title Block Processing - Simplest Syntax contains an object of type image.

Заметьте значимые программные продукты от обработки блоков. Для определения, является ли пиксель краевым или нет, требуется информация от соседних пикселей. Это означает, что каждый блок не может быть обработан полностью отдельно от окружающих его пикселей. Чтобы исправить это, используйте blockproc параметр 'BorderSize' для задания вертикальных и горизонтальных границ вокруг каждого блока. Необходимый параметр 'BorderSize' изменяется в зависимости от выполняемой задачи.

border_size = [10 10];
block_edges = blockproc(file_name,block_size,edgeFun,'BorderSize',border_size);

imshow(block_edges)
title('Block Processing - Block Borders')

Figure contains an axes. The axes with title Block Processing - Block Borders contains an object of type image.

Блоки теперь обрабатываются дополнительными 10 пикселями данных изображений на каждой стороне. Выглядит это лучше, но результат все равно существенно отличается от исходного результата в памяти. Причиной этого является то, что детектор ребра Канни использует порог, который вычисляется на основе полной гистограммы изображения. Начиная с blockproc функция вызывает edge функция для каждого блока, алгоритм Канни работает с неполными гистограммами и, следовательно, использует меняющиеся пороги по всему изображению.

При обработке изображений блоков важно понимать эти типы ограничений алгоритма. Некоторые функции не будут непосредственно преобразовываться в блочную обработку для всех синтаксисов. В этом случае edge функция позволяет вам проходить в фиксированном пороге как входном параметре вместо вычисления его. Измените указатель на функцию, чтобы использовать синтаксис трех аргументов edgeи, таким образом, удалите одно из «глобальных» ограничений функции. Некоторые пробы и ошибки находят, что порог 0,09 дает хорошие результаты.

thresh = 0.09;
edgeFun = @(block_struct) edge(block_struct.data,'canny',thresh);
block_edges = blockproc(file_name,block_size,edgeFun,'BorderSize',border_size);

imshow(block_edges)
title('Block Processing - Borders & Fixed Threshold')

Figure contains an axes. The axes with title Block Processing - Borders & Fixed Threshold contains an object of type image.

Результат теперь тесно совпадает с исходным результатом в памяти. Вы можете увидеть некоторые дополнительные программные продукты вдоль контуров. Это связано с различными способами заполнения, используемыми детектором ребра Канни. В настоящее время, blockproc поддерживает только заполнение нулем по контурам изображения.

См. также

|

Похожие примеры

Подробнее о