pyosv.pre.normalizer_bands

  1import numpy as np
  2
  3
  4def percentile_prescaler(img : np.ndarray , perc : list, mmin : list = None) -> np.ndarray:
  5    '''
  6        Clip image between minimum and maximum based on the percentile
  7    
  8        Parameters:
  9        -----------
 10            - img : np.ndarray 
 11                a WxHxB image, with W width, H height and B bands            
 12            - perc: list
 13                the percentile values (one for each band)
 14            - mmin : list
 15                the minimum values (one for each band) to clip the img (default : None), if None mmin is calculated from img
 16        
 17        Returns:
 18        --------
 19            - img : np.ndarray 
 20                normalized WxHxB image, with W width, H height and B bands
 21
 22        Usage:
 23        ------
 24        ```python
 25        import numpy as np  
 26
 27        img         = np.array(  
 28            [[
 29                [0.1, 0.2, 0.3],  
 30                [0.4, 0.5, 0.6],  
 31                [0.7, 0.8, 0.9]
 32                ],
 33                [
 34                [1.1, 1.2, 1.3],  
 35                [1.4, 1.5, 1.6],  
 36                [1.7, 1.8, 1.9]
 37                ]
 38            ]  
 39        ) 
 40
 41        # Making channels last
 42        img = np.moveaxis(img, 0, -1)
 43
 44        img_n = percentile_prescaler(img, perc=[95,95], mmin=[0,0])
 45        ```
 46
 47        Output:
 48        -------
 49        ```
 50            [[0.1  1.1 ] 
 51            [0.2  1.2 ]  
 52            [0.3  1.3 ]]  
 53            [[0.4  1.4 ]  
 54            [0.5  1.5 ]  
 55            [0.6  1.6 ]]  
 56            [[0.7  1.7 ]  
 57            [0.8  1.8 ]  
 58            [0.86 1.86]]]  
 59        ```
 60    '''
 61
 62    if len(img.shape) != 3:
 63        raise Exception('Error: lenght of image shape must be 3 - (space, space, channels)')
 64    
 65    if mmin is not None:
 66        if len(mmin) != img.shape[-1]:
 67            raise Exception('Error: lenght of mmin must be equals to number of bands')
 68    
 69    if len(perc) != img.shape[-1]:
 70        raise Exception('Error: lenght of perc must be equals to number of bands')
 71
 72
 73    if mmin is None: mmin = np.nanmin(img, axis=-1)
 74
 75    for i in range(img.shape[-1]):
 76        mmax = np.nanpercentile(img[:,:,i], perc[i])
 77        img[:,:,i] = np.clip(img[:,:,i], mmin[i], mmax)
 78    
 79    return img
 80
 81
 82def minmax_scaler(img : np.ndarray, mmin : list = None, mmax : list = None, clip : list = [None, None]) -> np.ndarray: 
 83    '''
 84        Apply the min max scaler to the input img:  
 85        
 86        out = (img - minimum)/(maximum - minimum + E)          (1)  
 87        
 88        where E stabilizes the division. 
 89        
 90        Parameters:
 91        -----------
 92             - img : np.ndarray 
 93                a WxHxB image, with W width, H height and B bands
 94            - mmin : list 
 95                the minimum in equation (1) (one for each band) (default : None)
 96            - mmax : lsit
 97                the maximum in equation (1) (one for each band) (default : None)
 98            - clip : list 
 99                a list of two values used to constrain the image values (default : [None, None])
100        
101        Returns:
102        --------
103            - img : np.ndarray
104                normalized WxHxB image, with W width, H height and B bands
105
106        Usage:
107        ------
108        ```python
109        import numpy as np  
110
111        img         = np.array(  
112            [[
113                [0.1, 0.2, 0.3],  
114                [0.4, 0.5, 0.6],  
115                [0.7, 0.8, 0.9]
116                ],
117                [
118                [1.1, 1.2, 1.3],  
119                [1.4, 1.5, 1.6],  
120                [1.7, 1.8, 1.9]
121                ]
122            ]  
123        ) 
124
125        # Making channels last
126        img = np.moveaxis(img, 0, -1)
127
128        img_n = minmax_scaler(img, mmin=[0,0], mmax=[1,1], clip = [0,0.5])
129        ```
130
131        Output:
132        -------
133        ```
134        [[[0.0999001 0.5      ]  
135        [0.1998002 0.5      ]  
136        [0.2997003 0.5      ]]  
137        [[0.3996004 0.5      ]  
138        [0.4995005 0.5      ]  
139        [0.5       0.5      ]]  
140        [[0.5       0.5      ]  
141        [0.5       0.5      ]  
142        [0.5       0.5      ]]]  
143        ```
144    '''
145
146    if len(img.shape) != 3:
147        raise Exception('Error: lenght of image shape must be 3 - (space, space, channels)')
148    
149    if mmin is not None:
150        if len(mmin) != img.shape[-1]:
151            raise Exception('Error: lenght of mmin must be equals to number of bands')
152    
153    if mmax is not None:
154        if len(mmax) != img.shape[-1]:
155            raise Exception('Error: lenght of mmax must be equals to number of bands')
156    
157    if mmin == None: mmin = np.nanmin(img, axis=-1)
158    if mmax == None: mmax = np.nanmax(img, axis=-1)
159    
160    for i in range(img.shape[-1]):  
161        num = img[:,:,i] - mmin[i]
162        den = mmax[i] - mmin[i]
163          
164        img[:,:,i] = np.divide(num, den, where=den != 0)
165    
166    if (clip[0] is not None) and (clip[1] is not None):
167        img = np.clip(img, clip[0], clip[-1])
168    
169    return img
170
171
172def std_scaler(img : np.ndarray, mmean : list = None, sstd : list = None, clip : list = [None, None]) -> np.ndarray:
173    '''
174        Apply the min max scaler to the input img:  
175        
176        out = (img - mean)/(std)             (1)  
177         
178        Parameters:
179        -----------
180             - img : np.ndarray 
181                a WxHxB image, with W width, H height and B bands
182            - mmean : list 
183                the mean in equation (1) (one for each band) (default : None)
184            - sstd : lsit
185                the standar deviation in equation (1) (one for each band) (default : None)
186            - clip : list 
187                a list of two values used to constrain the image values (default : [None, None])
188        
189        Returns:
190        --------
191            - img : np.ndarray
192                normalized WxHxB image, with W width, H height and B bands
193
194        Usage:
195        ------
196        ```python
197        import numpy as np  
198
199        img         = np.array(  
200            [[
201                [0.1, 0.2, 0.3],  
202                [0.4, 0.5, 0.6],  
203                [0.7, 0.8, 0.9]
204                ],
205                [
206                [1.1, 1.2, 1.3],  
207                [1.4, 1.5, 1.6],  
208                [1.7, 1.8, 1.9]
209                ]
210            ]  
211        ) 
212
213        # Making channels last
214        img = np.moveaxis(img, 0, -1)
215
216        img_n = std_scaler(img, None, None, clip = [0,0.5])
217        ```
218
219        Output:
220        -------
221        ```
222            [[[0.  0.4]  
223            [0.  0.4]  
224            [0.  0.4]]  
225            [[0.  0.5]  
226            [0.  0.5]  
227            [0.  0.5]]  
228            [[0.2 0.5]  
229            [0.2 0.5]  
230            [0.2 0.5]]]   
231        ```
232    '''
233
234    if len(img.shape) != 3:
235        raise Exception('Error: lenght of image shape must be 3 - (space, space, channels)')
236    
237    if mmean is not None:
238        if len(mmean) != img.shape[-1]:
239            raise Exception('Error: lenght of mmin must be equals to number of bands')
240    
241    if sstd is not None:
242        if len(sstd) != img.shape[-1]:
243            raise Exception('Error: lenght of mmax must be equals to number of bands')
244    
245    if mmean == None: mmean = np.nanmean(img, axis=-1)
246    if sstd  == None: sstd  = np.nanstd(img, axis=-1)
247    
248    for i in range(img.shape[-1]):    
249        img[:,:,i] = np.divide(img[:,:,i] - mmean[i], sstd[i], where=sstd[i] != 0)
250    
251    if (clip[0] is not None) and (clip[1] is not None):
252        img = np.clip(img, clip[0], clip[-1])
253    
254    return img
def percentile_prescaler(img: numpy.ndarray, perc: list, mmin: list = None) -> numpy.ndarray:
 5def percentile_prescaler(img : np.ndarray , perc : list, mmin : list = None) -> np.ndarray:
 6    '''
 7        Clip image between minimum and maximum based on the percentile
 8    
 9        Parameters:
10        -----------
11            - img : np.ndarray 
12                a WxHxB image, with W width, H height and B bands            
13            - perc: list
14                the percentile values (one for each band)
15            - mmin : list
16                the minimum values (one for each band) to clip the img (default : None), if None mmin is calculated from img
17        
18        Returns:
19        --------
20            - img : np.ndarray 
21                normalized WxHxB image, with W width, H height and B bands
22
23        Usage:
24        ------
25        ```python
26        import numpy as np  
27
28        img         = np.array(  
29            [[
30                [0.1, 0.2, 0.3],  
31                [0.4, 0.5, 0.6],  
32                [0.7, 0.8, 0.9]
33                ],
34                [
35                [1.1, 1.2, 1.3],  
36                [1.4, 1.5, 1.6],  
37                [1.7, 1.8, 1.9]
38                ]
39            ]  
40        ) 
41
42        # Making channels last
43        img = np.moveaxis(img, 0, -1)
44
45        img_n = percentile_prescaler(img, perc=[95,95], mmin=[0,0])
46        ```
47
48        Output:
49        -------
50        ```
51            [[0.1  1.1 ] 
52            [0.2  1.2 ]  
53            [0.3  1.3 ]]  
54            [[0.4  1.4 ]  
55            [0.5  1.5 ]  
56            [0.6  1.6 ]]  
57            [[0.7  1.7 ]  
58            [0.8  1.8 ]  
59            [0.86 1.86]]]  
60        ```
61    '''
62
63    if len(img.shape) != 3:
64        raise Exception('Error: lenght of image shape must be 3 - (space, space, channels)')
65    
66    if mmin is not None:
67        if len(mmin) != img.shape[-1]:
68            raise Exception('Error: lenght of mmin must be equals to number of bands')
69    
70    if len(perc) != img.shape[-1]:
71        raise Exception('Error: lenght of perc must be equals to number of bands')
72
73
74    if mmin is None: mmin = np.nanmin(img, axis=-1)
75
76    for i in range(img.shape[-1]):
77        mmax = np.nanpercentile(img[:,:,i], perc[i])
78        img[:,:,i] = np.clip(img[:,:,i], mmin[i], mmax)
79    
80    return img

Clip image between minimum and maximum based on the percentile

Parameters:

- img : np.ndarray 
    a WxHxB image, with W width, H height and B bands            
- perc: list
    the percentile values (one for each band)
- mmin : list
    the minimum values (one for each band) to clip the img (default : None), if None mmin is calculated from img

Returns:

- img : np.ndarray 
    normalized WxHxB image, with W width, H height and B bands

Usage:

import numpy as np  

img         = np.array(  
    [[
        [0.1, 0.2, 0.3],  
        [0.4, 0.5, 0.6],  
        [0.7, 0.8, 0.9]
        ],
        [
        [1.1, 1.2, 1.3],  
        [1.4, 1.5, 1.6],  
        [1.7, 1.8, 1.9]
        ]
    ]  
) 

# Making channels last
img = np.moveaxis(img, 0, -1)

img_n = percentile_prescaler(img, perc=[95,95], mmin=[0,0])

Output:

    [[0.1  1.1 ] 
    [0.2  1.2 ]  
    [0.3  1.3 ]]  
    [[0.4  1.4 ]  
    [0.5  1.5 ]  
    [0.6  1.6 ]]  
    [[0.7  1.7 ]  
    [0.8  1.8 ]  
    [0.86 1.86]]]  
def minmax_scaler( img: numpy.ndarray, mmin: list = None, mmax: list = None, clip: list = [None, None]) -> numpy.ndarray:
 83def minmax_scaler(img : np.ndarray, mmin : list = None, mmax : list = None, clip : list = [None, None]) -> np.ndarray: 
 84    '''
 85        Apply the min max scaler to the input img:  
 86        
 87        out = (img - minimum)/(maximum - minimum + E)          (1)  
 88        
 89        where E stabilizes the division. 
 90        
 91        Parameters:
 92        -----------
 93             - img : np.ndarray 
 94                a WxHxB image, with W width, H height and B bands
 95            - mmin : list 
 96                the minimum in equation (1) (one for each band) (default : None)
 97            - mmax : lsit
 98                the maximum in equation (1) (one for each band) (default : None)
 99            - clip : list 
100                a list of two values used to constrain the image values (default : [None, None])
101        
102        Returns:
103        --------
104            - img : np.ndarray
105                normalized WxHxB image, with W width, H height and B bands
106
107        Usage:
108        ------
109        ```python
110        import numpy as np  
111
112        img         = np.array(  
113            [[
114                [0.1, 0.2, 0.3],  
115                [0.4, 0.5, 0.6],  
116                [0.7, 0.8, 0.9]
117                ],
118                [
119                [1.1, 1.2, 1.3],  
120                [1.4, 1.5, 1.6],  
121                [1.7, 1.8, 1.9]
122                ]
123            ]  
124        ) 
125
126        # Making channels last
127        img = np.moveaxis(img, 0, -1)
128
129        img_n = minmax_scaler(img, mmin=[0,0], mmax=[1,1], clip = [0,0.5])
130        ```
131
132        Output:
133        -------
134        ```
135        [[[0.0999001 0.5      ]  
136        [0.1998002 0.5      ]  
137        [0.2997003 0.5      ]]  
138        [[0.3996004 0.5      ]  
139        [0.4995005 0.5      ]  
140        [0.5       0.5      ]]  
141        [[0.5       0.5      ]  
142        [0.5       0.5      ]  
143        [0.5       0.5      ]]]  
144        ```
145    '''
146
147    if len(img.shape) != 3:
148        raise Exception('Error: lenght of image shape must be 3 - (space, space, channels)')
149    
150    if mmin is not None:
151        if len(mmin) != img.shape[-1]:
152            raise Exception('Error: lenght of mmin must be equals to number of bands')
153    
154    if mmax is not None:
155        if len(mmax) != img.shape[-1]:
156            raise Exception('Error: lenght of mmax must be equals to number of bands')
157    
158    if mmin == None: mmin = np.nanmin(img, axis=-1)
159    if mmax == None: mmax = np.nanmax(img, axis=-1)
160    
161    for i in range(img.shape[-1]):  
162        num = img[:,:,i] - mmin[i]
163        den = mmax[i] - mmin[i]
164          
165        img[:,:,i] = np.divide(num, den, where=den != 0)
166    
167    if (clip[0] is not None) and (clip[1] is not None):
168        img = np.clip(img, clip[0], clip[-1])
169    
170    return img

Apply the min max scaler to the input img:

out = (img - minimum)/(maximum - minimum + E) (1)

where E stabilizes the division.

Parameters:

 - img : np.ndarray 
    a WxHxB image, with W width, H height and B bands
- mmin : list 
    the minimum in equation (1) (one for each band) (default : None)
- mmax : lsit
    the maximum in equation (1) (one for each band) (default : None)
- clip : list 
    a list of two values used to constrain the image values (default : [None, None])

Returns:

- img : np.ndarray
    normalized WxHxB image, with W width, H height and B bands

Usage:

import numpy as np  

img         = np.array(  
    [[
        [0.1, 0.2, 0.3],  
        [0.4, 0.5, 0.6],  
        [0.7, 0.8, 0.9]
        ],
        [
        [1.1, 1.2, 1.3],  
        [1.4, 1.5, 1.6],  
        [1.7, 1.8, 1.9]
        ]
    ]  
) 

# Making channels last
img = np.moveaxis(img, 0, -1)

img_n = minmax_scaler(img, mmin=[0,0], mmax=[1,1], clip = [0,0.5])

Output:

[[[0.0999001 0.5      ]  
[0.1998002 0.5      ]  
[0.2997003 0.5      ]]  
[[0.3996004 0.5      ]  
[0.4995005 0.5      ]  
[0.5       0.5      ]]  
[[0.5       0.5      ]  
[0.5       0.5      ]  
[0.5       0.5      ]]]  
def std_scaler( img: numpy.ndarray, mmean: list = None, sstd: list = None, clip: list = [None, None]) -> numpy.ndarray:
173def std_scaler(img : np.ndarray, mmean : list = None, sstd : list = None, clip : list = [None, None]) -> np.ndarray:
174    '''
175        Apply the min max scaler to the input img:  
176        
177        out = (img - mean)/(std)             (1)  
178         
179        Parameters:
180        -----------
181             - img : np.ndarray 
182                a WxHxB image, with W width, H height and B bands
183            - mmean : list 
184                the mean in equation (1) (one for each band) (default : None)
185            - sstd : lsit
186                the standar deviation in equation (1) (one for each band) (default : None)
187            - clip : list 
188                a list of two values used to constrain the image values (default : [None, None])
189        
190        Returns:
191        --------
192            - img : np.ndarray
193                normalized WxHxB image, with W width, H height and B bands
194
195        Usage:
196        ------
197        ```python
198        import numpy as np  
199
200        img         = np.array(  
201            [[
202                [0.1, 0.2, 0.3],  
203                [0.4, 0.5, 0.6],  
204                [0.7, 0.8, 0.9]
205                ],
206                [
207                [1.1, 1.2, 1.3],  
208                [1.4, 1.5, 1.6],  
209                [1.7, 1.8, 1.9]
210                ]
211            ]  
212        ) 
213
214        # Making channels last
215        img = np.moveaxis(img, 0, -1)
216
217        img_n = std_scaler(img, None, None, clip = [0,0.5])
218        ```
219
220        Output:
221        -------
222        ```
223            [[[0.  0.4]  
224            [0.  0.4]  
225            [0.  0.4]]  
226            [[0.  0.5]  
227            [0.  0.5]  
228            [0.  0.5]]  
229            [[0.2 0.5]  
230            [0.2 0.5]  
231            [0.2 0.5]]]   
232        ```
233    '''
234
235    if len(img.shape) != 3:
236        raise Exception('Error: lenght of image shape must be 3 - (space, space, channels)')
237    
238    if mmean is not None:
239        if len(mmean) != img.shape[-1]:
240            raise Exception('Error: lenght of mmin must be equals to number of bands')
241    
242    if sstd is not None:
243        if len(sstd) != img.shape[-1]:
244            raise Exception('Error: lenght of mmax must be equals to number of bands')
245    
246    if mmean == None: mmean = np.nanmean(img, axis=-1)
247    if sstd  == None: sstd  = np.nanstd(img, axis=-1)
248    
249    for i in range(img.shape[-1]):    
250        img[:,:,i] = np.divide(img[:,:,i] - mmean[i], sstd[i], where=sstd[i] != 0)
251    
252    if (clip[0] is not None) and (clip[1] is not None):
253        img = np.clip(img, clip[0], clip[-1])
254    
255    return img

Apply the min max scaler to the input img:

out = (img - mean)/(std) (1)

Parameters:

 - img : np.ndarray 
    a WxHxB image, with W width, H height and B bands
- mmean : list 
    the mean in equation (1) (one for each band) (default : None)
- sstd : lsit
    the standar deviation in equation (1) (one for each band) (default : None)
- clip : list 
    a list of two values used to constrain the image values (default : [None, None])

Returns:

- img : np.ndarray
    normalized WxHxB image, with W width, H height and B bands

Usage:

import numpy as np  

img         = np.array(  
    [[
        [0.1, 0.2, 0.3],  
        [0.4, 0.5, 0.6],  
        [0.7, 0.8, 0.9]
        ],
        [
        [1.1, 1.2, 1.3],  
        [1.4, 1.5, 1.6],  
        [1.7, 1.8, 1.9]
        ]
    ]  
) 

# Making channels last
img = np.moveaxis(img, 0, -1)

img_n = std_scaler(img, None, None, clip = [0,0.5])

Output:

    [[[0.  0.4]  
    [0.  0.4]  
    [0.  0.4]]  
    [[0.  0.5]  
    [0.  0.5]  
    [0.  0.5]]  
    [[0.2 0.5]  
    [0.2 0.5]  
    [0.2 0.5]]]