机器学习实战:K-近邻(KNN)算法识别26个大写英文字母(A到Z)(含拍照检验步骤详解)

news/2024/11/24 11:09:25/

步骤一:收集数据集

数据集来自于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=90012005526=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:62Jia_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*100if 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=7500re=~re;        %数组取反%放在矩阵里Matrix(j,:)=re;           %Matrix每一行中为文件中图像的endendstr1=int2str(i-11)                %str1是从0开始,一直到26的整数,为txt文件夹的名字str2=strcat(str1,'_')for N = 1:img_numchr = 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);                     %关闭文件endend

代码运行结束后,可以在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:75for k=1:100if i2(j,k)==0i2(j,k)=1;elsei2(j,k)=0;endend
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 listdirdef classify0(inX, dataSet, labels, k):   #对于该函数的解释,见后面图中dataSetSize = dataSet.shape[0]diffMat = tile(inX, (dataSetSize,1)) - dataSetsqDiffMat = diffMat**2sqDistances = sqDiffMat.sum(axis=1)  #every hang add togetherdistances = sqDistances**0.5sortedDistIndicies = distances.argsort()classCount={}          for i in range(k):voteIlabel = labels[sortedDistIndicies[i]]classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1sortedClassCount = 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 returnVectdef 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')

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


http://www.ppmy.cn/news/796735.html

相关文章

Ps部分重点

基本快捷键的使用: CtrlN 新建 CtrlO 打开 Ctrl 放大 Ctrl- 缩小 Ctrl1 100% Shift-Ctrl-l 反选 基本抠图功能:钢笔工具,套索工具,魔棒,橡皮擦,蒙版,通道等(抠图工具很多,了解…

Java去除中英文标点符号

利用的是Unicode编码,Unicode 编码并不只是为某个字符简单定义了一个编码,而且还将其进行了归类。 \pP 其中的小写 p 是 property 的意思,表示 Unicode 属性,用于 Unicode 正表达式的前缀。 大写 P 表示 Unicode 字符集七个字符…

linux命令ps详解

原文地址:http://apps.hi.baidu.com/share/detail/32573968 名称:ps 使用权限:所有使用者 使用方式:ps [options] [--help] 说明:显示瞬间行程 (process) 的动态 参数:ps的参数非常多, 在此仅列出几个常用…

怎么给大写字母标声调

用搜狗输入法设置:给大写字母标声调 1、切换输入法使它悬浮在桌面,如图: 2、打开word,点击小键盘图标---->打开软键盘----->选择“拼音字母”,如图: (1)先输入; &#xff08…

ps命令解释

名称:ps 使用权限:所有使用者 使用方式:ps [options] [--help] 说明:显示瞬间行程 (process) 的动态 参数:ps的参数非常多, 在此仅列出几个常用的参数并大略介绍含义 -A 列出所有的进程 -w 显示加宽可以显示较多…

解决Zotero导入参考文献作者名字字母全部大写问题

Zotero是一款开源的文献导入工具,非常好用,但是也存在一些问题,比如导入文献作者时候名字字母均为大写。 [1] DANELLJAN M, BHAT G, KHAN F S等. ECO: Efficient Convolution Operators for Tracking.[C]//CVPR. 2017, 1: 3. 但是在 GB/T 7…

java string 查找大写字母_java实现统计字符串中大写字母,小写字母及数字出现次数的方法示例...

本文实例讲述了java实现统计字符串中大写字母,小写字母及数字出现次数的方法。分享给大家供大家参考,具体如下: public class TestSubstring { public static void main(String[] args) { getCount("adsJKJ3K21AfaAD134F13241d134134s14…

centos7中ps显示的内容_值得收藏,史上最全Linux ps命令详解

原标题:值得收藏,史上最全Linux ps命令详解 一、程序员的疑惑 大概在十多年前,我当时还是一个产品经理。由于一些工作的原因,需要向运维工程师学习一些linux常用命令。 当使用linux ps这个十分常用的命令时,遇到了一个…