KNN是最简单的机器学习方法之一,很适合新手入门。不过我在网上搜索这个方法时,都是用网上的数据集,并没有人教怎样把自己的图片转化为算法可以识别的。作为一个小白好不容易研究出来了,在这里分享给大家。
原始图片-自己用电脑自带画图软件画的图,命名为3,并保存为PNG格式,放到文件夹下。
代码(Python):
// An highlighted block
from PIL import Image
import matplotlib.pylab as plt
import numpy as np
def picTo01(filename):
#读取图片
img=Image.open(filename).convert('RGBA')
raw_data=img.load()
#根据图片的RGBA值进行降噪
for y in range(img.size[1]):
for x in range(img.size[0]):
if raw_data[x,y][0]<90:
raw_data[x,y]=(0,0,0,255)
for y in range(img.size[1]):
for x in range(img.size[0]):
if raw_data[x,y][1]<136:
raw_data[x,y]=(0,0,0,255)
for y in range(img.size[1]):
for x in range(img.size[0]):
if raw_data[x,y][2]>0:
raw_data[x,y]=(255,255,255,255)
# 把图片转化为32x32
img=img.resize((32,32),Image.LANCZOS)
#把处理后的图片进行保存,便于对比
img.save('test'+filename.split('.')[0]+'.png')
#根据公式把图片黑的地方变成1,白的地方变成0
array=plt.array(img)
gray_array=np.zeros((32,32))
for x in range(array.shape[0]):
for y in range(array.shape[1]):
gray=0.299*array[x][y][0]+0.587 * array[x][y][1] + 0.114 * array[x][y][2]
#white
if gray==255:
gray_array[x][y]=0
#black
else:
gray_array[x][y]=1
#把txt文件命名为此数字并保存
name01=filename.split('.')[0]
name01=name01+'.txt'
np.savetxt(name01,gray_array,fmt='%d',delimiter='')
#执行
picTo01('3.PNG')
把testDigits和trainDigits数据集保存在名为Recognize的文件夹下,并分别创建test.py和train.py
train.py:
import os.path
import numpy as np
#把 32*32 转化为 1*1024
def img32to1024(filename):
returnVect=np.zeros((1,1024))
fr=open(filename,'r')
for i in range(32):
lineStr=fr.readline()
for j in range(32):
returnVect[0,32*i+j]=int(lineStr[j])
return returnVect
#整理train data 和 labels(文件名为label)
hwLabels=[]
trainingFileList=os.listdir('trainingDigits')
m=len(trainingFileList)
trainingMat=np.zeros((m,1024))
for i in range(m):
fileNameStr=trainingFileList[i]
fileStr=fileNameStr.split('.')[0]
classNumStr=int(fileStr.split('_')[0])
hwLabels.append(classNumStr)
trainingMat[i,:]=img32to1024('trainingDigits/%s' % fileNameStr)
test.py:
import os.path
import numpy as np
import train as tr
def classify(inX,k):
dataSetSize=tr.m
diffMat=inX-tr.trainingMat
sqDiffMat=diffMat**2
sqDistances=sqDiffMat.sum(axis=1)
distances=sqDistances**0.5
#get the rank
sortedDistances=distances.argsort()
classCount={}
for i in range(k):
voteIlabel=tr.hwLabels[sortedDistances[i]]
classCount[voteIlabel]=classCount.get(voteIlabel,0)+1
sortedClassCount=sorted(classCount.items(),reverse=True)
return sortedClassCount[0][0]
#test
testFileList=os.listdir('testDigits')
errorCount=0.0
mTest=len(testFileList)
realLabel=[]
testLabel=[]
for i in range(mTest):
fileNameStr=testFileList[i]
fileStr=fileNameStr.split('.')[0]
classNumStr=int(fileStr.split('_')[0])
vectorUnderTest=tr.img32to1024('testDigits/%s' % fileNameStr)
testLabel=classify(vectorUnderTest,3)
print("the classifier came back with:%s, the real answer is:%s" %(testLabel,classNumStr))
if(testLabel!=classNumStr):
errorCount+=1.0
print(errorCount/mTest)
代码及数据集下载