写在前面
在选择特征的时候,曾纠结过是用颜色矩、像素值还是图片卷积过后的值作为特征,我选择了后者,因为个人觉得手写数字识别相对于水质颜色识别来说,更关注图片的二维结构信息,如果用颜色矩或者像素值作为特征,就把图片的二维结构信息拆散了,这对于模型训练来说,是得不偿失的。本次大作业步骤分为以下几步。
步骤一:图片尺寸归一化
所使用到的图片数据可以到百度云上下载:
链接:https://pan.baidu.com/s/1iVxq669KNSB-FOP1CpdGPg
提取码:86w5
经过观察,trainImages和testImages文件夹下的图片尺寸不一,在构建特征集之前需要把图片尺寸归一化。
在trainImages和testImages文件夹下,提取目录下所有图片,更改尺寸后再保存回trainImages,testImages目录中。
# test1.py
from PIL import Image
import os.path
import glob
def convertjpg(jpgfile,outdir,width=28,height=28):
img=Image.open(jpgfile)
try:
new_img=img.resize((width,height),Image.BILINEAR)
new_img.save(os.path.join(outdir,os.path.basename(jpgfile)))
except Exception as e:
print(e)
for jpgfile in glob.glob(r".\trainImages\*.png"):
convertjpg(jpgfile,r".\trainImages")
此时trainImages和testImages文件夹下已经经过图片尺寸归一化。
步骤二:把图片转为像素矩阵并获取图片标签
把每一张28 x 28的图片分别转为长度为784的向量,再合并成一个大的像素矩阵pixel_data,并获取图片标签,函数功能封装如下。
# test2.py
from PIL import Image
import numpy as np
import re
import os
path = r".\trainImages"
#获取训练集和测试集图片名称
def get_img_names(path=path):
file_names = os.listdir(path)
img_names = []
for i in file_names:
if re.findall('^\d_\d+\.png$', i) != []:
img_names.append(i)
return img_names
#获取图片像素大矩阵,每一张图片占一行向量
def get_img_data(img_names):
pixel_data = []
for i in img_names:
img = Image.open(".\\trainImages\\" + i)
#因为图片是黑白图像,我只取一个颜色通道的像素信息作为特征集
img_vector = np.array(img.split()[0]).reshape(1,