Блокируйте обрабатывающие большие изображения

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

Чтобы избежать этих проблем, можно обработать большие изображения инкрементно: чтение, обработка и наконец обратная запись результатов к диску, одна область за один раз. Функция 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
imshow(normal_edges)
title('Conventional Edge Detection')

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

При работе с большими изображениями вы будете часто использовать 'Целевой' параметр, чтобы задать файл, в который 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);

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

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

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

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

Блоки теперь обрабатываются с дополнительными 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);

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

Результат теперь тесно совпадает с исходным результатом в оперативной памяти. Вы видите некоторые дополнительные артефакты вдоль контуров. Они происходят из-за различных методов дополнения используемого детектором ребра Кэнни. В настоящее время blockproc только поддерживает дополнение нуля вдоль границ изображения.

Смотрите также

|

Связанные примеры

Больше о