Source code for pyradar.filters.frost

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Copyright 2012 - 2013
# Matías Herranz <matiasherranz@gmail.com>
# Joaquín Tita <joaquintita@gmail.com>
#
# https://github.com/PyRadar/pyradar
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 3 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see <http://www.gnu.org/licenses/>.


import numpy as np
from scipy.stats import variation

from utils import assert_window_size
from utils import assert_indices_in_range

COEF_VAR_DEFAULT = 0.01


[docs]def compute_coef_var(image, x_start, x_end, y_start, y_end): """ Compute coefficient of variation in a window of [x_start: x_end] and [y_start:y_end] within the image. """ assert x_start >= 0, 'ERROR: x_start must be >= 0.' assert y_start >= 0, 'ERROR: y_start must be >= 0.' x_size, y_size = image.shape x_overflow = x_end > x_size y_overflow = y_end > y_size assert not x_overflow, 'ERROR: invalid parameters cause x window overflow.' assert not y_overflow, 'ERROR: invalid parameters cause y window overflow.' window = image[x_start:x_end, y_start:y_end] coef_var = variation(window, None) if not coef_var: # dirty patch coef_var = COEF_VAR_DEFAULT # print "squared_coef was equal zero but replaced by %s" % coef_var assert coef_var > 0, 'ERROR: coeffient of variation cannot be zero.' return coef_var
[docs]def calculate_all_Mi(window_flat, factor_A, window): """ Compute all the weights of pixels in the window. """ N, M = window.shape center_pixel = np.float64(window[N / 2, M / 2]) window_flat = np.float64(window_flat) distances = np.abs(window_flat - center_pixel) weights = np.exp(-factor_A * distances) return weights
[docs]def calculate_local_weight_matrix(window, factor_A): """ Returns an array with the weights for the pixels in the given window. """ weights_array = np.zeros(window.size) window_flat = window.flatten() weights_array = calculate_all_Mi(window_flat, factor_A, window) return weights_array
[docs]def frost_filter(img, damping_factor=2.0, win_size=3): """ Apply frost filter to a numpy matrix containing the image, with a window of win_size x win_size. By default, the window size is 3x3. """ assert_window_size(win_size) img_filtered = np.zeros_like(img) N, M = img.shape win_offset = win_size / 2 for i in xrange(0, N): xleft = i - win_offset xright = i + win_offset if xleft < 0: xleft = 0 if xright >= N: xright = N - 1 for j in xrange(0, M): yup = j - win_offset ydown = j + win_offset if yup < 0: yup = 0 if ydown >= M: ydown = M - 1 assert_indices_in_range(N, M, xleft, xright, yup, ydown) # inspired by http://www.pcigeomatics.com/cgi-bin/pcihlp/FFROST variation_coef = compute_coef_var(img, xleft, xright, yup, ydown) window = img[xleft:xright, yup:ydown] window_mean = window.mean() sigma_zero = variation_coef / window_mean # var / u^2 factor_A = damping_factor * sigma_zero weights_array = calculate_local_weight_matrix(window, factor_A) pixels_array = window.flatten() weighted_values = weights_array * pixels_array img_filtered[i, j] = weighted_values.sum() / weights_array.sum() return img_filtered
Read the Docs v: latest
Versions
latest
Downloads
PDF
HTML
Epub
On Read the Docs
Project Home
Builds

Free document hosting provided by Read the Docs.