quant1x 0.2.5__tar.gz → 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. {quant1x-0.2.5 → quant1x-0.3.0}/PKG-INFO +1 -1
  2. {quant1x-0.2.5 → quant1x-0.3.0}/quant1x/__init__.py +1 -1
  3. quant1x-0.3.0/quant1x/data/futu-basicinfo.py +27 -0
  4. quant1x-0.3.0/quant1x/findpeaks/__init__.py +13 -0
  5. quant1x-0.3.0/quant1x/findpeaks/filters/__init__.py +0 -0
  6. quant1x-0.3.0/quant1x/findpeaks/filters/frost.py +168 -0
  7. quant1x-0.3.0/quant1x/findpeaks/filters/kuan.py +139 -0
  8. quant1x-0.3.0/quant1x/findpeaks/filters/lee.py +147 -0
  9. quant1x-0.3.0/quant1x/findpeaks/filters/lee_enhanced.py +163 -0
  10. quant1x-0.3.0/quant1x/findpeaks/filters/mean.py +122 -0
  11. quant1x-0.3.0/quant1x/findpeaks/filters/median.py +103 -0
  12. quant1x-0.3.0/quant1x/findpeaks/findpeaks.py +1253 -0
  13. quant1x-0.3.0/quant1x/findpeaks/interpolate.py +194 -0
  14. quant1x-0.3.0/quant1x/findpeaks/stats.py +593 -0
  15. quant1x-0.3.0/quant1x/findpeaks/union_find.py +73 -0
  16. {quant1x-0.2.5 → quant1x-0.3.0}/quant1x.egg-info/PKG-INFO +1 -1
  17. {quant1x-0.2.5 → quant1x-0.3.0}/quant1x.egg-info/SOURCES.txt +13 -0
  18. {quant1x-0.2.5 → quant1x-0.3.0}/LICENSE +0 -0
  19. {quant1x-0.2.5 → quant1x-0.3.0}/README.rst +0 -0
  20. {quant1x-0.2.5 → quant1x-0.3.0}/quant1x/base/__init__.py +0 -0
  21. {quant1x-0.2.5 → quant1x-0.3.0}/quant1x/base/basic.py +0 -0
  22. {quant1x-0.2.5 → quant1x-0.3.0}/quant1x/base/formula.py +0 -0
  23. {quant1x-0.2.5 → quant1x-0.3.0}/quant1x/base/formula_plus.py +0 -0
  24. {quant1x-0.2.5 → quant1x-0.3.0}/quant1x/base/series.py +0 -0
  25. {quant1x-0.2.5 → quant1x-0.3.0}/quant1x/data/__init__.py +0 -0
  26. {quant1x-0.2.5 → quant1x-0.3.0}/quant1x/data/quotes.py +0 -0
  27. {quant1x-0.2.5 → quant1x-0.3.0}/quant1x/formula/__init__.py +0 -0
  28. {quant1x-0.2.5 → quant1x-0.3.0}/quant1x/indicator/__init__.py +0 -0
  29. {quant1x-0.2.5 → quant1x-0.3.0}/quant1x/indicator/ma1x.py +0 -0
  30. {quant1x-0.2.5 → quant1x-0.3.0}/quant1x/strategy/__init__.py +0 -0
  31. {quant1x-0.2.5 → quant1x-0.3.0}/quant1x/strategy/bad_base.py +0 -0
  32. {quant1x-0.2.5 → quant1x-0.3.0}/quant1x/strategy/linear_regression.py +0 -0
  33. {quant1x-0.2.5 → quant1x-0.3.0}/quant1x/util/__init__.py +0 -0
  34. {quant1x-0.2.5 → quant1x-0.3.0}/quant1x/util/font.py +0 -0
  35. {quant1x-0.2.5 → quant1x-0.3.0}/quant1x.egg-info/dependency_links.txt +0 -0
  36. {quant1x-0.2.5 → quant1x-0.3.0}/quant1x.egg-info/entry_points.txt +0 -0
  37. {quant1x-0.2.5 → quant1x-0.3.0}/quant1x.egg-info/not-zip-safe +0 -0
  38. {quant1x-0.2.5 → quant1x-0.3.0}/quant1x.egg-info/requires.txt +0 -0
  39. {quant1x-0.2.5 → quant1x-0.3.0}/quant1x.egg-info/top_level.txt +0 -0
  40. {quant1x-0.2.5 → quant1x-0.3.0}/setup.cfg +0 -0
  41. {quant1x-0.2.5 → quant1x-0.3.0}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: quant1x
3
- Version: 0.2.5
3
+ Version: 0.3.0
4
4
  Summary: Quant1X量化交易框架
5
5
  Home-page: https://gitee.com/quant1x/89k
6
6
  Author: WangFeng
@@ -5,7 +5,7 @@
5
5
  89K 努力打造一个适度的量化交易框架
6
6
  """
7
7
 
8
- __version__ = "0.2.5"
8
+ __version__ = "0.3.0"
9
9
  __author__ = "WangFeng"
10
10
 
11
11
  import sys
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/python
2
+ # -*- coding: UTF-8 -*-
3
+ """
4
+ 证券基本信息
5
+ """
6
+ from futu import *
7
+
8
+ quote_ctx = OpenQuoteContext(host='127.0.0.1', port=11111)
9
+ print('******************************************')
10
+ ret, data = quote_ctx.get_stock_basicinfo(Market.SH, SecurityType.STOCK)
11
+ if ret == RET_OK:
12
+ data.to_csv('sh.csv', index=False)
13
+ else:
14
+ print('error:', data)
15
+ print('******************************************')
16
+ ret, data = quote_ctx.get_stock_basicinfo(Market.SZ, SecurityType.STOCK)
17
+ if ret == RET_OK:
18
+ data.to_csv('sz.csv', index=False)
19
+ else:
20
+ print('error:', data)
21
+ ret, data = quote_ctx.get_stock_basicinfo(Market.HK, SecurityType.STOCK)
22
+ if ret == RET_OK:
23
+ data.to_csv('hk.csv', index=False)
24
+ else:
25
+ print('error:', data)
26
+
27
+ quote_ctx.close() # 结束后记得关闭当条连接,防止连接条数用尽
@@ -0,0 +1,13 @@
1
+ from quant1x.findpeaks.filters.frost import frost_filter
2
+ from quant1x.findpeaks.filters.kuan import kuan_filter
3
+ # Import the denosing filters
4
+ from quant1x.findpeaks.filters.lee import lee_filter
5
+ from quant1x.findpeaks.filters.lee_enhanced import lee_enhanced_filter
6
+ from quant1x.findpeaks.filters.mean import mean_filter
7
+ from quant1x.findpeaks.filters.median import median_filter
8
+ from quant1x.findpeaks.findpeaks import findpeaks
9
+ from quant1x.findpeaks.findpeaks import (
10
+ import_example,
11
+ stats,
12
+ interpolate,
13
+ )
File without changes
@@ -0,0 +1,168 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+
4
+ # Copyright 2012 - 2013
5
+ # Matías Herranz <matiasherranz@gmail.com>
6
+ # Joaquín Tita <joaquintita@gmail.com>
7
+ # https://github.com/PyRadar/pyradar
8
+ #
9
+ # 2020: Erdogan Taskesen: <erdogant@gmail.com> Converted to python3.
10
+ #
11
+ # This library is free software; you can redistribute it and/or
12
+ # modify it under the terms of the GNU Lesser General Public
13
+ # License as published by the Free Software Foundation; either
14
+ # version 3 of the License, or (at your option) any later version.
15
+ #
16
+ # This library is distributed in the hope that it will be useful,
17
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ # Lesser General Public License for more details.
20
+ #
21
+ # You should have received a copy of the GNU Lesser General Public
22
+ # License along with this library. If not, see <http://www.gnu.org/licenses/>.
23
+
24
+
25
+ import numpy as np
26
+ from scipy.stats import variation
27
+
28
+
29
+ def compute_coef_var(image, x_start, x_end, y_start, y_end):
30
+ """
31
+ Compute coefficient of variation in a window of [x_start: x_end] and
32
+ [y_start:y_end] within the image.
33
+ """
34
+ if x_start < 0: raise Exception('ERROR: x_start must be >= 0.')
35
+ if y_start < 0: raise Exception('ERROR: y_start must be >= 0.')
36
+
37
+ x_size, y_size = image.shape
38
+ x_overflow = x_end > x_size
39
+ y_overflow = y_end > y_size
40
+
41
+ if x_overflow: raise Exception('ERROR: invalid parameters cause x window overflow.')
42
+ if y_overflow: raise Exception('ERROR: invalid parameters cause y window overflow.')
43
+
44
+ window = image[x_start:x_end, y_start:y_end]
45
+
46
+ coef_var = variation(window, None)
47
+
48
+ if not coef_var: # dirty patch
49
+ coef_var = 0.01
50
+ # print "squared_coef was equal zero but replaced by %s" % coef_var
51
+ if coef_var <= 0: raise Exception('ERROR: coeffient of variation cannot be zero.')
52
+
53
+ return coef_var
54
+
55
+
56
+ def calculate_all_Mi(window_flat, factor_A, window):
57
+ """
58
+ Compute all the weights of pixels in the window.
59
+ """
60
+ N, M = window.shape
61
+ center_pixel = np.float64(window[int(N / 2), int(M / 2)])
62
+ window_flat = np.float64(window_flat)
63
+
64
+ distances = np.abs(window_flat - center_pixel)
65
+
66
+ weights = np.exp(-factor_A * distances)
67
+
68
+ return weights
69
+
70
+
71
+ def calculate_local_weight_matrix(window, factor_A):
72
+ """
73
+ Returns an array with the weights for the pixels in the given window.
74
+ """
75
+ weights_array = np.zeros(window.size)
76
+ window_flat = window.flatten()
77
+
78
+ weights_array = calculate_all_Mi(window_flat, factor_A, window)
79
+
80
+ return weights_array
81
+
82
+
83
+ def frost_filter(img, damping_factor=2.0, win_size=3):
84
+ """Frost filter.
85
+
86
+ Description
87
+ -----------
88
+ 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.
89
+
90
+ Parameters
91
+ ----------
92
+ img : array-like
93
+ Input image.
94
+ damping_factor : float (default: 2.0)
95
+ Damping factor.
96
+ win_size : int, int (default: 3)
97
+ Window size.
98
+
99
+ Returns
100
+ -------
101
+ img_filtered : array-like
102
+ Filtered image.
103
+
104
+ Examples
105
+ --------
106
+ >>> import findpeaks
107
+ >>> import matplotlib.pyplot as plt
108
+ >>> img = findpeaks.import_example('2dpeaks_image')
109
+ >>> # Resize
110
+ >>> img = findpeaks.stats.resize(img, size=(300,300))
111
+ >>> # Make grey image
112
+ >>> img = findpeaks.stats.togray(img)
113
+ >>> # Scale between [0-255]
114
+ >>> img = findpeaks.stats.scale(img)
115
+ >>> # frost filter
116
+ >>> img_filtered = findpeaks.stats.frost_filter(img.copy(), damping_factor=2, win_size=15)
117
+ >>>
118
+ >>> plt.figure()
119
+ >>> fig, axs = plt.subplots(1,2)
120
+ >>> axs[0].imshow(img, cmap='gray'); axs[0].set_title('Input')
121
+ >>> axs[1].imshow(img_filtered, cmap='gray'); axs[1].set_title('Frost filter')
122
+
123
+ """
124
+ if win_size < 3: raise Exception('[findpeaks] >ERROR: win size must be at least 3')
125
+ if len(img.shape) > 2: raise Exception(
126
+ '[findpeaks] >ERROR: Image should be 2D. Hint: set the parameter: togray=True')
127
+ if ((win_size % 2) == 0): print(
128
+ '[findpeaks] >It is highly recommended to user odd window sizes. You provided %s, an even number.' % (win_size))
129
+
130
+ img_filtered = np.zeros_like(img)
131
+ N, M = img.shape
132
+ win_offset = int(win_size / 2)
133
+
134
+ for i in np.arange(0, N):
135
+ xleft = i - win_offset
136
+ xright = i + win_offset
137
+ if xleft < 0:
138
+ xleft = 0
139
+ if xright >= N:
140
+ xright = N - 1
141
+ for j in np.arange(0, M):
142
+ yup = j - win_offset
143
+ ydown = j + win_offset
144
+ if yup < 0:
145
+ yup = 0
146
+ if ydown >= M:
147
+ ydown = M - 1
148
+
149
+ # inspired by http://www.pcigeomatics.com/cgi-bin/pcihlp/FFROST
150
+ variation_coef = compute_coef_var(img, xleft, xright, yup, ydown)
151
+ window = img[xleft:xright, yup:ydown]
152
+ window_mean = window.mean()
153
+ sigma_zero = variation_coef / window_mean # var / u^2
154
+ factor_A = damping_factor * sigma_zero
155
+
156
+ weights_array = calculate_local_weight_matrix(window, factor_A)
157
+ pixels_array = window.flatten()
158
+
159
+ weighted_values = weights_array * pixels_array
160
+
161
+ new_pix_value = weighted_values.sum() / weights_array.sum()
162
+
163
+ if (new_pix_value is None) or np.isnan(new_pix_value):
164
+ new_pix_value = 0
165
+
166
+ img_filtered[i, j] = new_pix_value
167
+
168
+ return img_filtered
@@ -0,0 +1,139 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+
4
+ # Copyright 2012 - 2013
5
+ # Matías Herranz <matiasherranz@gmail.com>
6
+ # Joaquín Tita <joaquintita@gmail.com>
7
+ # https://github.com/PyRadar/pyradar
8
+ #
9
+ # 2020: Erdogan Taskesen: <erdogant@gmail.com> Converted to python3.
10
+ #
11
+ # This library is free software; you can redistribute it and/or
12
+ # modify it under the terms of the GNU Lesser General Public
13
+ # License as published by the Free Software Foundation; either
14
+ # version 3 of the License, or (at your option) any later version.
15
+ #
16
+ # This library is distributed in the hope that it will be useful,
17
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ # Lesser General Public License for more details.
20
+ #
21
+ # You should have received a copy of the GNU Lesser General Public
22
+ # License along with this library. If not, see <http://www.gnu.org/licenses/>.
23
+
24
+
25
+ import numpy as np
26
+ from scipy.stats import variation
27
+
28
+
29
+ def weighting(window, cu=0.25):
30
+ """
31
+ Computes the weighthing function for Kuan filter using cu as the noise
32
+ coefficient.
33
+ """
34
+ two_cu = cu * cu
35
+
36
+ ci = variation(window, None)
37
+ two_ci = ci * ci
38
+
39
+ if not two_ci: # dirty patch to avoid zero division
40
+ two_ci = 0.01
41
+
42
+ divisor = 1.0 + two_cu
43
+
44
+ if not divisor:
45
+ divisor = 0.0001
46
+
47
+ if cu > ci:
48
+ w_t = 0.0
49
+ else:
50
+ w_t = (1.0 - (two_cu / two_ci)) / divisor
51
+
52
+ return w_t
53
+
54
+
55
+ def kuan_filter(img, win_size=3, cu=0.25):
56
+ """Kuan filter.
57
+
58
+ Description
59
+ -----------
60
+ Apply kuan to a numpy matrix containing the image, with a window of win_size x win_size.
61
+
62
+ Parameters
63
+ ----------
64
+ img : array-like
65
+ Input image.
66
+ win_size : int, int (default: 3)
67
+ Window size.
68
+ cu : float (default: 0.25)
69
+ cu factor.
70
+
71
+ Returns
72
+ -------
73
+ img_filtered : array-like
74
+ Filtered image.
75
+
76
+ Examples
77
+ --------
78
+ >>> import findpeaks
79
+ >>> import matplotlib.pyplot as plt
80
+ >>> img = findpeaks.import_example('2dpeaks_image')
81
+ >>> # Resize
82
+ >>> img = findpeaks.stats.resize(img, size=(300,300))
83
+ >>> # Make grey image
84
+ >>> img = findpeaks.stats.togray(img)
85
+ >>> # Scale between [0-255]
86
+ >>> img = findpeaks.stats.scale(img)
87
+ >>> # Filter
88
+ >>> img_filtered = findpeaks.stats.kuan_filter(img.copy(), win_size=15, cu=0.25)
89
+ >>>
90
+ >>> plt.figure()
91
+ >>> fig, axs = plt.subplots(1,2)
92
+ >>> axs[0].imshow(img, cmap='gray'); axs[0].set_title('Input')
93
+ >>> axs[1].imshow(img_filtered, cmap='gray'); axs[1].set_title('Kuan filter')
94
+
95
+ """
96
+ if win_size < 3: raise Exception('[findpeaks] >ERROR: win size must be at least 3')
97
+ if len(img.shape) > 2: raise Exception(
98
+ '[findpeaks] >ERROR: Image should be 2D. Hint: set the parameter: togray=True')
99
+ if ((win_size % 2) == 0): print(
100
+ '[findpeaks] >It is highly recommended to user odd window sizes. You provided %s, an even number.' % (win_size))
101
+
102
+ # we process the entire img as float64 to avoid type overflow error
103
+ img = np.float64(img)
104
+ img_filtered = np.zeros_like(img)
105
+
106
+ N, M = img.shape
107
+ # win_offset = win_size / 2
108
+ win_offset = int(win_size / 2)
109
+
110
+ for i in np.arange(0, N):
111
+ xleft = i - win_offset
112
+ xright = i + win_offset
113
+
114
+ if xleft < 0:
115
+ xleft = 0
116
+ if xright >= N:
117
+ xright = N
118
+
119
+ for j in np.arange(0, M):
120
+ yup = j - win_offset
121
+ ydown = j + win_offset
122
+
123
+ if yup < 0:
124
+ yup = 0
125
+ if ydown >= M:
126
+ ydown = M
127
+
128
+ pix_value = img[i, j]
129
+ window = img[xleft:xright, yup:ydown]
130
+ w_t = weighting(window, cu)
131
+ window_mean = window.mean()
132
+ new_pix_value = (pix_value * w_t) + (window_mean * (1.0 - w_t))
133
+
134
+ if (new_pix_value is None) or np.isnan(new_pix_value):
135
+ new_pix_value = 0
136
+
137
+ img_filtered[i, j] = round(new_pix_value)
138
+
139
+ return img_filtered
@@ -0,0 +1,147 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+
4
+ # Copyright 2012 - 2013
5
+ # Matías Herranz <matiasherranz@gmail.com>
6
+ # Joaquín Tita <joaquintita@gmail.com>
7
+ # https://github.com/PyRadar/pyradar
8
+ #
9
+ # 2020: Erdogan Taskesen: <erdogant@gmail.com> Converted to python3.
10
+ #
11
+ # This library is free software; you can redistribute it and/or
12
+ # modify it under the terms of the GNU Lesser General Public
13
+ # License as published by the Free Software Foundation; either
14
+ # version 3 of the License, or (at your option) any later version.
15
+ #
16
+ # This library is distributed in the hope that it will be useful,
17
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ # Lesser General Public License for more details.
20
+ #
21
+ # You should have received a copy of the GNU Lesser General Public
22
+ # License along with this library. If not, see <http://www.gnu.org/licenses/>.
23
+
24
+
25
+ import numpy as np
26
+
27
+
28
+ def _weighting(window, cu=0.25):
29
+ """
30
+ Computes the weighthing function for Lee filter using cu as the noise
31
+ coefficient.
32
+ """
33
+ # cu is the noise variation coefficient
34
+ two_cu = cu * cu
35
+
36
+ # ci is the variation coefficient in the window
37
+ window_mean = window.mean()
38
+ window_std = window.std()
39
+ ci = window_std / window_mean
40
+
41
+ two_ci = ci * ci
42
+
43
+ if not two_ci: # dirty patch to avoid zero division
44
+ two_ci = 0.01
45
+
46
+ if cu > ci: # preserve the original value (I guess)
47
+ w_t = 0.0
48
+ else: # use the filter
49
+ w_t = 1.0 - (two_cu / two_ci)
50
+
51
+ return w_t
52
+
53
+
54
+ def lee_filter(img, win_size=3, cu=0.25):
55
+ """Lee filter.
56
+
57
+ Description
58
+ -----------
59
+ The Additive Noise Lee Despeckling Filter.
60
+ Apply lee to a numpy matrix containing the image, with a window of win_size x win_size.
61
+ Let's assume that the despeckling noise is additive with a constant mean of zero, a constant variance, and drawn from a Gaussian distribution. Use a window (I x J pixels) to scan the image with a stride of 1 pixels (and I will use reflective boundary conditions). The despeckled value of the pixel in the center of the window located in the ith row and jth column is, zhat_ij = mu_k + W*(z_ij = mu_z), where mu_k is the mean value of all pixels in the window centered on pixel i,j, z_ij is the unfiltered value of the pixel, and W is a weight calculated as, W = var_k / (var_k + var_noise), where var_k is the variance of all pixels in the window and var_noise is the variance of the speckle noise. A possible alternative to using the actual value of the center pixel for z_ij is to use the median pixel value in the window.
62
+ The parameters of the filter are the window/kernel size and the variance of the noise (which is unknown but can perhaps be estimated from the image as the variance over a uniform feature smooth like the surface of still water). Using a larger window size and noise variance will increase radiometric resolution at the expense of spatial resolution.
63
+ For more info on the Lee Filter and other despeckling filters see http://desktop.arcgis.com/en/arcmap/10.3/manage-data/raster-and-images/speckle-function.htm
64
+ Assumes noise mean = 0
65
+ If you don't want the window to be a square of size x size, just replace uniform_filter with something else (convolution with a disk, gaussian filter, etc). Any type of (weighted) averaging filter will do, as long as it is the same for calculating both img_mean and img_square_mean.
66
+ The Lee filter seems rather old-fashioned as a filter. It won't behave well at edges because for any window that has an edge in it, the variance is going to be much higher than the overall image variance, and therefore the weights (of the unfiltered image relative to the filtered image) are going to be close to 1.
67
+
68
+ Parameters
69
+ ----------
70
+ img : array-like
71
+ Input image.
72
+ win_size : int, int (default: 3)
73
+ Window size.
74
+ cu : float (default: 0.25)
75
+ cu factor.
76
+
77
+ Returns
78
+ -------
79
+ img_filtered : array-like
80
+ Filtered image.
81
+
82
+ Examples
83
+ --------
84
+ >>> import findpeaks
85
+ >>> import matplotlib.pyplot as plt
86
+ >>> img = findpeaks.import_example('2dpeaks_image')
87
+ >>> # Resize
88
+ >>> img = findpeaks.stats.resize(img, size=(300,300))
89
+ >>> # Make grey image
90
+ >>> img = findpeaks.stats.togray(img)
91
+ >>> # Scale between [0-255]
92
+ >>> img = findpeaks.stats.scale(img)
93
+ >>> # Filter
94
+ >>> img_filtered = findpeaks.stats.lee_filter(img.copy(), win_size=15, cu=0.25)
95
+ >>>
96
+ >>> plt.figure()
97
+ >>> fig, axs = plt.subplots(1,2)
98
+ >>> axs[0].imshow(img, cmap='gray'); axs[0].set_title('Input')
99
+ >>> axs[1].imshow(img_filtered, cmap='gray'); axs[1].set_title('Lee filter')
100
+
101
+ """
102
+ if win_size < 3: raise Exception('[findpeaks] >ERROR: window size (win_size) must be at least 3')
103
+ if len(img.shape) > 2: raise Exception(
104
+ '[findpeaks] >ERROR: Image should be 2D. Hint: set the parameter: togray=True')
105
+ if ((win_size % 2) == 0): print(
106
+ '[findpeaks] >It is highly recommended to user odd window sizes. You provided %s, an even number.' % (win_size))
107
+
108
+ # we process the entire img as float64 to avoid type overflow error
109
+ img = np.float64(img)
110
+ img_filtered = np.zeros_like(img)
111
+ N, M = img.shape
112
+ win_offset = int(win_size / 2)
113
+
114
+ for i in np.arange(0, N):
115
+ xleft = i - win_offset
116
+ xright = i + win_offset
117
+
118
+ if xleft < 0:
119
+ xleft = 0
120
+ if xright >= N:
121
+ xright = N
122
+
123
+ for j in np.arange(0, M):
124
+ yup = j - win_offset
125
+ ydown = j + win_offset
126
+
127
+ if yup < 0:
128
+ yup = 0
129
+ if ydown >= M:
130
+ ydown = M
131
+
132
+ # assert_indices_in_range(N, M, xleft, xright, yup, ydown)
133
+
134
+ pix_value = img[i, j]
135
+ window = img[xleft:xright, yup:ydown]
136
+ w_t = _weighting(window, cu)
137
+ window_mean = window.mean()
138
+
139
+ new_pix_value = (pix_value * w_t) + (window_mean * (1.0 - w_t))
140
+
141
+ if new_pix_value < 0.0: raise Exception("ERROR: lee_filter(), pixel filtered can't be negative")
142
+ if (new_pix_value is None) or np.isnan(new_pix_value):
143
+ new_pix_value = 0
144
+
145
+ img_filtered[i, j] = round(new_pix_value)
146
+
147
+ return img_filtered
@@ -0,0 +1,163 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+
4
+ # Copyright 2012 - 2013
5
+ # Matías Herranz <matiasherranz@gmail.com>
6
+ # Joaquín Tita <joaquintita@gmail.com>
7
+ # https://github.com/PyRadar/pyradar
8
+ #
9
+ # 2020: Erdogan Taskesen: <erdogant@gmail.com> Converted to python3.
10
+ #
11
+ # This library is free software; you can redistribute it and/or
12
+ # modify it under the terms of the GNU Lesser General Public
13
+ # License as published by the Free Software Foundation; either
14
+ # version 3 of the License, or (at your option) any later version.
15
+ #
16
+ # This library is distributed in the hope that it will be useful,
17
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ # Lesser General Public License for more details.
20
+ #
21
+ # You should have received a copy of the GNU Lesser General Public
22
+ # License along with this library. If not, see <http://www.gnu.org/licenses/>.
23
+
24
+
25
+ from math import exp
26
+
27
+ import numpy as np
28
+
29
+ K_DEFAULT = 1.0
30
+ CU_DEFAULT = 0.523
31
+ CMAX_DEFAULT = 1.73
32
+
33
+
34
+ def weighting(pix_value, window, k=K_DEFAULT, cu=CU_DEFAULT, cmax=CMAX_DEFAULT):
35
+ """
36
+ Computes the weighthing function for Lee filter using cu as the noise
37
+ coefficient.
38
+ """
39
+
40
+ # cu is the noise variation coefficient
41
+
42
+ # ci is the variation coefficient in the window
43
+ window_mean = window.mean()
44
+ window_std = window.std()
45
+ ci = window_std / window_mean
46
+
47
+ if ci <= cu: # use the mean value
48
+ w_t = 1.0
49
+ elif cu < ci < cmax: # use the filter
50
+ w_t = exp((-k * (ci - cu)) / (cmax - ci))
51
+ elif ci >= cmax: # preserve the original value
52
+ w_t = 0.0
53
+ else: # use the mean value
54
+ w_t = 1.0
55
+
56
+ return w_t
57
+
58
+
59
+ def assert_parameters(win_size, k, cu, cmax):
60
+ """
61
+ Asserts parameters in range.
62
+ Parameters:
63
+ - k: in [0:10]
64
+ - cu: positive
65
+ - cmax: positive and greater equal than cu
66
+ """
67
+
68
+ if 0 > k > 10: raise Exception("k parameter out of range 0<= k <= 10, submitted %s" % (k))
69
+ if cu < 0: raise Exception("cu can't be negative")
70
+ if cmax < 0 and cmax < cu: raise Exception("cmax must be positive and greater equal to cu: %s" % (cu))
71
+ if win_size < 3: raise Exception('ERROR: win size must be at least 3')
72
+
73
+
74
+ def lee_enhanced_filter(img, win_size=3, k=K_DEFAULT, cu=CU_DEFAULT, cmax=CMAX_DEFAULT):
75
+ """Lee enhanced filter.
76
+
77
+ Description
78
+ -----------
79
+ Apply Enhanced Lee filter to a numpy matrix containing the image, with a window of win_size x win_size.
80
+
81
+ Parameters
82
+ ----------
83
+ img : array-like
84
+ Input image.
85
+ win_size : int, int (default: 3)
86
+ Window size.
87
+ cu : float (default: 0.25)
88
+ cu factor.
89
+ k : float, (default: 1.0)
90
+ Kvalue.
91
+ cmax : float, (default: 1.73)
92
+ cmax value.
93
+
94
+ Returns
95
+ -------
96
+ img_filtered : array-like
97
+ Filtered image.
98
+
99
+ Examples
100
+ --------
101
+ >>> import findpeaks
102
+ >>> import matplotlib.pyplot as plt
103
+ >>> img = findpeaks.import_example('2dpeaks_image')
104
+ >>> # Resize
105
+ >>> img = findpeaks.stats.resize(img, size=(300,300))
106
+ >>> # Make grey image
107
+ >>> img = findpeaks.stats.togray(img)
108
+ >>> # Scale between [0-255]
109
+ >>> img = findpeaks.stats.scale(img)
110
+ >>> # Filter
111
+ >>> img_filtered = findpeaks.stats.lee_enhanced_filter(img.copy(), win_size=15)
112
+ >>>
113
+ >>> plt.figure()
114
+ >>> fig, axs = plt.subplots(1,2)
115
+ >>> axs[0].imshow(img, cmap='gray'); axs[0].set_title('Input')
116
+ >>> axs[1].imshow(img_filtered, cmap='gray'); axs[1].set_title('Lee enhanced filter')
117
+
118
+ """
119
+ if win_size < 3: raise Exception('[findpeaks] >ERROR: win size must be at least 3')
120
+ if len(img.shape) > 2: raise Exception(
121
+ '[findpeaks] >ERROR: Image should be 2D. Hint: set the parameter: togray=True')
122
+ if ((win_size % 2) == 0): print(
123
+ '[findpeaks] >It is highly recommended to user odd window sizes. You provided %s, an even number.' % (win_size))
124
+ assert_parameters(win_size, k, cu, cmax)
125
+
126
+ # we process the entire img as float64 to avoid type overflow error
127
+ img = np.float64(img)
128
+ img_filtered = np.zeros_like(img)
129
+ N, M = img.shape
130
+ win_offset = int(win_size / 2)
131
+
132
+ for i in np.arange(0, N):
133
+ xleft = i - win_offset
134
+ xright = i + win_offset
135
+
136
+ if xleft < 0:
137
+ xleft = 0
138
+ if xright >= N:
139
+ xright = N
140
+
141
+ for j in np.arange(0, M):
142
+ yup = j - win_offset
143
+ ydown = j + win_offset
144
+
145
+ if yup < 0:
146
+ yup = 0
147
+ if ydown >= M:
148
+ ydown = M
149
+
150
+ pix_value = img[i, j]
151
+ window = img[xleft:xright, yup:ydown]
152
+ w_t = weighting(pix_value, window, k, cu, cmax)
153
+ window_mean = window.mean()
154
+
155
+ new_pix_value = (window_mean * w_t) + (pix_value * (1.0 - w_t))
156
+
157
+ if new_pix_value < 0.0: raise Exception("ERROR: lee_filter(), pixel filtered can't be negative")
158
+ if (new_pix_value is None) or np.isnan(new_pix_value):
159
+ new_pix_value = 0
160
+
161
+ img_filtered[i, j] = round(new_pix_value)
162
+
163
+ return img_filtered