removeStripes.m 6 KB
Newer Older
Leon Merten Lohse's avatar
Leon Merten Lohse committed
1
function [imCorr, corr2D] = removeStripes(imToCorr,settings)
mtoeppe's avatar
mtoeppe committed
2
% REMOVESTRIPES removes horizontal and vertical stripes from an image.
mtoeppe's avatar
mtoeppe committed
3
4
5
6
7
8
%
%    ``[imCorr, corr2D] = removeStripes(imToCorr,settings)``
% 
% Remove horizontal/vertical stripes from an image by averaging over a specified
% number of lines at the top/bottom or left/right edge of the image and linearly
% interpolating in between. If only one range is specified it is taken as the
mtoeppe's avatar
mtoeppe committed
9
% correction for the entire image.
mtoeppe's avatar
mtoeppe committed
10
11
12
13
14
15
16
17
18
19
%
% Parameters
% ----------
% imToCorr : numerical array
%     image from which stripes are removed
% settings : structure, optional
%     contains additional settings, see *Other Parameters*
%
% Other Parameters 
% ---------------- 
20
21
% rangeTop : Default = []
%     Range at the top of the image to average. [] results in the top most 4%
mtoeppe's avatar
mtoeppe committed
22
% rangeBottom : Default = []
23
24
25
%     Range at the bottom of the image to average. [] results in the bottom most 4%
% rangeLeft : Default = []
%     Range at the left edge of the image to average. [] results in the left most 4%
mtoeppe's avatar
mtoeppe committed
26
% rangeRight : Default = []
27
%     Range at the right edge of the image to average. [] results in the right most 4%
mtoeppe's avatar
mtoeppe committed
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
% windowSize : Default = 5
%     Window size for smoothing the profile via a moving mean.
% direction : Default = 'vertical'
%     Direction of the stripes to be removed. Chose between  'vertical', 'horizontal'
%     or 'both'.
% method : Default = 'multiplicative'
%     Method for removing the stripes. Choose 'multiplicative' for dividing the image by the
%     correction matrix or 'additive' for subtracting the correction matrix from the image.
%
% Returns 
% ------- 
% imCorr : numerical array
%     corrected image
% corr2D : numerical array
%     correction matrix used for correcting the corrupted image
%
%
mtoeppe's avatar
mtoeppe committed
45
46
% Example
% -------
mtoeppe's avatar
mtoeppe committed
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
%
% .. code-block:: matlab
%
%     image = phantom(512);
%     gaussSettings = gaussian;
%     gaussSettings.sigma = 10;
%     stripe = repmat(gaussian(512,gaussSettings),[512 1]);
%     image = image + 0.6*stripe + 0.5*stripe';
%     settings = removeStripes;
%     settings.rangeTop = 1:20;
%     settings.rangeBottom = size(image,1)-20+1:size(image,1);
%     settings.rangeLeft = 1:20;
%     settings.rangeRight = size(image,2)-20+1:size(image,2);
%     settings.direction = 'both';
%     settings.method = 'additive';
%     [imageCorrected,corr2D] = removeStripes(image,settings);
% 
%     subplot(1,3,1)
%     showImage(image)
%     subplot(1,3,2)
%     showImage(imageCorrected)
%     subplot(1,3,3)
%     showImage(corr2D)
    
% HoloTomoToolbox
% Copyright (C) 2019  Institut fuer Roentgenphysik, Universitaet Goettingen
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program.  If not, see <http://www.gnu.org/licenses/>.
Leon Merten Lohse's avatar
Leon Merten Lohse committed
86
87

if nargin<2
mtoeppe's avatar
mtoeppe committed
88
    settings = struct;
Leon Merten Lohse's avatar
Leon Merten Lohse committed
89
90
end

91
92
93
94
95
defaults.rangeTop = [];   
defaults.rangeBottom = [];     
defaults.rangeLeft = [];  
defaults.rangeRight = [];     
defaults.windowSize = 5;     
mtoeppe's avatar
mtoeppe committed
96
97
defaults.direction = 'vertical';      
defaults.method = 'multiplicative';   
Leon Merten Lohse's avatar
Leon Merten Lohse committed
98
99
100

% return default values
if (nargin == 0)
mtoeppe's avatar
mtoeppe committed
101
    imCorr = defaults;
Leon Merten Lohse's avatar
Leon Merten Lohse committed
102
103
104
105
    return
end

% complete settings with default values
mtoeppe's avatar
mtoeppe committed
106
settings = completeStruct(settings,defaults);
Leon Merten Lohse's avatar
Leon Merten Lohse committed
107

108
% set the bottom range to the bottom most 4% pixels for settings.rangeBottom = [] 
mtoeppe's avatar
mtoeppe committed
109
if isempty(settings.rangeBottom)
110
    settings.rangeBottom = size(imToCorr,1)-ceil(size(imToCorr,1)*0.04)+1:size(imToCorr,1);
Leon Merten Lohse's avatar
Leon Merten Lohse committed
111
112
end

113
% set the right range to the right most 4%  pixels for settings.rangeRight = [] 
mtoeppe's avatar
mtoeppe committed
114
if isempty(settings.rangeRight)
115
116
117
118
119
120
121
122
123
124
125
    settings.rangeRight = size(imToCorr,2)-ceil(size(imToCorr,2)*0.04)+1:size(imToCorr,2);
end

% set the bottom range to the bottom most 4% pixels for settings.rangeBottom = [] 
if isempty(settings.rangeTop)
    settings.rangeTop = 1:ceil(size(imToCorr,1)*0.04);
end

% set the right range to the right most 4%  pixels for settings.rangeRight = [] 
if isempty(settings.rangeLeft)
    settings.rangeLeft = 1:ceil(size(imToCorr,2)*0.04);
Leon Merten Lohse's avatar
Leon Merten Lohse committed
126
127
128
129
130
end

% create correction matrix
switch settings.direction
    case 'vertical'
131
        corr2D = removeStripesVertical(imToCorr, settings.rangeTop, settings.rangeBottom, settings.windowSize);
Leon Merten Lohse's avatar
Leon Merten Lohse committed
132
133
        
    case 'horizontal'
134
135
        corr2D = removeStripesVertical(imToCorr.', settings.rangeLeft, settings.rangeRight, settings.windowSize);
        corr2D = corr2D.';
Leon Merten Lohse's avatar
Leon Merten Lohse committed
136
137
138
139
        
    case 'both'
        % create correction matrix for horizontal and vertical
        % direction independently
140
141
        corr2D_vert = removeStripesVertical(imToCorr, settings.rangeTop, settings.rangeBottom, settings.windowSize);
        corr2D_horz = removeStripesVertical(imToCorr.', settings.rangeLeft, settings.rangeRight, settings.windowSize);
Leon Merten Lohse's avatar
Leon Merten Lohse committed
142
143
        
        % create the combined correction matrix by averaging
Leon Merten Lohse's avatar
Leon Merten Lohse committed
144
        corr2D = (corr2D_horz.' + corr2D_vert);
Leon Merten Lohse's avatar
Leon Merten Lohse committed
145
146
147
148
149
end

switch settings.method
    case 'multiplicative'
        % remove stripes by dividing by the correction matrix
150
151
        corr2D = corr2D - mean(corr2D(:)) + 1 ; 
        imCorr = imToCorr ./ corr2D ;
Leon Merten Lohse's avatar
Leon Merten Lohse committed
152
153
    case 'additive'
        % remove stripes by subtracting the correction matrix
154
        corr2D = corr2D - mean(corr2D(:));
Leon Merten Lohse's avatar
Leon Merten Lohse committed
155
156
157
        imCorr = imToCorr - corr2D;
end

Leon Merten Lohse's avatar
Leon Merten Lohse committed
158
159
end

160
161
162



Leon Merten Lohse's avatar
Leon Merten Lohse committed
163
function corr2D = removeStripesVertical(im, rangeTop, rangeBottom, windowSize) 
164
165
166
167
168
169
170
    % average over the specified ranges at the top and bottom of the
    % image
    profTop = mean(im(rangeTop,:),1);
    profTop = movmean(profTop, windowSize);
    
    profBottom = mean(im(rangeBottom,:),1);
    profBottom = movmean(profBottom, windowSize);
Leon Merten Lohse's avatar
Leon Merten Lohse committed
171
    
172
173
    lambda = reshape(linspace(0,1,size(im,1)), [size(im,1), 1] );
    corr2D = (1-lambda) * profTop + lambda * profBottom;
Leon Merten Lohse's avatar
Leon Merten Lohse committed
174
175
end