#!/usr/bin/env python
# Copyright (c) 2016, wradlib developers.
# Distributed under the MIT License. See LICENSE.txt for more info.
# 引用wradlib 雷达数据处理库函数- 学习......
"""
Clutter Identification 地物杂波识别
^^^^^^^^^^^^^^^^^^^^^^
.. autosummary::
:nosignatures:
:toctree: generated/
filter_gabella
filter_gabella_a 对应step1
filter_gabella_b 对应step2
"""
import numpy as np
import scipy.ndimage as ndi
from . import dp as dp
from . import util as util
def filter_gabella_a(img, wsize, tr1, cartesian=False, radial=False):
r"""First part of the Gabella filter looking for large reflectivity
gradients.
This function checks for each pixel in `img` how many pixels surrounding
it in a window of `wsize` are by `tr1` smaller than the central pixel.
Parameters
----------
img : array_like
radar image to which the filter is to be applied
wsize : int
Size of the window surrounding the central pixel
tr1 : float
Threshold value = 6dBZ
cartesian : boolean
Specify if the input grid is Cartesian or polar
radial : boolean
Specify if only radial information should be used
Returns
-------
output : array_like
an array with the same shape as `img`, containing the filter's results.
See Also
--------
filter_gabella_b : the second part of the filter
filter_gabella : the complete filter
Examples
--------
See :ref:`notebooks/classify/wradlib_clutter_gabella_example.ipynb`.
"""
nn = wsize // 2
count = -np.ones(img.shape, dtype=int)
range_shift = range(-nn, nn + 1)
azimuth_shift = range(-nn, nn + 1)
if radial:
azimuth_shift = [0]
for sa in azimuth_shift:
refa = np.roll(img, sa, axis=0)
for sr in range_shift:
refr = np.roll(refa, sr, axis=1)
count += (img - refr < tr1)(程序比较差值的美妙之处)
count[:, 0:nn] = wsize ** 2
count[:, -nn:] = wsize ** 2
if cartesian:
count[0:nn, :] = wsize ** 2
count[-nn:, :] = wsize ** 2
return count
def filter_gabella_b(img, thrs=0.):
r"""Second part of the Gabella filter comparing area to circumference of
contiguous echo regions.
Parameters
----------
img : array_like
thrs : float
Threshold below which the field values will be considered as no rain
Returns
-------
output : array_like
contains in each pixel the ratio between area and circumference of the
meteorological echo it is assigned to or 0 for non precipitation
pixels.
See Also
--------
filter_gabella_a : the first part of the filter
filter_gabella : the complete filter
Examples
--------
See :ref:`notebooks/classify/wradlib_clutter_gabella_example.ipynb`.
"""
conn = np.ones((3, 3))
# create binary image of the rainfall field
binimg = img > thrs
# label objects (individual rain cells, so to say)
labelimg, nlabels = ndi.label(binimg, conn)
# erode the image, thus removing the 'boundary pixels'
binimg_erode = ndi.binary_erosion(binimg, structure=conn)
# determine the size of each object
labelhist, edges = np.histogram(labelimg,
bins=nlabels + 1,
range=(-0.5, labelimg.max() + 0.5))
# determine the size of the eroded objects
erodelabelhist, edges = np.histogram(np.where(binimg_erode, labelimg, 0),
bins=nlabels + 1,
range=(-0.5, labelimg.max() + 0.5))
# the boundary is the difference between these two
boundarypixels = labelhist - erodelabelhist
# now get the ratio between object size and boundary
ratio = labelhist.astype(np.float32) / boundarypixels
# assign it back to the objects
# first get the indices
indices = np.digitize(labelimg.ravel(), edges) - 1
# then produce a new field with the ratios in the right place
result = ratio[indices.ravel()].reshape(img.shape)
return result
def filter_gabella(img, wsize=5, thrsnorain=0., tr1=6., n_p=6, tr2=1.3,
rm_nans=True, radial=False, cartesian=False):
r"""Clutter identification filter developed by :cite:`Gabella2002`.
This is a two-part identification algorithm using echo continuity and
minimum echo area to distinguish between meteorological (rain) and non-
meteorological echos (ground clutter etc.)
Parameters
----------
img : array_like
wsize : int
Size of the window surrounding the central pixel
thrsnorain : float
tr1 : float
n_p : int
tr2 : float
rm_nans : boolean
True replaces nans with Inf
False takes nans into acount
radial : boolean
True to use radial information only in filter_gabella_a.
cartesian : boolean
True if cartesian data are used, polar assumed if False.
Returns
-------
output : array
boolean array with pixels identified as clutter set to True.
See Also
--------
filter_gabella_a : the first part of the filter
filter_gabella_b : the second part of the filter
Examples
--------
See :ref:`notebooks/classify/wradlib_clutter_gabella_example.ipynb`.
"""
bad = np.isnan(img)
if rm_nans:
img = img.copy()
img[bad] = np.Inf
ntr1 = filter_gabella_a(img, wsize, tr1, cartesian, radial)
if not rm_nans:
f_good = ndi.filters.uniform_filter((~bad).astype(float), size=wsize)
f_good[f_good == 0] = 1e-10
ntr1 = ntr1 / f_good
ntr1[bad] = n_p
clutter1 = (ntr1 < n_p)
ratio = filter_gabella_b(img, thrsnorain)
clutter2 = (np.abs(ratio) < tr2)
return clutter1 | clutter2
网友评论