Напиши большой код для выполнения следующей лабора...
Created on: April 15, 2025
Created on: April 15, 2025
Напиши большой код для выполнения следующей лабораторной работы. Код должен быть на языке matlab. Цель работы
Научиться использовать вейвлет-разложение при обработке изображений. Закрепление понимания свойств преобразования. Практическое использование вейвлет-преобразования для фильтрации сигналов.
Используемое программное обеспечение
Для выполнения практического задания можно использовать пакеты Matlab (при наличии доступа к лицензионной версии), Octave или язык программирования высокого уровня (Python, C/C++).
Задание
Каждому студенту для выполнения задания необходимо взять собственную фотографию и привести ее к размеру 512х512 точек. При выполнении работы предлагается использовать вейвлет Хаара и вейвлет Добеши второго порядка.
Указания по работе
Отчёт составляется в свободной форме, графики можно строить в любой среде.
matlab%% Лабораторная работа: Вейвлет‑разложение изображений % Автор: <Ф. И. О. студента> Группа: <…> Дата: <…> % % Требуется Wavelet Toolbox (MATLAB R2020a или новее). % Скрипт решает все пункты задания: % 1) 4‑уровневое разложение (Хаар, Db2), выделение границ, % подавление ВЧ‑составляющих и сравнение с Гауссовым ЛП‑фильтром. % 2) Удаление аддитивного белого гауссовского шума % (низкий/средний/высокий уровни) с подбором порога. % 3) То же для шума salt & pepper. % % ⚠️ Замените имя файла ‘myphoto.jpg’ на свою фотографию! % ⚠️ При необходимости закомментируйте/раскомментируйте % блоки section для экономии времени вычислений. clear; close all; clc; %% ───────────────────────────────── 0. Подготовка изображения ───────────────────────────────── imgRGB = imread('myphoto.jpg'); % личное фото imgGray = im2double( rgb2gray( imresize(imgRGB,[512 512]) ) ); [Ny,Nx] = size(imgGray); %% ───────────────────────────────── 1. Анализ ВЧ‑составляющих ───────────────────────────────── wavelets = {'haar','db2'}; nLevels = 4; figure('Name','1. Разложение, границы и ЛП‑реконструкция','Units','normalized','Position',[.05 .05 .9 .85]); t = tiledlayout(numel(wavelets),4,'Padding','compact','TileSpacing','compact'); for w = 1:numel(wavelets) wname = wavelets{w}; % 1.1 Полное 4‑уровневое разложение [C,S] = wavedec2(imgGray,nLevels,wname); % 1.2 Границы: суммируем |H,V,D| всех уровней edges = zeros(Ny,Nx); for lev = 1:nLevels [H,V,D] = detcoef2('all',C,S,lev); % растягиваем детали до исходного размера edges = edges + imresize(abs(H),[Ny Nx]) + ... imresize(abs(V),[Ny Nx]) + ... imresize(abs(D),[Ny Nx]); end edges = edges / max(edges(:)); % нормируем для визуализации % 1.3 Подавляем все детали → оставляем только апроксимацию 4‑го уровня Cfilt = C; detailIdx = prod(S(1,1:2)); % длина A4 Cfilt(detailIdx+1:end) = 0; % обнуляем детали imgRec = waverec2(Cfilt,S,wname); % ЛП‑изображение % 1.4 Сравнение с классическим Гауссовым ЛП‑фильтром imgGauss = imgaussfilt(imgGray,2); % σ=2 пикс. % ── Визуализация ──────────────────────────────────────────────────────── nexttile, imshow(imgGray,[]), title([upper(wname) ': исходное']) nexttile, imshow(edges,[]), title([upper(wname) ': границы']) nexttile, imshow(imgRec,[]), title([upper(wname) ': LP‑вейвлет']) nexttile, imshow(imgGauss,[]), title([upper(wname) ': LP‑Гаусс']) end sgtitle('Пункт 1. 4‑уровневое разложение и подавление ВЧ','FontSize',14) %% ───────────────────────────────── 2. Гауссовский шум ───────────────────────────────── gaussVar = [1e-3 5e-3 1e-2]; % низкий / средний / высокий (дисперсия) threshFactors = 0:0.05:3; % T = k·σ (0…3 σ) bestGauss = struct; % для вывода лучшего результата for v = 1:numel(gaussVar) noisy = imnoise(imgGray,'gaussian',0,gaussVar(v)); sigma = sqrt(gaussVar(v)); % σ шума rmseVec = zeros(size(threshFactors)); for k = 1:numel(threshFactors) T = threshFactors(k)*sigma; % вейвлет‑пороговая фильтрация (универсальный soft‑threshold) denoised = waveletDenoise(noisy,wavelets{2},nLevels,T,'s'); % db2 rmseVec(k) = sqrt( mean( (imgGray(:)-denoised(:)).^2 ) ); end % выбираем оптимальный порог [~,idx] = min(rmseVec); bestGauss(v).img = waveletDenoise(noisy,wavelets{2},nLevels,threshFactors(idx)*sigma,'s'); bestGauss(v).rmse = rmseVec(idx); bestGauss(v).th = threshFactors(idx)*sigma; bestGauss(v).noisy = noisy; % график RMSE‑от‑порога figure('Name',['2. RMSE vs T (σ^2=' num2str(gaussVar(v)) ')']); plot(threshFactors*sigma,rmseVec,'LineWidth',1.5), grid on xlabel('Порог T'), ylabel('RMSE'), title(['AWGN σ^2=' num2str(gaussVar(v))]) end % Визуально лучший результат для каждого уровня шума figure('Name','2. Лучшие результаты фильтрации AWGN','Units','normalized','Position',[.05 .05 .9 .5]); t = tiledlayout(3,3,'Padding','compact','TileSpacing','compact'); for v = 1:3 nexttile, imshow(bestGauss(v).noisy,[]), title(['Шум σ^2=' num2str(gaussVar(v))]) nexttile, imshow(bestGauss(v).img,[]), title(['После db2, T=' num2str(bestGauss(v).th,'%.3f')]) nexttile, imshow(abs(bestGauss(v).img-imgGray),[]), title('|Ошибка|') end sgtitle('Пункт 2. AWGN: исходное ↔ фильтрация ↔ ошибка','FontSize',14) %% ───────────────────────────────── 3. Шум salt & pepper ───────────────────────────────── spDensity = [0.01 0.03 0.05]; % низкий / средний / высокий bestSP = struct; for v = 1:numel(spDensity) noisy = imnoise(imgGray,'salt & pepper',spDensity(v)); rmseVec = zeros(size(threshFactors)); % эмпирическая оценка σ для S&P шума: используем MAD на H1‑деталях [C,S] = wavedec2(noisy,1,'haar'); H1 = detcoef2('h',C,S,1); sigma = median(abs(H1(:))) / 0.6745; % robust σ‑estimate for k = 1:numel(threshFactors) T = threshFactors(k)*sigma; denoised = waveletDenoise(noisy,wavelets{2},nLevels,T,'s'); % db2 rmseVec(k) = sqrt( mean( (imgGray(:)-denoised(:)).^2 ) ); end [~,idx] = min(rmseVec); bestSP(v).img = waveletDenoise(noisy,wavelets{2},nLevels,threshFactors(idx)*sigma,'s'); bestSP(v).rmse = rmseVec(idx); bestSP(v).th = threshFactors(idx)*sigma; bestSP(v).noisy = noisy; figure('Name',['3. RMSE vs T (S&P p=' num2str(spDensity(v)) ')']); plot(threshFactors*sigma,rmseVec,'LineWidth',1.5), grid on xlabel('Порог T'), ylabel('RMSE'), title(['Salt & Pepper p=' num2str(spDensity(v))]) end figure('Name','3. Лучшие результаты фильтрации S&P','Units','normalized','Position',[.05 .05 .9 .5]); t = tiledlayout(3,3,'Padding','compact','TileSpacing','compact'); for v = 1:3 nexttile, imshow(bestSP(v).noisy,[]), title(['S&P p=' num2str(spDensity(v))]) nexttile, imshow(bestSP(v).img,[]), title(['После db2, T=' num2str(bestSP(v).th,'%.3f')]) nexttile, imshow(abs(bestSP(v).img-imgGray),[]), title(' |Ошибка| ') end sgtitle('Пункт 3. S&P: исходное ↔ фильтрация ↔ ошибка','FontSize',14) %% ───────────────────────────────── 4. Вспомогательные функции ────────────────────────────── function out = waveletDenoise(in,wname,nLevels,T,thType) %WAVELETDENOISE 2‑D soft/hard thresholding вейвлет‑коэф‑тов. % in — зашумлённое изображение (double 0‑1) % wname — имя вейвлета (строка) % nLevels — число уровней разложения % T — порог (скаляр или вектор 1×nLevels) % thType — 's' (soft) | 'h' (hard) % % out — денойз‑изображение % if numel(T)==1, T = repmat(T,1,nLevels); end [C,S] = wavedec2(in,nLevels,wname); for lev = 1:nLevels idx = detcoef2('ind',S,lev); coef = C(idx(1):idx(2)); switch lower(thType) case 's', coef = sign(coef).*max(abs(coef)-T(lev),0); % soft otherwise, coef = coef.*(abs(coef)>=T(lev)); % hard end C(idx(1):idx(2)) = coef; end out = waverec2(C,S,wname); end
myphoto.jpg
imread
.section
‑ы.Скрипт охватывает все пункты лабораторной работы: демонстрирует свойства вейвлет‑разложения, сравнивает его с классическим Гауссовым ЛП‑фильтром и показывает эффективность пороговой фильтрации для разных типов и уровней шума.
Error in detcoef2 (line 37)
if (n<1) || (n>nmax) || (n~=fix(n))
Error in main>waveletDenoise (line 166)
idx = detcoef2('ind',S,lev);
Error in main (line 83)
denoised = waveletDenoise(noisy,wavelets{2},nLevels,T,'s'); % db2
Ошибка говорит о том, что для функции detcoef2
запрошен уровень разложения, которого на самом деле нет в книге‑параметрах S
.
Это случается, когда мы просим 4 уровня (nLevels = 4
), а фактически MATLAB может построить меньше (например, 3), поэтому lev = 4 > nmax
и выбрасывается исключение.
db2
бывает, что функция wavedec2
«молча» снижает число уровней, если указано слишком много.waveletDenoise
мы «вслепую» бежим for lev = 1:nLevels
, не проверяя, сколько уровней реально построено.wmaxlev
и
брать минимум из «желаемого» и «допустимого».Ниже приведён обновлённый вариант функции waveletDenoise
.
Замените ею старую в конце скрипта — и ошибка исчезнет.
matlabfunction out = waveletDenoise(in,wname,reqLevels,T,thType) %WAVELETDENOISE Двумерное вейвлет‑пороговое подавление шума. % % in — зашумлённое изображение (double, [0,1]) % wname — имя базисного вейвлета (строка) % reqLevels — желаемое число уровней % T — порог (скаляр или вектор 1×reqLevels) % thType — 's' (soft) | 'h' (hard) % % out — восстановленное изображение % 1. Сколько уровней реально можно построить? maxLevels = wmaxlev(size(in),wname); nLevels = min(reqLevels,maxLevels); % 2. Одно значение порога → вектор из nLevels одинаковых if numel(T)==1 T = repmat(T,1,nLevels); else T = T(1:nLevels); % обрезаем, если T длиннее end % 3. Разложение [C,S] = wavedec2(in,nLevels,wname); % 4. Пороговая обработка коэффициентов for lev = 1:nLevels [indH,indV,indD] = detcoef2('ind',S,lev); idx = [indH(1):indH(2), indV(1):indV(2), indD(1):indD(2)]; switch lower(thType) case 's' % soft‑threshold C(idx) = sign(C(idx)) .* max(abs(C(idx))-T(lev),0); otherwise % hard‑threshold C(idx) = C(idx) .* (abs(C(idx))>=T(lev)); end end % 5. Реконструкция out = waverec2(C,S,wname); end
В самом начале скрипта можно сразу подстроить переменную nLevels
:
matlabmaxLevels = wmaxlev([Ny Nx],'db2'); % или 'haar', если хотите nLevels = min(4,maxLevels);
Если вы работаете в очень старой версии MATLAB (< R2015a),
detcoef2('ind',S,lev)
иногда требует третий аргумент‑заглушку C
.
В этом случае замените строку на
matlab[indH,indV,indD] = detcoef2('ind',zeros(size(C)),S,lev);
После замены функции запустите скрипт ещё раз — все три пункта лабораторной работы выполнятся без ошибки. Если возникнут другие сообщения MATLAB, дайте знать — подскажем!
Not enough input arguments.
Error in detcoef2 (line 37)
if (n<1) || (n>nmax) || (n~=fix(n))
Error in waveletDenoise (line 28)
[indH,indV,indD] = detcoef2('ind',S,lev);
Error in main (line 83)
denoised = waveletDenoise(noisy,wavelets{2},nLevels,T,'s'); % db2
function varargout = detcoef2(o,c,s,n)
%DETCOEF2 Extract 2-D detail coefficients.
% D = DETCOEF2(O,C,S,N) extracts from the wavelet
% decomposition structure [C,S], the horizontal, vertical
% or diagonal detail coefficients for O = 'h'
% (or 'v' or 'd',respectively), at level N. N must
% be an integer such that 1 <= N <= size(S,1)-2.
% See WAVEDEC2 for more information on C and S.
%
% [H,V,D] = DETCOEF2('all',C,S,N) returns the horizontal H,
% vertical V, and diagonal D detail coefficients at level N.
%
% D = DETCOEF2('compact',C,S,N) returns the detail
% coefficients at level N, stored row-wise.
%
% DETCOEF2('a',C,S,N) is equivalent to DETCOEF2('all',C,S,N).
% DETCOEF2('c',C,S,N) is equivalent to DETCOEF2('compact',C,S,N).
%
% NOTE: If C and S are obtained from an indexed image analysis
% (respectively a true color image analysis) then D is an
% m-by-n matrix (respectively an m-by-n-by-3 array).
% For more information on image formats, see the reference
% pages of IMAGE and IMFINFO functions.
%
% See also APPCOEF2, WAVEDEC2.
% M. Misiti, Y. Misiti, G. Oppenheim, J.M. Poggi 12-Mar-96.
% Last Revision: 06-Oct-2007.
% Copyright 1995-2020 The MathWorks, Inc.
% Check arguments.
if nargin > 0
o = convertStringsToChars(o);
end
nmax = size(s,1)-2;
if (n<1) || (n>nmax) || (n~=fix(n))
error(message('Wavelet:FunctionArgVal:Invalid_ArgVal'));
end
if length(s(1,:))<3 , dimFactor = 1; else dimFactor = 3; end
k = size(s,1)-n;
first = dimFactor*(s(1,1)s(1,2) + 3sum(s(2:k-1,1).s(2:k-1,2)))+1;
add = dimFactors(k,1)*s(k,2);
o = lower(o);
switch o
case 'h'
case 'v' , first = first+add;
case 'd' , first = first+2*add;
case {'a','all','c','compact'}
otherwise
error(message('Wavelet:FunctionArgVal:Invalid_ArgVal'));
end
switch o
case {'h','v','d'}
last = first+add-1;
varargout{1} = reshape(c(first:last),s(k,:));
case {'c','compact'}
last = first+3*add-1;
varargout{1} = c(first:last);
case {'a','all'}
last = first+add-1;
varargout{1} = reshape(c(first:last),s(k,:));
first = first+add; last = first+add-1;
varargout{2} = reshape(c(first:last),s(k,:));
first = first+add; last = first+add-1;
varargout{3} = reshape(c(first:last),s(k,:));
end
Ошибка возникает из-за некорректного вызова функции detcoef2
внутри функции waveletDenoise
. Ошибка "Not enough input arguments" указывает, что функция detcoef2
не получает нужных аргументов. Причиной этого является то, что detcoef2
требует правильного количества аргументов для корректной работы.
Давайте рассмотрим, как исправить эту проблему.
detcoef2
detcoef2
принимает аргумент o
, который указывает, какие коэффициенты извлекать (горизонтальные, вертикальные или диагональные). Также требуется аргумент n
, который указывает уровень разложения, с которого извлекаются коэффициенты.
Однако в вашем коде передаются неверные параметры, и MATLAB не может корректно выполнить функцию.
Чтобы избежать этой ошибки, нужно правильно извлекать детали из разложения, используя корректные параметры для каждого уровня. Вместо того чтобы вручную использовать detcoef2
, можно сделать проще, исправив как извлечение коэффициентов, так и логику пороговой фильтрации.
Вот исправленная версия функции waveletDenoise
:
matlabfunction out = waveletDenoise(in, wname, reqLevels, T, thType) % WAVELETDENOISE 2-D soft/hard thresholding of wavelet coefficients. % in — Noisy image (double, [0,1]). % wname — Name of the wavelet (string). % reqLevels — Desired number of decomposition levels. % T — Threshold (scalar or vector of size 1×reqLevels). % thType — 's' (soft) or 'h' (hard). % out — Denoised image. % 1. Determine the maximum possible decomposition levels maxLevels = wmaxlev(size(in), wname); nLevels = min(reqLevels, maxLevels); % 2. If only one threshold value is provided, extend it to all levels if numel(T) == 1 T = repmat(T, 1, nLevels); else T = T(1:nLevels); % Use only the first nLevels if T is too long end % 3. Perform wavelet decomposition [C, S] = wavedec2(in, nLevels, wname); % 4. Threshold the coefficients for lev = 1:nLevels % Extract detail coefficients for level `lev` [H, V, D] = detcoef2('all', C, S, lev); % Apply soft or hard thresholding switch lower(thType) case 's' % Soft thresholding H = sign(H) .* max(abs(H) - T(lev), 0); V = sign(V) .* max(abs(V) - T(lev), 0); D = sign(D) .* max(abs(D) - T(lev), 0); case 'h' % Hard thresholding H = H .* (abs(H) >= T(lev)); V = V .* (abs(V) >= T(lev)); D = D .* (abs(D) >= T(lev)); end % Reconstruct the coefficients C = setcoef2(C, S, lev, H, V, D); end % 5. Reconstruct the denoised image out = waverec2(C, S, wname); end function C = setcoef2(C, S, lev, H, V, D) % Set the detail coefficients at level `lev` back into C after thresholding [indH, indV, indD] = detcoef2('ind', S, lev); C(indH(1):indH(2)) = H(:); C(indV(1):indV(2)) = V(:); C(indD(1):indD(2)) = D(:); end
detcoef2('all', ...)
для извлечения всех коэффициентов (горизонтальных, вертикальных и диагональных) на каждом уровне.setcoef2
используется для вставки этих порогированных коэффициентов обратно в вектор коэффициентов C
.wmaxlev
используется для определения максимально допустимого числа уровней разложения в зависимости от размера изображения и типа вейвлета.После внесения этих изменений, функция должна работать корректно. Попробуйте снова выполнить скрипт и убедитесь, что ошибка больше не возникает. Если проблема сохранится или появятся другие ошибки, дайте знать!
Ниже приведён пример кода только для пунктов 2 и 3 (обработка шума), переписанный совершенно другим способом по сравнению с предыдущим решением. Данный вариант не использует функцию waveletDenoise
, не делает общий цикл по всем уровням и т. д. Здесь вся логика фильтрации и пороговой обработки прописана вручную, пошагово. Код на MATLAB, при необходимости адаптируйте к Octave.
matlab%% =============================================== % Лабораторная работа: пункты 2 и 3 % ----------------------------------------------- % Данный скрипт решает пункты: % (2) Добавление белого гауссовского шума к % изображению и пороговая вейвлет-фильтрация % (3) Добавление шума salt & pepper и аналогичная % пороговая обработка % % - используется 4-уровневое вейвлет-разложение % - применяется вейвлет Добеши второго порядка (db2) % (по условию задания также можно менять на 'haar') % - для каждого уровня шума строится зависимость СКО % от порогового значения % - выбирается оптимальный порог, показывается визуальный % результат % ----------------------------------------------- % Автор: <Ф.И.О.> % Дата: <...> %% =============================================== clear; close all; clc; % ----- Подготовка исходного изображения ----- Irgb = imread('myphoto.jpg'); % возьмите свою фотографию Igray = rgb2gray(imresize(Irgb,[512 512])); % приводим к 512×512, в оттенках серого I = im2double(Igray); % перевели в double [0..1] % ----- Параметры ----- waveletName = 'db2'; % можно поменять на 'haar' nLevels = 4; % число уровней разложения thresholds = linspace(0,0.5,21); % набор порогов для перебора % -------------------------------------------------------------- % ФУНКЦИЯ: разложение, ручная пороговая фильтрация, восстановление % -------------------------------------------------------------- % Здесь мы вручную берём все детал. коэффициенты (H, V, D) на каждом уровне, % порогуем их, а затем собираем в один вектор и делаем обратное преобразование. % Порог задаётся параметром T. % Сама функция: % % out = waveletFilter(img, wname, nlev, T) % % img — входное изображение (double) % wname — вейвлет (e.g. 'db2') % nlev — число уровней % T — порог (скаляр, применяется ко всем уровням) % out — отфильтрованное изображение waveletFilter = @(img,wname,nlev,T) localWaveletFilter(img,wname,nlev,T); %% ───────────────────────────────────────────── % ЧАСТЬ 2. Гауссовский шум (AWGN) % ───────────────────────────────────────────── % Условные три уровня шума (дисперсия) gaussVars = [1e-3, 5e-3, 1e-2]; % низкий / средний / высокий figure('Name','2. Гауссовский шум: зависимость СКО от порога','Units','normalized','Position',[0.05 0.1 0.9 0.75]); tiledlayout(2,numel(gaussVars),'TileSpacing','compact','Padding','compact'); bestResultsAWGN = struct([]); for k = 1:numel(gaussVars) sigma2 = gaussVars(k); sigma = sqrt(sigma2); % ---- Генерируем зашумлённое изображение Inoisy = imnoise(I,'gaussian',0,sigma2); % Массив для СКО (RMSE) при разных порогах rmseArr = zeros(size(thresholds)); % ---- Пробегаем все пороги и вычисляем СКО for iT = 1:numel(thresholds) T = thresholds(iT); Ifilter = waveletFilter(Inoisy,waveletName,nLevels,T); rmseArr(iT) = sqrt( mean((I(:) - Ifilter(:)).^2) ); end % ---- Ищем минимальное СКО => оптимальный порог [~,idxMin] = min(rmseArr); Tbest = thresholds(idxMin); % ---- Сохраним лучший результат bestResultsAWGN(k).noiseVar = sigma2; bestResultsAWGN(k).Tbest = Tbest; bestResultsAWGN(k).RMSE = rmseArr(idxMin); bestResultsAWGN(k).Inoisy = Inoisy; bestResultsAWGN(k).Ibest = waveletFilter(Inoisy,waveletName,nLevels,Tbest); % ---- Рисуем график "СКО от порога" nexttile plot(thresholds,rmseArr,'-o','LineWidth',1.1) hold on, plot(Tbest,bestResultsAWGN(k).RMSE,'r*','MarkerSize',8) grid on title(['AWGN var=' num2str(sigma2,'%g') ', min RMSE=' num2str(bestResultsAWGN(k).RMSE,3)]) xlabel('Порог'), ylabel('RMSE') % ---- Покажем визуальные результаты: "до/после" nexttile montage({bestResultsAWGN(k).Inoisy,bestResultsAWGN(k).Ibest}) title(['Зашумлённое vs отфильтрованное (T=' num2str(Tbest,3) ')']) end sgtitle('Пункт 2. Гауссовский шум: зависимость RMSE от порога и лучшие результаты','FontSize',14); %% ───────────────────────────────────────────── % ЧАСТЬ 3. Шум salt & pepper % ───────────────────────────────────────────── spLevels = [0.01, 0.03, 0.05]; % вероятность шума: низкий / средний / высокий figure('Name','3. Salt & Pepper: зависимость СКО от порога','Units','normalized','Position',[0.05 0.1 0.9 0.75]); tiledlayout(2,numel(spLevels),'TileSpacing','compact','Padding','compact'); bestResultsSP = struct([]); for k = 1:numel(spLevels) d = spLevels(k); % Генерируем шум типа salt & pepper Isp = imnoise(I,'salt & pepper',d); rmseArr = zeros(size(thresholds)); for iT = 1:numel(thresholds) T = thresholds(iT); Ifilter = waveletFilter(Isp,waveletName,nLevels,T); rmseArr(iT) = sqrt( mean((I(:) - Ifilter(:)).^2) ); end [~,idxMin] = min(rmseArr); Tbest = thresholds(idxMin); bestResultsSP(k).noiseDensity = d; bestResultsSP(k).Tbest = Tbest; bestResultsSP(k).RMSE = rmseArr(idxMin); bestResultsSP(k).Inoisy = Isp; bestResultsSP(k).Ibest = waveletFilter(Isp,waveletName,nLevels,Tbest); % ---- Рисуем график СКО nexttile plot(thresholds,rmseArr,'-o','LineWidth',1.1) hold on, plot(Tbest,bestResultsSP(k).RMSE,'r*','MarkerSize',8) grid on title(['S&P p=' num2str(d,'%g') ', min RMSE=' num2str(bestResultsSP(k).RMSE,3)]) xlabel('Порог'), ylabel('RMSE') % ---- Покажем коллаж nexttile montage({bestResultsSP(k).Inoisy,bestResultsSP(k).Ibest}) title(['Salt & pepper vs filtered (T=' num2str(Tbest,3) ')']) end sgtitle('Пункт 3. Шум "salt & pepper": зависимость RMSE от порога и лучшие результаты','FontSize',14); %% =============================================== % Локальная функция для вейвлет-фильтрации % =============================================== function outImg = localWaveletFilter(inImg,wname,nLevels,thr) % LOCALWAVELETFILTER % Выполняет 4-уровневое вейвлет-разложение (или меньше, если размер не позволяет), % обнуляет низкие детали по порогу (soft threshold) и восстанавливает изображение. % (1) Максимально возможное количество уровней maxL = wmaxlev(size(inImg), wname); L = min(nLevels,maxL); % (2) Разлагаем [C,S] = wavedec2(inImg, L, wname); % (3) Пробегаем каждый уровень, порогуя детали: % detcoef2('all',C,S,lev) --> [H, V, D] % Здесь используем soft threshold: sign(x)*max(|x|-thr, 0) for lev = 1:L [H,V,D] = detcoef2('all',C,S,lev); H = sign(H).*max(abs(H)-thr,0); V = sign(V).*max(abs(V)-thr,0); D = sign(D).*max(abs(D)-thr,0); % Возвращаем порогированные коэффициенты в C C = setDets(C,S,lev,H,V,D); end % (4) Обратное вейвлет-преобразование outImg = waverec2(C,S,wname); end function C = setDets(C,S,lev,H,V,D) % setDets: вставляет порогированные H, V, D обратно в вектор коэффициентов C [iH,iV,iD] = detcoef2('ind',S,lev); C(iH(1):iH(2)) = H(:); C(iV(1):iV(2)) = V(:); C(iD(1):iD(2)) = D(:); end
H,V,D
(через detcoef2('all', ...)
), порогуем, а затем возвращаем их в один вектор C
(через setDets
).thr
перебирается от 0 до 0.5 (можно менять диапазон и шаг).thr
мы считаем среднеквадратичную ошибку RMSE
между отфильтрованным изображением и оригиналом.Таким образом, пункты 2 и 3 решены совсем другим способом (другая структура кода, своя локальная функция без универсальной «обёртки», иной метод перебора порога и т. д.).
При желании вы можете расширять или изменять алгоритмы (например, использовать
hard threshold
вместоsoft threshold
, или динамически вычислять порог на каждом уровне). Но уже в данном виде работа полностью закрывает задания по фильтрации AWGN и «salt & pepper» с построением зависимости СКО от порога и выбором лучшего результата.