-
Notifications
You must be signed in to change notification settings - Fork 5
/
denoiseImageGlobal.m
136 lines (130 loc) · 5.92 KB
/
denoiseImageGlobal.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
function [IOut,output] = denoiseImageGlobal(Image, sigma, varargin)
%==========================================================================
% P E R F O R M D E N O I S I N G U S I N G G L O B A L
% ( O R G I V E N ) D I C T I O N A R Y
%==========================================================================
% function IOut = denoiseImageGlobal(Image, sigma, varargin)
% denoise an image by training a dictionary on patches from the noisy image,
% sparsely representing each block with this dictionary and averaging the represented parts.
% Detailed description can be found in "Image Denoising Via Sparse and Redundant
% representations over Learned Dictionaries", (appeared in the
% IEEE Trans. on Image Processing, Vol. 15, no. 12, December 2006).
% The trained dictionary is given in a specific file
% 'globalTrainedDictionary.mat' that must accompany this function.
% The user may also specify a different dictionary to be used by using the
% optional arguments.
% ===================================================================
% INPUT ARGUMENTS : Image - the noisy image (gray-level scale)
% sigma - the s.d. of the noise (assume to be white Gaussian).
% Optional arguments:
% 'blockSize' - the size of the blocks the algorithm
% works. All blocks are squares, therefore the given
% parameter should be one number (width or height).
% Default value: 8.
% 'errorFactor' - a factor that multiplies sigma in order
% to set the allowed representation error. In the
% experiments presented in the paper, it was set to 1.15
% (which is also the default value here).
% 'maxBlocksToConsider' - maximal number of blocks that
% can be processed. This number is dependent on the memory
% capabilities of the machine, and performances'
% considerations. If the number of available blocks in the
% image is larger than 'maxBlocksToConsider', the sliding
% distance between the blocks increases. The default value
% is: 250000.
% 'slidingFactor' - the sliding distance between processed
% blocks. Default value is 1. However, if the image is
% large, this number increases automatically (because of
% memory requirements). Larger values result faster
% performances (because of fewer processed blocks).
% 'givenDictionary' - a different dictionary to consider
% for denoising. The user is responsible that the number
% of rows in the dictionary will resemble the dimension of
% the blocks.
% 'waitBarOn' - can be set to either 1 or 0. If
% waitBarOn==1 a waitbar, presenting the progress of the
% algorithm will be displayed.
% OUTPUT ARGUMENTS : Iout - a 2-dimensional array in the same size of the
% input image, that contains the cleaned image.
% output - a struct that contains that following field:
% D - the dictionary used for denoising
% =========================================================================
fildNameForGlobalDictionary = 'globalTrainedDictionary';
Reduce_DC = 1;
[NN1,NN2] = size(Image);
waitBarOn = 1;
C = 1.15;
maxBlocksToConsider = 260000;
slidingDis = 1;
bb = 8;
givenDictionaryFlag = 0;
for argI = 1:2:length(varargin)
if (strcmp(varargin{argI}, 'slidingFactor'))
slidingDis = varargin{argI+1};
end
if (strcmp(varargin{argI}, 'errorFactor'))
C = varargin{argI+1};
end
if (strcmp(varargin{argI}, 'maxBlocksToConsider'))
maxBlocksToConsider = varargin{argI+1};
end
if (strcmp(varargin{argI}, 'givenDictionary'))
D = varargin{argI+1};
givenDictionaryFlag = 1;
end
if (strcmp(varargin{argI}, 'blockSize'))
bb = varargin{argI+1};
end
if (strcmp(varargin{argI}, 'waitBarOn'))
waitBarOn = varargin{argI+1};
end
end
if (~givenDictionaryFlag)
eval(['load ',fildNameForGlobalDictionary]);%%%%%%%%%%%%%
D = currDictionary;
end
errT = C*sigma;
%blocks = im2col(Image,[NN1,NN2],[bb,bb],'sliding');
while (prod(size(Image)-bb+1)>maxBlocksToConsider)
slidingDis = slidingDis+1;
end
[blocks,idx] = my_im2col(Image,[bb,bb],slidingDis);
if (waitBarOn)
counterForWaitBar = size(blocks,2);
h = waitbar(0,'Denoising In Process ...');
end
% go with jumps of 10000
for jj = 1:10000:size(blocks,2)
if (waitBarOn)
waitbar(jj/counterForWaitBar);
end
jumpSize = min(jj+10000-1,size(blocks,2));
if (Reduce_DC)
vecOfMeans = mean(blocks(:,jj:jumpSize));
blocks(:,jj:jumpSize) = blocks(:,jj:jumpSize) - repmat(vecOfMeans,size(blocks,1),1);
end
%Coefs = mexOMPerrIterative(blocks(:,jj:jumpSize),D,errT);
Coefs = OMPerr(D,blocks(:,jj:jumpSize),errT);
if (Reduce_DC)
%block=reshape(D*a+mm+MM,[bb,bb]);
blocks(:,jj:jumpSize)= D*Coefs + ones(size(blocks,1),1) * vecOfMeans;
else
blocks(:,jj:jumpSize)= D*Coefs ;
end
end
count = 1;
Weight=zeros(NN1,NN2);
IMout = zeros(NN1,NN2);
[rows,cols] = ind2sub(size(Image)-bb+1,idx);
for i = 1:length(cols)
col = cols(i); row = rows(i);
block =reshape(blocks(:,count),[bb,bb]);
IMout(row:row+bb-1,col:col+bb-1)=IMout(row:row+bb-1,col:col+bb-1)+block;
Weight(row:row+bb-1,col:col+bb-1)=Weight(row:row+bb-1,col:col+bb-1)+ones(bb);
count = count+1;
end;
if (waitBarOn)
close(h);
end
output.D = D;
IOut = (Image+0.034*sigma*IMout)./(1+0.034*sigma*Weight);