使用 PIL 之前需要 import Image 模块:
import Image
然后你就可以使用Image.open(‘xx.bmp’) 来打开一个位图文件进行处理了。打开文件你不用担心格式,也不用了解格式,
无论什么格式,都只要把文件名丢给 Image.open 就可以了。真所谓 bmp、jpg、png、gif……,一个都不能少。
支持向量机SVM(Support Vector Machine)是有监督的分类预测模型,本篇文章使用机器学习库scikit-learn中的手写数字数据集介绍使用Python对SVM模型进行训练并对手写数字进行识别的过程。
准备工作
手写数字识别的原理是将数字的图片分割为8X8的灰度值矩阵,将这64个灰度值作为每个数字的训练集对模型进行训练。手写数字所对应的真实数字作为分类结果。在机器学习sklearn库中已经包含了不同数字的8X8灰度值矩阵,因此我们首先导入sklearn库自带的datasets数据集。然后是交叉验证库,SVM分类算法库,绘制图表库等。
12345678910#导入自带数据集from sklearn import datasets#导入交叉验证库from sklearn import cross_validation#导入SVM分类算法库from sklearn import svm#导入图表库import matplotlib.pyplot as plt#生成预测结果准确率的混淆矩阵from sklearn import metrics读取并查看数字矩阵
从sklearn库自带的datasets数据集中读取数字的8X8矩阵信息并赋值给digits。
12#读取自带数据集并赋值给digitsdigits = datasets.load_digits()查看其中的数字9可以发现,手写的数字9以64个灰度值保存。从下面的8×8矩阵中很难看出这是数字9。
12#查看数据集中数字9的矩阵digits.data[9]以灰度值的方式输出手写数字9的图像,可以看出个大概轮廓。这就是经过切割并以灰度保存的手写数字9。它所对应的64个灰度值就是模型的训练集,而真实的数字9是目标分类。我们的模型所要做的就是在已知64个灰度值与每个数字对应关系的情况下,通过对模型进行训练来对新的手写数字对应的真实数字进行分类。
1234#绘制图表查看数据集中数字9的图像plt.imshow(digits.images[9], cmap=plt.cm.gray_r, interpolation='nearest')plt.title('digits.target[9]')plt.show()设置模型的特征X和预测目标Y
查看数据集中的分类目标,可以看到一共有10个分类,分布为0-9。我们将这个分类目标赋值给Y,作为模型的预测目标。
12#数据集中的目标分类digits.target 12#将数据集中的目标赋给YY=digits.target手写数字的64个灰度值作为特征赋值给X,这里需要说明的是64个灰度值是以8×8矩阵的形式保持的,因此我们需要使用reshape函数重新调整矩阵的行列数。这里也就是将8×8的两维数据转换为64×1的一维数据。
123#使用reshape函数对矩阵进行转换,并赋值给Xn_samples = len(digits.images)X = digits.images.reshape((n_samples, 64))查看特征值X和预测目标Y的行数,共有1797行,也就是说数据集中共有1797个手写数字的图像,64列是经过我们转化后的灰度值。
12#查看X和Y的行数X.shape,Y.shape将数据分割为训练集和测试集
将1797个手写数字的灰度值采用随机抽样的方法分割为训练集和测试集,其中训练集为60%,测试集为40%。
12#随机抽取生成训练集和测试集,其中训练集的比例为60%,测试集40%X_train, X_test, y_train, y_test = cross_validation.train_test_split(X, Y, test_size=0.4, random_state=0)查看分割后的测试集数据,共有1078条数据。这些数据将用来训练SVM模型。
12#查看训练集的行数X_train.shape,y_train.shape对SVM模型进行训练
将训练集数据X_train和y_train代入到SVM模型中,对模型进行训练。下面是具体的代码和结果。
12#生成SVM分类模型clf = svm.SVC(gamma=0.001) 12#使用训练集对svm分类模型进行训练clf.fit(X_train, y_train)使用测试集测对模型进行测试
使用测试集数据X_test和y_test对训练后的SVM模型进行检验,模型对手写数字分类的准确率为99.3%。这是非常高的准确率。那么是否真的这么靠谱吗?下面我们来单独测试下。
12#使用测试集衡量分类模型准确率clf.score(X_test, y_test)我们使用测试集的特征X,也就是每个手写数字的64个灰度值代入到模型中,让SVM模型进行分类。
12#对测试集数据进行预测predicted=clf.predict(X_test)然后查看前20个手写数字的分类结果,也就是手写数字所对应的真实数字。下面是具体的分类结果。
12#查看前20个测试集的预测结果predicted[:20]再查看训练集中前20个分类结果,也就是真实数字的情况,并将之前的分类结果与测试集的真实结果进行对比。
12#查看测试集中的真实结果expected=y_test以下是测试集中前20个真实数字的结果,与前面SVM模型的分类结果对比,前20个结果是一致的。
12#查看测试集中前20个真实结果expected[:20]使用混淆矩阵来看下SVM模型对所有测试集数据的预测与真实结果的准确率情况,下面是一个10X10的矩阵,左上角第一行第一个数字60表示实际为0,SVM模型也预测为0的个数,第一行第二个数字表示实际为0,SVM模型预测为1的数字。第二行第二个数字73表示实际为1,SVM模型也预测为1的个数。
12#生成准确率的混淆矩阵(Confusion matrix)metrics.confusion_matrix(expected, predicted)从混淆矩阵中可以看到,大部分的数字SVM的分类和预测都是正确的,但也有个别的数字分类错误,例如真实的数字2,SVM模型有一次错误的分类为1,还有一次错误分类为7。
1. 简介。
图像处理是一门应用非常广的技术,而拥有非常丰富第三方扩展库的 Python 当然不会错过这一门盛宴。PIL (Python Imaging Library)是 Python 中最常用的图像处理库,目前版本为 1.1.7,我们可以 在这里 下载学习和查找资料。
Image 类是 PIL 库中一个非常重要的类,通过这个类来创建实例可以有直接载入图像文件,读取处理过的图像和通过抓取的方法得到的图像这三种方法。
2. 使用。
导入 Image 模块。然后通过 Image 类中的 open 方法即可载入一个图像文件。如果载入文件失败,则会引起一个 IOError ;若无返回错误,则 open 函数返回一个 Image 对象。现在,我们可以通过一些对象属性来检查文件内容,即:
1 >>>import Image
2 >>>im = Image.open("j.jpg")
3 >>>print im.format, im.size, im.mode
4 JPEG (440, 330) RGB
这里有三个属性,我们逐一了解。
format : 识别图像的源格式,如果该文件不是从文件中读取的,则被置为 None 值。
size : 返回的一个元组,有两个元素,其值为象素意义上的宽和高。
mode : RGB(true color image),此外还有,L(luminance),CMTK(pre-press image)。
现在,我们可以使用一些在 Image 类中定义的方法来操作已读取的图像实例。比如,显示最新载入的图像:
1 >>>im.show()
2 >>>
输出原图:
3. 函数概貌。
3.1 Reading and Writing Images : open( infilename ) , save( outfilename )
3.2 Cutting and Pasting and Merging Images :
crop() : 从图像中提取出某个矩形大小的图像。它接收一个四元素的元组作为参数,各元素为(left, upper, right, lower),坐标系统的原点(0, 0)是左上角。
paste() :
merge() :
1 >>>box = (100, 100, 200, 200)
2 >>>region = im.crop(box)
3 >>>region.show()
4 >>>region = region.transpose(Image.ROTATE_180)
5 >>>region.show()
6 >>>im.paste(region, box)
7 >>>im.show()
其效果图为:
旋转一幅图片:
1 def roll(image, delta):
2 "Roll an image sideways"
3
4 xsize, ysize = image.size
5
6 delta = delta % xsize
7 if delta == 0: return image
8
9 part1 = image.crop((0, 0, delta, ysize))
10 part2 = image.crop((delta, 0, xsize, ysize))
11 image.paste(part2, (0, 0, xsize-delta, ysize))
12 image.paste(part1, (xsize-delta, 0, xsize, ysize))
13
14 return image
3.3 几何变换。
3.3.1 简单的几何变换。
1 >>>out = im.resize((128, 128)) #
2 >>>out = im.rotate(45) #逆时针旋转 45 度角。
3 >>>out = im.transpose(Image.FLIP_LEFT_RIGHT) #左右对换。
4 >>>out = im.transpose(Image.FLIP_TOP_BOTTOM) #上下对换。
5 >>>out = im.transpose(Image.ROTATE_90) #旋转 90 度角。
6 >>>out = im.transpose(Image.ROTATE_180) #旋转 180 度角。
7 >>>out = im.transpose(Image.ROTATE_270) #旋转 270 度角。
各个调整之后的图像为:
图片1:
图片2:
图片3:
图片4:
3.3.2 色彩空间变换。
convert() : 该函数可以用来将图像转换为不同色彩模式。
3.3.3 图像增强。
Filters : 在 ImageFilter 模块中可以使用 filter 函数来使用模块中一系列预定义的增强滤镜。
1 >>>import ImageFilter
2 >>>imfilter = im.filter(ImageFilter.DETAIL)
3 >>>imfilter.show()
3.4 序列图像。
即我们常见到的动态图,最常见的后缀为 .gif ,另外还有 FLI / FLC 。PIL 库对这种动画格式图也提供了一些基本的支持。当我们打开这类图像文件时,PIL 自动载入图像的第一帧。我们可以使用 seek 和 tell 方法在各帧之间移动。
1 import Image
2 im.seek(1) # skip to the second frame
3
4 try:
5 while 1:
6 im.seek( im.tell() + 1)
7 # do something to im
8 except EOFError:
9 pass
3.5 更多关于图像文件的读取。
最基本的方式:im = Image.open("filename")
类文件读取:fp = open("filename", "rb")im = Image.open(fp)
字符串数据读取:import StringIOim = Image.open(StringIO.StringIO(buffer))
从归档文件读取:import TarIOfp = TarIo.TarIO("Image.tar", "Image/test/lena.ppm")im = Image.open(fp)
基本的 PIL 目前就练习到这里。其他函数的功能可点击 这里 进一步阅读。