0%

CV入门——环境配置和detectron2安装、基础图象操作预处理

CV入门——在Windows 10上安装detectron2,并介绍了一些基本图像操作

环境配置和detectron2安装

环境依赖

安装 torch与torchvision

可以直接到Pytorch的whl仓库下载torch和torchvison的whl文件,然后执行以下命令进行安装。

1
pip install filename.whl

需要注意的是,下载torch和torchvison的whl文件时应有相同的cu并且与Python版本一致

测试是否安装完成。

1
python -c "import torch; print(torch.__version__)"

也可以直接在pytorch官网,选择操作系统、安装工具、语言以及CUDA版本,然后直接执行官网给出的命令。

安装 fvcore和pycocotools

1
2
3
pip install git+https://github.com/facebookresearch/fvcore

pip install git+https://github.com/cocodataset/cocoapi.git#subdirectory=PythonAPI

安装 Visual Studio

在微软的官网上下载Visual Studio Installer,安装时添加工作负载->使用C++的桌面开发即可。

将以下路径添加到系统变量中(根据安装位置自行修改)。

C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\bin\Hostx86\x86

测试cl是否正常。

1
2
3
4
5
> cl
用于 x64 的 Microsoft (R) C/C++ 优化编译器 19.27.29111 版
版权所有(C) Microsoft Corporation。保留所有权利。

用法: cl [ 选项... ] 文件名... [ /link 链接选项... ]

安装 detectron2

1
git clone https://github.com/facebookresearch/detectron2.git

在setup.py中找到以下内容将其注释掉即可。

1
# "pycocotools>=2.0.1",

随便下载一张图片,进行实例测试,(模型下载如果没有梯子会很慢)

1
python demo/demo.py --config-file configs/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml   --input input1.jpg   --output ./out.jpg --opts MODEL.WEIGHTS detectron2://COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x/137849600/model_final_f10217.pkl

输入的out.jpg如下所示,bingo!

如果代码报错,那么大概率是torch和torchvision的版本问题,应该重新检查是否版本对应

ninja错误

如果出现以下错误

1
subprocess.CalledProcessError: Command '['ninja', '-v']' returned non-zero exit status 1.

在以下路径中做如下修改即可。

1
2
3
4
# 路径:{Your Path}\Lib\site-packages\torch\utils\cpp_extension.py

# command = ['ninja', '-v'] # 修改前
command = ['ninja', '--v'] # 修改后

cl编码错误

如果出现以下错误

1
Error checking compiler version for cl

在以下路径中做如下修改即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 路径:{Your Path}\Lib\site-packages\torch\utils\cpp_extension.py

try:
if sys.platform.startswith('linux'):
minimum_required_version = MINIMUM_GCC_VERSION
version = subprocess.check_output([compiler, '-dumpfullversion', '-dumpversion'])
version = version.decode().strip().split('.')
else:
minimum_required_version = MINIMUM_MSVC_VERSION
compiler_info = subprocess.check_output(compiler, stderr=subprocess.STDOUT)
# match = re.search(r'(\d+)\.(\d+)\.(\d+)', compiler_info.decode().strip()) # 修改前
match = re.search(r'(\d+)\.(\d+)\.(\d+)', compiler_info.decode(' gbk').strip()) # 修改后
version = (0, 0, 0) if match is None else match.groups()
except Exception:
_, error, _ = sys.exc_info()
warnings.warn('Error checking compiler version for {}: {}'.format(compiler, error))
return False

cl连接错误

如果出现以下错误,

1
detectron2 failed with exit status 1181

那么应该是cl中link.exe无法正确生成obj文件所致,本机解决方法暂时未知;但可以通过打包别人已安装好的detectron2中的以下路径覆盖到本地解决。

1
{Your Path}\detectron2\build\temp.win-amd64-3.7\Release\{Your Path}\detectron2\detectron2\layers\csrc

基础图像操作与处理

本章学习操作和处理图像的基础知识,将通过大量示例介绍处理图像所需的Python工具包,并学习用于读取图像、图像转换和缩放、计算导数、画图和保存结果等的基本工具。本章的内容将贯穿本书的剩余章节。

PIL: Python图像处理类库

PIL(Python Imaging Library)提供了通用的图像处理功能,比如图像缩放、裁剪、旋转、颜色转换等。

读取图像

使用PIL中最重要的Image模块,读取图像并返回PIL图像对象。

1
2
3
from PIL import Image
pil_im = Image.open('empire.jpg') # 读取图像
pil_im_conv = pil_im.convert('L') # 转换为灰度图像

创建缩略图

使用PIL图像对象的thumbnail()方法,该方法接收一个元组参数,指定缩略图的大小。

1
pil_im.thumbnail((128,128))

复制和粘贴图像区域

用crop()方法可以从一幅图像中裁剪指定区域,该区域由元组参数指定,格式为(左,上,右,下)。使用paste()方法可以将图像粘贴。

1
2
3
4
box = (100,100,400,400)
region = pil_im.crop(box)
region = region.transpose(Image.ROTATE_180)
pil_im.paste(region,box)

效果如下所示(害怕):
dsNaEq.png
dsN4PK.png

调整尺寸和旋转

调整尺寸可以直接使用resize()方法,参数同样是元组。
旋转图像可以使用逆时针方式表示旋转角度,调用rotate()方法

1
2
out1 = pil_im.resize((128,128))
out2 = pil_im.rotate(45)

转换图像格式

通过Image的save方法,可以直接将图像保存为其他格式。

1
2
3
4
5
6
7
8
9
from PIL import Image
import os
for infile in filelist:
outfile = os.path.splitext(infile)[0] + ".png"
if infile != outfile:
try:
Image.open(infile).save(outfile)
except IOError:
print "cannot convert", infile

Matplotlib

处理数学运算、绘制图表,在图像上绘制点、直线和曲线时,尝试用Matplotlib库。

绘制图像、点和线

在CV中,常用来绘制兴趣点、对应点以及检测出的物体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from PIL import Image
from pylab import *
# 读取图像到数组中
im = array(Image.open('1.jpg'))
# 绘制图像
imshow(im)
# 一些点的横纵坐标
x = [100,400,200,200]
y = [200,500,200,500]
# 使用红色星状标记绘制点
plot(x,y,'r*')
# 绘制连接前两个点的线
plot(x[:2],y[:2])
# 添加标题,显示绘制的图像
title('Plotting: "1.jpg"')
# 不显示坐标轴
# axis('off')
show()

该例子的绘制结果如下 所示。show() 命令首先打开图形用户界面(GUI),然后新建一个图像窗口。该图形用户界面会循环阻断脚本,然后暂停,直到最后一个图像窗口关闭。在每个脚本里,只能调用一次show() 命令,而且通常是在脚本的结尾调用。

PyLab库绘图时的基本颜色格式命令如下

命令格式 颜色
‘b’ 蓝色
‘g’ 绿色
‘r’ 红色
‘c’ 青色
‘m’ 品红
‘y’ 黄色
‘k’ 黑色
‘w’ 白色

PyLab库绘图时的基本线型格式命令如下

命令格式 颜色
‘-‘ 实线
‘—‘ 虚线
‘:’ 点线

PyLab库绘图时的基本绘制标记格式命令如下

命令格式 颜色
‘.’
‘o’ 圆圈
‘s’ 正方形
‘*’ 星形
‘+’ 加号
‘x’ 叉号

图像轮廓和直方图

绘制图像的轮廓(或者其他二维函数的等轮廓线)在工作中非常有用。因为绘制轮廓需要对每个坐标[x, y] 的像素值施加同一个阈值,所以首先需要将图像灰度化。使用contour()即可绘制轮廓。

1
2
3
4
5
6
7
8
9
10
11
12
from PIL import Image
from pylab import *
# 读取灰度图像到数组中
im = array(Image.open('./image/1.jpg').convert('L'))
# 新建一个图像
figure()
# 不使用颜色信息
gray()
# 在原点的左上角显示轮廓图像
contour(im, origin='image')
axis('equal')
axis('off')

图像的直方图用来表征该图像像素值的分布情况。用一定数目的小区间(bin)来指定表征像素值的范围,每个小区间会得到落入该小区间表示范围的像素数目。该(灰度)图像的直方图可以使用hist() 函数绘制,其第一个参数必须是一维数组输入,因此需要用flatten()方法按行优先展平,第二个参数指定了小区间的数目。

1
2
3
figure()
hist(im.flatten(),128)
show()

图像轮廓和直方图的效果如下所示(害怕*2):
dsUvwR.png
dsaq4P.png

交互式标注

有时候需要用户交互来标记某些点或者标注训练数据,使用ginput()函数就可以实现交互式标注。

1
2
3
4
5
6
7
8
from PIL import Image
from pylab import *
im = array(Image.open('./image/1.jpg'))
imshow(im)
print ('Please click 3 points')
x = ginput(3)
print ('you clicked:',x)
show()

首先绘制一幅图像,然后等待用户在绘图窗口的图像区域点击三次。程序将这些点击的坐标[x, y] 自动保存在列表中。

NumPy

NumPy是著名的Python科学计算工具包。NumPy 中的数组对象几乎贯穿用于本书的所有例子中,数组对象可以帮助实现数组中重要的操作,比如矩阵乘积、转置、解方程系统、向量乘积和归一化,这为图像变形、对变化进行建模、图像分类、图像聚类等提供了基础。

图像数组表示

先前的例子中已经调用过array()方法将图像转换成NumPy的数组对象。NumPy的数组对象是多维的,可以用来表示向量、矩阵和图像。

对于图像数据,运行以下实例

1
2
3
4
im = array(Image.open('./image/1.jpg'))
print (im.shape, im.dtype)
im = array(Image.open('./image/1.jpg').convert('L'),'f')
print (im.shape, im.dtype)

输出为

1
2
(763, 720, 3) uint8
(763, 720) float32

其中每行的第一个元组表示图像数组的大小(行、列、颜色通道),紧接着的字符串表示数组元素的数据类型。因为图像通常被编码成无符号八位整数(uint8),所以在第一种情况下,载入图像并将其转换到数组中,数组的数据类型为“uint8”。

在第二种情况下,对图像进行灰度化处理,并且在创建数组时使用额外的参数“f”;该参数将数据类型转换为浮点型。注意,由于灰度图像没有颜色信息,所以在形状元组中,它只有两个数值。

数组中的元素可以使用下标访问,如果仅用一个下标,则该下标为行下标。位于坐标i、j,以及颜色通道k 的像素值可以像下面这样访问:

1
value = im[i,j,k]

同样也可以数组切片方式访问,例如:

1
2
3
4
5
6
7
im[i,:] = im[j,:] # 将第j 行的数值赋值给第i 行
im[:,i] = 100 # 将第i 列的所有数值设为100
im[:100,:50].sum() # 计算前100 行、前50 列所有数值的和
im[50:100,50:100] # 50~100 行,50~100 列(不包括第100 行和第100 列)
im[i].mean() # 第i 行所有数值的平均值
im[:,-1] # 最后一列
im[-2,:] (or im[-2]) # 倒数第二行

array()变换的逆操作可以用PIL的fromarray()函数完成:

1
2
pil_im = Image.fromarray(im)
pil_im = Image.fromarray(uint8(im)) # 如果通过一些操作将uint8转换为其他类型

图像灰度变换

将图像读入NumPy数组对象后,就可以对他们执行数学操作,如灰度变换:

1
2
3
4
im = array(Image.open('./image/1.jpg').convert('L'))
im2 = 255 - im # 对图像进行反相处理
im3 = (100.0/255) * im + 100 # 将图像像素值变换到100...200 区间
im4 = 255.0 * (im/255.0)**2 # 对图像像素值求平方后得到的图像

输出图像结果如下:
dyWXqI.png
dyWvZt.png
dyfpi8.png

图像缩放

NumPy并没有提供对图像进行缩放处理的方法,可以使用PIL实现:

1
2
3
4
def imresize(im,sz):
""" 使用PIL 对象重新定义图像数组的大小"""
pil_im = Image.fromarray(uint8(im))
return array(pil_im.resize(sz))

直方图均衡化

直方图均衡化是指将一幅图像的灰度直方图变平,使变换后的图像中每个灰度值的分布概率都相同
在对图像做进一步处理之前,直方图均衡化通常是对图像灰度值进行归一化的一个非常好的方法,并且可以增强图像的对比度。

1
2
3
4
5
6
7
8
9
def histeq(im,nbr_bins=256):
""" 对一幅灰度图像进行直方图均衡化"""
# 计算图像的直方图
imhist,bins = histogram(im.flatten(),nbr_bins,normed=True)
cdf = imhist.cumsum() # cumulative distribution function
cdf = 255 * cdf / cdf[-1] # 归一化
# 使用累积分布函数的线性插值,计算新的像素值
im2 = interp(im.flatten(),bins[:-1],cdf)
return im2.reshape(im.shape), cdf

该函数有两个输入参数,一个是灰度图像,一个是直方图中使用小区间的数目。函数返回直方图均衡化后的图像,以及用来做像素值映射的累积分布函数。注意,函数中使用到累积分布函数的最后一个元素(下标为-1),目的是将其归一化到0…1范围。

1
2
3
4
5
6
7
8
9
"""直方图均衡化"""
import utils
histeq_out = utils.histeq(im)
imshow(histeq_out[0])
figure()
hist(im.flatten(),128)
figure()
hist(histeq_out[1],128)
show()

直方图均衡化的输出结果如下。
dcszjI.png
dcyab6.png
dcywVK.png

图像平均

图像平均操作是减少图像噪声的一种简单方式,通常用于艺术特效。可以简单地从图像列表中计算出一幅平均图像。假设所有的图像具有相同的大小,可以将这些图像简单地相加,然后除以图像的数目,来计算平均图像。

1
2
3
4
5
6
7
8
9
10
11
12
def compute_average(imlist):
""" 计算图像列表的平均图像"""
# 打开第一幅图像,将其存储在浮点型数组中
averageim = array(Image.open(imlist[0]), 'f')
for imname in imlist[1:]:
try:
averageim += array(Image.open(imname))
except:
print imname + '...skipped'
averageim /= len(imlist)
# 返回uint8 类型的平均图像
return array(averageim, 'uint8')

该函数可以计算多个图像的平均图像。也可以用mean()函数计算平均图像,但是可能会占用很多内存。

dcjrFS.png

图像主成分分析(PCA)

PCA(Principal Component Analysis,主成分分析)是一个非常有用的降维技巧。它可以在使用尽可能少维数的前提下,尽量多地保持训练数据的信息。由于图像具有很高的维数,在许多计算机视觉应用中,我们经常使用降维操作。PCA 产生的投影矩阵可以被视为将原始坐标变换到现有的坐标系,坐标系中的各个坐标按照重要性递减排列。

将变平的图像堆积起来,我们可以得到一个矩阵,矩阵的一行表示一幅图像。在计算主方向之前,所有的行图像按照平均图像进行了中心化。我们通常使用SVD(SingularValue Decomposition,奇异值分解)方法来计算主成分;但当矩阵的维数很大时,SVD 的计算非常慢,所以此时通常不使用SVD 分解。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from PIL import Image
from numpy import *
def pca(X):
""" 主成分分析:
输入:矩阵X ,其中该矩阵中存储训练数据,每一行为一条训练数据返回:投影矩阵(按照维度的重要性排序)、方差和均值"""
# 获取维数
num_data,dim = X.shape
# 数据中心化
mean_X = X.mean(axis=0)
X = X - mean_X
if dim>num_data:
# PCA- 使用紧致技巧
M = dot(X,X.T) # 协方差矩阵
e,EV = linalg.eigh(M) # 特征值和特征向量
tmp = dot(X.T,EV).T # 这就是紧致技巧
V = tmp[::-1] # 由于最后的特征向量是我们所需要的,所以需要将其逆转
S = sqrt(e)[::-1] # 由于特征值是按照递增顺序排列的,所以需要将其逆转
for i in range(V.shape[1]):
V[:,i] /= S
else:
# PCA- 使用SVD 方法
U,S,V = linalg.svd(X)
V = V[:num_data] # 仅仅返回前nun_data 维的数据才合理
# 返回投影矩阵、方差和均值
return V,S,mean_X

PCA的过程无需了解,用下面的脚本可以计算图像的主成分。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from PIL import Image
from numpy import *
from pylab import *
from pca import *
im = array(Image.open(imlist[0])) # 打开一幅图像,获取其大小
m,n = im.shape[0:2] # 获取图像的大小
imnbr = len(imlist) # 获取图像的数目
# 创建矩阵,保存所有压平后的图像数据
immatrix = array([array(Image.open(im).convert('L')).flatten()
for im in imlist],'f')
# 执行PCA 操作
V,S,immean = pca(immatrix)

# 显示一些图像(均值图像和前3 个模式)
figure()
gray()
subplot(2,2,1)
imshow(immean.reshape(m,n))
axis('off')
for i in range(3):
subplot(2,2,i+2)
imshow(V[i].reshape(m,n))
axis('off')
show()

结果如下所示(害怕*3):
d2dbNQ.png

pickle模块

如果想要保存一些结果或者数据以方便后续使用,Python 中的pickle 模块非常有用。pickle 模块可以接受几乎所有的Python 对象,并且将其转换成字符串表示,该过程叫做封装(pickling)。从字符串表示中重构该对象,称为拆封(unpickling)。这些字符串表示可以方便地存储和传输。

1
2
3
4
5
6
7
8
9
10
11
# 保存均值和主成分数据
f = open('font_pca_modes.pkl', 'wb')
pickle.dump(immean,f)
pickle.dump(V,f)
f.close()

# 载入均值和主成分数据
f = open('font_pca_modes.pkl', 'rb')
immean = pickle.load(f)
V = pickle.load(f)
f.close()

使用with语句处理文件读写操作,可以自动打开和关闭文件(即使在文件打开时发生错误)。

1
2
3
4
5
6
7
8
9
# 打开文件并保存
with open('font_pca_modes.pkl', 'wb') as f:
pickle.dump(immean,f)
pickle.dump(V,f)

# 打开文件并载入
with open('font_pca_modes.pkl', 'rb') as f:
immean = pickle.load(f)
V = pickle.load(f)

NumPy也提供读写文本文件的简单函数。

1
2
savetxt('test.txt',x,'%i')
x = loadtxt('test.txt')

SciPy

SciPy 是建立在NumPy 基础上, 用于数值运算的开源工具包。
SciPy 提供很多高效的操作,可以实现数值积分、优化、统计、信号处理,以及图像处理功能。

图像模糊

图像的高斯模糊是非常经典的图像卷积例子。本质上是将灰度图像I和一个高斯核进行卷积操作:

其中 $G_\sigma$ 是标准差为 $\sigma$ 的二维高斯核,定义为:

高斯模糊通常是其他图像处理操作的一部分,比如图像插值操作、兴趣点计算以及很多其他应用。

SciPy 有用来做滤波操作的scipy.ndimage.filters 模块。该模块使用快速一维分离的方式来计算卷积。你可以像下面这样来使用它:

1
2
3
4
5
6
7
8
9
from PIL import Image
from numpy import *
from scipy.ndimage import filters
im = array(Image.open('./image/1.jpg').convert('L'))
for i in range(4):
subplot(2,2,i+1)
im2 = filters.gaussian_filter(im,5*i)
imshow(im2)
axis('off')

上面guassian_filter() 函数的最后一个参数表示标准差,其中$\sigma =0,5,10,15$的高斯滤波结果如下所示,$\sigma$越大,处理后的图像细节丢失越多。

dWxrqJ.png

如果打算模糊一幅彩色图像,只需简单地对每一个颜色通道进行高斯
模糊:

1
2
3
4
5
6
7
im = array(Image.open('./image/1.jpg'))
im2 = zeros(im.shape)
for i in range(3):
im2[:,:,i] = filters.gaussian_filter(im[:,:,i],5)
im2 = uint8(im2)
imshow(im2)
axis('off')

$\sigma = 5$时,彩色图像的高斯模糊结果如下。

dWzUwd.png

图像导数

图像强度的变化可以用灰度图像$I$(对于彩色图像,通常对每个颜色通道分别计算导数)的x和y 方向导数 $I_x$ 和 $I_y$ 进行描述。

图像的梯度向量为 $\nabla I = [I_x , I_y]^T$。梯度有两个重要的属性,一是梯度的大小:

它描述了图像强度变化的强弱,一是梯度的角度:

描述了图像中在每个点(像素)上强度变化最大的方向。NumPy 中的arctan2() 函数返回弧度表示的有符号角度,角度的变化区间为-π…π。

可以用离散近似的方式来计算图像的导数。图像导数大多数可以通过卷积简单地实现:

对于 $D_x$ 和 $D_y$ ,通常选用Prewitt滤波器:

或Sobel滤波器:

这些导数滤波器可以使用scipy.ndimage.filters 模块的标准卷积操作来简单地实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from PIL import Image
from numpy import *
from scipy.ndimage import filters
im = array(Image.open('./image/1.jpg').convert('L'))
# Sobel 导数滤波器
imx = zeros(im.shape)
filters.sobel(im,1,imx)
imy = zeros(im.shape)
filters.sobel(im,0,imy)
magnitude = sqrt(imx**2+imy**2)
subplot(1,3,1)
imshow(imx)
axis('off')
subplot(1,3,2)
imshow(imy)
axis('off')
subplot(1,3,3)
imshow(magnitude)
axis('off')

使用Sobel导数滤波器的输出如下所示
dftNuV.png

这种方法计算图像导数需要滤波器尺度随着图像分辨率变化而变化,为了在图像噪声方面更稳健,以及在任意尺度上计算导数,我可以使用高斯导数滤波器

其中$G_{\sigma x}$ 和 $G_{\sigma x}$ 表示 $G_\sigma$ 在$x$和$y$方向上的导数, $G_{\sigma x}$ 为标准差为 $\sigma$ 的高斯函数。

之前用于模糊的 filters.gaussian_filter()函数可以接收额外的参数,用于计算高斯导数。

1
2
3
4
5
6
7
sigma = 5 # 标准差

imx = zeros(im.shape)
filters.gaussian_filter(im, (sigma,sigma), (0,1), imx)

imy = zeros(im.shape)
filters.gaussian_filter(im, (sigma,sigma), (1,0), imy)

该函数的第三个参数指定对每个方向计算哪种类型的导数,第二个参数为使用的标准差。

对象计数

形态学(或数学形态学)是度量和分析基本形状的图像处理方法的基本框架与集合。形态学通常用于处理二值图像,也可以用于灰度图像。二值图像是指图像的每个像素只能取两个值,通常是0和1。二值图像通常是,在计算物体的数目,或者度量其大小时,对一幅图像进行阈值化后的结果。

scipy.ndimage 中的morphology 模块可以实现形态学操作。你可以使用scipy.ndimage 中的measurements 模块来实现二值图像的计数和度量功能。计算该图像中的对象个数可以通过下面的脚本实现:

1
2
3
4
5
6
7
8
from scipy.ndimage import measurements,morphology
# 载入图像,然后使用阈值化操作,以保证处理的图像为二值图像
im = array(Image.open('./image/1.jpg').convert('L'))
im = 1*(im<128)
labels, nbr_objects = measurements.label(im)
print ("Number of objects:", nbr_objects)
imshow(im)
axis('off')

上面的脚本首先载入图像,通过阈值化确保该图像是二值图像。使用label() 函数寻找单个的物体,并且按照它们属于哪个对象将整数标签给像素赋值。下图是labels 数组的图像。图像的灰度值表示对象的标签。可以看到,在一些对象之间有一些小的连接。进行二进制开(binary open)操作,我们可以将其移除:

wNK4MV.png

1
2
3
4
5
6
# 形态学开操作更好地分离各个对象
im_open = morphology.binary_opening(im,ones((5,5)),iterations=2)
labels_open, nbr_objects_open = measurements.label(im_open)
print ("Number of objects:", nbr_objects_open)
imshow(im_open)
axis('off')

经过开操作后的图像如下图所示。
wNMiid.png

binary_opening() 函数的第二个参数指定一个数组结构元素。该数组表示以一个像素为中心时使用的相邻像素。在这种情况下,我们在y 方向上使用9 个像素(上面4 个像素、像素本身、下面4 个像素),在x 方向上使用5 个像素。可以指定任意数组为结构元素,数组中的非零元素决定使用哪些相邻像素。参数iterations 决定执行该操作的次数。binary_closing() 函数实现相反的操作。

一些有用的SciPy模块

SciPy中的io和misc模块可以用于输入和输出。

读写.mat文件

数据以Matlab的.mat文件格式存储时,可以用scipy.io模块进行读取

1
data = scipy.io.loadmat('test.mat')

上面代码中data 对象包含一个字典,字典中的键对应于保存在原始.mat 文件中的变量名。由于这些变量是数组格式的,因此可以很方便地保存到.mat 文件中。仅需创建一个字典(其中要包含你想要保存的所有变量),然后使用savemat() 函数:

1
2
3
data = {}
data['x'] = x
scipy.io.savemat('test.mat',data)

以图像形式保存数组

将数组直接保存为图像文件非常有用。imsave() 函数可以从scipy.misc 模块中载入。要将数组im 保存到文件中,可以使用下面的命令:

1
2
from scipy.misc import imsave
imsave('test.jpg',im)

scipy.misc 模块同样包含了著名的Lena 测试图像:

1
lena = scipy.misc.lena()

该脚本返回一个512×512 的灰度图像数组。

你可以打赏我哦!