В этом примере показано, как выполнить обнаружение краев для изображения 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')

imshow(normal_edges)
title('Conventional Edge Detection')
Попробуйте выполнить ту же задачу с помощью обработки блоков. 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')

Обратите внимание на значительные артефакты обработки блоков. Определение того, является ли пиксель краевым пикселем, требует информации от соседних пикселей. Это означает, что каждый блок не может быть обработан полностью отдельно от окружающих его пикселей. Чтобы исправить это, используйте blockproc параметр BorterSize для указания вертикальных и горизонтальных границ вокруг каждого блока. Необходимый «Размер основания» зависит от выполняемой задачи.
border_size = [10 10]; block_edges = blockproc(file_name,block_size,edgeFun,'BorderSize',border_size); 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); imshow(block_edges) title('Block Processing - Borders & Fixed Threshold')

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