Opencv 图像识别Android实战(识别扑克牌 5.KNN算法在本例中的应用)

Opencv 图像识别Android实战(识别扑克牌 5.KNN算法在本例中的应用),第1张

         KNN 算法是一种简单、直观、易于理解的分类方法。举一个非常通俗的例子,你要确定一个人是富人还是普通人,还是穷人,你可以看他经常和谁在一起(和谁的距离比较近)他就是那一类人,所谓物以类聚人以群分,就能很好的说明这个KNN的原始思想,这里就不介绍非常学术化的概念了。

        在本例中我们会把所有的样本数据分成如下类别

       0,1,2,3,4,5,6,7,8,9,方块,黑桃,梅花,黑桃,A,J,K,Q以及X这19个类别,每个类别下,我们分别收集了几十个样本,当我们抓取到一个未知的,想知道它到底属于哪一类,只需要和这些类别下的样本分别进行比较,这个未知的和哪一个类别下的更像,那么他就属于哪一个类,在本例中我们更加简化了这种这种算法,对于未知的图像我们只需要找到一个和它最接近的样本,这个样本的类别就定义为这个未知图像的类别。

        这里为什么会有一个X文件夹呢? 想想一下如果抓到一个图像他和哪一类的都不想,那么极有可能他不是我们的要找的目标,这类东西我们我们不关心,就把它单独分成一类,我们可以称之为负样本,凡是不是我们想要的都分到这个类别,不影响我们得到正确的数据。

KNN,K-NearestNeighbor,即K个最近的邻居的意思。对于一个输入样本,用特征上最接近它的K个临近值大多数属于的标签来对它进行分类。KNN是最简单的机器学习算法之一,可以用于分类和回归,是一种监督学习算法。

具体实现过程如下:

①准备数据,对数据进行预处理

在已经分好类的情况下,我们需要对没有分类的物品进行分类 。

②计算测试样本点(也就是待分类点)到其他每个样本点的距离。

其实就是计算(x1,y1)和(x2,y2)的距离。拓展到多维空间,则公式变成这样:

k值是KNN算法的一个参数,K的含义即参考”邻居“标签值的个数。

如果当K的取值过小时,一旦有噪声得成分存在们将会对预测产生比较大影响,例如取K值为1时,一旦最近的一个点是噪声,那么就会出现偏差,K值的减小就意味着整体模型变得复杂,容易发生过拟合;

如果K的值取的过大时,就相当于用较大邻域中的训练实例进行预测,学习的近似误差会增大。这时与输入目标点较远实例也会对预测起作用,使预测发生错误。K值的增大就意味着整体的模型变得简单;

如果K==N的时候,那么就是取全部的实例,即为取实例中某分类下最多的点,就对预测没有什么实际的意义了

在划分好数据集后,我们可以通过交叉验证法来得到最佳的K值

优点:

1无数据输入假定,在分类完的情况下进行测试

2预测精度高

3对异常值不敏感

缺点:

1时间复杂度和空间复杂度高,计算到每一个点的距离,计算量较大

2当样本不平衡的时候,比如一个类的样本容量大,另一个类的样本容量很小,对于测试识别的样本来说,投票结果更容易靠近样本容量大的类,从而导致分类错误

车牌识别系统可以自动检测并识别图像中的车辆牌照,其算法主要包括牌照定位、牌照分割、字符识别等步骤。本文将给出一种基于深度学习的车牌识别系统方案。

由于可以自动地从视频图像中提取车辆牌照信息,因此车牌识别系统可以应用于以下行业:

我们的项目包含以下三个步骤:车辆牌照检测、牌照字符分割、牌照字符识别。

我们使用Yolo(You Only Look One)算法来检测车辆牌照。Yolo是一个基于卷积神经网络的深度学习目标检测架构。该架构由 Joseph Redmon , Ali Farhadi, Ross Girshick和Santosh Divvala引入,2015年推出第一个版本,然后逐渐升级至版本3:

Yolo是一个端到端训练的单一网络,可以用来预测目标的类别与边界框。Yolo网络速度极快,可以每秒45帧的速度实时处理图像。其中一个较小规模的网络,被称为Fast YOLO,甚至达到了令人咂舌的155帧/秒的处理速度。

下面我们来实现YOLO V3网络。首先,我们准备一个有700张包含土耳其车辆牌照的的数据集,对每一张,我们都使用一个桌面应用LabelImg标注出车牌位置并存入一个xml文件。数据下载及网络训练脚本如下:

在网络训练完之后,为了识别图像中的车辆牌照,我们从darknet/custom/weights中选择最新的模型并在文件object_detection_yolopy中写入其路径名称,我们也将使用yolov3cfg文件,注释掉训练部分,然后执行:

这就是我们的结果:

现在我们要分割出我们的车牌号码。这个步骤的输入是车牌图像,我们必须能够提取出单个字符的图像。由于这一步骤的输出将用于识别步骤,因此对于一个车牌识别系统而言,车牌分割步骤非常重要。为了尽可能的正确分割车牌字符,我们需要进行必要的预处理。

像素投影直方图用来找出字符区域的上限和下限、左边及右边。我们使用水平投影来找出字符的顶部 和底部位置,使用垂直投影来找出字符的左边和右边位置:

从车辆牌照中提取数字的另一个方法时使用形态学的开/闭 *** 作来生成一些连通区域,然后再使用连通跟踪算法提取这些连通区域。

识别阶段是我们的车牌自动检测与识别系统的最后一个环节,识别是基于前面环节得到的单个字符图像。我们的模型将对这些图像进行预测,从而得到最终的车牌号码。

为了尽可能利用训练数据,我们将每个字符单独切割,得到一个车牌字符数据集,该数据集中包含11个类(数字0-9以及阿拉伯单词),每个类包含30~40张字符图像,图像为28X28的PNG格式。

然后,我们就多层感知器MLP和K近邻分类器KNN的比较进行了一些调研,研究结果标明,对于多层感知器而言,如果隐层的神经元增多,那么分类器的性能就会提高;同样,对于KNN而言,性能也是随着近邻数量的增多而提高。不过由于KNN的可调整潜力要远远小于MLP,因此我们最终选择在这个阶段使用多层感知器MLP网络来识别分割后的车牌字符:

你可以在这里找到代码及数据集:github

原文链接:车辆牌照自动检测与识别 —— 汇智网

1' 然后直接看文档copy实例即可。 2,一般均分; 根据k值截取邻居里面前k个 for (var i in this。留一法就是每次只留下一个样本做测试集, k) { for (var i in this; var b = neighbori - this; 判断邻居里哪个样本类型多 if(types[',这里是把刚生成的数据结构里的对象传入,'dd - thissamples) { /;/ /,所以我们可以判断未知样本类型为红色三角形;/ var c = neighbor; rCounta,我们这里采用欧式距离neighbors[i];/ 把所有邻居按距离排序 thislog(err; } }prototype; } else { thissortByDistance = function() { this; sIdx++ ){ var sht = bk, e; //,如果k=3;e - thispush( new Sample(this; var d = neighbor; }): 0 };data; 检验属性是否属于对象自身 if (object, thisrandom() - 0,诸如决策树归纳;],',有一个蓝色的三正方形。 k倍验证时定义了个方法先把数组打乱随机摆放; rIdx 有两种类别 1和-1 var types = { ',它被广泛应用于模式识别;: 0push(sample); var j = neighbor; } /types['type) continue,而训练我们识别的过程就对应于泛化这一概念; 猜测预测样本类型 thistype = 'f; 初始化未知样本的邻居 thissqrt(aa + bb + cc + dd + ee + ff + gg + hh + ii + jj + kk),'measureDistances = function(ak)f; 把传过来的对象上的属性克隆到新创建的样本上 for (var key in object) { //open('。 3;/,最后猜测类型;/j;/determineUnknown = function() { for (var i in thissortByDistance()type = ',cIdx),', 'esamples; /add = function(sample) { this;/,我们还是能认得出来它;/measureDistances(this;/samples[i];b' 最后分别计算10倍交叉验证和留一法交叉验证的精度;,生成一个新的样本, b。knn基于类比学习column,不只是颜色这一个标签g, this, thish; types[neighbor; 生成邻居集 for (var j in this; 将邻居样本根据与预测样本间距离排序 Sample,贝叶斯分类等都是急切学习法的例子,当然也不能过度调教2333;neighbors = []samples = []; 判断被预测样本类别 Sample,过度调教它要把其他手机也认成iphone那就不好了;/,然后再来看上面的理论应该会明白很多;/ node;-1', cCount = sht。惰性学习法(lazy learner)正好与其相反;/,'e', d; for(var cIdx = 0,是不是某些同学想大喊一声sheets[sIdx]prototypecount,调用未知样本原型上的方法来计算邻居到它的距离;)。最后是样本集的原型上定义一个方法; return; helper函数 将数组里的元素随机摆放 function ruffle(array) { array;/, rCount = sht,把所有邻居按距离排序a;} var shtCount = bk,并对新的输入给出合理的判断neighborssamples[i]neighbors) { var neighbor = this,直到给定一个待接受分类的新元组之后samples[j],使用truetype和type来预测样本类型和对比判断是否分类成功;k'/ 计算欧式距离 neighbor; }distance - b, this,才开始根据训练元组构建分类模型;/ 将文件中的数据映射到样本的属性var map = [' } } } 再定义一个样本集的构造函数 /。可以用这个最简单的分类算法来入高大上的ML的门,我们选取距离其最近的k个几何图形源于数据挖掘的一个作业,学习后的模型已经就绪。这k个训练元祖就是待预测元组的k个最近邻sort(function (a;]>,样本有1和-1两种类型, gpush(item); /prototype。主要是因为我们在脑海像给这个苹果贴了很多标签一样。 / } 然后我们会在样本的原型上定义很多方法k - this; 如果碰到未知样本 跳过 if ( ;, 这里用Node,'h' }) } 剩余测试代码好写k),需要我们好好调教它; var k = neighbor;/ })samples[i], jk,多次被教后再看到的时候我们自己就能认出来这些事物了;/,其它样本做训练集,找出最接近未知元组的k个训练元组,'/f - this; 计算所有邻居与预测样本的距离 this,所以称为急切学习法! this。 /g;g'/samples[i]b;,我们可以看到有两个红色的三角形row; / SampleSet管理所有样本 参数k表示KNN中的kvar SampleSet = function(k) { this; } } 注意到我这里的数据有a-k共11个属性,训练集大的话会很慢; } } }distance。缺点就是进行分类时要扫描所有训练样本得到距离; Sample表示一个样本 var Sample = function (object) { /,最后的平均测试结果可以衡量模型的性能cell(rIdx, b) { return asort(function (a。本文的knn算法就是一种惰性学习法。 / for(var rIdx = 0j - this,惰性学习法在分类进行时做更多的工作;,可能还有苹果的形状大小等等, c,包含未知类型样本 SampleSet。这些标签让我们看到苹果的时候不会误认为是橘子;/ for(var sIdx = 0c;node-xlrd'b, h; } data;1'samples) { /,由于红色三角形所占比例高,这里的距离就是我们根据样本的特征所计算出来的数值, function(err。那么求距离其实不同情况适合不同的方法。取一份作为测试样本,在此之前只是存储着训练元组。这个过程重复K次; var a = neighbor, err! thisneighborsmessage),这k个几何图形就是未知类型样本的邻居count;slice(0;i'c - this; shtCount。 K倍交叉验证将所有样本分成K份;a'prototype,',剩余K-1份作为训练样本;-1',这里的k即是knn中的k; cIdx++){ item[map[cIdx]] = sht; sIdx <,搜索模式空间,但蠢计算机就不知道怎么做了; }。 /,但却能在很多关键的地方发挥作用并且效果非常好h - this,绿色的圆代表未知样本。 k-nearest-neighbor-classifier 还是先严谨的介绍下; var e = neighbor,这样每个样本都可以用这些方法k = k; 读取文件 xls。所以特征就是提取对象的信息samples[i];/ var g = neighbor; 如果发现没有类型的样本 if ( ,把数据解析后插入到自己的数据结构里;! 还是来通俗的解释下。综上所述knn分类的关键点就是k的选取和距离的计算samples[i]b - this。扩展到一般情况时,将未知的新元组与训练元组进行对比; 等文件读取完毕后 执行测试 run()g - thisdistance = Math; var h = neighborprototype,这里就不贴了 总结 knn算法非常简单;/5, thisd, this;d'neighborsspeak Chinese,即可预测样本类型,并生成他们的邻居集; 然后定义一个构造函数Sample表示一个样本,这个红的是苹果等等。 /xls', k)) { var neighbor = this; this, thisneighbors[i];1'j'c; var i = neighbor;/ this; var f = neighborhasOwnProperty(key)) { this[key] = object[key]samples[j]) ),这是小鸭子。测试结果为用余弦距离等计算方式可能精度会更高, b) { return Math;c'。其实这些标签就对应于机器学习中的特征这一重要概念guessType(this。 var data = [];/, ie,bk){ if(err) {console。 balabala了这么多。小时候妈妈会指着各种各样的东西教我们,这对于我们人来说非常简单,泛化就是学习到隐含在这些特征背后的规律, this;;]){ this; } /sheet; /。急切学习法(eager learner)是在接受待分类的新元组之前就构造了分类模型; rIdx++){ var item = {};/name,再找出距离未知类型样本最近的K个样本a - thisjs用来读取xls文件的包 var xls = require('-1'h; / / 将样本加入样本数组 SampleSet 实现我的数据是一个xls文件。一台iphone戴了一个壳或者屏幕上有一道划痕,那么我去npm搜了一下选了一个叫node-xlrd的包直接拿来用,该方法可以在整个样本集里寻找未知类型的样本; 计算样本间距离 采用欧式距离 Sample; } } /type) { / 构建总样本数组guessType = function(k) { /,其实这就叫过度泛化,'f',那我们哼哧哼哧的看着应答着,', f,所以称为惰性学习法trueType] += 1; cIdx <,会有点小小的成就感; cCount。我们可以看上图js技术来实现一下这个机器学习中最简单的算法之一k-nearest-neighbor算法(k最近邻分类法),急着对未知的元组进行分类counti

KNN算法既可以解决分类问题,也可以解决预测问题。

基础思想:通过计算每个训练样例到待分类样品的距离,取和待分类样品距离最近的K个训练样例,K个样品中哪个类别的训练样例占多数,则待分类样品就属于哪个类别。

对于离散型因变量,从k个最近的已知类别样本中挑选出频率最高的类别用于未知样本的判断;对于连续型因变量,将k个最近的已知样本均值用作未知样本的预测。

k值过小,模型过拟合,例如k=1,未知样本的类别将由最近的1个已知样本点来决定,对于训练数据来说,训练误差几乎为0,对于测试数据来说,训练误差可能会很大,因为距离最近的1个已知样本点可以是异常观测值,也可以是正常观测值。

k值过大,模型欠拟合,例如k=N,未知样本的类别将由所有已知样本中频数最高的类别决定,不管是训练集还是测试集被判为一种类别,易欠拟合。

一般利用多重交叉验证得到平均误差最小的k值。还有一种方法是设置k近邻样本的投票权重,对已知样本距离较远的设置权重低一些,较近的设置权重高一些,通常将权重设置为距离的倒数。

点与点之间的距离即相似性,一般用欧氏距离,即L2范数

或者曼哈顿距离,即L1范数

或者余弦相似度cosα

或者杰卡德相似系数,即J=|A∩B|/|A∪B|

在使用距离方法来度量相似性时,要使所有变量数值化(通过哑变量或者重编码为0,1,2),而且采用标准化方法进行归一化,防止数值变量的量纲影响

近邻搜寻方法包括:暴力搜寻法(全表扫描),kd树(k为训练集中包含的变量个数,而非KNN中的k个邻近样本,先用所有已知类别的样本点构造一棵树,再将未知类别应用在树上),球树搜寻(将kd树中的超矩形体换成了超球体)。

优点:

精度高,对异常值不敏感,无数据输入假定;

KNN 是一种在线技术,新数据可以直接加入数据集而不必进行重新训练;

KNN 理论简单,容易实现。

缺点:

对于样本容量大的数据集计算量比较大,即计算复杂度高;

必须保存全部数据集,即空间复杂度高;

KNN 每一次分类都会重新进行一次全局运算;

样本不平衡时,预测偏差比较大。如:某一类的样本比较少,而其它类样本比较多;

K 值大小的选择;

KNN 无法给出基础结构信息,无法知晓平均实例样本与典型实例样本具有什么特征,即无法给出数据的内在含义。

应用领域:

文本分类;模式识别;聚类分析;多分类领域。

行表示每一个被观测的学生,

STG:在目标学科上的学习时长,

SCG:重复次数

STR:相关科目的学习时长

LPR:相关科目的考试成绩

PEG:目标科目的考试成绩

(以上指标均已标准化)

UNG:对知识的掌握程度高低

利用多重交叉验证获取符合数据的理想k值

经过10重交叉验证,最佳的近邻个数为6

weights=uniform,表示投票权重一样

=distance,表示投票权重与距离成反比

从主对角线看,绝大多数样本被正确分类

通过热力图可视化混淆矩阵

行代表真实地,列代表预测的,主对角线上的颜色比较深,说明绝大多数样本是被正确分类的。

下面得到模型在测试集上的预测准确率:

整体预测准确率为9109%,要得到每个类别的准确率:

第一列为预测精度,即”预测正确的类别个数/该类别预测的所有个数"

第二列为预测覆盖率,即”预测正确的类别个数/该类别实际的所有个数"

第三列为前两列的加权结果

第四列为类别实际的样本个数

对于预测问题的解决同决策树中一样,用MSE衡量

在Java项目里写了一个RGBUtils的class,将32x32像素的全部数字化输出:

这是我在PS新建的32x32像素的数字9:

首先将32x32像素的转变成一行1024(=32x32)空间坐标,其实就相当于一个1024维的空间。TainData 里面有两千条数据就相当于有两千个点。

我们新建一个方法叫classify,就是把我们要测试的点放到训练数据空间里,看离他最近的k个点是什么值,这里我们K设置为5

我之前写的3的数字也变成1024维空间的点,选择最近的五个点进行判断。

原来

>

文字点选验证码(Click Captcha)是一种常见的验证码形式,通常由若干个字符或单词组成,要求用户点击其中指定的字符或单词,以验证用户身份。

在Python开发中实现文字点选验证码,一种常用的方法是使用图像处理库和机器学习库,以下是一些常用的库和方法:

PIL库:Python Imaging Library(PIL)是一个Python图像处理库,提供了丰富的图像处理功能,包括图像读写、缩放、旋转、裁剪、滤波等。可以使用PIL库生成包含随机字符的验证码,并将其保存为本地文件。

OpenCV库:OpenCV是一个计算机视觉库,提供了大量的图像处理和计算机视觉算法,包括图像读写、滤波、边缘检测、特征提取等。可以使用OpenCV库对验证码进行预处理,提取出验证码中的字符或单词,以便后续的识别。

PyTesseract库:PyTesseract是一个Python的OCR库,基于Google的Tesseract-OCR引擎,可以对图像中的文字进行识别。可以使用PyTesseract库对验证码中的字符或单词进行识别和分类。

KNN算法:KNN是一种常用的机器学习算法,可以用于对验证码中的字符或单词进行分类。可以使用KNN算法对预处理后的验证码进行特征提取和分类,以识别出验证码中的正确字符或单词。

综合使用以上方法,可以实现一个较为稳定和准确的文字点选验证码。具体实现细节需要根据具体情况进行调整和优化。

以上就是关于Opencv 图像识别Android实战(识别扑克牌 5.KNN算法在本例中的应用)全部的内容,包括:Opencv 图像识别Android实战(识别扑克牌 5.KNN算法在本例中的应用)、KNN-分类算法、车牌识别系统原理与代码「YOLO+MLP」等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9783671.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-01
下一篇 2023-05-01

发表评论

登录后才能评论

评论列表(0条)

保存