-
Notifications
You must be signed in to change notification settings - Fork 180
/
EBSDFilling.m
198 lines (142 loc) · 5.52 KB
/
EBSDFilling.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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
%% Fill Missing Data in Orientation Maps
%
% Orientation maps determined by EBSD or any other technique are, as all
% experimental data, effected by measurement errors. Those measurement
% errors can be divided into systematic errors and random errors.
% Systematic errors mostly occur due to a bad calibration of the EBSD
% system and require additional knowledge to be corrected. Deviations from
% the true orientation due to noisy Kikuchi pattern or tolerances of the
% indexing algorithm can be modeled as random errors. In this section we
% demonstrate how random errors can be significantly reduced using
% denoising techniques.
%%
% We shall demonstrate the denoising capabilities of MTEX at the hand of an
% orientation map of deformed Magnesium
% import the data
mtexdata ferrite
% consider only indexed data
ebsd = ebsd('indexed');
% reconstruct the grain structure
[grains,ebsd.grainId,ebsd.mis2mean] = calcGrains(ebsd,'angle',10*degree);
% remove some very small grains
ebsd(grains(grains.grainSize<5)) = [];
% redo grain segmentation
[grains,ebsd.grainId] = calcGrains(ebsd,'angle',10*degree);
% smooth grain boundaries
grains = smooth(grains,5);
% plot the orientation map
plot(ebsd,ebsd.orientations)
% and on top the grain boundaries
hold on
plot(grains.boundary,'linewidth',1.5)
hold off
%% A Very Sparse Measured Data Set
%
% Although the data set has already some not indexed pixels we artificially
% make the situation more worse by throwing away 75 percent of all data.
ebsdSub = ebsd(discretesample(length(ebsd),round(length(ebsd)*25/100)));
% plot the reduced data
plot(ebsdSub,ebsdSub.orientations)
%%
% Our aim is now to recover the orginal orientation map. In a first step we
% reconstruct the grain structure from the remaining 25 percent of pixels.
% reconstruct the grain structure
[grainsSub,ebsdSub.grainId] = calcGrains(ebsdSub,'angle',10*degree);
grainsSub = smooth(grainsSub,5);
hold on
plot(grainsSub.boundary,'linewidth',1.5)
hold off
%%
% The easiest way to reconstruct missing data is to use the command
% <EBSD.fill.html fill> which interpolates missing data using the method of
% nearest neighbor. It is very recommended to pass the grain structure
% |grainsSub| as an additional argument to the |fill| function. In this
% case the nearest neighbors are choosen within the grains.
ebsdSub_filled = fill(ebsdSub,grainsSub);
plot(ebsdSub_filled('indexed'),ebsdSub_filled('indexed').orientations);
hold on
plot(grainsSub.boundary,'linewidth',1.5)
hold off
%%
% A much more powerful method is to use any denoising method and set the
% option |fill|.
F = halfQuadraticFilter;
F.alpha = 0.25;
% interpolate the missing data
ebsdSub_filled = smooth(ebsdSub,F,'fill',grainsSub);
ebsdSub_filled = ebsdSub_filled('indexed');
plot(ebsdSub_filled('indexed'),ebsdSub_filled('indexed').orientations);
hold on
plot(grainsSub.boundary,'linewidth',1.5)
hold off
%% An Example from Geoscience
%
% Data sets with many missing pixels most often appear when measuring
% geological samples. The following data set of forsterite contains about
% 25 percent missing pixels. Lets start by importing the data and
% reconstructing the grain structure.
close all; plotx2east
mtexdata forsterite
ebsd = ebsd(inpolygon(ebsd,[10 4 5 3]*10^3));
plot(ebsd('Fo'),ebsd('Fo').orientations)
hold on
plot(ebsd('En'),ebsd('En').orientations)
plot(ebsd('Di'),ebsd('Di').orientations)
% compute grains
[grains,ebsd.grainId] = calcGrains(ebsd('indexed'),'angle',10*degree);
% remove small grains
ebsd(grains(grains.grainSize < 3)) = [];
% and repeat the grain computation
[grains,ebsd.grainId] = calcGrains(ebsd('indexed'),'angle',10*degree);
%
grains = smooth(grains,5);
% plot the boundary of all grains
plot(grains.boundary,'linewidth',2)
hold off
%%
% Using the option |fill| the command |smooth| fills the holes inside the
% grains. Note that the nonindexed pixels at the grain boundaries are kept
% untouched. In order to allow MTEX to decide whether a pixel is inside a
% grain or not, the |grain| variable has to be passed as an additional
% argument.
F = halfQuadraticFilter;
F.alpha = 10;
ebsdS = smooth(ebsd('indexed'),F,'fill',grains);
plot(ebsdS('Fo'),ebsdS('Fo').orientations)
hold on
plot(ebsdS('En'),ebsdS('En').orientations)
plot(ebsdS('Di'),ebsdS('Di').orientations)
% plot the boundary of all grains
plot(grains.boundary,'linewidth',1.5)
% stop overide mode
hold off
%%
% In order to visualize the orientation gradient within the grains, we plot
% the misorientation to the meanorientation. We observe that the mis2mean
% varies smoothly also within the regions of not indexed orientations.
% plot mis2mean for all phases
ipfKey = axisAngleColorKey(ebsdS('Fo'));
ipfKey.oriRef = grains(ebsdS('fo').grainId).meanOrientation;
ipfKey.maxAngle = 2.5*degree;
color = ipfKey.orientation2color(ebsdS('Fo').orientations);
plot(ebsdS('Fo'),color,'micronbar','off')
hold on
ipfKey.oriRef = grains(ebsdS('En').grainId).meanOrientation;
plot(ebsdS('En'),ipfKey.orientation2color(ebsdS('En').orientations))
% plot boundary
plot(grains.boundary,'linewidth',4)
plot(grains('En').boundary,'lineWidth',4,'lineColor','r')
hold off
%%
% For comparison
ipfKey.oriRef = grains(ebsd('fo').grainId).meanOrientation;
ipfKey.maxAngle = 2.5*degree;
color = ipfKey.orientation2color(ebsd('Fo').orientations);
plot(ebsd('Fo'),color,'micronbar','off')
hold on
ipfKey.oriRef = grains(ebsd('En').grainId).meanOrientation;
plot(ebsd('En'),ipfKey.orientation2color(ebsd('En').orientations))
% plot boundary
plot(grains.boundary,'linewidth',4)
plot(grains('En').boundary,'lineWidth',4,'lineColor','r')
hold off