ivan@138
|
1 function y = inpaintFrame_consOMP(problemData,param)
|
ivan@138
|
2 % Inpainting method based on OMP with a constraint
|
ivan@138
|
3 % on the amplitude of the reconstructed samples an optional constraint
|
ivan@138
|
4 % on the maximum value of the clipped samples
|
ivan@138
|
5 %
|
ivan@138
|
6 % Usage: y = inpaintFrame_consOMP(problemData,param)
|
ivan@138
|
7 %
|
ivan@138
|
8 %
|
ivan@138
|
9 % Inputs:
|
ivan@138
|
10 % - problemData.x: observed signal to be inpainted
|
ivan@138
|
11 % - problemData.Imiss: Indices of clean samples
|
ivan@138
|
12 % - param.D - the dictionary matrix (optional if param.D_fun is set)
|
ivan@138
|
13 % - param.D_fun - a function handle that generates the dictionary
|
ivan@138
|
14 % matrix param.D if param.D is not given. See, e.g., DCT_Dictionary.m and Gabor_Dictionary.m
|
ivan@138
|
15 % - param.wa - Analysis window
|
ivan@138
|
16 % - param.Upper_Limit - if present and non-empty this fiels
|
ivan@138
|
17 % indicates that an upper limit constraint is active and its
|
ivan@138
|
18 % integer value is such that
|
ivan@138
|
19 %
|
ivan@138
|
20 % Outputs:
|
ivan@138
|
21 % - y: estimated frame
|
ivan@138
|
22 %
|
ivan@138
|
23 % Note that the CVX library is needed.
|
ivan@138
|
24 %
|
ivan@138
|
25 % -------------------
|
ivan@138
|
26 %
|
ivan@138
|
27 % Audio Inpainting toolbox
|
ivan@138
|
28 % Date: June 28, 2011
|
ivan@138
|
29 % By Valentin Emiya, Amir Adler, Michael Elad, Maria Jafari
|
ivan@138
|
30 % This code is distributed under the terms of the GNU Public License version 3 (http://www.gnu.org/licenses/gpl.txt).
|
ivan@138
|
31 % ========================================================
|
ivan@138
|
32
|
ivan@138
|
33 %% Load data and parameters
|
ivan@138
|
34
|
ivan@138
|
35 x = problemData.x;
|
ivan@138
|
36 IObs = find(~problemData.IMiss);
|
ivan@138
|
37 p.N = length(x);
|
ivan@138
|
38 E2 = param.OMPerr^2;
|
ivan@138
|
39 E2M=E2*length(IObs);
|
ivan@138
|
40 wa = param.wa(param.N);
|
ivan@138
|
41
|
ivan@138
|
42 % build the dictionary matrix if only the dictionary generation function is given
|
ivan@138
|
43 if ~isfield(param,'D')
|
ivan@138
|
44 param.D = param.D_fun(param);
|
ivan@138
|
45 end
|
ivan@138
|
46
|
ivan@138
|
47
|
ivan@138
|
48 % clipping level detection
|
ivan@138
|
49 clippingLevelEst = max(abs(x(:)./wa(:)));
|
ivan@138
|
50
|
ivan@138
|
51 IMiss = true(length(x),1);
|
ivan@138
|
52 IMiss(IObs) = false;
|
ivan@138
|
53 IMissPos = find(x>=0 & IMiss);
|
ivan@138
|
54 IMissNeg = find(x<0 & IMiss);
|
ivan@138
|
55
|
ivan@138
|
56 DictPos=param.D(IMissPos,:);
|
ivan@138
|
57 DictNeg=param.D(IMissNeg,:);
|
ivan@138
|
58
|
ivan@138
|
59 % Clipping level: take the analysis window into account
|
ivan@138
|
60 wa_pos = wa(IMissPos);
|
ivan@138
|
61 wa_neg = wa(IMissNeg);
|
ivan@138
|
62 b_ineq_pos = wa_pos(:)*clippingLevelEst;
|
ivan@138
|
63 b_ineq_neg = -wa_neg(:)*clippingLevelEst;
|
ivan@138
|
64 if isfield(param,'Upper_Limit') && ~isempty(param.Upper_Limit)
|
ivan@138
|
65 b_ineq_pos_upper_limit = wa_pos(:)*param.Upper_Limit*clippingLevelEst;
|
ivan@138
|
66 b_ineq_neg_upper_limit = -wa_neg(:)*param.Upper_Limit*clippingLevelEst;
|
ivan@138
|
67 else
|
ivan@138
|
68 b_ineq_pos_upper_limit = Inf;
|
ivan@138
|
69 b_ineq_neg_upper_limit = -Inf;
|
ivan@138
|
70 end
|
ivan@138
|
71
|
ivan@138
|
72 %%
|
ivan@138
|
73 Dict=param.D(IObs,:);
|
ivan@138
|
74 W=1./sqrt(diag(Dict'*Dict));
|
ivan@138
|
75 Dict=Dict*diag(W);
|
ivan@138
|
76 xObs=x(IObs);
|
ivan@138
|
77
|
ivan@138
|
78 residual=xObs;
|
ivan@138
|
79 maxNumCoef = param.sparsityDegree;
|
ivan@138
|
80 indx = [];
|
ivan@138
|
81 currResNorm2 = E2M*2; % set a value above the threshold in order to have/force at least one loop executed
|
ivan@138
|
82 j = 0;
|
ivan@138
|
83 while currResNorm2>E2M && j < maxNumCoef,
|
ivan@138
|
84 j = j+1;
|
ivan@138
|
85 proj=Dict'*residual;
|
ivan@138
|
86 [dum pos] = max(abs(proj));
|
ivan@138
|
87 indx(j)=pos;
|
ivan@138
|
88 a=pinv(Dict(:,indx(1:j)))*xObs;
|
ivan@138
|
89 residual=xObs-Dict(:,indx(1:j))*a;
|
ivan@138
|
90 currResNorm2=sum(residual.^2);
|
ivan@138
|
91 end;
|
ivan@138
|
92
|
ivan@138
|
93
|
ivan@138
|
94 if isinf(b_ineq_pos_upper_limit)
|
ivan@138
|
95 %% CVX code
|
ivan@138
|
96 cvx_begin
|
ivan@138
|
97 cvx_quiet(true)
|
ivan@138
|
98 variable a(j)
|
ivan@138
|
99 %minimize( sum(square(xObs-Dict*a)))
|
ivan@138
|
100 minimize(norm(Dict(:,indx)*a-xObs))
|
ivan@138
|
101 subject to
|
ivan@138
|
102 DictPos(:,indx)*(W(indx).*a) >= b_ineq_pos
|
ivan@138
|
103 DictNeg(:,indx)*(W(indx).*a) <= b_ineq_neg
|
ivan@138
|
104 cvx_end
|
ivan@138
|
105 if cvx_optval>1e3
|
ivan@138
|
106 cvx_begin
|
ivan@138
|
107 cvx_quiet(true)
|
ivan@138
|
108 variable a(j)
|
ivan@138
|
109 minimize(norm(Dict(:,indx)*a-xObs))
|
ivan@138
|
110 cvx_end
|
ivan@138
|
111 end
|
ivan@138
|
112 else
|
ivan@138
|
113 %% CVX code
|
ivan@138
|
114 cvx_begin
|
ivan@138
|
115 cvx_quiet(true)
|
ivan@138
|
116 variable a(j)
|
ivan@138
|
117 %minimize( sum(square(xObs-Dict*a)))
|
ivan@138
|
118 minimize(norm(Dict(:,indx)*a-xObs))
|
ivan@138
|
119 subject to
|
ivan@138
|
120 DictPos(:,indx)*(W(indx).*a) >= b_ineq_pos
|
ivan@138
|
121 DictNeg(:,indx)*(W(indx).*a) <= b_ineq_neg
|
ivan@138
|
122 DictPos(:,indx)*(W(indx).*a) <= b_ineq_pos_upper_limit
|
ivan@138
|
123 DictNeg(:,indx)*(W(indx).*a) >= b_ineq_neg_upper_limit
|
ivan@138
|
124 cvx_end
|
ivan@138
|
125 if cvx_optval>1e3
|
ivan@138
|
126 cvx_begin
|
ivan@138
|
127 cvx_quiet(true)
|
ivan@138
|
128 variable a(j)
|
ivan@138
|
129 minimize(norm(Dict(:,indx)*a-xObs))
|
ivan@138
|
130 cvx_end
|
ivan@138
|
131 end
|
ivan@138
|
132 end
|
ivan@138
|
133
|
ivan@138
|
134 %% Frame Reconstruction
|
ivan@138
|
135 indx(length(a)+1:end) = [];
|
ivan@138
|
136
|
ivan@138
|
137 Coeff = sparse(size(param.D,2),1);
|
ivan@138
|
138 if (~isempty(indx))
|
ivan@138
|
139 Coeff(indx) = a;
|
ivan@138
|
140 Coeff = W.*Coeff;
|
ivan@138
|
141 end
|
ivan@138
|
142 y = param.D*Coeff;
|
ivan@138
|
143
|
ivan@138
|
144 return
|