likes
comments
collection
share

图像识别原理详解

作者站长头像
站长
· 阅读数 5

计算机不能直接识别一张图片,我们需要通过一些预处理手段将图片转换成计算机能识别的内容,如数字0和1。本节讲解在Python中如何对一张图片进行简单处理,使其变成计算机能识别的内容。

1、图片大小调整及显示

Pillow库是一款功能强大、简单好用的第三方图像处理库,使用人数众多。如果没有该库,可以通过“pip install pillow”命令进行安装。演示代码如下。

数字4.png

from PIL import Image
img = Image.open("数字4.png")
img = img.resize((32,32))
img.show()

输出如下:

图像识别原理详解

2、图片灰度处理

原始图片是一个彩色的数字4,我们需要对其进行灰度处理,将其转换为黑白的数字4,以便之后将其转换为数字0和1,代码如下。

img = img.convert("L")
img.show()

输出如下:

图像识别原理详解

3、图片二值化处理

获得黑白的数字4后,就要进行关键的图像二值化处理了,代码如下。

import numpy as np
img_new = img.point(lambda x:0 if x > 128 else 1) 
arr = np.array(img_new)
  • 第1行代码引入NumPy库,为之后将图像转换为二维数组做准备。

  • 第2行代码中的point()函数可以操控每一个像素点,point()函数中传入的内容为之前讲pandas库时讲过的lambda匿名函数,其含义为将色彩数值大于128的像素点赋值为0,反之赋值为1。图像在进行灰度处理后,每一个像素点由一个取值范围为0~255的数字表示,其中0代表黑色,255代表白色,所以这里以128为阈值进行划分,即原来偏白色的区域赋值为0,原来偏黑色的区域赋值为1。这样便完成了将颜色转换成数字0和1的工作。

  • 第3行代码用NumPy库的array()函数将已经转换成数字0和1的32×32像素的图片转换为32×32的二维数组,并赋给变量arr。

此时可以直接用print()函数将arr打印出来,不过因为其行列较多,可能显示不全,所以我们通过如下代码依次打印arr的每一行。第1行代码中的arr.shape获取的是数组的行数和列数,arr.shape[0]对应行数,arr.shape[1]则对应列数,这样通过for循环就可以打印每行内容了。

for i in range(arr.shape[0]):
    print(arr[i])

图像识别原理详解

4、将二维数组转换为一维数组

上面获得的32×32的二维数组不能用于数据建模,因此还需要用reshape(1,-1)函数将其转换成一行(若写成reshape(-1,1)则转换成一列),即1×1024的一维数组,代码如下。

arr_new = arr.reshape(1,-1)
arr_new

图像识别原理详解

通过如下代码打印输出一维数组arr_new的行列数。

arr_new.shape
(1, 1024)

把处理好的一维数组arr_new传入前面训练好的knn模型中,代码如下。

下载 手写字体识别.xlsx

import pandas as pd
df = pd.read_excel("手写字体识别.xlsx")
x = df.drop(columns="对应数字")
y = df["对应数字"]
from sklearn.model_selection import train_test_split 
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.2,random_state=123)
from sklearn.neighbors import KNeighborsClassifier as KNN 
knn = KNN(n_neighbors=5) 
knn.fit(x_train,y_train)
answer = knn.predict(arr_new)

输出如下:

图像识别原理详解

5、总结

总体来说,K近邻算法是一种非常经典的机器学习算法,其原理清晰简单,容易理解,不过也有一些缺点,例如,样本量较大时计算量大,拟合速度较慢。