Дифференциальные уравнения в задачах обработки изображений. Анизотропная диффузия и шумопонижение.

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

В этой статье рассмотрим метод подавления шума, в основе которого лежит уравнение теплопроводности (диффузии). Идея метода и реализация предложены  в работе [1].

Предположим, что имеется зашумленное черно-белое изображение. Будем интерпретировать яркость пикселя, которая задаётся целым числом от 0 до 255, как температуру (или концентрацию вещества) в данной точке, а изображение на входе, как распределение температур в начальный момент времени в тонкой прямоугольной мембране. В условиях теплоизоляции такой мембраны, температура в ней со временем будет выравниваться, а области, соответствующие шуму, будут подвержены этому эффекту наиболее интенсивно. Это хорошо видно на следующей анимации, где температура точки передаётся её высотой и цветом. Большой круг в центре теряет тепло медленно, а точка слева — быстро.

image001
Рис. 1. Распределение тепла в прямоугольной мембране с течением времени

Таким образом, если остановить процесс в нужное время, то шум станет значительно слабее, а само изображение ещё не успеет заметно исказиться.

Ниже приведем алгоритм в действии. Пусть исходное изображение содержит основной объект (круг) и шум (белую точку),

Рис. 2. Модельное изображение: белый круг — это основной объект, а белая точка — это шум
Рис. 2. Модельное изображение: белый круг — это основной объект, а белая точка — это шум

тогда, применив к нему уравнение теплопроводности (диффузии), получим

Рис. 3. Анимация шумоподавления с помощью уравнения теплопроводности
Рис. 3. Анимация шумоподавления с помощью уравнения теплопроводности


Код в MATLAB


T = imread(‘1.png’); % чтение изображения из файла
T = rgb2gray(T); % перевод изображения в черно-белое
[m, n] = size(T);
XX = linspace(1, m, m);
YY = linspace(1, n, n);
[X, Y] = meshgrid(XX, YY); % создание сетки
CFL = 0.125; % Критерий Куранта — Фридрихса — Леви
dx = XX(2) — XX(1); % приращение пространственных переменных
dt = CFL*dx^2; % приращение времени
imshow(T); % вывод изображения в начальный момент времени
title(strcat(‘Время t =’, sprintf(‘ %.1f’, 0)));
Z = T;
for t = dt:dt:2.5
   for i = 2:(m-1)
       for j = 2:(n-1)
          % численное решение уравнения теплопроводности
          Z(i, j) = T(i, j) + dt*(T(i+1, j) + T(i-1, j) + …
             T(i, j-1) + T(i, j+1) — 4*T(i, j))/dx^2;
       end
    end
    T = Z;
    T = uint8(round(T));
    imshow(T); % вывод текущего изображения
    title(strcat(‘Время t =’, sprintf(‘ %.1f’, t)));
    pause(0.05);
    T = double(T);
end


Идея этого кода базируется на использовании уравнения теплопроводности следующего вида

image004                                                                             (1)

где  image006— температура точки image008 в момент времени image010, image012 — оператор Лапласа. Для численного решения производные в уравнении были заменены конечными разностями:

image014image016image018

Следует отметить существенный недостаток предложенного алгоритма — размытие кромок объектов, и как следствие — потерю чёткости изображения. Поэтому далее будет предложен модифицированный алгоритм.

Кромки объектов можно определять с помощью модуля градиента:

image020

где

image022image024

Если модуль градиента вывести как изображение, то получим

Рис. 4. Модуль градиента выявляет кромки на изображении
Рис. 4. Модуль градиента выявляет кромки на изображении

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


Код в MATLAB


T = imread(‘1.png’); % чтение изображения из файла
T = rgb2gray(T); % перевод изображения в черно-белое
[m, n] = size(T);
XX = linspace(1, m, m);
YY = linspace(1, n, n);
[X, Y] = meshgrid(XX, YY); % создание сетки
T = double(T);
u = T;
for i = 2:(m-1)
    for j = 2:(n-1)
        % вычисление градиента
       u(i, j) = sqrt((T(i+1,j)-T(i-1,j))^2+(T(i,j+1)-T(i,j-1))^2)/4;
    end
end
u = uint8(round(u));
imshow(u); % вывод изображения


Чтобы иметь возможность управлять процессом теплопередачи вблизи кромок, перейдем к уравнению теплопроводности в более общей форме:

image028                                                                  (2)

где image030 — коэффициент теплопроводности, image032 — плотность, image034 — теплоемкость, image036 — градиент температуры image038.

Будем полагать, что image040. Если положить image042, то получим уравнение вида (1). Мы же потребуем, чтобы коэффициент image030 зависел от величины градиента image044, причем так, чтобы image046 при image048, т. е. коэффициент теплопроводности должен быть тем ближе к нулю, чем больше величина градиента. Тогда перенос тепла вблизи кромок будет минимальным, и размытия кромок не произойдет, а ровные шумные области, наоборот, будут хорошо сглажены.

На роль функции image050 можно подобрать множество кандидатов, например, в работе [1] были предложены

image052где константа image054 позволяет регулировать чувствительность алгоритма и подбирается опытным путем. Пусть далее

image056Так как коэффициент теплопроводности в нашем случае зависит от градиента, а значит зависит от image058 и image060, то дивергенцию, входящую в уравнение (2), можно расписать следующим образом:

image062Выполним переход от непрерывного уравнения (2) к дискретному

image022image024image016image018image068image070image072image074Ниже приводится анимация работы алгоритма, основанного на уравнении (2), с шумом типа «соль и перец»:

Рис. 5. Результат работы алгоритма
Рис. 5. Результат работы алгоритма


Код в MATLAB


T = imread(‘2.png’); % чтение изображения из файла
T = rgb2gray(T); % перевод изображения в черно-белое
[m, n] = size(T);
XX = linspace(1, m, m);
YY = linspace(1, n, n);
[X, Y] = meshgrid(XX, YY); % создание сетки
CFL = 0.125; % Критерий Куранта — Фридрихса — Леви
dx = XX(2) — XX(1); % приращение пространственных переменных
dt = CFL*dx^2; % приращение времени
subplot 121, imshow(T,[]);
title(strcat(‘Время t =’, sprintf(‘ %.1f’, 0)));
Z = T;
K = 10; % регулирует чувствительность
T = double(T);
% численное решение
for t = dt:dt:1
    for i = 2:(m-1)
       for j = 2:(n-1)
          T_x = (T(i+1,j) — T(i-1,j))/2;
          T_y = (T(i,j+1) — T(i,j-1))/2;
          T_xx = T(i+1,j) — 2*T(i,j) + T(i-1,j);
          T_yy = T(i,j+1) — 2*T(i,j) + T(i,j-1);
          T_xy = T(i+1,j) — 2*T(i,j) + T(i,j-1);
          k = exp(-1/K^2*(T_x^2 + T_y^2));
          k_x = k*2/K^2*(T_x*T_xx + T_y*T_xy);
          k_y = k*2/K^2*(T_x*T_xy + T_y*T_yy);
          Z(i, j) = T(i, j) + dt*(k*(T_xx+T_yy)+k_x*T_x+k_y*T_y);
      end
    end
    T = Z;
    % вывод текущего изображения
    T = uint8(round(T));
    subplot 122, imshow(T,[])
    title(strcat(‘Время t =’, sprintf(‘ %.1f’, t)));
    pause(0.05);
    T = double(T);
end


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

Литература

  1. Perona and J. Malik. Scale-space and edge detection using anisotropic diffusion. IEEE Trans. Pattern Anal. Machine Intell., vol. 12, pp. 629–639, 1990.
  2. https://en.wikipedia.org/wiki/Anisotropic_diffusion
  3. https://habrahabr.ru/post/144288/
  4. http://cgm.computergraphics.ru/content/view/74#

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *