C#中调用Matlab人工神经网络算法实现手写数字识别
- 手写数字识别实现
设计技术参数:通过由数字构成的图像,自动实现几个不同数字的识别,设计识别方法,有较高的识别率
关键字:二值化 投影 矩阵 目标定位 Matlab
手写数字图像识别简介:
手写阿拉伯数字识别是图像内容识别中较为简单的一个应用领域,原因有被识别的模式数较少(只有0到9,10个阿拉伯数字)、阿拉伯数字笔画少并且简单等。手写阿拉伯数字的识别采用的方法相对于人脸识别、汉字识别等应用领域来说可以采用更为灵活的方法,例如基于规则的方法、基于有限状态自动机的方法、基于统计的方法和基于神经网络的方法等。本文的开始部分先对手写阿拉伯数字识别的整个处理流程进行论述,而这个流程也可以用于图像中其他模式的识别。当然这个处理流程也不是唯一的,可以根据不同的模式识别应用场景进行与之不同的预处理流程。
手写数字图像识别的主要流程:
第一步:对源图像进行黑白二值化处理;0数字的二值化(左)和1的二值化处理(右)
第二步:将图像在水平方向上和竖直方向上进行投影,这样通过投影图形就可以区分1和0的特征;
第三步:用投影计算出区域的横纵坐标,将其分为九份。定位出数字所在图像中的位置,提取该部分进行分析。
第四步:数字0和1的特征比较与识别
在0和一的比较中发现,在分成的九个区域的中间区域,0中间区域灰度为0,1中间区域灰度为1。
- 人工神经网络
人类之所以能够思考,学习,判断,大部分都要归功于人脑中复杂的神经网络。虽然现在人脑的机理还没有完全破译,但是人脑中神经元之间的连接,信息的传递都已为人所知晓。于是人们就想能否模拟人脑的功能用于解决其他问题,这就发展出人工神经网络。
人工神经网络(artificial neural network,缩写ANN),是一种模仿生物神经网络的结构和功能的数学模型或计算模型。神经网络由大量的人工神经元联结进行计算。大多数情况下人工神经网络能在外界信息的基础上改变内部结构,是一种自适应系统。现代神经网络是一种非线性统计性数据建模工具,常用来对输入和输出间复杂的关系进行建模,或用来探索数据的模式。
神经网络是一种运算模型,由大量的节点(或称“神经元”,或“单元”)和之间相互联接构成。每个节点代表一种特定的输出函数,称为激励函数(activation function)。每两个节点间的连接都代表一个对于通过该连接信号的加权值,称之为权重(weight),这相当于人工神经网络的记忆。网络的输出则依网络的连接方式,权重值和激励函数的不同而不同。而网络自身通常都是对自然界某种算法或者函数的逼近,也可能是对一种逻辑策略的表达。
- samples
- 识别流程
流程如图,首先要对数据进行处理,这个主要是批量读取图片和特征提取的过程,特征提取的方法很多,这里只挑选最简单的来实现,然后是训练出一个神经网络的模型,最后用测试数据进行测试。为了方便,这里的神经网络的创建,训练和测试采用Matlab函数来实现。
- 构造标签
要构造出适合神经网络的标签,在这个例子中有10个类,若为某个标签,那么这个位置的值为1,其余为0。
- Matlab实现代码
数字特征提取部分
featureextract.m
% featureextract clear; clc; % global定义全局变量P T,by:chen global P
I = imread('0.bmp'); % 读入数字图片,为个人用画图板制作的图片 p(1,:)=inputvar(I); % inputvar(x)函数为特征提取函数,对第一个0样本的图片进行特征提取
%I = imread('00.bmp'); I = imread('cccc0.bmp'); p(2,:)=inputvar(I); % 读入第二个关于字符0的样本
I = imread('000.bmp'); p(3,:)=inputvar(I);
I = imread('0000.bmp'); p(4,:)=inputvar(I);
I = imread('1.bmp'); p(5,:)=inputvar(I);
%I = imread('11.bmp'); I = imread('cc15.bmp'); p(6,:)=inputvar(I);
I = imread('111.bmp'); p(7,:)=inputvar(I);
I = imread('1111.bmp'); p(8,:)=inputvar(I);
I = imread('2.bmp'); p(9,:)=inputvar(I);
I = imread('22.bmp'); p(10,:)=inputvar(I);
%I = imread('222.bmp'); I = imread('cccc2.bmp'); p(11,:)=inputvar(I);
I = imread('2222.bmp'); p(12,:)=inputvar(I);
%I = imread('3.bmp'); I = imread('cccc3.bmp'); p(13,:)=inputvar(I);
I = imread('33.bmp'); p(14,:)=inputvar(I);
I = imread('333.bmp'); p(15,:)=inputvar(I);
I = imread('3333.bmp'); p(16,:)=inputvar(I);
I = imread('4.bmp'); %I = imread('cc444.bmp'); p(17,:)=inputvar(I);
I = imread('44.bmp'); p(18,:)=inputvar(I);
I = imread('444.bmp'); p(19,:)=inputvar(I);
%I = imread('4444.bmp'); I = imread('cc444.bmp'); p(20,:)=inputvar(I);
%I = imread('5.bmp'); I = imread('cccc5.bmp'); p(21,:)=inputvar(I);
I = imread('55.bmp'); p(22,:)=inputvar(I);
I = imread('555.bmp'); p(23,:)=inputvar(I);
I = imread('5555.bmp'); p(24,:)=inputvar(I);
I = imread('6.bmp'); p(25,:)=inputvar(I);
I = imread('66.bmp'); p(26,:)=inputvar(I);
I = imread('666.bmp'); p(27,:)=inputvar(I);
I = imread('6666.bmp'); p(28,:)=inputvar(I);
I = imread('7.bmp'); p(29,:)=inputvar(I);
I = imread('77.bmp'); p(30,:)=inputvar(I);
I = imread('777.bmp'); p(31,:)=inputvar(I);
I = imread('7777.bmp'); p(32,:)=inputvar(I);
I = imread('8.bmp'); p(33,:)=inputvar(I);
I = imread('88.bmp'); p(34,:)=inputvar(I);
I = imread('888.bmp'); p(35,:)=inputvar(I);
I = imread('8888.bmp'); p(36,:)=inputvar(I);
I = imread('9.bmp'); p(37,:)=inputvar(I);
I = imread('99.bmp'); p(38,:)=inputvar(I);
I = imread('999.bmp'); p(39,:)=inputvar(I);
I = imread('9999.bmp'); p(40,:)=inputvar(I);
I = imread('test0.bmp'); p(41,:)=inputvar(I);
I = imread('test00.bmp'); p(42,:)=inputvar(I);
I = imread('test1.bmp'); p(43,:)=inputvar(I);
I = imread('test11.bmp'); p(44,:)=inputvar(I);
I = imread('test2.bmp'); p(45,:)=inputvar(I);
I = imread('test22.bmp'); p(46,:)=inputvar(I);
I = imread('test3.bmp'); p(47,:)=inputvar(I);
I = imread('test33.bmp'); p(48,:)=inputvar(I);
I = imread('test4.bmp'); p(49,:)=inputvar(I);
I = imread('test44.bmp'); p(50,:)=inputvar(I);
I = imread('test5.bmp'); p(51,:)=inputvar(I);
I = imread('test55.bmp'); p(52,:)=inputvar(I);
I = imread('test6.bmp'); p(53,:)=inputvar(I);
I = imread('test7.bmp'); p(54,:)=inputvar(I);
I = imread('test8.bmp'); p(55,:)=inputvar(I);
I = imread('test9.bmp'); p(56,:)=inputvar(I);
P = p; % 输入的训练与测试样本集 T = [0 0 0 0; 0 0 0 0; 0 0 0 0; 0 0 0 0; 0 0 0 1; 0 0 0 1; 0 0 0 1; 0 0 0 1; 0 0 1 0; 0 0 1 0; 0 0 1 0; 0 0 1 0; 0 0 1 1; 0 0 1 1; 0 0 1 1; 0 0 1 1; 0 1 0 0; 0 1 0 0; 0 1 0 0; 0 1 0 0; 0 1 0 1; 0 1 0 1; 0 1 0 1; 0 1 0 1; 0 1 1 0; 0 1 1 0; 0 1 1 0; 0 1 1 0; 0 1 1 1; 0 1 1 1; 0 1 1 1; 0 1 1 1; 1 0 0 0; 1 0 0 0; 1 0 0 0; 1 0 0 0; 1 0 0 1; 1 0 0 1; 1 0 0 1; 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 0 1 0 0 0 1 1 0 0 1 1 0 1 0 0 0 1 0 0 0 1 0 1 0 1 0 1 0 1 1 0 0 1 1 1 1 0 0 0 1 0 0 1]; % 输出的训练与测试样本 ttest = [0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 1 0 1 0 0 0 1 0 1 0 1 1 0 0 1 1 1 1 0 0 0 1 0 0 1]; % 1至9数字的标准输出
P = P'; T = T'; ttest = ttest'; save featureextractPTttest % 保存特征提取后的输入输出样本数据,生成mat文件以便训练与测试时对样本数据的调用 |
特征提取
% inputvar
特征提取
function y=inputvar(I) % inputvar 特征提取 b = find(I>130);%I:读入的待辨认的数字图片,find(I>130):找出I中大于130的坐标,返回的是线性索引 I(b) = 1;%将图像中大于130的地方置1 % 对数字图片进行二值化处理,读入的图片形式简单以致于二值化方法简单 % 图像预处理部分
[m,n] = size(I);%获取图片的尺寸,m=16,n=8 p = zeros(1,17);%产生一个1*17的零向量 for for i=1+(k-1)*4:m/4+(k-1)*4 for j=1:n/2 if I(i,j)==0 p(k) = p(k)+1; else p(k) = p(k); end end for j=n/2+1:n if I(i,j)==0 p(k+4) = p(k+4)+1; else p(k+4) = p(k+4); end end end end % 把图片分成八个独立区域计算各自的图象密度,作为部分特征向量 p(9) = p(1)+p(2); p(10) = p(3)+p(4); p(11) = p(5)+p(6); p(12) = p(7)+p(8); p(13) = p(1)+p(5); p(14) = p(2)+p(6); p(15) = p(3)+p(7); p(16) = p(4)+p(8); p(17) = p(9)+p(10)+p(11)+p(12); y = p/128; % 合并区域的图像密度作为其他部分特征向量 |
网络训练与仿真部分
网络训练与仿真部分
% bpnntrain 网络训练与仿真部分 clear clc
%load featureextract; load('D:\featureextract'); % 调用输入输出样本数据 P_train = P(:,1:40); %P_train:训练样本集合 T_train = T(:,1:40); P_test = P(:,40:56); T_test = T(:,40:56);
echo on net=newff(minmax(P_train),[9 4],{'tansig','tansig','tansig'},'trainlm'); %newff:建立一个BP网络 %minmax(P_train):对神经网络输入的最大最小值的限制 %[9 4]:神经网络的层结构 %{'tansig','tansig','tansig'}:神经网络各层转移函数 %'trainlm':训练函数 % 利用工具箱建立前向BP网络,输入输出隐层的传递函数均为S型的正切函数,使用Levenberg-Marquard算法进行训练 % 隐层设置9个神经元,4个神经元输出 net = init(net); % 网络初始化 [m1,n1]=size(net.IW{1,1}); net.IW{1,1}=0.3*ones(m1,n1); % 初始化当前输入层权值 [m2,n2]=size(net.LW{2,1}); net.LW{2,1}=0.3*ones(m2,n2); % 初始化隐层与输出层的连接权值 net.trainParam.show=100; %显示的间隔次数 net.trainParam.lr=0.01; %网络学习速率 net.trainParam.mc=0.9; %动量因子 net.trainParam.epochs=1000; %最大训练次数 net.trainParam.goal=0.001;%性能目标值 % 设置训练参数 [net,tr] = train(net,P_train,T_train); % 静态批处理方式进行网络训练,net:更新了权值的神经网络,tr:训练次数和每次训练的误差 fig = plotperf(tr)
Y = sim(net,P_train); % 对训练后的网络进行仿真 E = T_train-Y; perf=mse(E) % 计算仿真误差 echo off
save bpnntrainnetfig
|
网络测试与检测部分
% nnceshi 网络测试与检测部分 function result = TestDigit( img ) %UNTITLED Summary of this function goes here % Detailed
% global定义全局变量P T,by:chen global P % 数字特征提取 %load featureextract; load('D:\featureextract');
% 网络训练与仿真部分 %load bpnntrain net; load('D:\bpnntrain');
% P_test:测试样本的特征向量 P_test = P(:,40:56); T_test = T(:,40:56);
% 对训练后的网络进行测试,net:训练完成了的网络,P_test:测试样本的特征向量,Y:神经网络的输出 % 仿真 Y = sim(net,P_test);
E = T_test-Y;
% 计算测试误差,暂时注释掉====== %perf=mse(E) perf=mse(E); % 读入待辨认的数字图片,检测网络 I = imread(img); % 调用特征提取函数提取数据特征 ptest = inputvar(I);
ptest = ptest'; Y = sim(net,ptest); D = round(Y);%对Y取整 Num = 8*D(1,1)+4*D(2,1)+2*D(3,1)+D(4,1); % 暂时注释掉ttest======= by:chenqp % ttest = ttest(:,Num+1) ttest = ttest(:,Num+1); E = ttest-abs(Y); %均方误差 perf=mse(E); result = Num;
end
|
封装成C#可以调用的DLL
C#调用代码实现
using System;
using System.Collections.Generic;
using QpSolution;
using MathWorks.MATLAB.NET.Arrays;
using MathWorks.MATLAB.NET.Utility; namespace TestMatlab
{
class Program
{
static void Main(string[] args)
{
// 直接使用Math.Pow计算x的y次方
List<double> x = new List<double>();
List<double> y = new List<double>();
List<double> z1 = new List<double>();
List<double> z2 = new List<double>();
Random random = new Random(); for (int i = 0; i < 1000000; i++)
{
x.Add(random.Next(1000) * random.NextDouble());
y.Add(random.Next(1000) * random.NextDouble());
}
DateTime a = DateTime.Now;
for (int i = 0; i < x.Count; i++)
{
z1.Add(Math.Pow(x[i], y[i]));
}
DateTime b = DateTime.Now;
// 直接使用Math.Pow计算x的y次方,第一次运算花费时间ms
Console.WriteLine((b - a).TotalMilliseconds); a = DateTime.Now;
for (int i = 0; i < x.Count; i++)
{
z2.Add(Math.Pow(x[i], y[i]));
}
b = DateTime.Now;
// 直接使用Math.Pow计算x的y次方,第二次运算花费时间ms
Console.WriteLine((b - a).TotalMilliseconds); a = DateTime.Now;
TestClass tc1 = new TestClass();
var z3 = tc1.TestFun((MWNumericArray)x.ToArray(), (MWNumericArray)y.ToArray()).ToArray();
b = DateTime.Now;
Console.WriteLine((b - a).TotalMilliseconds); a = DateTime.Now;
TestClass tc2 = new TestClass();
var z4 = tc2.TestFun((MWNumericArray)x.ToArray(), (MWNumericArray)y.ToArray()).ToArray();
b = DateTime.Now;
Console.WriteLine((b - a).TotalMilliseconds); // MWArray是数据类型的一个父类,下面包括了很多数据类
MWNumericArray mw1 = new MWNumericArray(MWArrayComplexity.Real, 1);
mw1[1] = 2;
MWNumericArray mw2 = new MWNumericArray(MWArrayComplexity.Real, 1);
mw2[1] = 3;
var z5 = tc1.TestFun(mw1, mw2);
Console.WriteLine(z5); // 8 // 传入字符串
MWCharArray str = "D:\\test7.bmp";
var z6 = tc1.TestChar(str);
Console.WriteLine(z6); // 测试传入的文件是否存在,并拿到Matlab返回值
MWCharArray file = "D:\\test7.bmp";
var z7 = tc1.TestFileExist(file);
Console.WriteLine(z7); // 测试人工神经网络识别手写数字,返回matlab函数识别结果
MWCharArray img1 = "D:\\testPic\\c2.bmp";
Console.WriteLine("开始识别第1个图片....");
var pic1 = tc1.TestDigit(img1);
Console.WriteLine("第1个图片识别结果为:" + pic1); MWCharArray img2 = "D:\\testPic\\cccc0.bmp";
Console.WriteLine("开始识别第2个图片....");
var pic2 = tc1.TestDigit(img2);
Console.WriteLine("第2个图片识别结果为:" + pic2); MWCharArray img3 = "D:\\testPic\\cccc2.bmp";
Console.WriteLine("开始识别第3个图片....");
var pic3 = tc1.TestDigit(img3);
Console.WriteLine("第3个图片识别结果为:" + pic3); MWCharArray img4 = "D:\\testPic\\cccc3.bmp";
Console.WriteLine("开始识别第4个图片....");
var pic4 = tc1.TestDigit(img4);
Console.WriteLine("第4个图片识别结果为:" + pic4); MWCharArray img5 = "D:\\testPic\\cccc5.bmp";
Console.WriteLine("开始识别第5个图片....");
var pic5 = tc1.TestDigit(img5);
Console.WriteLine("第5个图片识别结果为:" + pic5); MWCharArray img6 = "D:\\testPic\\abc7.bmp";
Console.WriteLine("开始识别第6个图片....");
var pic6 = tc1.TestDigit(img6);
Console.WriteLine("第6个图片识别结果为:" + pic6); MWCharArray img7 = "D:\\testPic\\abc8.bmp";
Console.WriteLine("开始识别第7个图片....");
var pic7 = tc1.TestDigit(img7);
Console.WriteLine("第7个图片识别结果为:" + pic7); Console.Read(); }
}
}
运行结果
C#中调用Matlab人工神经网络算法实现手写数字识别的更多相关文章
- 基于OpenCV的KNN算法实现手写数字识别
基于OpenCV的KNN算法实现手写数字识别 一.数据预处理 # 导入所需模块 import cv2 import numpy as np import matplotlib.pyplot as pl ...
- 使用AI算法进行手写数字识别
人工智能 人工智能(Artificial Intelligence,简称AI)一词最初是在1956年Dartmouth学会上提出的,从那以后,研究者们发展了众多理论和原理,人工智能的概念也随之扩展 ...
- 学习笔记CB009:人工神经网络模型、手写数字识别、多层卷积网络、词向量、word2vec
人工神经网络,借鉴生物神经网络工作原理数学模型. 由n个输入特征得出与输入特征几乎相同的n个结果,训练隐藏层得到意想不到信息.信息检索领域,模型训练合理排序模型,输入特征,文档质量.文档点击历史.文档 ...
- Pytorch1.0入门实战一:LeNet神经网络实现 MNIST手写数字识别
记得第一次接触手写数字识别数据集还在学习TensorFlow,各种sess.run(),头都绕晕了.自从接触pytorch以来,一直想写点什么.曾经在2017年5月,Andrej Karpathy发表 ...
- 【TensorFlow-windows】(四) CNN(卷积神经网络)进行手写数字识别(mnist)
主要内容: 1.基于CNN的mnist手写数字识别(详细代码注释) 2.该实现中的函数总结 平台: 1.windows 10 64位 2.Anaconda3-4.2.0-Windows-x86_64. ...
- KNN分类算法实现手写数字识别
需求: 利用一个手写数字“先验数据”集,使用knn算法来实现对手写数字的自动识别: 先验数据(训练数据)集: ♦数据维度比较大,样本数比较多. ♦ 数据集包括数字0-9的手写体. ♦每个数字大约有20 ...
- CNN:人工智能之神经网络算法进阶优化,六种不同优化算法实现手写数字识别逐步提高,应用案例自动驾驶之捕捉并识别周围车牌号—Jason niu
import mnist_loader from network3 import Network from network3 import ConvPoolLayer, FullyConnectedL ...
- 实验楼 1. k-近邻算法实现手写数字识别系统--《机器学习实战 》
首先看看一些关键词:K-NN算法,训练集,测试集,特征(空间),标签 举实验楼中的样例,通俗的讲讲K-NN算法:电影有两个分类(标签)-动作片-爱情片.两个特征--打斗场面--亲吻画面. 将那些数字和 ...
- KNN算法案例--手写数字识别
import numpy as np import matplotlib .pyplot as plt import pandas as pd from sklearn.neighbors impor ...
随机推荐
- css页面布局基础
1.盒模型属性包括boder.margin.padding.width.height,这些属性可以使用快捷方式表示,顺序为上右下左,值之间用空格隔开. 2.使用clip和overflow属性时,pos ...
- JS中的混合模式
function Animation(list) { this.box = document.getElementById(list.id); this.size = list.size; this. ...
- Android开发常见问题系列之一:eclipse中adb.exe启动失败或者无法启动
这种情况下大多数是因为存在kadb.exe在执行,或者adb.exe端口被占用. 1,检查是否存在kadb.exe程序正在执行 打开任务管理器,打开详细信息,按照字母顺序找到kadb.exe,结束进程 ...
- Asp.net mvc web api 在项目中的实际应用
Asp.net mvc web api 在项目中的实际应用 前言:以下只是记录本人在项目中的应用,而web api在数据传输方面有多种实现方式,具体可根据实际情况而定! 1:数据传输前的加密,以下用到 ...
- kafka 生产者java编码
public class KafkaProducerDemo { public static void main(String[] args) throws InterruptedException ...
- Cross-Site Scripting(XSS)的类型
本文源自: https://www.owasp.org/index.php/Types_of_Cross-Site_Scripting 在原文理解上翻译为中文. 背景 本文描述多种不同类型的XSS攻击 ...
- Linux:挂载外部U盘,移动数据
背景: 我自己电脑连网采用拨号上网方式,为了把自己的虚拟机中的服务器ip域本机设置为一个局域网,而且ip固定下来,虚拟机网络连接采用了桥接方式.所以也导致了虚拟机内部没法连接外网.(不过可以通过在虚拟 ...
- Entity Framework CodeFirst commands
TOPIC about_EntityFramework SHORT DESCRIPTION Provides information about Entity Framework commands. ...
- VS 编辑并继续(转载)
转]Microsoft Visual Studio vs2008 vs2010 调试 编辑 修改 代码 在vs2008的文件菜单下,前两个菜单项分别是新建项目 和 新建网站. 这两项里,都可以建web ...
- mongoDB windows安装
http://www.mongodb.org/ mongodb的官方文档. http://www.cnblogs.com/lipan/archive/2011/03/08/1966463.html ...