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实现图像数字识别(二)-基本流程 做一个项目之前呢,我们应该有一个总体把握,或者是进度条:来一步步的督促着我们来完成这个项目,在我们正式开始前呢,我们先讨论下流程. 我做的主要 ...
随机推荐
- 解决jsp页面乱码问题
页面也需要设置转码的:页面:(.jsp) <%@ page language="java" import="java.util.*" pageEncodi ...
- 转:Visual C++ sprintf()函数用法
将字串格式化命令.sprintf 是个变参函数,使用时经常出问题,而且只要出问题通常就是能导致程序崩溃的内存访 问错误,但好在由sprintf 误用导致的问题虽然严重,却很容易找出,无非就是那么几种情 ...
- js只能输入数字
$("#SeatCount, #Charge").on("keyup", function () { if (this.value.replace(/^0|\D ...
- PHP curl 模拟登陆
一个比较好的类: $cookie_file=tempnam("C:/users","tmp");生成以以tmp为前缀的文件. <?php define ( ...
- ffdshow 源代码分析1 : 整体结构
ffdshow是一个非常强大的DirectShow解码器,封装了ffmpeg,libmpeg2等解码库.它也提供了丰富的加工处理选项,可以锐化画面,调节画面的亮度等等.不止是视频,FFDShow现在同 ...
- js中()()问题
var aa=function(){}(); var bb=(function(){})(); 今天被问到这个问题,这段js有撒区别. 总结一下,两个函数都是立即执行的意思.但是不同之处是执行的顺序, ...
- BZOJ3296: [USACO2011 Open] Learning Languages
3296: [USACO2011 Open] Learning Languages Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 81 Solved: ...
- Delphi Dcp 和BPL的解释
dcp = delphi compiled package,是 package 编译时跟 bpl 一起产生出来的,记录着 package 中公开的 class.procedure.function.v ...
- HDU5029--Relief grain (树链剖分+线段树 )
题意:n个点构成的无根树,m次操作, 对于操作 x y z, 表示 x 到 y 路径上的 每个点 加一个 z 数字,可重复加.最后输出每个点 加的次数最多的那个数字,如果没有输出0. 赤裸裸的树链剖分 ...
- eclipse 编码设置
eclipse 编码设置 浏览:2840 | 更新:2013-12-31 10:07 一般Java文件编码格式是UTF-8的.以下以默认GBK改为UTF-8为例. 1.改变整个工作空间的编码格式,这样 ...