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 ...
随机推荐
- 使用TCP协议的NAT穿透技术
一直以来,说起NAT穿透,很多人都会被告知使用UDP打孔这个技术,基本上没有人会告诉你如何使用TCP协议去穿透(甚至有的人会直接告诉你TCP协议是无法实现穿透的).但是,众所周知的是,UDP是一个无连 ...
- sampleGradient(sampler,uv,dds,ddy)
vsm里面用这个梯度采样 采放了z,z*z的shadowmap 这种采样方式和普通sample有什么区别
- 编程计算并输出1~n之间所有素数之和
http://www.tuicool.com/articles/qaaA3i TODO
- https+ssl详解
这是转载别人的写的很好,(转:崔永秀) 把这几天学习到的关于ssl和https协议的内容在这里分享一下,适合一些像我一样的网络协议初学者. ssl协议的起源和历史我就不再多说了,就是那个Netscap ...
- codeforces #236 div2 简洁题解
A:A. Nuts time limit per test 1 second memory limit per test 256 megabytes input standard input outp ...
- redis集群部署之codis 维护脚本
搞了几天redis cluster codis 的部署安装,测试,架构优化,配合研发应用整合,这里记一些心得! 背景需求: 之前多个业务都在应用到redis库,各业务独立占用主从两台服务器,硬件资源利 ...
- Grid行编辑插件
//操作列不显示应该就是autoLoad的问题. Ext.onReady(function () { Ext.BLANK_IMAGE_URL = "E ...
- 初识layer 快速入门
http://layer.layui.com/hello.html 如果,你初识layer,你对她不知所措,你甚至不知如何绑定事件… 那或许你应该用秒做单位,去认识她. 开始了解 第一步:部署 下载l ...
- Acdream1217 Cracking' RSA(高斯消元)
题意:给你m个数(m<=100),每个数的素因子仅来自于前t(t<=100)个素数,问这m个数的非空子集里,满足子集里的数的积为完全平方数的有多少个. 一开始就想进去里典型的dp世界观里, ...
- oracle创建表空间,创建用户(转)
//创建临时表空间 create temporary tablespace test_temp tempfile 'E:\oracle\product\10.2.0\oradata\testserve ...