autojs-KNN算法手写数字识别的OpenCV实现

简介: 牙叔教程 简单易懂

牙叔教程 简单易懂



上面这张图片网上说是opencv自带的, 我下载的4.5.2的opencv的安卓版本, 就没找到


knn简介


百科简介


邻近算法,或者说K最近邻(KNN,K-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一。所谓K最近邻,就是K个最近的邻居的意思,说的是每个样本都可以用它最接近的K个邻近值来代表。近邻算法就是将数据集合中每一个记录进行分类的方法  。


网友大奸猫对knn的算法描述


S1 算距离
给定未知样本点A,计算它与训练集中的每个样本点的距离
S2 找邻居
将S1计算好的距离升序排列,取前k个最近的样本点作为A的邻居
S3 确定分类
这k个邻居中,包含邻居数最多的类别作为A的类别


knn示意图


目标是黄色多边形, 距离黄色多边形最近的3个邻居, 有两个是红色, 一个是蓝色,


按照近朱者赤近墨者黑, 少数服从多数来推断, 就认为黄色多边形是红色


也可以说是, 你身边那种人多, 你就会成为那种人


算法常用的距离


曼哈顿距离(城市街区距离)


欧式距离


马氏距离(闵可夫斯基距离)


余弦距离


切比雪夫距离


海明距离


汉明距离


编辑距离


autojs版本


8.8.16-0


本版本自带3.4.3的opencv


knn简要流程


  1. 图片是一大张, 所以第一步是切割图片, 每个图片只包含一个数字
  2. 训练
  3. 预测


训练


训练就是把特征和标签一一对应起来, 再对数据做一些处理,


这里主要说一下特征提取,


特征: 取图片每个像素点的数值, 一张图片是20X20, 就是400个像素, 并且图片是一个通道


关键代码:

let tempData = Imgcodecs.imread(filePath, 0); // 一个通道
tempData = tempData.reshape(0, 1); // 矩阵变为一行
tempData.convertTo(tempData, CvType.CV_32F); // 数据变为浮点数
tempData.copyTo(tmp); // 保存特征
trainlabel.put(0, 0, trainClasses); // 打标签
knn.train(trainData, Ml.ROW_SAMPLE, trainlabel); // 训练


预测


预测就是拿一小部分数据测试,


训练的时候留一小部分数据, 不参加训练, 而是用于预测


预测, 和训练一样,


提取图片特征, 拿去和训练好的数据计算距离,


然后返回匹配度最高的值


关键代码

let tempData = Imgcodecs.imread(filePath, 0); // 一个通道
tempData = tempData.reshape(0, 1); // 矩阵变为一行
tempData.convertTo(tempData, CvType.CV_32F); // 数据变为浮点数
let response = knn.findNearest(tempData, k, nearests); // 计算最佳匹配


统计

log("测试总数: " + testNum);
log("正确分类数: --> " + trueNum);
log("准确率:" + (trueNum / testNum) * 100 + "%");


Mat


mat是opencv常用的数据类型, 理解Mat的格式后, 对理解opencv代码很有帮助


修改Mat


autojs的Mat没有at方法, 那么修改数据就用get和put

runtime.images.initOpenCvIfNeeded();
log(new org.opencv.core.Mat().getClass());
delete org.opencv.core.Mat;
log(new org.opencv.core.Mat().getClass());
importClass(org.opencv.core.Mat);
importClass(org.opencv.core.CvType);
//32位浮点数 1个channel
let trainlabel = Mat.ones(100, 1, CvType.CV_32FC1);
for (var i = 0; i < 100; i++) {
  log("修改前" + i + ": ", trainlabel.get(i, 0));
  let item = util.java.array("float", 1);
  item[0] = i;
  log(trainlabel.put(i, 0, item));
  log("修改后" + i + ": ", trainlabel.get(i, 0));
}


打印Mat常用属性

let trainlabel = Mat.ones(100, 1, CvType.CV_32FC1);
let infoList = [
  "\n",
  "row: " + mat.rows(),
  "col: " + mat.cols(),
  "height: " + mat.height(),
  "width: " + mat.width(),
  "dim: " + mat.dims(),
  "channel: " + mat.channels(),
  "depth: " + mat.depth(),
];
// dims:Mat所代表的矩阵的维度,如 3 * 4 的矩阵为 2 维, 3 * 4 * 5 的为3维
// channels:通道,矩阵中的每一个矩阵元素拥有的值的个数,比如说 3 * 4 矩阵中一共 12 个元素,如果每个元素有三个值,那么就说这个矩阵是 3 通道的,即 channels = 3。常见的是一张彩色图片有红、绿、蓝三个通道
// depth:深度,即每一个像素的位数(bits),在opencv的Mat.depth()中得到的是一个 0 – 6 的数字,分别代表不同的位数:enum { CV_8U=0, CV_8S=1, CV_16U=2, CV_16S=3, CV_32S=4, CV_32F=5, CV_64F=6 }; 可见 0和1都代表8位, 2和3都代表16位,4和5代表32位,6代表64位
log(infoList.join("\n"));
// row: 100
// col: 1
// height: 100
// width: 1


把Mat想象成一堵墙就可以了,


横着的是row,  竖着的是col,


有多少row, 就有多height,


有多少col, 就有多width



Mat参数一般是row前, col后


先看数据在第几行, 再看数据在第几列


也符合人的思维


我们读书也是从左往右, 从上往下


古人的话估计是先看第几列, 再看第几行,


因为古人的书是竖着写的


打印Mat具体的数据

runtime.images.initOpenCvIfNeeded();
importClass(org.opencv.core.Mat);
importClass(org.opencv.core.CvType);
// 3行2列
let trainlabel = Mat.ones(3, 2, CvType.CV_32FC1);
let width = trainlabel.width();
let height = trainlabel.height();
let arr = [];
// height和行数 数值一样
// 可以认为 hegith ⇔ 行数
for (var i = 0; i < height; i++) {
  let childArr = [];
  for (var j = 0; j < width; j++) {
    let item = trainlabel.get(i, j);
    childArr.push(item);
  }
  arr.push(childArr);
}
log(JSON.stringify(arr, null, "    "));
// [
//   [[1.0], [1.0]],
//   [[1.0], [1.0]],
//   [[1.0], [1.0]]
// ]


声明

部分内容来自网络

本教程仅用于学习, 禁止用于其他用途






相关文章
|
3月前
|
算法 计算机视觉 Python
圆形检测算法-基于颜色和形状(opencv)
该代码实现了一个圆检测算法,用于识别视频中的红色、白色和蓝色圆形。通过将图像从RGB转换为HSV颜色空间,并设置对应颜色的阈值范围,提取出目标颜色的区域。接着对这些区域进行轮廓提取和面积筛选,使用霍夫圆变换检测圆形,并在原图上绘制检测结果。
101 0
|
5月前
|
算法 定位技术 vr&ar
一文了解PnP算法,python opencv中的cv2.solvePnP()的使用,以及使用cv2.sovlePnP()方法标定相机和2D激光雷达
一文了解PnP算法,python opencv中的cv2.solvePnP()的使用,以及使用cv2.sovlePnP()方法标定相机和2D激光雷达
820 0
一文了解PnP算法,python opencv中的cv2.solvePnP()的使用,以及使用cv2.sovlePnP()方法标定相机和2D激光雷达
|
7月前
|
机器学习/深度学习 算法 计算机视觉
基于opencv的SVM算法的车牌识别系统设计与实现
基于opencv的SVM算法的车牌识别系统设计与实现
195 3
基于opencv的SVM算法的车牌识别系统设计与实现
|
7月前
|
移动开发 算法 计算机视觉
技术笔记:openCV特征点识别与findHomography算法过滤
技术笔记:openCV特征点识别与findHomography算法过滤
130 0
|
7月前
|
机器学习/深度学习 编译器 算法框架/工具
OpenCV算法库
numba是一个用于编译Python数组和数值计算函数的编译器,这个编译器能够大幅提高直接使用Python编写的函数的运算速度。
|
8月前
|
算法 计算机视觉
【OpenCV】- 分水岭算法
【OpenCV】- 分水岭算法
|
8月前
|
算法 C++ 计算机视觉
Opencv(C++)学习系列---Laplacian拉普拉斯边缘检测算法
Opencv(C++)学习系列---Laplacian拉普拉斯边缘检测算法
359 0
|
8月前
|
算法 C++ 计算机视觉
Opencv(C++)学习系列---Canny边缘检测算法
Opencv(C++)学习系列---Canny边缘检测算法
198 0
|
1天前
|
算法 数据安全/隐私保护
室内障碍物射线追踪算法matlab模拟仿真
### 简介 本项目展示了室内障碍物射线追踪算法在无线通信中的应用。通过Matlab 2022a实现,包含完整程序运行效果(无水印),支持增加发射点和室内墙壁设置。核心代码配有详细中文注释及操作视频。该算法基于几何光学原理,模拟信号在复杂室内环境中的传播路径与强度,涵盖场景建模、射线发射、传播及接收点场强计算等步骤,为无线网络规划提供重要依据。
|
14天前
|
机器学习/深度学习 算法
基于改进遗传优化的BP神经网络金融序列预测算法matlab仿真
本项目基于改进遗传优化的BP神经网络进行金融序列预测,使用MATLAB2022A实现。通过对比BP神经网络、遗传优化BP神经网络及改进遗传优化BP神经网络,展示了三者的误差和预测曲线差异。核心程序结合遗传算法(GA)与BP神经网络,利用GA优化BP网络的初始权重和阈值,提高预测精度。GA通过选择、交叉、变异操作迭代优化,防止局部收敛,增强模型对金融市场复杂性和不确定性的适应能力。
146 80

热门文章

最新文章