В этом примере показано, как выполнить обнаружение ребра на изображении 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
аргумент значения имени "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")
Блоки теперь обрабатываются с дополнительными 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
только дополнение нуля поддержек вдоль границ изображения.