基于人工神经网络的数字字符识别系统demo(一):字符去噪、分割

最近尝试利用神经网络做数字字符识别,大概做了一下。整体很简陋,就是先对测试图片做下预处理,然后通过重采样提取特征,最后通过神经网络进行训练和识别。感兴趣的可以点击这里 了解一下,欢迎多多指教。

这里我大概介绍一下怎样将一副包含多个字符的图片进行去噪处理进而分割出单个字符,关于opencv中怎样使用ANN详见Opencv中ANN神经网络使用示例

原始图:

效果图:

下面介绍一下处理步骤,

1.载入图像并作灰度化

2.二值化并作反色处理

3.提取外轮廓

4.根据轮廓大小去除噪声

5.再次查找轮廓并根据轮廓找出其boundingRect

6.将boundingRect分别保存为图像即可。

好,这样就基本结束了。直接上源码:

//--------------------------------------【程序说明】-------------------------------------------
//      程序说明:基于ANN的数字字符识别系统
//      程序描述:
//      开发测试所用操作系统: Windows 7 64bit
//      开发测试所用IDE版本:Visual Studio 2010
//      开发测试所用OpenCV版本: 2.4.8
//------------------------------------------------------------------------------------------------

#include <opencv2/opencv.hpp>  //头文件
using namespace cv;  //包含cv命名空间
//#include <fstream>
//using namespace std;  

void main( )
{
    //载入图像
    Mat srcImage = imread("scanDigit.bmp");
    imshow("【原始图】",srcImage);//显示载入的图片
    //灰度化
    Mat grayImage;
    cvtColor(srcImage, grayImage, CV_RGB2GRAY);//RGB图像的灰度化
    imshow("【灰度图】",grayImage);
//  imwrite("grayImage.jpg",grayImage);//保存图片
    //二值化
    Mat biImage;
    threshold(grayImage, biImage, 200, 255, CV_THRESH_BINARY_INV ); //对灰度图进行二值化处理,前景变为白色后findContours()寻找外轮廓才好用
    imshow("【二值化图】",biImage);
//  imwrite("biImage.jpg",biImage);
/*
    //查看图片数据
    ofstream outImage("imagedata.txt", ios::out | ios::binary);
    for( unsigned int nrow = 0; nrow < srcImage.rows; nrow++)
    {
        for(unsigned int ncol = 0; ncol < srcImage.cols; ncol++)
        {
            uchar val = srcImage.at<unsigned char>(nrow,ncol);
            outImage << (int(val) > 200 ? 1 :0) ; //File3<<int(val)<< endl ;
        }
        outImage << endl ;
    }
    outImage.close();
*/
    //去除噪声
    Mat contourImage(biImage.rows, biImage.cols, CV_8UC1, Scalar(0, 0, 0));
    Mat noiseRemoveImage = biImage.clone();
    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;
    findContours( biImage, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE );
    for(int i = 0; i< contours.size(); i++ )
    {
        Scalar color( 255, 255, 255 );
        drawContours( contourImage, contours, i, color, 1, 8, hierarchy, 1);//绘制轮廓
//      printf("轮廓[%d]的面积: %.2f\n", i, contourArea(contours[i]));
        if (contourArea(contours[i]) < 20)          //此处面积20为经验值
        {
            drawContours( noiseRemoveImage, contours, i, Scalar(0, 0, 0), -1, 8, hierarchy, 0);
        }
    }
    imshow( "外轮廓图", contourImage );
    imshow( "去除噪声图", noiseRemoveImage );
/*
    //先做反色处理
    Mat dstImage;
    bitwise_not(srcImage, dstImage);
    imshow( "反色图", dstImage );
*/
/*
    //整体倾斜度调整
    Mat rotMat(2, 3, CV_32FC1);
    Mat rotateImage(noiseRemoveImage.rows, noiseRemoveImage.cols, noiseRemoveImage.type(), Scalar(0, 0, 0));
    Point center = Point(noiseRemoveImage.cols/2, noiseRemoveImage.rows/2);
    double angle = 2.1;//此处指定旋转角度
    //  double angle = slopeImage(noiseImage);
    double scale = 1;
    rotMat = getRotationMatrix2D(center, angle, scale);
    warpAffine(noiseRemoveImage, rotateImage, rotMat, rotateImage.size(),INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));
    imshow( "旋转图", rotateImage );
*/
/*
    //对图像进行膨胀操作
    Mat element = getStructuringElement(MORPH_RECT, Size(3, 3));//定义核
    Mat dilateImage = srcImage.clone();
    morphologyEx(srcImage, dilateImage, MORPH_DILATE, element);
    imshow( "膨胀图", dilateImage);
*/
    //字符分割并作尺寸归一化处理
    Mat SegmentationImage = noiseRemoveImage.clone();
    vector<vector<Point> > segcontours;
    vector<Vec4i> seghierarchy;
    findContours( noiseRemoveImage, segcontours, seghierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
    Mat characterImage;
    Mat dstImage;
    char name[50];
    for (int i = 0; i < segcontours.size(); i++)
    {
        Rect rect = boundingRect(Mat(segcontours[i]));
//      rectangle(SegmentationImage, rect.tl(), rect.br(), Scalar(255, 0, 0));  //将每个方框显示
        //将每个字符的尺寸归一化并保存为图片
        Mat roi = SegmentationImage(rect);
        resize(roi,characterImage,Size(32, 64 ),(0,0),(0,0),INTER_NEAREST);
        //再反色处理
        bitwise_not(characterImage, dstImage);
        sprintf(name, "TestData\\%d.jpg", i);
        imwrite(name,dstImage);
    }
    imshow( "分割图", SegmentationImage);
    //等待任意按键按下
    waitKey(0);
}  

如果想了解整个project,欢迎访问https://github.com/NodYoung/ANNDigitRec

时间: 2024-11-09 00:38:42

基于人工神经网络的数字字符识别系统demo(一):字符去噪、分割的相关文章

基于BP神经网络的简单字符识别算法自小结(C语言版)

本文均属自己阅读源码的点滴总结,转账请注明出处谢谢. 欢迎和大家交流.qq:1037701636 email:[email protected] 写在前面的闲话: 自我感觉自己应该不是一个很擅长学习算法的人,过去的一个月时间里因为需要去接触了BP神经网络.在此之前一直都认为算法界的神经网络.蚁群算法.鲁棒控制什么的都是特别高大上的东西,自己也就听听好了,未曾去触碰与了解过.这次和BP神经网络的邂逅,让我初步掌握到,理解透彻算法的基本原理与公式,转为计算机所能识别的代码流,这应该就是所谓的数学和计

基于SVM与人工神经网络的车牌识别系统

最近研究了支持向量机(Support Vector Machine,SVM)和人工神经网络(Artifical Neural Network,ANN)等模式识别理论,结合OpenCV的书:<Mastering OpenCV with Practical Computer Vision Projects>,将两种思想运用到车辆的车牌识别算法中.车辆识别结合了多种图像处理技术,如视频监控.图像检测.图像分割和光学字符识别(OCR)等,在道路交通监控中有着重要的作用.以下内容主要包含几个方面: 车牌

基于BP神经网络的数字识别

一.BP神经网络 BP(Back Propagation)表示反向传播.BP网络能学习和存贮大量的输入-输出模式映射关系,而无需事前揭示描述这种映射关系的数学方程.它的学习规则是使用最速下降法,通过反向传播来不断调整网络的权值和阈值,使网络的误差平方和最小.BP神经网络模型拓扑结构包括输入层(input).隐层(hidden layer)和输出层(output layer). 图1 三层BP网 如图所示,最下面一层为输入层,中间为隐藏层,最上面为输出层.其中X={x1,x2.......xn},

基于BP神经网络的手写数字识别

一.BP神经网络原理及结构 本部分先介绍神经网络基本单元神经元的结构和作用,再主要介绍BP神经网络的结构和原理. 1.神经元 神经元作为神经网络的基本单元,对于外界输入具有简单的反应能力,在数学上表征为简单的函数映射.如下图是一个神经元的基本结构,  神经元结构 图中是神经元的输入,是神经元输入的权重,是神经元的激活函数,y是神经元的输出,其函数映射关系为 激活函数来描述层与层输出之间的关系,从而模拟各层神经元之间的交互反应.激活函数必须满足处处可导的条件.常用的神经元函数有四种,分别是线性函数

适用于磁性和光学字符识别系统的MICR字符集条码控件MICR E13B

MICR E13B字体是一种在美国.加拿大.波多黎各.巴拿马.英国和其它少数国家的银行支票和汇票中使用的专用条形码字体,主要用来打印适用于磁性和光学字符识别系统的MICR字符.MICR E13B字体包含有十个特别设计的从0到9的数字字符和四个专用符号:transit.amount.on-us和dash.MICR CMC-7字体是一种在墨西哥.法国.西班牙以及大多数西班牙语国家的银行支票中使用的一种专用字体 具体功能: 直接从ISO规范中创建 - MICR E13B字体是按照E13B MICR的I

用BP人工神经网络识别手写数字

http://wenku.baidu.com/link?url=HQ-5tZCXBQ3uwPZQECHkMCtursKIpglboBHq416N-q2WZupkNNH3Gv4vtEHyPULezDb50ZcKor41PEikwv5TfTqwrsQ4-9wmH06L7bYD04u 用BP人工神经网络识别手写数字 yzw20091201上传于2013-01-31|暂无评价|356人阅读|13次下载|暂无简介|举报文档 在手机打开 赖勇浩( http://laiyonghao.com ) 这是我读工

C#中调用Matlab人工神经网络算法实现手写数字识别

手写数字识别实现 设计技术参数:通过由数字构成的图像,自动实现几个不同数字的识别,设计识别方法,有较高的识别率 关键字:二值化  投影  矩阵  目标定位  Matlab 手写数字图像识别简介: 手写阿拉伯数字识别是图像内容识别中较为简单的一个应用领域,原因有被识别的模式数较少(只有0到9,10个阿拉伯数字).阿拉伯数字笔画少并且简单等.手写阿拉伯数字的识别采用的方法相对于人脸识别.汉字识别等应用领域来说可以采用更为灵活的方法,例如基于规则的方法.基于有限状态自动机的方法.基于统计的方法和基于神

基于三维GIS技术的公路交通数字孪生系统

交通运输系统是四个现代化建设的重要保障,在"一带一路"倡议规划背景下,互联网+.智慧交通提升到国家新战略.智慧交通的基石是建立可映射物理世界的虚拟世界,因此大多数交通管理平台项目通过抽象建模构造二维电子地图,并在抽象模型上集成数据及分析工具,实现运营期信息化管理.随着设计.施工.运营全生命周期细化管理日益增长的需求,传统的交通地理信息(Geographic Informa-tion System-Transportation,GIS-T)系统的压力也随之增加.交通基础设施数字化映射为三

数据挖掘入门系列教程(八)之使用神经网络(基于pybrain)识别数字手写集MNIST

目录 数据挖掘入门系列教程(八)之使用神经网络(基于pybrain)识别数字手写集MNIST 下载数据集 加载数据集 构建神经网络 反向传播(BP)算法 进行预测 F1验证 总结 参考 数据挖掘入门系列教程(八)之使用神经网络(基于pybrain)识别数字手写集MNIST 在本章节中,并不会对神经网络进行介绍,因此如果不了解神经网络的话,强烈推荐先去看<西瓜书>,或者看一下我的上一篇博客:数据挖掘入门系列教程(七点五)之神经网络介绍 本来是打算按照<Python数据挖掘入门与实践>