-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 6a612e4
Showing
93 changed files
with
1,919 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
%SEPARATE_BLOCKS - Enlarge 2D image by inserting a margin between blocks of a given size. | ||
|
||
% Author: Uwe Schmidt, TU Darmstadt ([email protected]) | ||
% | ||
% This file is part of the implementation as described in the CVPR 2014 paper: | ||
% Uwe Schmidt and Stefan Roth. Shrinkage Fields for Effective Image Restoration. | ||
% Please see the file LICENSE.txt for the license governing this code. | ||
|
||
function I = separate_blocks(I,blockdims,pad,pad_val) | ||
if ~exist('pad','var'), pad = 1; end | ||
if ~exist('pad_val','var'), pad_val = nan; end | ||
|
||
blockfunc = @(b) padarray(b.data,[pad,pad],pad_val,'pre'); | ||
I = blockproc(I,blockdims,blockfunc); | ||
I = padarray(I,[pad,pad],pad_val,'post'); | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
%STRUCT2VEC - Convert a STRUCT to a row vector. | ||
% See also VEC2STRUCT. | ||
|
||
% Author: Uwe Schmidt, TU Darmstadt ([email protected]) | ||
% | ||
% This file is part of the implementation as described in the CVPR 2014 paper: | ||
% Uwe Schmidt and Stefan Roth. Shrinkage Fields for Effective Image Restoration. | ||
% Please see the file LICENSE.txt for the license governing this code. | ||
|
||
function vec = struct2vec(theta) | ||
assert(isstruct(theta)); | ||
% theta = orderfields(theta); | ||
fnames = fieldnames(theta); | ||
vec = []; | ||
for i = 1:numel(fnames) | ||
value = theta.(fnames{i}); | ||
vec = [vec; value(:)]; %#ok | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
%STRUCT_PUT - Set fields of a STRUCT based on the names and contents of provided arguments. | ||
|
||
% Author: Uwe Schmidt, TU Darmstadt ([email protected]) | ||
% | ||
% This file is part of the implementation as described in the CVPR 2014 paper: | ||
% Uwe Schmidt and Stefan Roth. Shrinkage Fields for Effective Image Restoration. | ||
% Please see the file LICENSE.txt for the license governing this code. | ||
|
||
function s = struct_put(s, varargin) | ||
for i = 1:numel(varargin) | ||
s.(inputname(i+1)) = varargin{i}; | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
%VEC2STRUCT - Convert a row vector to a STRUCT (based on the provided template). | ||
% See also STRUCT2VEC. | ||
|
||
% Author: Uwe Schmidt, TU Darmstadt ([email protected]) | ||
% | ||
% This file is part of the implementation as described in the CVPR 2014 paper: | ||
% Uwe Schmidt and Stefan Roth. Shrinkage Fields for Effective Image Restoration. | ||
% Please see the file LICENSE.txt for the license governing this code. | ||
|
||
function theta = vec2struct(vec, THETA) | ||
assert(isstruct(THETA)); | ||
% theta = orderfields(THETA); | ||
theta = THETA; | ||
fnames = fieldnames(theta); | ||
e = 0; % end-point | ||
for i = 1:numel(fnames) | ||
field_size = size(theta.(fnames{i})); | ||
field_numel = prod(field_size); | ||
% special case of last field that takes remaining elements of vec | ||
if field_numel == 0 && i == numel(fnames) | ||
field_numel = numel(vec)-e; | ||
field_size = [field_numel,1]; | ||
end | ||
field_value = reshape( vec(e+1:e+field_numel), field_size ); | ||
theta.(fnames{i}) = field_value; | ||
e = e + field_numel; | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
%VIS_BNDRY - Visualize image boundary (and embed blur kernel). | ||
|
||
% Author: Uwe Schmidt, TU Darmstadt ([email protected]) | ||
% | ||
% This file is part of the implementation as described in the CVPR 2014 paper: | ||
% Uwe Schmidt and Stefan Roth. Shrinkage Fields for Effective Image Restoration. | ||
% Please see the file LICENSE.txt for the license governing this code. | ||
|
||
function x = vis_bndry(x,k,t) | ||
if t > 0 | ||
% scale by inner region | ||
x_inside = x(1+t:end-t,1+t:end-t); | ||
x = x - min(x_inside(:)); | ||
x = x / max(x_inside(:)); | ||
% clip values at boundary | ||
x = min(max(x,0),1); | ||
|
||
x = repmat(x,[1,1,3]); | ||
x([1+t,end-t],1+t:end-t,:) = 0; | ||
x([1+t,end-t],1+t:end-t,2) = 1; | ||
x(1+t:end-t,[1+t,end-t],:) = 0; | ||
x(1+t:end-t,[1+t,end-t],2) = 1; | ||
if numel(k) > 1 | ||
kdims = size(k); | ||
k = k / max(k(:)); | ||
x(1:kdims(1),1:kdims(2),:) = repmat(k,[1,1,3]); | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
%EDGETAPER_ALPHA - Weights for edge tapering. | ||
% Based on Matlab's EDGETAPER function, | ||
% and used as in Sec. 1.1. of the supplemental material. | ||
% | ||
% See also EDGETAPER. | ||
|
||
% Author: Uwe Schmidt, TU Darmstadt ([email protected]) | ||
% | ||
% This file is part of the implementation as described in the CVPR 2014 paper: | ||
% Uwe Schmidt and Stefan Roth. Shrinkage Fields for Effective Image Restoration. | ||
% Please see the file LICENSE.txt for the license governing this code. | ||
|
||
function alpha = edgetaper_alpha(k,imdims) | ||
assert(all(imdims > 2*size(k)), 'kernel too small for image size') | ||
alpha = 1; | ||
for i = 1:2 | ||
z = real(ifft(abs(fft(sum(k,3-i),imdims(i)-1)).^2)); | ||
alpha = alpha * (1 - z([1:end,1])/max(z)); | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
%FILTER_CIRC_CONV - 2D convolution with circular boundary handling. | ||
|
||
% Author: Uwe Schmidt, TU Darmstadt ([email protected]) | ||
% | ||
% This file is part of the implementation as described in the CVPR 2014 paper: | ||
% Uwe Schmidt and Stefan Roth. Shrinkage Fields for Effective Image Restoration. | ||
% Please see the file LICENSE.txt for the license governing this code. | ||
|
||
function r = filter_circ_conv(img,j,s) | ||
r = imfilter(img,s.f{j},'same','circular','conv'); | ||
% r = real( ifft2( s.f_otf{j} .* fft2(img)) ); | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
%FILTER_CIRC_CORR - 2D correlation with circular boundary handling. | ||
|
||
% Author: Uwe Schmidt, TU Darmstadt ([email protected]) | ||
% | ||
% This file is part of the implementation as described in the CVPR 2014 paper: | ||
% Uwe Schmidt and Stefan Roth. Shrinkage Fields for Effective Image Restoration. | ||
% Please see the file LICENSE.txt for the license governing this code. | ||
|
||
function r = filter_circ_corr(img,j,s) | ||
r = imfilter(img,s.f{j},'same','circular','corr'); | ||
% r = real( ifft2( s.f_otf_tr{j} .* fft2(img)) ); | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
%FIX_BNDRY - Boundary operations (padding, truncation, edge tapering). | ||
% See Sec. 1.1. of the supplemental material. | ||
|
||
% Author: Uwe Schmidt, TU Darmstadt ([email protected]) | ||
% | ||
% This file is part of the implementation as described in the CVPR 2014 paper: | ||
% Uwe Schmidt and Stefan Roth. Shrinkage Fields for Effective Image Restoration. | ||
% Please see the file LICENSE.txt for the license governing this code. | ||
|
||
function I = fix_bndry(I,k,alpha,s,transpose) | ||
if ~exist('transpose','var'), transpose = false; end | ||
if transpose | ||
if numel(k)~=1 || k ~= 1 % no edgetapering when denoising | ||
I = s.rs(I); | ||
for i = 1:s.ntapers | ||
blurredI = train.kernel_circ((1-alpha).*I,k,'corr',s); | ||
I = alpha.*I + blurredI; | ||
end | ||
end | ||
I = s.rs(s.PT' * I(:)); | ||
else | ||
I = s.rs(s.PT * I(:)); | ||
if numel(k)~=1 || k ~= 1 % no edgetapering when denoising | ||
for i = 1:s.ntapers | ||
blurredI = train.kernel_circ(I,k,'conv',s); | ||
I = alpha.*I + (1-alpha).*blurredI; | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
%GET_DATA - Load and generate training data. | ||
|
||
% Author: Uwe Schmidt, TU Darmstadt ([email protected]) | ||
% | ||
% This file is part of the implementation as described in the CVPR 2014 paper: | ||
% Uwe Schmidt and Stefan Roth. Shrinkage Fields for Effective Image Restoration. | ||
% Please see the file LICENSE.txt for the license governing this code. | ||
|
||
function data = get_data(p,s) | ||
|
||
assert(s.nimages <= 20); | ||
assert(all([128,128]==s.imdims) && s.npixels == prod(s.imdims), 'size must be 128x128 pixels in this example') | ||
|
||
[X,Y] = deal(zeros(s.npixels,s.nimages)); | ||
if s.is_deblurring | ||
ks = cell(s.nimages,1); | ||
alphas = zeros([s.imdims,s.nimages]); | ||
else | ||
[ks,alphas] = deal([]); | ||
end | ||
|
||
for i = 1:s.nimages | ||
fprintf('Loading image %02d/%02d\r',i,s.nimages); | ||
img = double(imread(sprintf('%s/images/image_%02d.png',p,i))); | ||
X(:,i) = img(:); | ||
|
||
if s.is_deblurring | ||
k = dlmread(sprintf('%s/kernels/image_%02d.dlm',p,i),'\t'); k = k/sum(k(:)); | ||
blurred = conv2(img,k,'valid'); | ||
blurred = blurred + s.sigma * randn(size(blurred)); | ||
blurred = double(uint8(blurred)); | ||
|
||
% suboptimal, but simplifies training: pad all kernels with 0s to have the same size (s.k_sz_max) | ||
kdims = size(k); assert(all(mod(s.k_sz_max-kdims,2)==0)) | ||
k = padarray(k,(s.k_sz_max-kdims)/2,0,'both'); ks{i} = k; | ||
% crop blurred image to correct for kernel padding | ||
excess = (size(k)-kdims)/2; | ||
blurred = blurred(1+excess(1):end-excess(1),1+excess(2):end-excess(2)); | ||
% padarray & edgetaper | ||
alphas(:,:,i) = train.edgetaper_alpha(k,s.imdims); | ||
blurred = train.fix_bndry(s.T'*blurred(:),ks{i},alphas(:,:,i),s); | ||
Y(:,i) = blurred(:); | ||
else | ||
img = img + s.sigma * randn(size(img)); | ||
img = double(uint8(img)); | ||
Y(:,i) = s.PT * img(:); % truncate and pad corrupted images | ||
end | ||
end | ||
fprintf('\n') | ||
|
||
data = struct; | ||
for str = {'nimages','imdims','npixels','sigma'}, data.(char(str)) = s.(char(str)); end | ||
[data.X,data.Y,data.ks,data.alphas] = deal(X,Y,ks,alphas); | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
%GET_FILTERS - Get filter bank. | ||
|
||
% Author: Uwe Schmidt, TU Darmstadt ([email protected]) | ||
% | ||
% This file is part of the implementation as described in the CVPR 2014 paper: | ||
% Uwe Schmidt and Stefan Roth. Shrinkage Fields for Effective Image Restoration. | ||
% Please see the file LICENSE.txt for the license governing this code. | ||
|
||
function s = get_filters(s) | ||
|
||
switch s.fbank | ||
case 'pw' | ||
s.f = {[1 -1 0];[1 -1 0]'}; | ||
case 'dct' | ||
n = s.fbank_sz; | ||
% dct filters without DC component | ||
assert(mod(n,2)==1, 'filters must be odd-sized') | ||
N = n^2; | ||
s.f = cell(N-1,1); | ||
s.filter_basis = zeros(N,N-1); | ||
for i = 2:N | ||
d = zeros(n,n); d(i) = 1; | ||
s.f{i-1} = idct2(d'); | ||
s.filter_basis(:,i-1) = s.f{i-1}(:); | ||
end | ||
otherwise | ||
error('unsupported fbank: %s', s.fbank) | ||
end | ||
s.nfilters = numel(s.f); | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
%GET_MINIMIZER - Find suitable optimization algorithm. | ||
|
||
% Author: Uwe Schmidt, TU Darmstadt ([email protected]) | ||
% | ||
% This file is part of the implementation as described in the CVPR 2014 paper: | ||
% Uwe Schmidt and Stefan Roth. Shrinkage Fields for Effective Image Restoration. | ||
% Please see the file LICENSE.txt for the license governing this code. | ||
|
||
function minimizer = get_minimizer(s, cost_func, theta0) | ||
|
||
if exist('minFunc') == 2 %#ok | ||
% 'minFunc' by Mark Schmidt (http://www.di.ens.fr/~mschmidt/Software/minFunc.html) | ||
options = struct('MaxIter',s.maxoptiters); | ||
if s.do_joint_training, minimizer = @() minFunc(cost_func,theta0,options); | ||
else minimizer = @(U) minFunc(cost_func,theta0,options,U); end | ||
elseif exist('minimize') == 2 %#ok | ||
% 'minimize' by Carl Edward Rasmussen (http://www.gatsby.ucl.ac.uk/~edward/code/minimize/) | ||
if s.do_joint_training, minimizer = @() minimize(theta0,cost_func,s.maxoptiters); | ||
else minimizer = @(U) minimize(theta0,cost_func,s.maxoptiters,U); end | ||
elseif exist('fminunc') == 2 %#ok | ||
% 'fminunc' from Matlab's optimization toolbox (http://www.mathworks.de/help/optim/ug/fminunc.html) | ||
options = optimset('MaxIter',s.maxoptiters, 'Display','iter', 'GradObj','on', 'LargeScale','off'); | ||
if s.do_joint_training, minimizer = @() fminunc(cost_func,theta0,options); | ||
else minimizer = @(U) fminunc(cost_func,theta0,options,U); end | ||
else | ||
error('No suitable minimization algorithm found.') | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
%GRAD_PARAMS - Compute gradient w.r.t. all model parameters of one stage of a shrinkage field cascade. | ||
% See Sec. 1.2.2 of the supplemental material. | ||
% See also OBJECTIVE_ONE_STAGE, OBJECTIVE_ALL_STAGES. | ||
|
||
% Author: Uwe Schmidt, TU Darmstadt ([email protected]) | ||
% | ||
% This file is part of the implementation as described in the CVPR 2014 paper: | ||
% Uwe Schmidt and Stefan Roth. Shrinkage Fields for Effective Image Restoration. | ||
% Please see the file LICENSE.txt for the license governing this code. | ||
|
||
function [g,c_prev] = grad_params(s,x,x_old,y,k,alpha,c,lambda,gw,gx,z,fx_old,fnorms,bottom) | ||
% c_prev is for the previous model stage as defined in Eq. (34) of the supplemental material | ||
|
||
GRAD = struct; | ||
do_c_prev = nargout == 2; | ||
g_weights = zeros(size(gw{1},1),s.nfilters); | ||
if s.do_filterlearning, g_filt = zeros(size(s.filter_basis,2),s.nfilters); end | ||
if do_c_prev, c_prev = zeros(s.imdims); end | ||
|
||
if s.do_filterlearning | ||
cliques_c = s.filter_basis' * c(s.cliques_of_circ_conv); | ||
cliques_x = s.filter_basis' * x(s.cliques_of_circ_conv); | ||
cliques_x_old = s.filter_basis' * x_old(s.cliques_of_circ_conv); | ||
end | ||
|
||
% grad wrt. (log) lambda | ||
if s.is_deblurring | ||
kc = train.kernel_circ(c,k,'conv',s); | ||
kx = train.kernel_circ(x,k,'conv',s); | ||
GRAD.lambda = kc(:)' * (y(:)-kx(:)); | ||
else | ||
GRAD.lambda = c(:)' * (y(:)- x(:)); | ||
end | ||
GRAD.lambda = GRAD.lambda * lambda; | ||
|
||
for j = 1:s.nfilters | ||
fc = s.vec(train.filter_circ_conv(c,j,s)); | ||
% grad wrt. shrinkage weights | ||
g_weights(:,j) = gw{j} * fc; | ||
fc_gx = fc .* gx{j}(:); | ||
if s.do_filterlearning | ||
% grad wrt. filter coefficients | ||
fx = s.vec(train.filter_circ_conv(x,j,s)); | ||
z_minus_fx = z{j}(:) - fx; | ||
g_filt(:,j) = cliques_x_old*fc_gx + cliques_c*z_minus_fx - cliques_x*fc; | ||
if s.unitnorm_filter | ||
g_filt(:,j) = g_filt(:,j) - s.filter_basis' * s.f{j}(:) * (fc' * (fx_old{j}(:).*gx{j}(:) + z_minus_fx - fx)); | ||
g_filt(:,j) = g_filt(:,j) / fnorms(j); | ||
end | ||
end | ||
% c for previous stage | ||
if do_c_prev | ||
c_prev = c_prev + train.filter_circ_corr(s.rs(fc_gx),j,s); | ||
end | ||
end | ||
% c for previous stage | ||
if do_c_prev | ||
c_prev = real(ifft2( fft2(train.fix_bndry(c_prev,k,alpha,s,true)) ./ bottom )); | ||
end | ||
|
||
GRAD.weights = g_weights(:); | ||
if s.do_filterlearning, GRAD.filters = g_filt(:); end | ||
g = misc.struct2vec(GRAD); | ||
|
||
end |
Oops, something went wrong.