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

В этом примере показано, как выполнить обнаружение ребра на изображении 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 contains an axes object. The axes object with title Original Image contains an object of type image.

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

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

Теперь попробуйте ту же обработку блока использования задачи. 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 object. The axes object 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 object. The axes object 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 object. The axes object with title Block Processing - Borders & Fixed Threshold contains an object of type image.

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

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

|

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

Больше о