opencv实现KNN手写数字的识别
人工智能是当下很热门的话题,手写识别是一个典型的应用。为了进一步了解这个领域,我阅读了大量的论文,并借助opencv完成了对28x28的数字图片(预处理后的二值图像)的识别任务。
预处理一张图片:
首先采用opencv读取图片的构造函数读取灰度的图片,再采用大津法求出图片的二值化的阈值,并且将图片二值化。
int otsu(const IplImage* src_image) {
double sum = 0.0;
double w0 = 0.0;
double w1 = 0.0;
double u0_temp = 0.0;
double u1_temp = 0.0;
double u0 = 0.0;
double u1 = 0.0;
double delta_temp = 0.0;
double delta_max = 0.0;
int pixel_count[] = { };
float pixel_pro[] = { };
int threshold = ;
uchar* data = (uchar*)src_image->imageData;
for (int i = ; i < src_image->height; i++) {
for (int j = ; j < src_image->width; j++) {
pixel_count[(int)data[i * src_image->width + j]]++;
sum += (int)data[i * src_image->width + j];
}
}
for (int i = ; i < ; i++) {
pixel_pro[i] = (float)pixel_count[i] / (src_image->height * src_image->width);
}
for (int i = ; i < ; i++) {
w0 = w1 = u0_temp = u1_temp = u0 = u1 = delta_temp = ;
for (int j = ; j < ; j++) {
if (j <= i) {
w0 += pixel_pro[j];
u0_temp += j * pixel_pro[j];
}
else {
w1 += pixel_pro[j];
u1_temp += j * pixel_pro[j];
}
}
u0 = u0_temp / w0;
u1 = u1_temp / w1;
delta_temp = (float)(w0 *w1* pow((u0 - u1), ));
if (delta_temp > delta_max) {
delta_max = delta_temp;
threshold = i;
}
}
return threshold;
}
大津法
void imageBinarization(IplImage* src_image) {
IplImage* binImg = cvCreateImage(cvGetSize(src_image), src_image->depth, src_image->nChannels);
CvScalar s;
int ave = ;
int binThreshold = otsu(src_image);
for (int i = ; i < src_image->height; i++) {
for (int j = ; j < src_image->width; j++) {
s = cvGet2D(src_image, i, j);
ave = (s.val[] + s.val[] + s.val[]) / ;
if (ave < binThreshold) {
s.val[] = s.val[] = s.val[] = 0xff;
cvSet2D(src_image, i, j, s);
}
else {
s.val[] = s.val[] = s.val[] = 0x00;
cvSet2D(src_image, i, j, s);
}
}
}
cvCopy(src_image, binImg);
cvSaveImage(bined, binImg);
//cvShowImage("binarization", binImg);
//waitKey(0);
}
二值化
由于是只进行简单的识别模拟,因此没有做像素断点的处理。获取minst提供的数据集,提取每个图片的hog特征,参数如下:
HOGDescriptor *hog = new HOGDescriptor(
cvSize(ImgWidht, ImgHeight), cvSize(, ), cvSize(, ), cvSize(, ), );
(9个方向换成18个可能会取得更准确的结果,这取决于对图片本身的复杂程度的分析
之后即可训练knn分类器,进行分类了。
void knnTrain() {
#ifdef SAVETRAINED
//knn training;
samples.clear();
dat_mat = Mat::zeros( * nImgNum, , CV_32FC1);
res_mat = Mat::zeros( * nImgNum, , CV_32FC1);
for (int i = ; i != ; i++) {
getFile(dirNames[i], i);
}
preTrain();
cout << "------ Training finished. -----" << endl << endl;
knn.train(dat_mat, res_mat, Mat(), false, );
#ifdef SAVEASXML
knn.save("./trained/knnTrained.xml");
#endif
#else
knn.load("./trained/knnTrained.xml");
#endif
//knn test
cout << endl << "--- KNN test mode : ---" << endl;
int tCnt = ;
int tAc = ;
selfknnTest(tCnt, tAc);
cout << endl << endl << "Total number of test samples : " << tCnt << endl;
cout << "Accuracy : " << float(float(tAc) / float(tCnt)) * << "%" << endl;
}
train
训练结果如下,准确率还是很令人满意的。

opencv实现KNN手写数字的识别的更多相关文章
- OpenCV+TensorFlow图片手写数字识别(附源码)
初次接触TensorFlow,而手写数字训练识别是其最基本的入门教程,网上关于训练的教程很多,但是模型的测试大多都是官方提供的一些素材,能不能自己随便写一串数字让机器识别出来呢?纸上得来终觉浅,带着这 ...
- 手把手教你使用LabVIEW OpenCV DNN实现手写数字识别(含源码)
@ 目录 前言 一.OpenCV DNN模块 1.OpenCV DNN简介 2.LabVIEW中DNN模块函数 二.TensorFlow pb文件的生成和调用 1.TensorFlow2 Keras模 ...
- 机器学习(二)-kNN手写数字识别
一.kNN算法是机器学习的入门算法,其中不涉及训练,主要思想是计算待测点和参照点的距离,选取距离较近的参照点的类别作为待测点的的类别. 1,距离可以是欧式距离,夹角余弦距离等等. 2,k值不能选择太大 ...
- kaggle 实战 (1): PCA + KNN 手写数字识别
文章目录 加载package read data PCA 降维探索 选择50维度, 拆分数据为训练集,测试机 KNN PCA降维和K值筛选 分析k & 维度 vs 精度 预测 生成提交文件 本 ...
- 用Keras搭建神经网络 简单模版(三)—— CNN 卷积神经网络(手写数字图片识别)
# -*- coding: utf-8 -*- import numpy as np np.random.seed(1337) #for reproducibility再现性 from keras.d ...
- 10,knn手写数字识别
# 导包 import numpy as np import matplotlib.pyplot as plt from sklearn.neighbors import KNeighborsClas ...
- KNN手写数字识别
import numpy as np import matplotlib .pyplot as plt from sklearn.neighbors import KNeighborsClassifi ...
- caffe+opencv3.3dnn模块 完成手写数字图片识别
最近由于项目需要用到caffe,学习了下caffe的用法,在使用过程中也是遇到了些问题,通过上网搜索和问老师的方法解决了,在此记录下过程,方便以后查看,也希望能为和我一样的新手们提供帮助. 顺带附上老 ...
- 用tensorflow求手写数字的识别准确率 (简单版)
import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data #载入数据集 mnist = in ...
随机推荐
- vsm shadowmap format
遇到个奇怪的问题. 在做vsm ,shadowmap format RGBA8 结果正常 RGBA16F 场景不形成阴影的地方变纯黑,因为sm里面这些地方变纯黑(感觉这个好修一些) RGBA32F 阴 ...
- PowerDesigner(六)-物理数据模型(PDM逆向工程)(转)
物理数据模型PDM 物理数据模型(Physical Data Model,PDM):在数据库的逻辑结构设计好之后,就需要完成其物理设计,PDM就是为实现这一目的而设计的. 物理数据模型是以常用的DBM ...
- 零成本实现WEB性能测试(一)性能测试基础
1.1 初识性能测试 概念:负载测试&压力测试. 目的:评估系统的能力,识别系统弱点,系统调优,检测问题,验证稳定性. 分类:负载测试,压力测试,容量测试 B/S指标: Avg Rps,平均每 ...
- 关于Web与JS
Web包含的范围比较广, JS只是代码逻辑而已. Web比如HTTP Message, SOAP Message, 浏览器流程,工具等. 不仅仅是代码.
- css选择器浏览器支持情况
css选择器浏览器支持情况
- sql盲注及其相关方法
Sql注入过程数据(后台数据不能回显到页面)不回显采用方法 1:构造逻辑判断 ▲left(database(),1)>’s’ //left()函数 ▲and ascii( ...
- 编写更好的CSS
编写好的CSS代码能提升页面的渲染速度.本质上,一条规则都没有引擎解析的最快.MDN上将CSS选择符归拆分成四个主要类别,如下所示,性能依次降低. ID 规则 Class 规则 标签规则 通用规则 对 ...
- 【译】Python中如何创建mock?
原文地址:http://engineroom.trackmaven.com/blog/making-a-mockery-of-python/ 今天我们来谈论下mock的使用.当然,请不要误会,这里的m ...
- RDLC报表BC4000错误
如果RDLC报表报 BC4000错误,那是因为在矩阵外上面添加了文本框的缘故,导致系统不能读到RDLC报表表体,告诉你报表没有定义: 解决办法: 把表头文字放入矩阵中.
- ExtJs之Ext.isEmpty
<!DOCTYPE html> <html> <head> <title>ExtJs</title> <meta http-equiv ...