Sie sind auf Seite 1von 9

function aufgabe_5()

close all;
% Oeffne bild (bildgroesse sollte zweierpotenz sein)
% Phantombild
imagesize = 256;
img_nonoise = phantom(imagesize)*255;
% Weisses Quadrat auf scharzem Hintergrund
% img_nonoise = zeros(imagesize);
% img_nonoise(2:imagesize/4,4:imagesize/4) = 255;
% Natuerliche Bilder
img_nonoise = double(imread('cameraman.png'));
img_nonoise = imresize(img_nonoise, [imagesize, imagesize], 'bilinear');
% Oder: cameraman.png, lena.png...
% Eigene Bilder (von Handy, Digicam etc. ausprobieren!)
% addiere gegebenenfalls rauschen
noise = randn(imagesize, imagesize) * 20;
img = img_nonoise + noise;
% berechne den mittleren quadratischen fehler zwischen original und dem
% verrauschten bild
mse_noisy = mean((img_nonoise(:) - img(:)).^2)
clim = [0, 255];
figure;
subplot(2,2,1);
imagesc(img,clim);
title('Original');
colormap gray;
axis image;
%----------------------------% DWT mit beliebigem Wavelet
%----------------------------% possible names are:
% Daubechies: 'db1' or 'haar', 'db2', ..., 'db45'
% Coiflets: 'coif1', ..., 'coif5'
% Symlets: 'sym2', ..., 'sym45'
% discrete Meyer wavelet: 'dmey'
wavelet = 'db2';
% erzeuge hoch- und tiefpassfilter fuer analyse und synthese mit wfilters
% oder setzte die filter selbst
[lp,hp,rlp,rhp] = wfilters(wavelet);
% berechne 2d-Wavelettransformation des bildes
[approx, detailH, detailV, detailD] = mydwt2(img, lp, hp);
% waveletcoeffs = mra2D(img, 3, lp, hp);
%
%
%
%
%

fuege die vier koeffizienten-bloecke zu einem bild zusammen


|-------------------|
| approx | detailH |
|-------------------|
| detailV | detailD |

% |-------------------|
waveletcoeffs = [approx detailH; detailV detailD];
subplot(2,2,2);
imagesc(waveletcoeffs);
title('Wavelet-Koeffizienten')
colormap gray;
axis image;
% berechne inverse 2d-Wavelettransformation
recon = myidwt2(approx, detailH, detailV, detailD, rlp, rhp);
% recon = mrs2D(waveletcoeffs, 3, rlp, rhp);
subplot(2,2,3)
imagesc(recon,clim);
title('Rekonstruktion')
colormap gray;
axis image;
subplot(2,2,4)
imagesc(recon-img);
title('Differenz zum Original')
colormap gray;
axis image;
%----------------------------% 2D Entrauschung
%----------------------------% berechne peak signal to noise ratio in db
psnr_noisy = 10*log10(((max(img(:)))^2)/(mse_noisy));
figure;
subplot(2,2,1);
imagesc(img,clim);
title(['Original, psnr = ' num2str(psnr_noisy)]);
colormap gray;
axis image;
% anzahl zerlegungslevel
ndec = 3;
% gewichtung des thresholds - je groesser desto staerker wird entrauscht
thrweight = 0.5;
% thresholding mode: 0 - hard, 1 - soft thresholding
thrmode = 1;
% denoising mit globalem Threshold
% global (la=0) or level adaptive (la=1) threshold
la = 1;
denoised_UT = denoise_UT(img, wavelet, ndec, thrweight, thrmode, la);
% berechne den mittleren quadratischen fehler zwischen original und dem
% entrauschten bild
mse_UT = mean((img(:) - denoised_UT(:)).^2);
% berechne peak signal to noise ratio in db
psnr_UT = 10*log10(((max(img(:)))^2)/(mse_UT));
subplot(2,2,2);
imagesc(denoised_UT,clim);
colormap gray;
axis image;

title(['Denoised - Universal Threshold, psnr = ' num2str(psnr_UT)]);


% denoising mit level-adaptivem Threshold
la = 1;
denoised_LAT = denoise_UT(img, wavelet, ndec, thrweight, thrmode, la);
% berechne den mittleren quadratischen fehler zwischen original und dem
% entrauschten bild
mse_LAT = mean((img(:) - denoised_LAT(:)).^2);
% berechne peak signal to noise ratio in db
psnr_LAT = 10*log10(((max(img(:)))^2)/(mse_LAT));
subplot(2,2,3);
imagesc(denoised_LAT,clim);
colormap gray;
axis image;
title(['Denoised - la Threshold, psnr = ' num2str(psnr_LAT)]);
% entrausche bild unter verwendung von interscale korrelationen
denoised_IC = denoise_IC(img, wavelet, ndec, thrweight, thrmode);
% berechne den mittleren quadratischen fehler zwischen original und dem
% entrauschten bild
mse_IC = mean((img(:) - denoised_IC(:)).^2);
% berechne peak signal to noise ratio in db
psnr_IC = 10*log10(((max(img(:)))^2)/(mse_IC));
subplot(2,2,4);
imagesc(denoised_IC,clim);
colormap gray;
axis image;
title(['Denoised - IC, psnr = ' num2str(psnr_IC)]);
end
%-------------------------------------------------------------------------% Schaetzen der Varianz des Rauschens
%-------------------------------------------------------------------------function sigma = estimateNoise(waveletcoeffs)
% greife auf die diagonalen detail-koeffizienten im ersten zerlegungslevel
% zu
wHH = waveletcoeffs(size(waveletcoeffs,1)/2+1:size(waveletcoeffs,1), size(wavele
tcoeffs,2)/2+1:size(waveletcoeffs,2));
% schaetze die standardabweichung des rauschens
sigma = median(abs(wHH(:)))/0.6745;
end
%-------------------------------------------------------------------------% Entrauschen unter Verwendung des 'Universal Thresholds'
%-------------------------------------------------------------------------function denoisedimg = denoise_UT(signal, wavelet, maxlevel, thrweight, thrmode,
la)
% hole filterkoeffizienten fuer angegebenes wavelet
[lp,hp,rlp,rhp] = wfilters(wavelet);

% berechne multiresolutionsanalyse bis maxlevel


waveletcoeffs = mra2D(signal, maxlevel, lp, hp);
% geschaetzte standardabweichung des rauschens
sigma = estimateNoise(waveletcoeffs);
coeffsize = size(waveletcoeffs);
denoised = waveletcoeffs; % initialisiere mit ungewichteten koeffizienten
if la
% berechne threshold fuer jedes zerlegungslevel
% initialisiere mit 0 fuer jeden koeffizienten
threshold = zeros(coeffsize);
for i = 1:maxlevel
% berechnung des thresholds
threshold(1:coeffsize(1)/(2^(i-1)),1:coeffsize(2)/(2^(i-1))) = ...
sigma * sqrt(2*log((size(signal,1)/(2^i))*(size(signal,2)/(2^i))));
end
else
% berechne globalen universal threshold
threshold = ones(coeffsize)*sigma* sqrt(2*log(size(signal,1)*size(signal,2))
);
end
% weighting with thrweight
threshold = threshold .* thrweight;
% setze threshold fuer bereich der approximations-koeffizienten auf 0
% auf approximation soll kein threshold angewendet werden!
threshold(1:end/2^maxlevel, 1:end/2^maxlevel) = 0;
% wende threshold auf koeffizienten an
% entscheide zwischen hard- oder soft-thresholding
switch(thrmode)
case 0 % hard thresholding
% alle koeffizienten mit absolutbetrag kleiner als threshold
% werden gleich 0 gesetzt
waveletcoeffs(abs(waveletcoeffs)<threshold) = 0;
case 1 % soft thresholding
% alle koeffizienten mit absolutbetrag kleiner als threshold
% werden auf 0 gesetzt,
% alle darueber werden um betrag des thresholds betragsmaessig
% verringert
waveletcoeffs(abs(waveletcoeffs) < threshold) = 0;
logicalMatrix = abs(waveletcoeffs) > threshold;
% auf approximation soll kein threshold angewendet werden!
logicalMatrix(1:end/2^maxlevel, 1:end/2^maxlevel) = 0;
waveletcoeffs(logicalMatrix) = sign(waveletcoeffs(logicalMatrix)).*(abs(
waveletcoeffs(logicalMatrix))-threshold(logicalMatrix));
end
% wavelet-synthese
denoisedimg = mrs2D(waveletcoeffs, maxlevel, rlp, rhp);
end
%--------------------------------------------------------------------------

% Entrauschen unter Verwendung von Interscale-Korrelationen


%-------------------------------------------------------------------------function denoisedimg = denoise_IC(signal, wavelet, maxlevel, thrweight, thrmode)
% hole filterkoeffizienten fuer angegebenes wavelet
[lp,hp,rlp,rhp] = wfilters(wavelet);
% berechne multiresolutionsanalyse bis maxlevel+1
waveletcoeffs = mra2D(signal, maxlevel+1, lp, hp);
sigma = estimateNoise(waveletcoeffs)
coeffsize = size(waveletcoeffs);
denoised = waveletcoeffs; % initialisiere mit ungewichteten koeffizienten
threshold = zeros(coeffsize);
mask = zeros(coeffsize);
% iteriere ueber alle zerlegungslevel und berechne threshold
for i = 1:maxlevel
% horizontale details
% x-,y-bereiche in denen horizontale details in waveletcoeffs stehen
% prev - level l+1, cur - level l
y_mid_prev = coeffsize(2)/2^(i+1);
y_mid_cur = coeffsize(2)/2^i;
y_prev = y_mid_prev+1:y_mid_cur;
x_prev = 1:coeffsize(1)/2^(i+1);
y_cur = y_mid_cur+1:coeffsize(2)/2^(i-1);
x_cur = 1:coeffsize(1)/2^i;
% hole koeffizineten des level l+1
hprev = waveletcoeffs(x_prev , y_prev);
hpreve = [hprev hprev(:,1); hprev(1,:) hprev(1,1)];
% interpolation auf feineres gitter
hprevi = INTERP2(hpreve);
% falten mit boxfilter
hprevi = conv2(hprevi, [0.25 0.25; 0.25 0.25], 'valid');
hcur = denoised(x_cur, y_cur);
% bilde produkt
mask(x_cur,y_cur) = sqrt(2)*hprevi.*hcur;
% vertikale details
% x-,y-bereiche in denen vertikale details in waveletcoeffs stehen
% prev - level l+1, cur - level l
x_mid_prev = coeffsize(1)/2^(i+1);
x_mid_cur = coeffsize(1)/2^i;
y_prev = 1:coeffsize(2)/2^(i+1);
x_prev = x_mid_prev+1:x_mid_cur;
y_cur = 1:coeffsize(2)/2^i;
x_cur = x_mid_cur+1:coeffsize(1)/2^(i-1);
% hole koeffizineten des level l+1
vprev = waveletcoeffs(x_prev , y_prev);
vpreve = [vprev vprev(:,1); vprev(1,:) vprev(1,1)];
% interpolation auf feineres gitter
vprevi = INTERP2(vpreve);
% falten mit boxfilter
vprevi = conv2(vprevi, [0.25 0.25; 0.25 0.25], 'valid');
vcur = denoised(x_cur, y_cur);
% bilde produkt

mask(x_cur,y_cur) = sqrt(2)*vprevi.*vcur;
% diagonale details
% x-,y-bereiche in denen diagonale details in waveletcoeffs stehen
% prev - level l+1, cur - level l
y_prev = y_mid_prev+1:y_mid_cur;
x_prev = x_mid_prev+1:x_mid_cur;
y_cur = y_mid_cur+1:coeffsize(2)/2^(i-1);
x_cur = x_mid_cur+1:coeffsize(1)/2^(i-1);
% hole koeffizineten des level l+1
dprev = waveletcoeffs(x_prev , y_prev);
dpreve = [dprev dprev(:,1); dprev(1,:) dprev(1,1)];
% interpolation auf feineres gitter
dprevi = INTERP2(dpreve);
% falten mit boxfilter
dprevi = conv2(dprevi, [0.25 0.25; 0.25 0.25], 'valid');
dcur = denoised(x_cur, y_cur);
% bilde produkt
mask(x_cur,y_cur) = sqrt(2)*dprevi.*dcur;
% berechnung des thresholds - verwende nun sigma.^2
threshold(1:coeffsize(1)/(2^(i-1)),1:coeffsize(2)/(2^(i-1))) = ...
sigma^2 * sqrt(2*log((size(signal,1)/(2^i))*(size(signal,2)/(2^i))));
end
% weighting with thrweight
threshold = threshold .* thrweight;
% setze threshold fuer bereich der approximations-koeffizienten auf 0
% auf approximation soll kein threshold angewendet werden!
threshold(1:end/2^maxlevel, 1:end/2^maxlevel) = 0;
% figure; imagesc(threshold); axis image;
% figure; imagesc(mask); colormap gray; axis image;
% wende threshold auf koeffizienten an
% entscheide zwischen hard- oder soft-thresholding
switch(thrmode)
case 0 % hard thresholding
% alle koeffizienten mit absolutbetrag der maske kleiner als threshold
% werden gleich 0 gesetzt
waveletcoeffs(abs(mask) < threshold) = 0;
case 1 % soft thresholding
% alle koeffizienten mit absolutbetrag der maske kleiner als threshold
% werden auf 0 gesetzt,
% alle darueber werden entsprechend des thresholds betragsmaessig
% verringert
waveletcoeffs(abs(mask) < threshold) = 0;
waveletcoeffs(abs(mask) > threshold) = sign(waveletcoeffs(abs(mask) > th
reshold)).*(abs(waveletcoeffs(abs(mask) > threshold))-threshold(abs(mask) > thre
shold));
end
% wavelet-synthese
denoisedimg = mrs2D(waveletcoeffs, maxlevel+1, rlp, rhp);
end

%-------------------------------------------------------------------------% 2D Multiresolutions-Analyse-Filterbank
%-------------------------------------------------------------------------function waveletcoeffs = mra2D(signal, ndec, lp, hp)
% initialisiere waveletkoeffizienten mit signal
% fuer ndec = 0 entspricht die wavelet-zerlegung dem signal selbst
waveletcoeffs = signal;
sizex = size(signal,1);
sizey = size(signal,2);
for i=1:ndec
% berechne dht2 fuer aktuelle approximation
% greife dazu auf die approximation in den waveletkoeffizienten zu
[approx, detailH, detailV, detailD] = mydwt2(waveletcoeffs(1:sizex,1:sizey),
lp, hp);
% ersetze die approximation des letzten zerlegungslevels durch die
% zerlegung
waveletcoeffs(1:sizex,1:sizey) = [approx, detailH; detailV, detailD];
% reduziere index-bereich auf die haelfte
sizex = sizex/2;
sizey = sizey/2;
end
end
%-------------------------------------------------------------------------% 2D Multiresolutions-Synthese-Filterbank
%-------------------------------------------------------------------------function recon = mrs2D(waveletcoeffs, ndec, rlp, rhp)
sizex = size(waveletcoeffs,1)/(2^ndec);
sizey = size(waveletcoeffs,2)/(2^ndec);
for i=ndec:-1:1
% berechne inverse haar-transformation
waveletcoeffs(1:2*sizex,1:2*sizey) = myidwt2(...
waveletcoeffs(1:sizex,1:sizey),...
waveletcoeffs(1:sizex,sizey+1:2*sizey), ...
waveletcoeffs(sizex+1:2*sizex,1:sizey), ...
waveletcoeffs(sizex+1:2*sizex,sizey+1:2*sizey), rlp, rhp);
% nach jeder iteration verdoppelt sich die anzahl von
% approximationskoeffizienten
sizex = sizex*2;
sizey = sizey*2;
end
% gib ergebnis zurueck
recon = waveletcoeffs;
end

%-------------------------------------------------------------------------% discrete Wavelet transform


%-------------------------------------------------------------------------function [approx, detailH, detailV, detailD] = mydwt2(signal, lp, hp)
%-------------filter length----------fLength = size(lp,2);
% ------------zeilen------------% 1D dht entlang der zeilen
% periodische ergaenzung des signals um ein element
signal = [signal(:,end-(fLength/2-2):end), signal, signal(:,1:fLength/2)];
% berechnung der faltung mit hoch- und tiefpassfilter
approximation = conv2(signal, lp, 'valid');
detail = conv2(signal, hp, 'valid');
% downsampling um den faktor 2 von detail und approximation
approximation = downsample(approximation', 2)';
detail = downsample(detail',2)';
% ------------spalten------------% 1D dht entlang der spalten der approximation
% periodische ergaenzung des signals um ein element
signal = [approximation(end-(fLength/2-2):end,:); approximation; approximation(1
:fLength/2,:)];
% berechnung der faltung mit hoch- und tiefpassfilter
% kleiner tipp: mit lp' bildet man den transponierten vektor von lp
approx = conv2(signal, lp', 'valid');
detailH = conv2(signal, hp', 'valid');
% downsampling um den faktor 2 von detail und approximation
approx = downsample(approx, 2);
detailH = downsample(detailH,2);
% 1D dht entlang der spalten des details
% periodische ergaenzung des signals um ein element
detail = [detail(end-(fLength/2-2):end,:);detail; detail(1:fLength/2,:)];
% berechnung der faltung mit hoch- und tiefpassfilter
detailV = conv2(detail, lp', 'valid');
detailD = conv2(detail, hp', 'valid');
% downsampling um den faktor 2 von detail und approximation
detailV = downsample(detailV, 2);
detailD = downsample(detailD,2);
end
%-------------------------------------------------------------------------% inverse discrete Wavelet transform
%-------------------------------------------------------------------------function recon = myidwt2(approx, detailH, detailV, detailD, rlp, rhp)
%------------filter length------------fLength = size(rlp,2);
% berechne inverse dht entlang der spalten
% kombiniere dazu approx und detailH zu approx
% sowie detailV und detailD zu detail
% ------------spalten-------------

% upsampling der approximations- und detailkoeffizienten um faktor 2 entlang


% der spalten
usapprox = zeros(2*size(approx, 1), size(approx, 2));
usapprox(2:2:end, :) = approx;
usdetail = zeros(2*size(detailH, 1), size(detailH, 2));
usdetail(2:2:end, :) = detailH;
% periodische ergaenzung der beiden teile um ein element
usapprox = [usapprox(end-(fLength/2-2):end,:); usapprox; usapprox(1:fLength/2,:)
];
usdetail= [usdetail(end-(fLength/2-2):end,:); usdetail; usdetail(1:fLength/2,:)]
;
% faltung der spalten mit hoch- und tiefpassfilter und addition der beiden teile
approx = conv2(usapprox, rlp', 'valid') + conv2(usdetail, rhp', 'valid');
% upsampling der approximations- und detailkoeffizienten um faktor 2 entlang
% der spalten
usapprox = zeros(2*size(detailV, 1), size(detailV, 2));
usapprox(2:2:end, :) = detailV;
usdetail = zeros(2*size(detailD, 1), size(detailD, 2));
usdetail(2:2:end, :) = detailD;
% periodische ergaenzung der beiden teile um ein element
usapprox = [usapprox(end-(fLength/2-2):end,:); usapprox; usapprox(1:fLength/2,:)
];
usdetail= [usdetail(end-(fLength/2-2):end,:); usdetail; usdetail(1:fLength/2,:)]
;
% faltung der spalten mit hoch- und tiefpassfilter und addition der beiden teile
detail = conv2(usapprox, rlp', 'valid') + conv2(usdetail, rhp', 'valid');
% ------------zeilen------------% upsample der approximations- und detailkoeffizienten um faktor 2 entlang
% der spalten
usapprox = zeros(size(approx, 1), 2*size(approx, 2));
usapprox(:,2:2:end) = approx;
usdetail = zeros(size(detail, 1), 2*size(detail, 2));
usdetail(:,2:2:end) = detail;
% periodische ergaenzung der beiden teile um ein element
usapprox = [usapprox(:,end-(fLength/2-2):end), usapprox, usapprox(:, 1:fLength/2
)];
usdetail= [usdetail(:,end-(fLength/2-2):end),usdetail, usdetail(:,1:fLength/2)];
% faltung der zeilen mit hoch- und tiefpassfilter und addition der beiden teile
recon = conv2(usapprox, rlp, 'valid') + conv2(usdetail, rhp, 'valid');
end