机器学习实战:K

您所在的位置:网站首页 两万英文字符 机器学习实战:K

机器学习实战:K

2023-07-24 04:16| 来源: 网络整理| 查看: 265

步骤一:收集数据集

数据集来自于Character Recognition in Natural Images网站。 具体的文件链接为:link 中的EnglishHnd.tgz文件。 在该文件夹中,Img文件内含有Sample001—Sample062等62个文件,每个文件中含有55张900*1200像素的图片。其中Sample001—Sample010文件中是0-9数字的图像;其中Sample011—Sample036文件中是26个大写英文字母的图像;Sample037—Sample062文件中是26个小写英文字母的图像。 本文中,只使用Sample011—Sample036文件,处理大写英文字母图像。

步骤二:批量处理图像

1.由于每一幅图像像素点都为900 * 1200,每一个文件夹中含有55幅图片,26个英文字母有26个文件夹,则最终训练的0,1数据量将要达到 z = 900 ∗ 1200 ∗ 55 ∗ 26 = 1544400000   z = 900*1200*55*26=1544400000\, z=900∗1200∗55∗26=1544400000 处理这么大的数据量,在pycharm环境中,用python处理这些数据时,如果不用GPU加速,可能会提示memory error错误。 因此,需要把文件夹中的图片像素按比例处理到大小为75*100。

2.用Photoshop批量处理图像(CS5.1版本)的具体步骤如下: ① 在ps中打开Sample011文件夹中的图像img011-001.png。 ② 按下‘Alt+F9’,出现动作栏: 在这里插入图片描述 ③ 新建动作,并点击记录(动作名称自取)。 在这里插入图片描述 在这里插入图片描述 ④ 点击:图像——图像大小——修改像素点大小,并约束比例——确定 在这里插入图片描述 ⑤ 点击:文件——储存——文件——关闭 ⑥点击下图所示按钮停止动作: 在这里插入图片描述 ⑦动作录入结束。之后可以点击文件——自动——批处理来处理文件夹中的所有图像,但是我一打开PS批处理就会自动弹出,不知道什么原因。因此,我使用另外一种方法,打开到Sample011文件夹,把所有的图像都一起拖到PS面板中: 在这里插入图片描述 ⑧拖到PS面板后,对每一副图像都点击如下按钮。记得光标要让移动到自己命名的动作上。就可以对每一副图像进行处理。(笨办法,但是很有效,每2分钟大约能处理55张图片) 在这里插入图片描述 这样,就可以依次处理Sample011—Sample036等26个文件中的图像。处理后,这些文件夹中图片的像素大小都变为了75*100。

步骤三:批量处理图像,转化为二进制‘txt’文件

用MATLAB处理,把这26个文件夹中的每一副图像处理为一个1*7500的数组并保存在另一个文件夹中,转换为相应的txt文件。 此时,我的Sample文件路径在:

E:\Machinelearning\MachineLearninginAction\DEMO\machinelearninginaction\Ch02\EnglishHnd\Img

转换后的TXT文件名称为’0_0’到’0_54’,再到’25_54’。’ _ ‘之前的数为26个英文字母的序列,如0对应A,1对应B,以此类推;’_'之后的数为55张照片转换成的对应的文件。 批量转换为相应txt文件的MATLAB代码为:

%识别26个大写字母 for i=11:36 %i为文件夹Sample011—Sample036,如果需要识别小写字母的,则改成i=37:62 Jia_numble=int2str(i); %i转化为字符串形式 Wenjianjia_name=strcat('Sample0',strcat(Jia_numble,'\')); %把两字符串结合在一起 file_pathshort = 'E:\Machine learning\MachineLearninginAction\DEMO\machinelearninginaction\Ch02\EnglishHnd\Img\'; %存储图像的文件夹路径 file_path=strcat(file_pathshort,Wenjianjia_name) img_path_list = dir(strcat(file_path,'*.png')); %获取该文件夹中所有'png'格式的图像名称 img_num = length(img_path_list); %获取图像总数量 Matrix=zeros(55,7500); %55幅图片,像素点为75*100 if img_num > 0 %有满足条件的图像 for j = 1:img_num %逐一读取图像 image_name = img_path_list(j).name; % 图像名,如‘img011-041.png’ I = imread(strcat(file_path,image_name)); fprintf('%d %d %s\n',j,img_num,strcat(file_path,image_name)) % 显示正在处理的图像名 i1=rgb2gray(I); %i1灰度图像 i2=im2bw(i1); % i2是二值图像,不需要求阈值 %图像处理过程 N=size(i2) %求图像维数 %转换为一维数组 re=reshape(i2,1,prod(N)); % prod是累乘,prod(N)=75*100=7500 re=~re; %数组取反 %放在矩阵里 Matrix(j,:)=re; %Matrix每一行中为文件中图像的 end end str1=int2str(i-11) %str1是从0开始,一直到26的整数,为txt文件夹的名字 str2=strcat(str1,'_') for N = 1:img_num chr = int2str(N-1) %N转化为字符串形式 file_retrit='E:\Machine learning\MachineLearninginAction\DEMO\machinelearninginaction\Ch02\EnglishHnd\txt\'; str=strcat(file_retrit,strcat(strcat(str2,chr),'.txt')) fid=fopen(str,'wt'); %写的方式打开文件(若不存在,建立文件); fprintf(fid,'%d',Matrix(N,:)); % d 表示以整数形式写入数据,这正是我想要的; fclose(fid); %关闭文件 end end

代码运行结束后,可以在txt文件夹中找到各种txt文件,如下图: 在这里插入图片描述 为了便于理解,把该文件夹改名为:training_A_TO_Z(训练集数据文件)。

步骤四:用手机拍照并把二值化后的像素矩阵存为txt文件

①在纸上写一个大写的B,并用手机拍照: 在这里插入图片描述 ②用手机自行剪辑的小一点: 在这里插入图片描述 ③然后,用 link 中用PS处理数字2的方法,处理该图片,改成75*100像素大小。 再用MATLAB处理该图像,得到一组测试集文本文件:test_b_recognise.txt MATLAB代码如下:

%单个图片转化为txt文件 i=imread('E:\Machine learning\MachineLearninginAction\DEMO\machinelearninginaction\Ch02\B.jpg'); %图片的存储路径 i1=rgb2gray(i); %i1灰度图像 i2=im2bw(i1); %i2是二值图像,不需要求阈值 for j=1:75 for k=1:100 if i2(j,k)==0 i2(j,k)=1; else i2(j,k)=0; end end end fid=fopen('E:\Machine learning\MachineLearninginAction\DEMO\machinelearninginaction\Ch02\test_b_recognise.txt','wt'); %写的方式打开文件(若不存在,建立文件); fprintf(fid,'%d',i2); %d 表示以整数形式写入数据,这正是我想要的; fclose(fid); %关闭文件 步骤五:用KNN算法识别大写字母

所用到的Python代码及其解释如下:

from numpy import * import operator from os import listdir def classify0(inX, dataSet, labels, k): #对于该函数的解释,见后面图中 dataSetSize = dataSet.shape[0] diffMat = tile(inX, (dataSetSize,1)) - dataSet sqDiffMat = diffMat**2 sqDistances = sqDiffMat.sum(axis=1) #every hang add together distances = sqDistances**0.5 sortedDistIndicies = distances.argsort() classCount={} for i in range(k): voteIlabel = labels[sortedDistIndicies[i]] classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1 sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True) return sortedClassCount[0][0] def img_myself_A_TO_Z(filename): #该函数是针对文本中为1*7500的数组进行处理,返回一个1*7500的数组 returnVect=zeros((1,7500)) fr=open(filename) lineStr=fr.readline() #读取一行,即1*7500个字符 for i in range(7500): returnVect[0,i]=int(lineStr[i]) return returnVect def handwriting_A_TO_Z(filename): #filename为待测试的txt文件,本例中为'test_b_recognise.txt'文件 hwLabels = [] trainingFileList = listdir('training_A_TO_Z') #储存训练集'training_A_TO_Z'文件夹中所有的文件名到列表trainingFileList中 m = len(trainingFileList) trainingMat = zeros((m, 7500)) #每行储存一个图像 for i in range(m): fileNameStr = trainingFileList[i] #第i个文件的文件名储存在fileNameStr中,如‘0_0.txt’ fileStr = fileNameStr.split('.')[0] #把文件名用‘.’分开成两部分,取第一部分,如把‘0_0.txt’分开成‘0_0’与‘txt’两部分,0代表取前一部分 classNumStr = int(fileStr.split('_')[0]) #同理,取‘0_0’中前一部分0,并转换为int类型 hwLabels.append(classNumStr) #训练集的标签矩阵 trainingMat[i, :] = img2vector('training_A_TO_Z/%s' % fileNameStr) #打开training_A_TO_Z文件夹下的文件,读取并转化为1*7500的矩阵后,添加到trainingMat的对应行中,组成训练集的矩阵 test_myself=img_myself(filename) #读取filename文件并转化为1*7500的矩阵,组成测试集 test_myself_label=classify0(test_myself,trainingMat,hwLabels,5) #进行训练并测试,把结果放到test_myself_label中 print("The test_myself_label is ",test_myself_label) List1=['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'] #把结果转化为对应的字母 print("The test_myself_label is ",List1[test_myself_label])

classify0()函数的解释如下图: 在这里插入图片描述 最后检验识别效果:

handwriting_A_TO_Z('test_b_recognise.txt')

得到运行结果: 在这里插入图片描述 识别正确!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3