Вычисление статистики для больших изображений

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

Этот пример выполняет задачу, подобную той, которая обнаружена в примере Enhand Multispectral Color Composite Images, но адаптирована для больших изображений, используя blockproc. Вы будете расширять видимые полосы данных файла LAN Erdas rio.lan. Эти типы методов обработки блоков обычно более полезны для больших изображений, но небольшое изображение будет работать с целью этого примера.

Шаг 1: Создайте композит Truecolor

Использование blockproc, считайте данные из rio.lan, файл, содержащий тематические изображения mapper Landsat в формате файла локальной сети Erdas. blockproc имеет встроенную поддержку чтения только TIFF и JPEG2000 файлов. Чтобы считать другие типы файлов, необходимо записать класс Image Adapter для поддержки ввода-вывода в конкретном формате файла. Этот пример использует предварительно созданный класс Image Adapter, LanAdapter, который поддерживает чтение файлов LAN. Для получения дополнительной информации о записи классов Image Adapter, смотрите Выполните Обработку Блоков для Файлов Изображений в неподдерживаемых Форматах.

Формат Erdas LAN содержит видимый красный, зеленый и синий спектр в полосах 3, 2 и 1 соответственно. Использование blockproc для извлечения видимых полос в изображение RGB.

Создайте объект LanAdapter, сопоставленный с rio.lan.

input_adapter = LanAdapter('rio.lan');

Выберите видимые R, G и B полос.

input_adapter.SelectedBands = [3 2 1];

Создайте функцию блока, чтобы просто вернуть данные блока без изменений.

identityFcn = @(block_struct) block_struct.data;

Создайте начальное изображение труколора.

truecolor = blockproc(input_adapter,[100 100],identityFcn);

Отображение результатов перед расширением.

imshow(truecolor)
title('Truecolor Composite (Not Enhanced)')

Figure contains an axes. The axes with title Truecolor Composite (Not Enhanced) contains an object of type image.

Получившееся изображение truecolor подобно изображению paris.lan в примере «Улучшение мультиспектральных цветных композитных изображений». Изображение RGB выглядит тусклым, с небольшой контрастностью.

Шаг 2: Улучшите изображение - первая попытка

Во-первых, попробуйте растянуть данные в динамической области значений с помощью blockproc. Эта первая попытка просто задает новый указатель на функцию, который вызывает stretchlim и imadjust по каждому блоку данных индивидуально.

adjustFcn = @(block_struct) imadjust(block_struct.data,...
    stretchlim(block_struct.data));
truecolor_enhanced = blockproc(input_adapter,[100 100],adjustFcn);

imshow(truecolor_enhanced)
title('Truecolor Composite with Blockwise Contrast Stretch')

Figure contains an axes. The axes with title Truecolor Composite with Blockwise Contrast Stretch contains an object of type image.

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

Шаг 3: Исследуйте класс аккумулятора гистограммы

Чтобы изучить распределение данных по динамической области значений изображения, можно вычислить гистограмму для каждой из трёх видимых полос.

При работе с достаточно большими изображениями нельзя просто вызвать imhist для создания гистограммы изображения. Один из способов пошагово создать гистограмму - использовать blockproc с классом, который суммирует гистограммы каждого блока при перемещении по изображению.

Исследуйте HistogramAccumulator класс.

type HistogramAccumulator
% HistogramAccumulator Accumulate incremental histogram.
%   HistogramAccumulator is a class that incrementally builds up a
%   histogram for an image.  This class is appropriate for use with 8-bit
%   or 16-bit integer images and is for educational purposes ONLY.

%   Copyright 2009 The MathWorks, Inc.

classdef HistogramAccumulator < handle
   
    properties
        Histogram
        Range
    end
    
    methods
        
        function obj = HistogramAccumulator()
            obj.Range = [];
            obj.Histogram = [];
        end
        
        function addToHistogram(obj,new_data)
            if isempty(obj.Histogram)
                obj.Range = double(0:intmax(class(new_data)));
                obj.Histogram = hist(double(new_data(:)),obj.Range);
            else
                new_hist = hist(double(new_data(:)),obj.Range);
                obj.Histogram = obj.Histogram + new_hist;
            end
        end
    end
end

Класс является простой оберткой вокруг hist функция, позволяющая добавлять данные к гистограмме пошагово. Он не специфичен для blockproc. Наблюдайте следующее простое использование HistogramAccumulator класс.

Создайте HistogramAccumulator объект.

hist_obj = HistogramAccumulator;

Разделите образец изображения на 2 половины.

full_image = imread('liftingbody.png');
top_half = full_image(1:256,:);
bottom_half = full_image(257:end,:);

Вычислите гистограмму пошагово.

addToHistogram(hist_obj,top_half);
addToHistogram(hist_obj,bottom_half);
computed_histogram = hist_obj.Histogram;

Сравните с результатами IMHIST.

normal_histogram = imhist(full_image);

Исследуйте результаты. Гистограммы численно идентичны.

figure
subplot(1,2,1)
stem(computed_histogram,'Marker','none')
title('Incrementally Computed Histogram')
subplot(1,2,2)
stem(normal_histogram','Marker','none')
title('IMHIST Histogram')

Figure contains 2 axes. Axes 1 with title Incrementally Computed Histogram contains an object of type stem. Axes 2 with title IMHIST Histogram contains an object of type stem.

Шаг 4: Используйте класс HistogramAccumulator с BLOCKPROC

Теперь используйте HistogramAccumulator класс с blockproc построение гистограммы красной полосы данных в rio.lan. Можно задать указатель на функцию для blockproc который будет вызывать addToHistogram способ на каждом блоке данных. При просмотре этой гистограммы можно увидеть, что данные сосредоточены в небольшой части доступной динамической области значений. Другие видимые полосы имеют аналогичные распределения. Это одна из причин, почему оригинальный композит truecolor выглядит тусклым.

Создайте объект HistogramAccumulator.

hist_obj = HistogramAccumulator;

Настройка blockproc указатель на функцию

addToHistFcn = @(block_struct) addToHistogram(hist_obj, block_struct.data);

Вычислите гистограмму красного канала. Заметьте, что addToHistFcn указатель на функцию генерирует любой выход. Поскольку указатель на функцию перешел к blockproc ничего не возвращает, blockproc ничего не вернёт и.

input_adapter.SelectedBands = 3;
blockproc(input_adapter,[100 100],addToHistFcn);
red_hist = hist_obj.Histogram;

Отображение результатов.

figure
stem(red_hist,'Marker','none')
title('Histogram of Red Band (Band 3)')

Figure contains an axes. The axes with title Histogram of Red Band (Band 3) contains an object of type stem.

Шаг 5: Улучшите композит Truecolor с контрастным растяжением

Теперь можно выполнить правильное контрастное растяжение изображения. Для обычных рабочих процессов в памяти можно просто использовать stretchlim функция для вычисления аргументов в imadjust (как и MultispectralImageEnhancementExample пример делает). При работе с большими изображениями, как мы видели, stretchlim не легко приспособлен для использования с blockproc поскольку он опирается на полную гистограмму изображения.

После вычисления гистограмм изображений для каждой из видимых областей вычислите соответствующие аргументы, чтобы imadjust вручную (подобно тому, как stretchlim делает.

Сначала вычислите гистограммы для зелёных и синих полос.

hist_obj = HistogramAccumulator;
addToHistFcn = @(block_struct) addToHistogram(hist_obj,block_struct.data);
input_adapter.SelectedBands = 2;
blockproc(input_adapter,[100 100],addToHistFcn);
green_hist = hist_obj.Histogram;

hist_obj = HistogramAccumulator;
addToHistFcn = @(block_struct) addToHistogram(hist_obj,block_struct.data);
input_adapter.SelectedBands = 1;
blockproc(input_adapter,[100 100],addToHistFcn);
blue_hist = hist_obj.Histogram;

Вычислите CDF каждой гистограммы.

computeCDF = @(histogram) cumsum(histogram) / sum(histogram);
findLowerLimit = @(cdf) find(cdf > 0.01, 1, 'first');
findUpperLimit = @(cdf) find(cdf >= 0.99, 1, 'first');

red_cdf = computeCDF(red_hist);
red_limits(1) = findLowerLimit(red_cdf);
red_limits(2) = findUpperLimit(red_cdf);

green_cdf = computeCDF(green_hist);
green_limits(1) = findLowerLimit(green_cdf);
green_limits(2) = findUpperLimit(green_cdf);

blue_cdf = computeCDF(blue_hist);
blue_limits(1) = findLowerLimit(blue_cdf);
blue_limits(2) = findUpperLimit(blue_cdf);

Подготовим аргумент для IMADJUST.

rgb_limits = [red_limits' green_limits' blue_limits'];

Масштабируйте до области значений [0, 1].

rgb_limits = (rgb_limits - 1) / (255);

Создайте новую adjustFcn который применяет глобальные пределы растяжения и использует blockproc для настройки изображения truecolor.

adjustFcn = @(block_struct) imadjust(block_struct.data,rgb_limits);

Выберите полные данные RGB.

input_adapter.SelectedBands = [3 2 1];
truecolor_enhanced = blockproc(input_adapter,[100 100],adjustFcn);

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

imshow(truecolor_enhanced)
title('Truecolor Composite with Corrected Contrast Stretch')

Figure contains an axes. The axes with title Truecolor Composite with Corrected Contrast Stretch contains an object of type image.

См. также

Классы

Функции

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

Подробнее о