-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRemoveXRays.m
More file actions
executable file
·149 lines (130 loc) · 5.27 KB
/
Copy pathRemoveXRays.m
File metadata and controls
executable file
·149 lines (130 loc) · 5.27 KB
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
137
138
139
140
141
142
143
144
145
146
147
148
149
function B = RemoveXRays(varargin)
% function B = RemoveXRays(A)
% B = RemoveXRays(A,'plot')
% B = RemoveXRays(A,'noplot')
% B = RemoveXRays(A,'plot',[offset threshold])
% B = RemoveXRays(A,'noplot',[offset threshold])
%
% Attempts to remove X-rays that hit the CCD from the image A.
% If the optional argument 'plot' is given, a diagnostic plot is generated
% in the current figure.
%
% Algorithm: compare every pixel to the average of a surrounding ring. If
% it exceeds this by a certain threshold, it is considered to be an X-ray.
% In that case, the region is expanded by one pixel in every direction and
% the values are replaced by a smooth function that is determined by
% imposing Laplace f = 0.
%
% This version is optimized for the Princeton 16-bit camera that was used to
% measure the downstream energy spectrum in E-167.
% This camera often shows X-rays that extend over more than one pixel.
%
% 2005-08-31: initial version (Rasmus, with help from Ben, ChrisS & Neil)
switch nargin
case 0, error('usage: B = RemoveXRays(A,''plot'')')
case 1, A = double(varargin{1});
doPlot = 0;
offset = 30; threshold = 1.4;
case 2, A = double(varargin{1});
if strcmp(varargin(2),'plot'), doPlot=1; else doPlot=0; end
offset = 30; threshold = 1.4;
case 3, A = double(varargin{1});
if strcmp(varargin(2),'plot'), doPlot=1; else doPlot=0; end
offset = varargin{3}(1);
threshold = varargin{3}(2);
end
% %% Remove first two columns
% % The two leftmost columns of our "timeint" camera appear to contain
% % garbage.
%
% A = A(:,3:end);
% %% Common mode subtraction
% % the zero of the ADC fluctuates by a few counts for every image.
% % For the validity of the thresholds, this must be removed first.
% % find the maximum of the histogram (assuming our camera has at most 16 bits)
% %[y,x] = hist(A(:),-20:2^16);
% Background = A(1:50,:);
% [y,x] = hist(Background(:),-20:400);
% y = y(2:end-1); x = x(2:end-1); % remove overflow bins
% [m,i] = max(y); i = i(1);
% if i<3, error('The ADC offset appears to be too small'), end
% % we want to have a value with sub-LSB resolution, so we take the weighted
% % average of the top 5 points:
% zero = sum(y(i-2:i+2) .* x(i-2:i+2)) / sum(y(i-2:i+2));
% A = A - zero;
% %% pad the image
% % to avoid X-rays to be detected at the edge of the image, we pad the image
% % with equal values at the edges
% padsize = 3;
% A = padarray(A,[padsize padsize],'replicate');
%% make a smoothed image
% make an image where every pixel is replaced by the average of
% surrounding pixels
ring = [0 0 1 1 1 0 0; ...
0 1 0 0 0 1 0; ...
1 0 0 0 0 0 1; ...
1 0 0 0 0 0 1; ...
1 0 0 0 0 0 1; ...
0 1 0 0 0 1 0; ...
0 0 1 1 1 0 0];
ring = ring / sum(ring(:));
Asmooth = conv2(A, ring, 'same');
% this was the first algorithm, but it was not very successful
%B = A;
%B(XR) = Asmooth(XR);
%% find X-rays
% now, the difficult part is to find the X-rays.
% the following criteria have to be met by this algorithm:
% - the density of X-rays is constant across the regions where ther is beam
% and outside of the beam
% - no part of the beam is removed
% - no X-rays are detected from the noise in the background
% - the end result is somewhat independent of the exact values of arbitrarily
% chosen numbers
% the noise in the background is about 2 ADC counts; for the noise in the
% number of photons, assume something proportional to the number of ADC
% counts
%sigma_bg = 2;
%threshold = 5*sigma_bg + 5*sqrt(abs(Asmooth));
%XR = A > Asmooth + threshold;
% Another way is to find points with a negative Laplacian (more precisely,
% where the relative value of the Laplacian is smaller than a certain threshold
%L = del2(A);
%XR = -L./A > 0.1;
% I have found that a combined relative-absolute criterion with arbitrarily
% choosen offset and threshold works better than the previous idea
XR = (A+offset)./(Asmooth+offset) > threshold;
% I have observed that the X-rays are sometimes a bit larger than what was
% detected using this method. Therefore, I expand the X-Rays by 1 pixel in
% all directions:
SE = strel('square',3);
XR2 = imdilate(XR,SE);
%% eliminate the X-rays
% replace every X-ray by a smooth function.
% This is achieved by finding a function that satisfies
% Laplace f = 0
% inside the eliminated region and is equal to the image outside those
% regions.
% (Ben knows how to do this. Luckily, there is an Image Processing Toolbox
% function that does exactly what we want)
B = roifill(A,XR2);
% %% remove the padded border
% B = B(1+padsize:end-padsize, 1+padsize:end-padsize);
%% plot results
if doPlot
subplot(1,3,1)
% contour(A(1+padsize:end-padsize, 1+padsize:end-padsize),20:20:200)
contour(A,20:20:200)
set(gca,'YDir','reverse'), colorbar, axis image
title('original image')
subplot(1,3,2)
% contour(A(1+padsize:end-padsize, 1+padsize:end-padsize)-B,20:20:200)
contour(A-B,20:20:200)
set(gca,'YDir','reverse'), colorbar, axis image
title('X-Rays')
subplot(1,3,3)
contour(B,20:20:200)
set(gca,'YDir','reverse'), colorbar, axis image
title('cleaned image')
drawnow
end