10.4 计算机图像识别
本节使用Python及NumPy、PIL等模块、机器学习方法进行图像识别,编写代码实现手写数字识别,实现思路如下:
(1)从文件中载入图像,将图像转换成矩阵形式。
(2)将彩色图像转换为黑白图像。分析图像的平均颜色,将它作为阈值,高于阈值则接近白色,低于阈值接近黑色。
(3)图像对比。要识别一个图像,先将图像数据转换为数组,然后和数据文件中已有的图像数组进行对比,统计对比结果次数最多的数字,为识别的结果数字。
(4)使用机器学习算法进行图像识别。
接下来介绍具体实现过程。
(1)加载图像,将图像转换成矩阵形式。
image_recognition1.py的源代码如下:
dot.png图像是一个由8个矩阵块组成的集合,如图10-8所示。每个矩阵块表示一行像素,图像有8个像素行,对应8个矩阵块。图像的第一个像素行是由一个黑色像素后面跟着7个白色像素组成的,第一个像素([0 0 0 255])为黑色,其余7个像素(均为[255 255 255 255])为白色。其中[0 0 0 255]的第4个数值是255,记为α值,α表示图像的透明度,α值越低,透明度越高;α值越高,透明度越低。
图10-8 dot.png图像
在Spyder中运行image_recognition1.py,运行结果如下:
(2)将彩色图像转换为黑白图像。
当计算机识别手写数字时,有些数字可能看上去模糊、褪色或变形,类似于验证码中的数字。如果系统要处理数百万种颜色(256×256×256×256),不仅增加了计算的复杂度,且不容易识别出所有图像白色或深色的背景。我们计算图像的平均颜色,将它作为阈值,高于阈值认为更接近白色,低于阈值认为接近黑色。使用阈值函数,可把任何图像变成黑白两色,这种方法使得系统不必困惑于数百万种颜色,从而简化了图像识别的工作量。
image_recognition2.py的源代码如下:
image_recognition2.py的第34、37、39、41行代码加载的图像如图10-9所示。
在Spyder中运行image_recognition2.py,运行结果如图10-10所示,左侧图像为彩色图像,右侧图像为转换成黑白颜色的图像。
(3)使用图像数组比对方式进行图像识别。
通过NumPy函数对图像进行预处理,将图像数据转化成数组,存入数据文件numArEx.txt,这样可以节约时间,而不必每次处理图像时都先将其转化为数组。numArEx.txt文件中包含了所有不同的数字以及它们的数组形式。
图10-9 加载的图像
图10-10 将彩色图像转换为黑白图像
numArEx.txt部分记录如下:
当我们要识别一个数字图像时,将该数字的图像数组和数据文件中已有的数组信息进行对比。如果对比结果是一致的,则识别输出这个数字。whatNumIsThis(filePath)函数用于对比指定图像和数据文件中的图像数组,根据传入的文件路径提取图像,将图像转为数组,并跟数据文件中的数组进行比对。分割函数分割所有像素数组,计数器记录每一次成功的对比。
image_recognition3.py的源代码如下:
在Spyder中运行image_recognition3.py,运行结果如图10-11所示,图10-11(a)中像素数组对比成功次数最多的数字是2(2766次),要比对的图像数字也是2,因此图像2识别成功。图10-11(b)中像素数组对比成功次数最多的数字是9(3060次),要比对的图像数字也是9,因此图像9识别成功。
(4)使用SVM分类器进行图像识别。
加载sklearn提供的数据集,使用支持向量机(SVM)进行分类。
图10-11 使用数组方式对比识别图像
image_recognition4.py的源代码如下:
在Spyder中运行image_recognition3.py,运行结果如图10-12所示,支持向量机模型预测值为数字6,实际上第42张图像的数字也是6,手写数字识别成功。
图10-12 使用SVM分类器识别图像