Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/scipy/ndimage/_fourier.py: 15%

73 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-12-12 06:31 +0000

1# Copyright (C) 2003-2005 Peter J. Verveer 

2# 

3# Redistribution and use in source and binary forms, with or without 

4# modification, are permitted provided that the following conditions 

5# are met: 

6# 

7# 1. Redistributions of source code must retain the above copyright 

8# notice, this list of conditions and the following disclaimer. 

9# 

10# 2. Redistributions in binary form must reproduce the above 

11# copyright notice, this list of conditions and the following 

12# disclaimer in the documentation and/or other materials provided 

13# with the distribution. 

14# 

15# 3. The name of the author may not be used to endorse or promote 

16# products derived from this software without specific prior 

17# written permission. 

18# 

19# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 

20# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 

21# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 

22# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 

23# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 

24# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 

25# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 

26# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 

27# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 

28# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 

29# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 

30 

31import numpy 

32from numpy.core.multiarray import normalize_axis_index 

33from . import _ni_support 

34from . import _nd_image 

35 

36__all__ = ['fourier_gaussian', 'fourier_uniform', 'fourier_ellipsoid', 

37 'fourier_shift'] 

38 

39 

40def _get_output_fourier(output, input): 

41 if output is None: 

42 if input.dtype.type in [numpy.complex64, numpy.complex128, 

43 numpy.float32]: 

44 output = numpy.zeros(input.shape, dtype=input.dtype) 

45 else: 

46 output = numpy.zeros(input.shape, dtype=numpy.float64) 

47 elif type(output) is type: 

48 if output not in [numpy.complex64, numpy.complex128, 

49 numpy.float32, numpy.float64]: 

50 raise RuntimeError("output type not supported") 

51 output = numpy.zeros(input.shape, dtype=output) 

52 elif output.shape != input.shape: 

53 raise RuntimeError("output shape not correct") 

54 return output 

55 

56 

57def _get_output_fourier_complex(output, input): 

58 if output is None: 

59 if input.dtype.type in [numpy.complex64, numpy.complex128]: 

60 output = numpy.zeros(input.shape, dtype=input.dtype) 

61 else: 

62 output = numpy.zeros(input.shape, dtype=numpy.complex128) 

63 elif type(output) is type: 

64 if output not in [numpy.complex64, numpy.complex128]: 

65 raise RuntimeError("output type not supported") 

66 output = numpy.zeros(input.shape, dtype=output) 

67 elif output.shape != input.shape: 

68 raise RuntimeError("output shape not correct") 

69 return output 

70 

71 

72def fourier_gaussian(input, sigma, n=-1, axis=-1, output=None): 

73 """ 

74 Multidimensional Gaussian fourier filter. 

75 

76 The array is multiplied with the fourier transform of a Gaussian 

77 kernel. 

78 

79 Parameters 

80 ---------- 

81 input : array_like 

82 The input array. 

83 sigma : float or sequence 

84 The sigma of the Gaussian kernel. If a float, `sigma` is the same for 

85 all axes. If a sequence, `sigma` has to contain one value for each 

86 axis. 

87 n : int, optional 

88 If `n` is negative (default), then the input is assumed to be the 

89 result of a complex fft. 

90 If `n` is larger than or equal to zero, the input is assumed to be the 

91 result of a real fft, and `n` gives the length of the array before 

92 transformation along the real transform direction. 

93 axis : int, optional 

94 The axis of the real transform. 

95 output : ndarray, optional 

96 If given, the result of filtering the input is placed in this array. 

97 

98 Returns 

99 ------- 

100 fourier_gaussian : ndarray 

101 The filtered input. 

102 

103 Examples 

104 -------- 

105 >>> from scipy import ndimage, datasets 

106 >>> import numpy.fft 

107 >>> import matplotlib.pyplot as plt 

108 >>> fig, (ax1, ax2) = plt.subplots(1, 2) 

109 >>> plt.gray() # show the filtered result in grayscale 

110 >>> ascent = datasets.ascent() 

111 >>> input_ = numpy.fft.fft2(ascent) 

112 >>> result = ndimage.fourier_gaussian(input_, sigma=4) 

113 >>> result = numpy.fft.ifft2(result) 

114 >>> ax1.imshow(ascent) 

115 >>> ax2.imshow(result.real) # the imaginary part is an artifact 

116 >>> plt.show() 

117 """ 

118 input = numpy.asarray(input) 

119 output = _get_output_fourier(output, input) 

120 axis = normalize_axis_index(axis, input.ndim) 

121 sigmas = _ni_support._normalize_sequence(sigma, input.ndim) 

122 sigmas = numpy.asarray(sigmas, dtype=numpy.float64) 

123 if not sigmas.flags.contiguous: 

124 sigmas = sigmas.copy() 

125 

126 _nd_image.fourier_filter(input, sigmas, n, axis, output, 0) 

127 return output 

128 

129 

130def fourier_uniform(input, size, n=-1, axis=-1, output=None): 

131 """ 

132 Multidimensional uniform fourier filter. 

133 

134 The array is multiplied with the Fourier transform of a box of given 

135 size. 

136 

137 Parameters 

138 ---------- 

139 input : array_like 

140 The input array. 

141 size : float or sequence 

142 The size of the box used for filtering. 

143 If a float, `size` is the same for all axes. If a sequence, `size` has 

144 to contain one value for each axis. 

145 n : int, optional 

146 If `n` is negative (default), then the input is assumed to be the 

147 result of a complex fft. 

148 If `n` is larger than or equal to zero, the input is assumed to be the 

149 result of a real fft, and `n` gives the length of the array before 

150 transformation along the real transform direction. 

151 axis : int, optional 

152 The axis of the real transform. 

153 output : ndarray, optional 

154 If given, the result of filtering the input is placed in this array. 

155 

156 Returns 

157 ------- 

158 fourier_uniform : ndarray 

159 The filtered input. 

160 

161 Examples 

162 -------- 

163 >>> from scipy import ndimage, datasets 

164 >>> import numpy.fft 

165 >>> import matplotlib.pyplot as plt 

166 >>> fig, (ax1, ax2) = plt.subplots(1, 2) 

167 >>> plt.gray() # show the filtered result in grayscale 

168 >>> ascent = datasets.ascent() 

169 >>> input_ = numpy.fft.fft2(ascent) 

170 >>> result = ndimage.fourier_uniform(input_, size=20) 

171 >>> result = numpy.fft.ifft2(result) 

172 >>> ax1.imshow(ascent) 

173 >>> ax2.imshow(result.real) # the imaginary part is an artifact 

174 >>> plt.show() 

175 """ 

176 input = numpy.asarray(input) 

177 output = _get_output_fourier(output, input) 

178 axis = normalize_axis_index(axis, input.ndim) 

179 sizes = _ni_support._normalize_sequence(size, input.ndim) 

180 sizes = numpy.asarray(sizes, dtype=numpy.float64) 

181 if not sizes.flags.contiguous: 

182 sizes = sizes.copy() 

183 _nd_image.fourier_filter(input, sizes, n, axis, output, 1) 

184 return output 

185 

186 

187def fourier_ellipsoid(input, size, n=-1, axis=-1, output=None): 

188 """ 

189 Multidimensional ellipsoid Fourier filter. 

190 

191 The array is multiplied with the fourier transform of an ellipsoid of 

192 given sizes. 

193 

194 Parameters 

195 ---------- 

196 input : array_like 

197 The input array. 

198 size : float or sequence 

199 The size of the box used for filtering. 

200 If a float, `size` is the same for all axes. If a sequence, `size` has 

201 to contain one value for each axis. 

202 n : int, optional 

203 If `n` is negative (default), then the input is assumed to be the 

204 result of a complex fft. 

205 If `n` is larger than or equal to zero, the input is assumed to be the 

206 result of a real fft, and `n` gives the length of the array before 

207 transformation along the real transform direction. 

208 axis : int, optional 

209 The axis of the real transform. 

210 output : ndarray, optional 

211 If given, the result of filtering the input is placed in this array. 

212 

213 Returns 

214 ------- 

215 fourier_ellipsoid : ndarray 

216 The filtered input. 

217 

218 Notes 

219 ----- 

220 This function is implemented for arrays of rank 1, 2, or 3. 

221 

222 Examples 

223 -------- 

224 >>> from scipy import ndimage, datasets 

225 >>> import numpy.fft 

226 >>> import matplotlib.pyplot as plt 

227 >>> fig, (ax1, ax2) = plt.subplots(1, 2) 

228 >>> plt.gray() # show the filtered result in grayscale 

229 >>> ascent = datasets.ascent() 

230 >>> input_ = numpy.fft.fft2(ascent) 

231 >>> result = ndimage.fourier_ellipsoid(input_, size=20) 

232 >>> result = numpy.fft.ifft2(result) 

233 >>> ax1.imshow(ascent) 

234 >>> ax2.imshow(result.real) # the imaginary part is an artifact 

235 >>> plt.show() 

236 """ 

237 input = numpy.asarray(input) 

238 if input.ndim > 3: 

239 raise NotImplementedError("Only 1d, 2d and 3d inputs are supported") 

240 output = _get_output_fourier(output, input) 

241 if output.size == 0: 

242 # The C code has a bug that can result in a segfault with arrays 

243 # that have size 0 (gh-17270), so check here. 

244 return output 

245 axis = normalize_axis_index(axis, input.ndim) 

246 sizes = _ni_support._normalize_sequence(size, input.ndim) 

247 sizes = numpy.asarray(sizes, dtype=numpy.float64) 

248 if not sizes.flags.contiguous: 

249 sizes = sizes.copy() 

250 _nd_image.fourier_filter(input, sizes, n, axis, output, 2) 

251 return output 

252 

253 

254def fourier_shift(input, shift, n=-1, axis=-1, output=None): 

255 """ 

256 Multidimensional Fourier shift filter. 

257 

258 The array is multiplied with the Fourier transform of a shift operation. 

259 

260 Parameters 

261 ---------- 

262 input : array_like 

263 The input array. 

264 shift : float or sequence 

265 The size of the box used for filtering. 

266 If a float, `shift` is the same for all axes. If a sequence, `shift` 

267 has to contain one value for each axis. 

268 n : int, optional 

269 If `n` is negative (default), then the input is assumed to be the 

270 result of a complex fft. 

271 If `n` is larger than or equal to zero, the input is assumed to be the 

272 result of a real fft, and `n` gives the length of the array before 

273 transformation along the real transform direction. 

274 axis : int, optional 

275 The axis of the real transform. 

276 output : ndarray, optional 

277 If given, the result of shifting the input is placed in this array. 

278 

279 Returns 

280 ------- 

281 fourier_shift : ndarray 

282 The shifted input. 

283 

284 Examples 

285 -------- 

286 >>> from scipy import ndimage, datasets 

287 >>> import matplotlib.pyplot as plt 

288 >>> import numpy.fft 

289 >>> fig, (ax1, ax2) = plt.subplots(1, 2) 

290 >>> plt.gray() # show the filtered result in grayscale 

291 >>> ascent = datasets.ascent() 

292 >>> input_ = numpy.fft.fft2(ascent) 

293 >>> result = ndimage.fourier_shift(input_, shift=200) 

294 >>> result = numpy.fft.ifft2(result) 

295 >>> ax1.imshow(ascent) 

296 >>> ax2.imshow(result.real) # the imaginary part is an artifact 

297 >>> plt.show() 

298 """ 

299 input = numpy.asarray(input) 

300 output = _get_output_fourier_complex(output, input) 

301 axis = normalize_axis_index(axis, input.ndim) 

302 shifts = _ni_support._normalize_sequence(shift, input.ndim) 

303 shifts = numpy.asarray(shifts, dtype=numpy.float64) 

304 if not shifts.flags.contiguous: 

305 shifts = shifts.copy() 

306 _nd_image.fourier_shift(input, shifts, n, axis, output) 

307 return output