|
| 1 | +# -*- coding: utf-8 -*- |
1 | 2 | """ |
2 | 3 | Handling of no-data in Lucas-Kanade |
3 | 4 | =================================== |
4 | 5 |
|
5 | 6 | Areas of missing data in radar images are typically caused by visibility limits |
6 | | -such as beam blockage and the radar coverage itself. These artifacts can mislead |
| 7 | +such as beam blockage and the radar coverage itself. These artifacts can mislead |
7 | 8 | the echo tracking algorithms. For instance, precipitation leaving the domain |
8 | 9 | might be erroneously detected as having nearly stationary velocity. |
9 | 10 |
|
10 | | -This example shows how the Lucas-Kanade algorithm can be tuned to avoid the |
11 | | -erroneous interpretation of velocities near the maximum range of the radars by |
12 | | -buffering the no-data mask in the radar image in order to exclude all vectors |
| 11 | +This example shows how the Lucas-Kanade algorithm can be tuned to avoid the |
| 12 | +erroneous interpretation of velocities near the maximum range of the radars by |
| 13 | +buffering the no-data mask in the radar image in order to exclude all vectors |
13 | 14 | detected nearby no-data areas. |
14 | 15 | """ |
15 | 16 |
|
|
71 | 72 | mask[~np.isnan(ref_mm)] = np.nan |
72 | 73 |
|
73 | 74 | # Log-transform the data [dBR] |
74 | | -R, metadata = transformation.dB_transform(R, metadata, threshold=0.1, zerovalue=-15.0) |
| 75 | +R, metadata = transformation.dB_transform( |
| 76 | + R, metadata, threshold=0.1, zerovalue=-15.0 |
| 77 | +) |
75 | 78 |
|
76 | 79 | # Keep the reference frame in dBR (for plotting purposes) |
77 | 80 | ref_dbr = R[0].copy() |
|
109 | 112 | R.data[R.mask] = np.nan |
110 | 113 |
|
111 | 114 | # Use default settings (i.e., no buffering of the radar mask) |
112 | | -x, y, u, v = LK_optflow(R, dense=False, buffer_mask=0, quality_level_ST=0.1) |
| 115 | +fd_kwargs1 = {"buffer_mask":0} |
| 116 | +xy, uv = LK_optflow(R, dense=False, fd_kwargs=fd_kwargs1) |
113 | 117 | plt.imshow(ref_dbr, cmap=plt.get_cmap("Greys")) |
114 | 118 | plt.imshow(mask, cmap=colors.ListedColormap(["black"]), alpha=0.5) |
115 | | -plt.quiver(x, y, u, v, color="red", angles="xy", scale_units="xy", scale=0.2) |
| 119 | +plt.quiver( |
| 120 | + xy[:, 0], |
| 121 | + xy[:, 1], |
| 122 | + uv[:, 0], |
| 123 | + uv[:, 1], |
| 124 | + color="red", |
| 125 | + angles="xy", |
| 126 | + scale_units="xy", |
| 127 | + scale=0.2, |
| 128 | +) |
116 | 129 | circle = plt.Circle((620, 245), 100, color="b", clip_on=False, fill=False) |
117 | 130 | plt.gca().add_artist(circle) |
118 | 131 | plt.title("buffer_mask = 0 (default)") |
|
129 | 142 | # 'x,y,u,v = LK_optflow(.....)'. |
130 | 143 |
|
131 | 144 | # with buffer |
132 | | -x, y, u, v = LK_optflow(R, dense=False, buffer_mask=20, quality_level_ST=0.2) |
| 145 | +buffer = 10 |
| 146 | +fd_kwargs2 = {"buffer_mask":buffer} |
| 147 | +xy, uv = LK_optflow(R, dense=False, fd_kwargs=fd_kwargs2) |
133 | 148 | plt.imshow(ref_dbr, cmap=plt.get_cmap("Greys")) |
134 | 149 | plt.imshow(mask, cmap=colors.ListedColormap(["black"]), alpha=0.5) |
135 | | -plt.quiver(x, y, u, v, color="red", angles="xy", scale_units="xy", scale=0.2) |
| 150 | +plt.quiver( |
| 151 | + xy[:, 0], |
| 152 | + xy[:, 1], |
| 153 | + uv[:, 0], |
| 154 | + uv[:, 1], |
| 155 | + color="red", |
| 156 | + angles="xy", |
| 157 | + scale_units="xy", |
| 158 | + scale=0.2, |
| 159 | +) |
136 | 160 | circle = plt.Circle((620, 245), 100, color="b", clip_on=False, fill=False) |
137 | 161 | plt.gca().add_artist(circle) |
138 | | -plt.title("buffer_mask = 20") |
| 162 | +plt.title("buffer_mask = %i" % buffer) |
139 | 163 | plt.show() |
140 | 164 |
|
141 | 165 | ################################################################################ |
|
148 | 172 | # the negative bias that is introduced by the the erroneous interpretation of |
149 | 173 | # velocities near the maximum range of the radars. |
150 | 174 |
|
151 | | -UV1 = LK_optflow(R, dense=True, buffer_mask=0, quality_level_ST=0.1) |
152 | | -UV2 = LK_optflow(R, dense=True, buffer_mask=20, quality_level_ST=0.2) |
| 175 | +UV1 = LK_optflow(R, dense=True, fd_kwargs=fd_kwargs1) |
| 176 | +UV2 = LK_optflow(R, dense=True, fd_kwargs=fd_kwargs2) |
153 | 177 |
|
154 | 178 | V1 = np.sqrt(UV1[0] ** 2 + UV1[1] ** 2) |
155 | 179 | V2 = np.sqrt(UV2[0] ** 2 + UV2[1] ** 2) |
156 | 180 |
|
157 | | -plt.imshow((V1 - V2) / V2, cmap=cm.RdBu_r, vmin=-0.1, vmax=0.1) |
| 181 | +plt.imshow((V1 - V2) / V2, cmap=cm.RdBu_r, vmin=-0.5, vmax=0.5) |
158 | 182 | plt.colorbar(fraction=0.04, pad=0.04) |
159 | 183 | plt.title("Relative difference in motion speed") |
160 | 184 | plt.show() |
|
184 | 208 |
|
185 | 209 | # Find the veriyfing observations in the archive |
186 | 210 | fns = io.archive.find_by_date( |
187 | | - date, root_path, path_fmt, fn_pattern, fn_ext, timestep=5, num_next_files=12 |
| 211 | + date, |
| 212 | + root_path, |
| 213 | + path_fmt, |
| 214 | + fn_pattern, |
| 215 | + fn_ext, |
| 216 | + timestep=5, |
| 217 | + num_next_files=12, |
188 | 218 | ) |
189 | 219 |
|
190 | 220 | # Read and convert the radar composites |
|
200 | 230 | score_2.append(skill(R_f2[i, :, :], R_o[i + 1, :, :])["corr_s"]) |
201 | 231 |
|
202 | 232 | x = (np.arange(12) + 1) * 5 # [min] |
203 | | -plt.plot(x, score_1, label="no mask buffer") |
204 | | -plt.plot(x, score_2, label="with mask buffer") |
| 233 | +plt.plot(x, score_1, label="buffer_mask = 0") |
| 234 | +plt.plot(x, score_2, label="buffer_mask = %i" % buffer) |
205 | 235 | plt.legend() |
206 | 236 | plt.xlabel("Lead time [min]") |
207 | 237 | plt.ylabel("Corr. coeff. []") |
|
0 commit comments