这个是树莓派上运行的, 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——识别手写体数字的更多相关文章

  1. OpenCV——识别印刷体数字

    数字识别和其他的所有计算机视觉相关的应用都会分为两个步骤:ROI抽取和识别. 1. ROI抽取即将感兴趣的区域从原始图像中分离初来,这个步骤包括二值化,噪点的消除等2. 识别即通过一些分类器将第一步中 ...

  2. TensorFlow与Flask结合识别手写体数字

    阅读本文约“2.2分钟” TensorFlow框架 ——TensorFlow是谷歌基于DistBelief进行研发的第二代人工智能学习系统 ——可被用于语音识别或图像识别等多项机器学习和深度学习领域 ...

  3. Python 3 利用机器学习模型 进行手写体数字识别

    0.引言 介绍了如何生成数据,提取特征,利用sklearn的几种机器学习模型建模,进行手写体数字1-9识别. 用到的四种模型: 1. LR回归模型,Logistic Regression 2. SGD ...

  4. caffe-windows之手写体数字识别例程mnist

    caffe-windows之手写体数字识别例程mnist 一.训练测试网络模型 1.准备数据 Caffe不是直接处理原始数据的,而是由预处理程序将原始数据变换存储为LMDB格式,这种方式可以保持较高的 ...

  5. Python 3 利用机器学习模型 进行手写体数字检测

    0.引言 介绍了如何生成手写体数字的数据,提取特征,借助 sklearn 机器学习模型建模,进行识别手写体数字 1-9 模型的建立和测试. 用到的几种模型: 1. LR,Logistic Regres ...

  6. Java基于opencv实现图像数字识别(五)—投影法分割字符

    Java基于opencv实现图像数字识别(五)-投影法分割字符 水平投影法 1.水平投影法就是先用一个数组统计出图像每行黑色像素点的个数(二值化的图像): 2.选出一个最优的阀值,根据比这个阀值大或小 ...

  7. Java基于opencv实现图像数字识别(四)—图像降噪

    Java基于opencv实现图像数字识别(四)-图像降噪 我们每一步的工作都是基于前一步的,我们先把我们前面的几个函数封装成一个工具类,以后我们所有的函数都基于这个工具类 这个工具类呢,就一个成员变量 ...

  8. Java基于opencv实现图像数字识别(三)—灰度化和二值化

    Java基于opencv实现图像数字识别(三)-灰度化和二值化 一.灰度化 灰度化:在RGB模型中,如果R=G=B时,则彩色表示灰度颜色,其中R=G=B的值叫灰度值:因此,灰度图像每个像素点只需一个字 ...

  9. Java基于opencv实现图像数字识别(二)—基本流程

    Java基于opencv实现图像数字识别(二)-基本流程 做一个项目之前呢,我们应该有一个总体把握,或者是进度条:来一步步的督促着我们来完成这个项目,在我们正式开始前呢,我们先讨论下流程. 我做的主要 ...

随机推荐

  1. 后台返回data直接在页面转换

    <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <fmt: ...

  2. 09 - 删除vtkDataObject中的ShouldIReleaseData() and ReleaseDataFlag 方法 VTK 6.0 迁移

    VTK6 引入了许多不兼容的变.其中之一是删除vtkDataObject中所有有关管道的方法.下面列出来的就是其中的一些方法: ShouldIReleaseData() SetReleaseDataF ...

  3. 在网页上看到想要的颜色,如何知道这种颜色的颜色代码和 RGB 颜色值?

    启动QQ的情况下,按截图快捷键(ctrl+alt+A),鼠标移动到要取色的地方即可看到,如下图: references: http://www.zhihu.com/question/20328538

  4. 【转】Java中 List的遍历

    原文网址:http://blog.csdn.net/player26/article/details/3955906 import java.util.ArrayList; import java.u ...

  5. Java---设计模块(工厂方法)

    ★ 场景和问题 Java程序开发讲究面向接口编程,隐藏具体的实现类,可是如何得到接口呢? 工厂类的命名规范:***Factory 单例工厂方法的命名规范:getInstance() 工厂的本质是&qu ...

  6. 笔记:java并发实践2

    public interface Executor { void execute(Runnable command); } 虽然Executor是一个简单的接口,但它为灵活且强大的异步任务框架提供了基 ...

  7. MongoDB开发学习(1)开天辟地,经典入门

    原文地址:http://www.cnblogs.com/xumingxiang/archive/2012/04/08/2437468.html 如果你从来没有接触MongoDB或对MongoDB有一点 ...

  8. 使用MapReduce将HDFS数据导入到HBase(一)

    package com.bank.service; import java.io.IOException; import org.apache.hadoop.conf.Configuration;im ...

  9. ios 限制输入长度

    ----------------UITextField限制输入的长度------------ - (BOOL)textField:(UITextField *)textField shouldChan ...

  10. mysql中文名字按首字母排序

    在mysql数据库中可以使用GBK编码对中文进行排序,如名字按首字母排序 order by convert(substr(tu.username,1,1) using 'GBK') 其中substr方 ...