文章目录
一、简介
scipy 官方网站
使用建议:搜索想要了解的函数,会有非常详细的解释以及函数源码。
SciPy:是基于NumPy构建的数学算法和便利函数的集合
。它通过为用户提供用于操作和可视化数据的高级命令和类,为 Python 增添了强大的功能。
Scipy 本身是一个专注于科学计算的库,而不是图像处理,因此没有提供读写图像的API。
二、安装
(1)pip 安装:pip install scipy
(2)conda 安装:conda install scipy
import scipy
print("SciPy 版本号:", scipy.__version__)
# 使用命令行,查看版本号
python -c "import scipy; print(scipy.__version__)"
三、模块简介:API reference
SciPy 被组织成涵盖不同科学计算领域的子包。
"""
主要子模块列表如下:
(1)cluster 聚类算法 (如:层次聚类、k-means聚类、向量量化)
(2)constants 数学常数+物理常数 (如:圆周率π、黄金比例、光速、引力常数)
(3)fft 傅立叶变换 (如:快速傅立叶变换、离散正弦和余弦变换、快速汉克尔变换)
(3)fftpack 快速傅立叶变换 (如:快速傅立叶变换、微分和伪微分算子、卷积)
(4)integrate 积分和常微分方程求解器(如:定积分、常微分方程求解)
(5)interpolate 插值 (如:单变量插值、多元插值、一维样条、2-D样条)
(6)io 读写文件但不支持图像 (如:MATLAB文件、IDL文件、Fortran文件、Wav 声音文件、Arff 文件)
(7)linalg 线性代数 (如:矩阵求逆、特征值、矩阵函数、矩阵方程求解器)
(8)ndimage N维图像处理 (如:滤波器、几何变换)
(9)odr 正交距离回归ODR (如:正交距离回归分析)
(10)optimize 优化和寻根 (如:最小二乘和曲线拟合)
(11)signal 信号处理 (如:卷积、B 样条、连续和离散时间线性系统、光谱分析)
(12)sparse 稀疏矩阵 (如:压缩稀疏行矩阵、求解稀疏线性系统)
(13)spatial 空间算法和数据结构 (如:最近邻查询、凸包和 Voronoi 图)
(14)special 特殊函数 (如:椭圆函数和积分、贝塞尔函数、统计函数:二项分布、beta分布、伽马分布、正态分布、泊松分布、卡方分布、信息论函数、误差函数)
(15)stats 统计函数 (如:概率分布、相关性测试、独立样本测试、统计距离、采样)
"""
四、项目实战
4.1、插值与缩放:scipy.ndimage.zoom
import numpy as np
from scipy.ndimage import zoom
import time
# (1)生成随机数据
original_image = np.random.random((100, 200, 300))
# (2)设置目标长宽高
zoom_factor = (2, 2, 2)
# (3)order阶数越高,精度越高,但耗时越长。
for ii in range(6):
t = time.time()
image = zoom(original_image, zoom_factor, order=ii)
print("总共耗时:", time.time() - t)
"""
总共耗时: 0.25276637077331543
总共耗时: 1.2199947834014893
总共耗时: 3.5486414432525635
总共耗时: 7.243218421936035
总共耗时: 13.442247867584229
总共耗时: 22.708620071411133
"""
"""###########################################################################
# 函数作用:采用插值的方式对多维数组进行缩放
# 函数说明:scipy.ndimage.zoom(input, zoom, output=None, order=3, mode='constant', cval=0.0, prefilter=True, *, grid_mode=False)[source]
# 输入参数:
# input: 输入数组。可以是任何形状的多维数组。
# zoom: 缩放因子。可以是一个浮点数或包含每个维度缩放因子的元组。
# output(可选): 输出数组,默认情况下,将创建与input相同类型的数组。
# order(可选): 插值的阶数。较低的阶数会提高计算速度,但可能会导致图像质量下降。
# 在scipy1.5.0版本之前,order的默认值是1,之后的默认值更改为3。
# 0: 最近邻插值(Nearest-neighbor) 选择最接近目标位置的原始数据点的值。
# 1: 双线性插值(Bi-linear默认值) 使用目标位置周围的四个最近邻数据点,按线性权重进行插值。
# 2: 双二次插值(Bi-quadratic) 使用目标位置周围的16个最近邻数据点进行二次插值。
# 3: 双三次插值(Bi-cubic) 使用目标位置周围的64个最近邻数据点进行三次插值。
# 4: 双四次插值(Bi-quartic)
# 5: 双五次插值(Bi-quintic)
# mode(可选): 数组边界的处理方式
# 'constant'(常数填充)
# 'nearest'(最近邻插值)
# 'reflect'(边界反射)
# cval(可选): 当 mode='constant' 时,指定在边界处的常数值。
# prefilter(可选): 控制是否应用预滤器。可以提高高阶插值的效果。
# grid_mode(可选): 如果为False,则缩放到像素中心的距离。否则,使用包含全像素范围的距离。
# 例如,当网格模式为False时,长度为5的1d信号被认为长度为4,但当网格模式为True时,长度为5。
##############################################################################"""
# 备注:当order=0,1,2时,时间开销比例1:5:15,内存开销没有区别。
4.2、快速傅里叶变换卷积:scipy.signal.fftconvolve()
4.2.1、信号处理
import numpy as np
from scipy.signal import fftconvolve
import matplotlib.pyplot as plt
# (1)创建两个示例信号
signal1 = np.array([1, 2, 3, 4, 5, 6, 7, 8])
signal2 = np.array([0.5, 1, 0.2, 0.7])
# (2)执行傅里叶变换卷积
result = fftconvolve(signal1, signal2, mode='full')
# (3)图形化
plt.subplot(311), plt.stem(signal1, label='Signal 1'), plt.legend()
plt.subplot(312), plt.stem(signal2, label='Signal 2'), plt.legend()
plt.subplot(313), plt.stem(result, label='Convolution Result'), plt.legend()
plt.show()
"""###########################################################################
# 函数作用:(1)使用快速傅里叶变换(FFT)来加速卷积运算,特别是对于大型数据集。
# (2)将卷积操作转换为频域上的乘法操作,从而降低了计算的复杂度。
#
# 函数说明:scipy.signal.fftconvolve(in1, in2, mode='full', axes=None)
# 输入参数:
# in1: 第一个输入数组。
in2: 第二个输入数组。
mode: 卷积模式,决定输出的大小。
'full': 输出大小为 (N+M-1),其中 N 和 M 分别是输入数组的大小。
'valid': 输出大小为 max(M, N) - min(M, N) + 1,仅计算重叠部分。
'same': 输出大小与较大的输入信号相同,通过在较小信号周围填充零来实现。
axes: 指定要在哪些轴上进行卷积。默认为 None,表示对所有轴进行卷积。
##############################################################################"""
4.2.2、图像处理
import numpy as np
from scipy.signal import fftconvolve
import matplotlib.pyplot as plt
# (1)创建一个二维图像和卷积核
image = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
kernel = np.array([[0, 1, 0],
[1, -4, 1],
[0, 1, 0]])
# (2)使用fftconvolve进行二维卷积
result = fftconvolve(image, kernel, mode='same')
# (3)图形化
plt.subplot(1, 3, 1), plt.imshow(image, cmap='gray'), plt.title('raw')
plt.subplot(1, 3, 2), plt.imshow(kernel, cmap='gray'), plt.title('kernel')
plt.subplot(1, 3, 3), plt.imshow(result, cmap='gray'), plt.title('result')
plt.show()
"""###########################################################################
# 函数作用:(1)使用快速傅里叶变换(FFT)来加速卷积运算,特别是对于大型数据集。
# (2)将卷积操作转换为频域上的乘法操作,从而降低了计算的复杂度。
#
# 函数说明:scipy.signal.fftconvolve(in1, in2, mode='full', axes=None)
# 输入参数:
# in1: 第一个输入数组。
in2: 第二个输入数组。
mode: 卷积模式,决定输出的大小。
'full': 输出大小为 (N+M-1),其中 N 和 M 分别是输入数组的大小。
'valid': 输出大小为 max(M, N) - min(M, N) + 1,仅计算重叠部分。
'same': 输出大小与较大的输入信号相同,通过在较小信号周围填充零来实现。
axes: 指定要在哪些轴上进行卷积。默认为 None,表示对所有轴进行卷积。
##############################################################################"""
4.3、根据数组的已知点,计算新坐标点的插值结果:scipy.ndimage.map_coordinates
import numpy as np
import scipy
"""
在 ndimage.map_coordinates 中,image 的维度 [Z, Y, X] 和 coords_array 中的维度 [X, Y, Z] 的顺序是一致的。
"""
image = np.random.randint(200, 256, (10, 10, 10), dtype=np.uint8) # 创建一个三维数组[Z, Y, X]
coords_array = np.random.rand(3, 2000) # 数组每个像素对应的3D坐标[3, 1000],其中 1000 是点的数量,3 是每个点的维度[X, Y, Z]
coords = [coords_array[0], coords_array[1], coords_array[2]] # 将 [3, 1000] 形状的数组转换为三维坐标列表格式
b = scipy.ndimage.map_coordinates(image, coords, order=1) # 对三维数组进行插值操作
transform_image = b.reshape((20, 10, 10)) # 改变数组形状
import napari
viewer = napari.Viewer()
viewer.add_image(image, name='image')
viewer.add_image(transform_image, name='transform_image')
napari.run()
"""#############################################################################################
# 函数功能:通过插值将输入数组映射到新的坐标 ———— 根据输入数组中的已知数据点,计算出在新坐标处的插值结果。
# 函数说明:output = scipy.ndimage.map_coordinates(input, coordinates, order=3, mode='constant', cval=0.0, prefilter=True)
# 参数说明:
# input:输入数组。
# coordinates:坐标数组,形状为 (dim, N),其中 dim 是三个维度,N 是插值点的数量。
# (1)根据坐标数组中的坐标自动索引到输入数组中的位置,然后通过周边已知点进行插值
# (2)坐标可以是浮点数或整数
# ———— 若为浮点数[0.5, 0.5, 0.5],则通过周边已知点进行插值
# ———— 若为整数[1, 1, 1],则插值与该位置的值相同。
# (3)坐标数组的数量没有限制,且可以大于输入数组的总数。
# order:表示插值方法的阶数。默认为 3。范围为 0(最近邻插值)到 5(五次插值)。
# mode:表示边界条件处理模式。默认为 'constant'。
# 选项包括 'constant'(常量填充)、'nearest'(最近邻填充)、'reflect'(反射填充)、'wrap'(重复填充)等。
# cval:常量模式下 mode='constant' 填充的值,默认是0.0。
# prefilter:表示是否在应用插值之前对输入数组进行预滤波,以减少插值误差。默认为 True。
# 返回值:
# output:返回插值后的数组,形状为 (1, N) ———— 插值数组与坐标数组中的插值点数量一致。
#############################################################################################"""