plot(x,y) #默认为蓝色实线
plot(x,y,'r*') #红色星状标记
plot(x,y,'go-') #带有圆圈标记的绿线
plot(x,y,'ks:') #带有正方形标记的黑色点线
用PyLab库绘图的基本颜色格式命令
代码 | 颜色 |
‘b’ | 蓝色 |
‘g’ | 绿色 |
‘r’ | 红色 |
‘c’ | 青色 |
‘m’ | 品红 |
‘y’ | 黄色 |
‘k’ | 黑色 |
‘w’ | 白色 |
用PyLab库绘图的基本线型格式命令
代码 | 线型 |
‘-’ | 实线 |
‘–’ | 虚线 |
‘:’ | 点线 |
用PyLab库绘图的基本绘制标记格式命令
代码 | 标记 |
‘.’ | 点 |
‘o’ | 圆圈 |
‘s’ | 正方形 |
‘*’ | 星形 |
‘+’ | 加号 |
‘x’ | 叉号 |
访问坐标i、j,以及颜色通道k的像素值可以如下访问:
value = im[i,j,k]
多个数组元素可以使用数组切片方式访问。切片方式返回的是以指定间隔下标访问该数组的元素值。以下为关于灰度图像的一些例子:
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]) #倒数第二列
主成分分析
PCA是非常有用的降维技巧,可以在使用尽可能少维数的前提下,尽量多地保持训练数据的信息。即使是100*100像素的小灰度图像,也有10000维。由于图像具有很高的维度,在计算机视觉中,降维操作必不可少。PCA产生的投影矩阵可以将视为原始坐标变换到现有的坐标系,坐标系中的各个坐标按照重要性递减排列。
- 为了对对象进行PCA变换,需要将图像转换成一维向量表示。可以使用NumPy类库的flatten()方法进行变换。
- 图像需要从一维表示重新转换成二维图像,可以使用reshape()函数。
将变平的图像堆积起来,可以得到一个矩阵,矩阵的一行表示一幅图像。在计算主方向之前,所有的行图像按照平均图像进行了中心化。通常使用SVD方法来计算主成分;但当矩阵的维数很大时,SVD的计算非常慢,此时通常不使用SVD分解。
- 可以通过arange()函数返回一个数组,或者使用xrange()函数返回一个产生器(可能会提升速度)。一般常用range()函数。
pickle模块
如果想要保存一些结果或者数据以便后续使用,pickle模块非常有用。pickle模块可以接受几乎所有的Python对象,并且将其转换成字符串表示,该过程叫做封装(pickling)。从字符串表示中重构该对象,称为拆封(unpickling)。这些字符串可以方便地存储和传输。
SciPy
SciPy建立在NumPy基础上,用于数值运算的开源工具包。
- 图像的高斯模糊是非常经典的图像卷积例子。本质上,图像模糊就是将(灰度)图像I和一个高斯核进行卷积操作。
其中*表示卷积操作;
是标准差为
的二维高斯核,定义为:
高斯模糊通常是其他图像处理操作的一部分,比如图像插值操作、兴趣点计算等等。
- 图像导数
图像强度的变化信息是非常重要的信息。强度变化可以用灰度图像I(对于彩色图像,通常对每个颜色通道分别计算导数)的x和y方向导数和
进行表述。
图像的梯度向量为。梯度有两个重要属性:
- 梯度的大小:
。描述了图像强度变化的强弱。
- 梯度的角度:
。描述了图像中每个点(像素)上强度变化最大的方向。
可以用离散近似的方式来计算图像的导数。图像导数大多数可以通过卷积简单地实现:对于
和
通常选择Prewitt滤波器:
或者Sobel滤波器:
- 形态学:对象计数
形态学(或数学形态学)是度量和分析基本形状的图像处理方法的基本框架和集合。 - 一些有用的SciPy模块
- 读写.mat文件
使用scipy.io模块进行读取
data = scipy.io.loadmat('test.mat')
- 保存用savemat()函数
data = {}
data['x'] = x
scipy.io.savemat('test.mat',data)
- scipy.io模块
- 以图像形式保存数据
imsave()函数可以从scipy.misc模块中导入。要将数组im保存到文件中,可以使用:
from scipy.misc import imsave
imsave('test.jpg',im)
- scipy.misc模块同样包含了著名的Lena测试图像:
lena = scipy.misc.lena()
图像去噪
图像去噪是在去除图像噪声的同时,尽可能地保留图像细节和结构的处理技术。这里使用ROF(Rudin-Osher-Fatemi)去噪模型。1
ROF模型具有很好的性质:使处理后的图像更平滑,同时保持图像边缘和结构信息。
一幅(灰度)图像I的全变差(Total Variation, TV)定义为梯度范数之和。在连续表示的情况下,全变差表示为:离散情况下表示为:
是在所有图像坐标x = [x,y]上取和。
Chambolle提出的ROF模型里,目标函数为寻找降噪后的图像U,使下式最小:其中范数
是去噪后图像U和原始图像I差异的度量。本质上,该模型去噪后的图像像素值“平坦”变化,但是在图像区域的边缘上,允许去噪后的图像像素值“跳跃”变化。
from numpy import *
def denoise(im, U_init, tolerance = 0.1, tau = 0.125, tv_weight = 100):
"""使用A。Chambolle(2005)公式(11)计算步骤实现ROF去噪模型
输入:含有噪声的输入图像(灰度图像)、U的初始值、TV正则项权值、步长、停业条件
输出:去噪和去除纹理后的图像、文里残留"""
m,n = im.shape #噪声图像的大小
#初始化
U = U_init
Px = im #对偶域的x分量
Py = im #对偶域的y分量
error = 1
while (error > tolerance):
Uold = U
#原始变量的梯度
GradUx = roll(U, -1, axis = 1) - U #变量U梯度的x分量
GradUy = roll(U, -1, axis = 0) - U #变量U梯度的y分量
#更新对偶变量
PxNew = Px + (tau/tv_weight) * GradUx
PyNew = Py + (tau/tv_weight) * GradUy
NormNew = maximum(1, sqrt(PxNew ** 2 + PyNew ** 2))
Px = PxNew/NormNew #更新x分量(对偶)
Py = PyNew/NormNew #更新y分量(对偶)
#更新原始变量
RxPx = roll(Px, 1, axis = 1) #对x分量进行向右x轴平移
RyPy = roll(Py, 1, axis = 0) #对y分量进行向右x轴平移
DivP = (Px - RxPx) + (Py - RyPy) #对偶域的散度
U = im + tv_weight * DivP #更新原始变量
#更新误差
error = linalg.norm(U - Uold)/sqrt(n*m)
return U, im - U
通过合成的噪声图像进行说明(函数denoise()保存到rof.py文件):
from numpy import *
from numpy import random
from scipy.ndimage import filters
import rof
# 使用噪声创建合成对象
im = zeros((500,500))
im[100:400,100:400] = 128
im[200:300,200:300] = 255
im = im + 30 *random.standard_normal((500,500))
U, T = denoise(im,im)
G = filters.gaussian_filter(im, 10)
#保存生成结果
from scipy.misc import imsave
imsave('synth_rof.pdf', U)
imsave('synth_gaussiam.pdf', G)
实际图像运用:
#使用实际图像
from PIL import Image
from pylab import *
import rof
im = array(Image.open('Lighthouse.jpg').convert('L'))
U, T = rof.denoise(im, im)
figure()
gray()
imshow(U)
axis('equal')
axis('off')
show()
练习
- 将一幅图像进行高斯模糊处理。随着
的增加,绘制出图像轮廓。在绘制出的图中,图像的轮廓有何变化?解释发生这种现象的原因。
- 通过将图像模糊化,然后从原始图像中减去模糊图像,来实现反锐化图像掩模操作。反锐化图像掩模操作可以实现图像锐化效果。试在彩色和灰度图像上使用反锐化图像掩模操作,观察该操作的效果。
- 除了直方图均衡化,商图像是另一种图像归一化的方法。商图像可以通过除以模糊后的图像
获得。尝试使用该方法,并使用一些样本图像进行验证。
- 使用图像梯度,编写一个在图像中获得简单物体(例如,白色背景中正方形)轮廓的函数。
- 使用梯度方向和大小检测图像中的线段。估计线段的长度以及线段的参数,并在原始图像中重新绘制该线段。
- 使用label()函数处理二值化图像,并使用直方图和标签图像绘制图像中物体的大小分布。
- 使用形态学操作处理阈值化图像。在发现一些参数能够产生好的结果后,使用morphology模块里的center_of_mass()函数寻找每个物体的中心坐标,将其在图像中绘制出来。