OpenCV——识别手写体数字
这个是树莓派上运行的, opencv3
opencv提供了一张手写数字图片给我们,如下图所示,可以作为识别手写数字的样本库。

0到9共十个数字,每个数字有五行,一行100个数字。首先要把这5000个数字截取出来。
图片大小为1000*2000,则每个数字块大小为20*20。
1.截取样本并存储
以下代码为截取以上数字并将其存储在矩阵中的过程
训练的数据,一般都会是两个矩阵,一个矩阵存放着数据图像,另一个矩阵存放数据图像对应的数字
Mat src = imread("sample.png");
Mat grayImage;
cvtColor(src, grayImage, CV_BGR2GRAY);
threshold(grayImage, grayImage, , , CV_THRESH_BINARY);
int p = ; //一个数字大小为20*20
int m = grayImage.rows / p; //横行的数字个数m
int n = grayImage.cols / p; //纵列的数字个数n
Mat data, labels; //data存放样本数据,label为data样本所对应的数字
for( int i = ; i < n; i++){
int y = i * p; //纵列第i个数字开始的位置
for(int j = ; j < m; j++){
int x = j * p; //横行第i个数字开始的位置
Mat dst;
grayImage(Range(x,x + p), Range(y, y + p)).copyTo(dst);
data.push_back(dst.reshape(,)); //将20*20大小矩阵变为1*400 向量
labels.push_back( j / ); //对应数据向量存储的数字
}
}
data.convertTo(data, CV_32F); //改变像素的数据类型为浮点型
Mat trainData, trainLabels;
trainData = data(Range(, ), Range::all());
trainLabels = labels(Range(, ), Range::all());
2.处理待识别数字的图像
//处理代检测图像
Mat Image, dst;
Image = imread("6.png");
cvtColor(Image, Image, COLOR_BGR2GRAY);
threshold(Image, Image, , , CV_THRESH_BINARY_INV);
imshow("Image", Image);
Image.copyTo(dst);
vector< vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours(Image,contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
vector<Point> point = contours[];
Rect rect = boundingRect(point);
int x = rect.x, y = rect.y;
int h=rect.height, w = rect.width;
Mat now = dst(Range(x, x+h-), Range(y, y+w-));
//dst(rect).copyTo(now);
resize(now,now,Size(,));
3.使用knn算法进行识别,要将识别的图像也进行像训练样本一样的处理
我在运行程序时,一直有如下的错误,换了好几种处理图片的方式,仍然没有用
Mat_<float> nums;
nums = now.reshape(,);
nums.convertTo(nums, CV_32F);
imshow("待测图像", now);
/* Mat mm;
mm.push_back(now.reshape(0,1));
mm.convertTo(mm,CV_32F);
Mat nums = mm(Range(0,1),Range::all());
/*float imagedata[20*20];
for(int i =0; i < 20; i++){
for(int j=0;j<20;j++){
imagedata[ i *20 +j] = now.data[i *20+j];
}
}
Mat nums(1,20*20, CV_32F, imagedata);*/
最后查看源代码才发现不是其他参数的问题:
/// 错误 knn->findNearest(nums, 1, Mat()); Mat temp;
knn->findNearest(nums, 1, temp);
//要传入一个具体的Mat类型
最后的识别代码为
//创建knn分类器
Ptr<ml::KNearest> knn = (ml::KNearest::create());
knn->setIsClassifier(true);
Ptr<ml::TrainData> tData = ml::TrainData::create(trainData,ml::ROW_SAMPLE, trainLabels);
knn->train(tData);
Mat temp;
float result = knn->findNearest(nums, , temp); cout << result<<endl;
检查了好多遍,也只是不能识别出所有
程序缺陷:待检测的图像处理问题。不能截取出合适的roi区域
再改进吧。
OpenCV——识别手写体数字的更多相关文章
- OpenCV——识别印刷体数字
数字识别和其他的所有计算机视觉相关的应用都会分为两个步骤:ROI抽取和识别. 1. ROI抽取即将感兴趣的区域从原始图像中分离初来,这个步骤包括二值化,噪点的消除等2. 识别即通过一些分类器将第一步中 ...
- TensorFlow与Flask结合识别手写体数字
阅读本文约“2.2分钟” TensorFlow框架 ——TensorFlow是谷歌基于DistBelief进行研发的第二代人工智能学习系统 ——可被用于语音识别或图像识别等多项机器学习和深度学习领域 ...
- Python 3 利用机器学习模型 进行手写体数字识别
0.引言 介绍了如何生成数据,提取特征,利用sklearn的几种机器学习模型建模,进行手写体数字1-9识别. 用到的四种模型: 1. LR回归模型,Logistic Regression 2. SGD ...
- caffe-windows之手写体数字识别例程mnist
caffe-windows之手写体数字识别例程mnist 一.训练测试网络模型 1.准备数据 Caffe不是直接处理原始数据的,而是由预处理程序将原始数据变换存储为LMDB格式,这种方式可以保持较高的 ...
- Python 3 利用机器学习模型 进行手写体数字检测
0.引言 介绍了如何生成手写体数字的数据,提取特征,借助 sklearn 机器学习模型建模,进行识别手写体数字 1-9 模型的建立和测试. 用到的几种模型: 1. LR,Logistic Regres ...
- Java基于opencv实现图像数字识别(五)—投影法分割字符
Java基于opencv实现图像数字识别(五)-投影法分割字符 水平投影法 1.水平投影法就是先用一个数组统计出图像每行黑色像素点的个数(二值化的图像): 2.选出一个最优的阀值,根据比这个阀值大或小 ...
- Java基于opencv实现图像数字识别(四)—图像降噪
Java基于opencv实现图像数字识别(四)-图像降噪 我们每一步的工作都是基于前一步的,我们先把我们前面的几个函数封装成一个工具类,以后我们所有的函数都基于这个工具类 这个工具类呢,就一个成员变量 ...
- Java基于opencv实现图像数字识别(三)—灰度化和二值化
Java基于opencv实现图像数字识别(三)-灰度化和二值化 一.灰度化 灰度化:在RGB模型中,如果R=G=B时,则彩色表示灰度颜色,其中R=G=B的值叫灰度值:因此,灰度图像每个像素点只需一个字 ...
- Java基于opencv实现图像数字识别(二)—基本流程
Java基于opencv实现图像数字识别(二)-基本流程 做一个项目之前呢,我们应该有一个总体把握,或者是进度条:来一步步的督促着我们来完成这个项目,在我们正式开始前呢,我们先讨论下流程. 我做的主要 ...
随机推荐
- php实现冒泡排序
冒泡排序是非常容易理解和实现,,以从小到大排序举例:设数组长度为N.1.比较相邻的前后二个数据,如果前面数据大于后面的数据,就将二个数据交换.2.这样对数组的第0个数据到N-1个数据进行一次遍历后,最 ...
- MemCached高级缓存
MemCached高级缓存配置 Memcache相关介绍: memcache 是一个高性能的分布式的内存对象缓存系统,它能够存储各种各样的的数据,包括图片,视频,文件等等.缓存功能. DB.数据源-- ...
- HTML5数据存储
介绍两种对象使用方法: sessionStorage方法如果关闭了浏览器,这个保存的数据就丢失. 1.sessionStorage 保存数据:sessionStorage.setItem(key,va ...
- C#泛型理解(转)
[译]C# 理解泛型 PDF 浏览:http://www.tracefact.net/document/generics-in-csharp.pdf源码下载:http://www.tracefact ...
- TFS 如何恢复到指定版本
一. 签出文件,然后获得指定版本. 二. 覆盖本地文件. 三.选择合并冲突. 四. 签入恢复的文件. 五. 解决冲突,选择抛弃服务器版本.
- Swift—重写-备
========================= 重写实例属性 我们可以在子类中重写从父类继承来的属性,属性有实例属性和静态属性之分,他们在具体实现也是不同的. 实例属性的重写一方面可以重写gett ...
- 方便john破解linux密码批处理
Title:方便john破解linux密码批处理 -- 2011-11-23 17:31 自定义文件HASH名和字典名批处理(单一文件): @echo offcolor 0asetlocal enab ...
- Android使用百度地图定位
下面事例是使用Android平台的部分代码.对于这个平台百度的开放人员已经写了完整的demo,把工程导入到eclipse中之后一般没有错误,如果报错的话,eclipse也会给出提示.一般可以通过将pr ...
- mobile优化
原文: http://queue.acm.org/detail.cfm?id=2510122 译文: http://www.w3cfuns.com/forum.php?mod=viewthread&a ...
- Altium Designer如何批量修改名称,数值,封装
方法一: altium里的封装管理库 1,Tools -> Footprint Manager -> ...2,在Component List里选择要改的器件3,在View and Edi ...