基于贝叶斯识别器的手写数字识别和线性识别器的手写数字识别matlab仿真

目录

一、理论基础

二、核心程序

三、仿真结论


一、理论基础

      手写数字识别是计算机视觉领域中的一个重要问题,其目的是从手写数字图像中自动识别出数字。基于贝叶斯识别器和基于线性识别器是两种常见的手写数字识别算法,本文将从数学公式和算法实现两方面详细介绍这两种算法。

基于贝叶斯识别器的手写数字识别

数学公式

       基于贝叶斯识别器的手写数字识别算法的基本思想是,根据贝叶斯定理计算每个数字的后验概率,并选择具有最高后验概率的数字作为识别结果。具体来说,对于一个手写数字图像 $x$,其属于数字 $i$ 的后验概率为:

$$
p(i|x)=\frac{p(x|i)p(i)}{p(x)}
$$

      其中,$p(x|i)$ 表示数字 $i$ 生成图像 $x$ 的概率,$p(i)$ 表示数字 $i$ 出现的先验概率,$p(x)$ 表示图像 $x$ 出现的概率。由于 $p(x)$ 对所有数字都是相同的,因此可以省略,得到:

$$
p(i|x)\propto p(x|i)p(i)
$$

其中,$\propto$ 表示“正比于”。

$p(x|i)$ 可以通过训练数据集中数字 $i$ 的样本计算得到,通常使用高斯分布来建模,即:

$$
p(x|i)=\frac{1}{(2\pi)^{d/2}|\Sigma_i|^{1/2}}\exp\left(-\frac{1}{2}(x-\mu_i)^T\Sigma_i^{-1}(x-\mu_i)\right)
$$

       其中,$d$ 表示图像的维度,$\mu_i$ 表示数字 $i$ 的均值向量,$\Sigma_i$ 表示数字 $i$ 的协方差矩阵。

$p(i)$ 可以通过训练数据集中数字 $i$ 的样本计算得到,即 $p(i)=n_i/N$,其中 $n_i$ 表示数字 $i$ 的样本数量,$N$ 表示总样本数量。

算法实现

下面是基于贝叶斯识别器的手写数字识别算法的具体实现过程:

预处理
      首先,需要对输入的手写数字图像进行一些预处理操作,包括灰度化、二值化、形态学处理和特征提取等。这些操作可以通过常见的图像处理算法实现。

训练模型
接下来,需要使用训练数据集来训练模型。训练过程包括以下几个步骤:

(1)对于训练数据集中的每个数字 $i$,计算其均值向量 $\mu_i$ 和协方差矩阵 $\Sigma_i$。

(2)计算每个数字 $i$ 的先验概率 $p(i)$。

测试识别
对于测试数据集中的每个手写数字图像,需要使用训练好的模型进行识别。具体过程如下:

(1)对于输入的手写数字图像,进行预处理操作。

(2)对于每个数字 $i$,计算 $p(x|i)p(i)$ 的值,并选择具有最大值的数字作为识别结果。

(3)输出识别结果。

基于线性识别器的手写数字识别

数学公式

      基于线性识别器的手写数字识别算法的基本思想是,使用线性分类器对手写数字图像进行分类。具体来说,对于一个手写数字图像 $x$,其被分类为数字 $i$的概率可以表示为:

$$
p(i|x)=\frac{\exp(w_i^Tx+b_i)}{\sum_{j=0}^9\exp(w_j^Tx+b_j)}
$$

其中,$w_i$ 表示数字 $i$ 的权重向量,$b_i$ 表示数字 $i$ 的偏置项。

算法实现

下面是基于线性识别器的手写数字识别算法的具体实现过程:

预处理
      与基于贝叶斯识别器的手写数字识别算法类似,首先需要对输入的手写数字图像进行一些预处理操作,包括灰度化、二值化、形态学处理和特征提取等。这些操作可以通过常见的图像处理算法实现。

训练模型
接下来,需要使用训练数据集来训练模型。训练过程包括以下几个步骤:

(1)对于训练数据集中的每个数字 $i$,计算其权重向量 $w_i$ 和偏置项 $b_i$。通常使用梯度下降等优化算法来最小化损失函数,具体实现过程可以参考机器学习相关的教材和论文。

测试识别
对于测试数据集中的每个手写数字图像,需要使用训练好的模型进行识别。具体过程如下:

(1)对于输入的手写数字图像,进行预处理操作。

(2)对于每个数字 $i$,计算 $p(i|x)$ 的值,并选择具有最大值的数字作为识别结果。

(3)输出识别结果。

       基于贝叶斯识别器和基于线性识别器都是常见的手写数字识别算法。基于贝叶斯识别器利用贝叶斯定理计算后验概率,建模复杂度较高,但其具有较好的识别性能。基于线性识别器使用线性分类器对手写数字图像进行分类,建模复杂度较低,但其识别性能可能会受到数据分布的影响。应根据实际应用场景选择合适的算法。

二、核心程序


global flag
global pos0
global x0 y0

 pos=get(handles.WritingAxes,'currentpoint');   
 x=pos(1,1);
 y=pos(1,2);
 if flag && (pos(1,1)>=0&pos(1,1)<100) && (pos(1,2)>=0&pos(1,2)<100)  
      line(x,y, 'marker', '.','markerSize',18, 'LineStyle','-','LineWidth',2,'Color','Black');
      if x>x0
          stepX=0.1;
      else
          stepX=-0.1;
      end
      if y>y0
          stepY=0.1;
      else
          stepY=-0.1;
      end
      X=x0:stepX:x;      
                          
      if abs(x-x0)<0.01    
          Y=y0:stepY:y;     
      else
         Y=(y-y0)*(X-x0)/(x-x0)+y0;   
      end
      line(X ,Y, 'marker', '.','markerSize',18, 'LineStyle','-','LineWidth',2,'Color','Black');
      x0=x;
      y0=y;
      pos0=pos;
 else
      flag=0;
 end
 %-------------------------------------------------------------------------
 
 

 %-------------------------------------------------------------------------
function figure1_WindowButtonUpFcn(hObject, eventdata, handles)
%clc
%手写板实现程序---释放鼠标左键结束画线的程序
global flag
flag=0;

%global data
data=[];
Img=getframe(handles.WritingAxes);
imwrite(Img.cdata,'当前手写数字.bmp','bmp');
I=imread('当前手写数字.bmp');
I=rgb2gray(I);
I=im2bw(I);    
imwrite(I,'当前手写数字.bmp','bmp');
I=imread('当前手写数字.bmp');
data=GetFeature(I);
%--------------------------------------------------------------------------





% --- Executes on selection change in popupmenuNUM.
function popupmenuNUM_Callback(hObject, eventdata, handles)
%-------------------------------------------------------------------------

% --- Executes during object creation, after setting all properties.
function popupmenuNUM_CreateFcn(hObject, eventdata, handles)
if ispc
    set(hObject,'BackgroundColor','white');
else
    set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end
%-------------------------------------------------------------------------

%-------------------------------------------------------------------------
function pushbuttonSave_Callback(hObject, eventdata, handles)

%global data
I=imread('当前手写数字.bmp');
data=GetFeature(I);

load template pattern;

num=get(handles.popupmenuNUM,'value');
switch num
    case 1
        msgbox('请选择数字类别再保存','提示');
    case 2
        pattern(1,1).num=pattern(1,1).num+1;
        pattern(1,1).feature(:,pattern(1,1).num)=data;
    case 3
        pattern(1,2).num=pattern(1,2).num+1;
        pattern(1,2).feature(:,pattern(1,2).num)=data;
    case 4
        pattern(1,3).num=pattern(1,3).num+1;
        pattern(1,3).feature(:,pattern(1,3).num)=data;
   case 5
        pattern(1,4).num=pattern(1,4).num+1;
        pattern(1,4).feature(:,pattern(1,4).num)=data;
    case 6
        pattern(1,5).num=pattern(1,5).num+1;
        pattern(1,5).feature(:,pattern(1,5).num)=data;
    case 7
        pattern(1,6).num=pattern(1,6).num+1;
        pattern(1,6).feature(:,pattern(1,6).num)=data;
    case 8
        pattern(1,7).num=pattern(1,7).num+1;
        pattern(1,7).feature(:,pattern(1,7).num)=data;
    case 9
        pattern(1,8).num=pattern(1,8).num+1;
        pattern(1,8).feature(:,pattern(1,8).num)=data;
    case 10
        pattern(1,9).num=pattern(1,9).num+1;
        pattern(1,9).feature(:,pattern(1,9).num)=data;
    case 11
         pattern(1,10).num=pattern(1,10).num+1;
        pattern(1,10).feature(:,pattern(1,10).num)=data;
end
        
save template pattern;       
%--------------------------------------------------------------------------


%-------------------------------------------------------------------------
function pushbuttonFeature_Callback(hObject, eventdata, handles)

%global data
I=imread('当前手写数字.bmp');
data=GetFeature(I);
data=data';

fprintf('当前手写数字的特征如下所示:\n')
for i=1:25
    if data(i)>0.1
        data(i)=1;
    else
        data(i)=0;
    end
   fprintf(num2str(data(i)));
   fprintf('   ');
   
   if i/5==1 || i/5==2 || i/5==3 || i/5==4 || i/5==5
       fprintf('\n');
   end
end
%-------------------------------------------------------------------------

%--------------------------------------------------------------------------
function pushbuttonNUM_Callback(hObject, eventdata, handles)

load template;
num0=pattern(1,1).num;
disp(['数字0的样本数量为:',num2str(num0)])

num1=pattern(1,2).num;
disp(['数字1的样本数量为:',num2str(num1)])

num2=pattern(1,3).num;
disp(['数字2的样本数量为:',num2str(num2)])

num3=pattern(1,4).num;
disp(['数字3的样本数量为:',num2str(num3)])

num4=pattern(1,5).num;
disp(['数字4的样本数量为:',num2str(num4)])

num5=pattern(1,6).num;
disp(['数字5的样本数量为:',num2str(num5)])

num6=pattern(1,7).num;
disp(['数字6的样本数量为:',num2str(num6)])

num7=pattern(1,8).num;
disp(['数字7的样本数量为:',num2str(num7)])

num8=pattern(1,9).num;
disp(['数字8的样本数量为:',num2str(num8)])

num9=pattern(1,10).num;
disp(['数字9的样本数量为:',num2str(num9)])
%-------------------------------------------------------------------------
up2136

三、仿真结论

 

猜你喜欢

转载自blog.csdn.net/ccsss22/article/details/131319087