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

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

Этот пример выполняет задачу, похожую на найденный в Улучшении Многоспектрального Цветного Составного примера Изображений, но адаптированный к большим изображениям с помощью blockprocПример.This улучшает видимые полосы файла LAN Эрдаса rio.lan. Эти типы методов обработки блока обычно более полезны для больших изображений, но маленькое изображение используется, чтобы проиллюстрировать концепции в этом примере.

Шаг 1: создайте составной объект истинного цвета

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

Формат 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 object. The axes object with title Truecolor Composite (Not Enhanced) contains an object of type image.

Получившееся изображение истинного цвета похоже на тот из 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 object. The axes object 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 objects. Axes object 1 with title Incrementally Computed Histogram contains an object of type stem. Axes object 2 with title imhist Histogram contains an object of type stem.

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

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

Создайте 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 object. The axes object with title Histogram of Red Band (Band 3) contains an object of type stem.

Шаг 5: улучшите составной объект истинного цвета с контрастным фрагментом

Можно теперь выполнить соответствующий контрастный фрагмент на изображении. Для обычных, рабочих процессов в оперативной памяти можно просто использовать stretchlim функция, чтобы вычислить аргументы к imadjust (как пример Улучшают Многоспектральные Цветные Составные Изображения). При работе с большими изображениями, как мы видели, 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 настраивать изображение истинного цвета.

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 object. The axes object with title Truecolor Composite with Corrected Contrast Stretch contains an object of type image.

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

Классы

Функции

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

Больше о