人工智能-用matlab实现数字识别

给定一张模板图待识别图,将待识别的数字都读写出来。(模板图和待识别的图片中数字的字体的大小一致)

(国庆研究了很久,放弃了,找到师姐,在师姐的基础上增加了三行识别,如果要多行,需要改进。)

注意:图片格式为单色位图.bmp

模板图:1.bmp

待识别图:3.bmp

clc
clear
%读取
x=imread('1.bmp');%读取标准图片
[M,N]=size(x);    %计算图片大小
t0=0;
t1=0;
A_number=1;
for i=1:1:M      %获取上下边界
    if (t0==0)&&(sum(x(i,:))~=N)
        I0=i;
        t0=1;
    end
    if (t0==1)&&(sum(x(i,:))==N)
        I1=i-1;
        t0=0;
    end
end
distanceI=I1-I0;  %标准图像上下边界差

distanceJ=0;  %标准图像左右距离赋值
for j=1:1:N    %获取左右边界
    if (t1==0) &&sum(x(I0:I1,j))~=I1-I0+1
        J0=j;
        t1=1;
    end
    if (t1==1) &&sum(x(I0:I1,j))==I1-I0+1
        J1=j-1;
        t1=0;
        if J1-J0>distanceJ
            distanceJ=J1-J0;   %获取左右边界最大值
        end
    end
end
if mod(distanceI,5)~=0
    distanceI=distanceI+(5-mod(distanceI,5));%求出标准框的宽
end
if mod(distanceJ,5)~=0
    distanceJ=distanceJ+(5-mod(distanceJ,5));%求出标准框的高
end
height=distanceI/5;
weight=distanceJ/5;%得到每个小框的高和宽
for C_number=1:10
     c1(C_number).C=ones(distanceI,distanceJ);%建立标准框
end
jishu=1;
for j=1:1:N    %获取左右边界
    if (t1==0) &&sum(x(I0:I1,j))~=I1-I0+1
        J0=j;
        t1=1;
    end
    if (t1==1) &&sum(x(I0:I1,j))==I1-I0+1
        J1=j-1;
        t1=0;
        c1(jishu).C(round((distanceI-(I1-I0))/2):round((distanceI-(I1-I0))/2+I1-I0),round((distanceJ-(J1-J0))/2):round((distanceJ-(J1-J0))/2+J1-J0))=x(I0:I1,J0:J1);
        %将数字写入标准框
        jishu=jishu+1; 
    end
end
temp=1;
for i=1:1:(jishu-1)
        for r = 1:1:5
            for s= 1:1:5
                x1=c1(temp).C(((r-1)*height+1):(r*height),((s-1)*weight+1):(s*weight));%获取图中各个数字
                u(r,s)=((weight*height)-sum(sum(x1(:,:))))/(height*weight);%隶属度
            end
        end
        temp=temp+1;
        a(A_number).A=u;%范例的隶属度矩阵集a
        A_number=A_number+1;
end

%识别
y=imread('3.bmp');%读图
[C,D]=size(y);    %计算图片大小
t0=0;
t1=0;
m=1;
for i=1:1:3
  S0(i)=zeros(1,1);
  S1(i)=zeros(1,1);
  disI(i)=zeros(1,1);
end
yanz=[];
bij_value = [];
for i=1:1:C%获取上下边界
    if (t0==0)&&sum(y(i,:))~=D
        S0(m)=i;
        t0=1;
    end
    if (t0==1)&&(sum(y(i,:))==D)
        S1(m)=i-1;
        t0=0;
        disI(m)=S1(m)-S0(m);
        m=m+1;
    end
end
for k=1:1:(m-1)
    B_number=1;
    number=1;
    for j=1:1:D%获取左右边界
        if (t1==0) &&sum(y(S0(k):S1(k),j))~=S1(k)-S0(k)+1
            J0=j;
            t1=1;
        end
        if (t1==1) &&sum(y(S0(k):S1(k),j))==S1(k)-S0(k)+1
            J1=j-1;
            t1=0;
            number=number+1;%计数:一共读取了多少个数字
        end
    end
    for D_number = 1:(number-1)%最终计数会比真实数字个数多一
        c2(D_number).C=ones(distanceI,distanceJ);%建立标准框
    end
    jishu1=1;
    for j=1:1:D%获取左右边界
        if (t1==0) &&sum(y(S0(k):S1(k),j))~=S1(k)-S0(k)+1
            J0=j;
            t1=1;
        end
        if (t1==1) &&sum(y(S0(k):S1(k),j))==S1(k)-S0(k)+1
            J1=j-1;
            t1=0;
            c2(jishu1).C(round((distanceI-(S1-S0))/2):round((distanceI-(S1-S0))/2)+S1(k)-S0(k),round((distanceJ-(J1-J0))/2):round((distanceJ-(J1-J0))/2)+J1-J0)=y(S0(k):S1(k),J0:J1);
            %将数字写入标准框
            jishu1=jishu1+1;
        end
    end
    temp1=1;
    for i=1:1:(number-1)
        for r = 1:1:5
            for s= 1:1:5
                x1=c2(temp1).C(((r-1)*height+1):(r*height),((s-1)*weight+1):(s*weight));%获取图中各个数字
                u(r,s)=((weight*height)-sum(sum(x1(:,:))))/(height*weight);%隶属度
            end
        end
        temp1=temp1+1;
        b(B_number).B=u;%需识别图片的隶属度矩阵集b
        B_number=B_number+1;
    end
    
    %计算贴近度
    for i=1:1:B_number-1
        for j=1:1:10
            tiejd(i,j)=corr2(a(j).A,b(i).B);%用matlab自带的corr2()函数计算贴近度
        end
    end
    
    %function [ bij_value ] = bij( a,b )
    %获取待识别数字与各范例数字的贴近度中最大的,该贴近度的索引减一即为实际数字
    
    for i=1:1:(B_number-1)
        [~,index]=max(tiejd(i,:));%max输出最大元素的索引
        bij_value(k,i)=index-1;
    end
    yanz(k,:)=bij_value(k,:);
    %yanz(k,:)=bij(tiejd,B_number-1);%用matlab自带的corr2()函数识别出的各个数字
    %Out=sprintf('%d',yanz(k,:))%输出
end
Out = sprintf('%d%d%d',yanz(1,:),yanz(2,:),yanz(3,:));
% for k=1:1:(m-1)
%     out=sprintf('%d',yanz(k,:))%多次输出
% end

% function [ bij_value ] = bij( a,b )
% %获取待识别数字与各范例数字的贴近度中最大的,该贴近度的索引减一即为实际数字
% for i=1:1:b
%     [~,index]=max(a(i,:));
%     bij_value(1,i)=index-1;
%     
% end
% end

得到的结果图:

我的分析图:

 

  • 29
    点赞
  • 200
    收藏
    觉得还不错? 一键收藏
  • 26
    评论
以下是基于MATLAB实现数字识别的代码: 1. 加载训练数据和测试数据 ```matlab load('mnist_train.mat'); load('mnist_test.mat'); ``` 2. 数据预处理 ```matlab % 转换成二维数组 X_train = reshape(X_train, [28*28, 60000])'; X_test = reshape(X_test, [28*28, 10000])'; % 标准化 mean_train = mean(X_train); std_train = std(X_train); X_train = (X_train - mean_train) ./ std_train; X_test = (X_test - mean_train) ./ std_train; % 转换为分类问题 Y_train = zeros(size(X_train, 1), 10); for i = 1:size(X_train, 1) Y_train(i, y_train(i)+1) = 1; end ``` 3. 训练模型 ```matlab input_size = 28*28; hidden_size = 25; output_size = 10; W1 = randn(input_size, hidden_size) * 0.01; b1 = zeros(1, hidden_size); W2 = randn(hidden_size, output_size) * 0.01; b2 = zeros(1, output_size); num_epochs = 100; learning_rate = 0.1; batch_size = 100; for epoch = 1:num_epochs % 随机打乱数据 shuffle_index = randperm(size(X_train, 1)); X_train = X_train(shuffle_index, :); Y_train = Y_train(shuffle_index, :); % 分批处理 for batch_start = 1:batch_size:size(X_train, 1) batch_end = min(batch_start+batch_size-1, size(X_train, 1)); X_batch = X_train(batch_start:batch_end, :); Y_batch = Y_train(batch_start:batch_end, :); % 前向传播 Z1 = X_batch * W1 + b1; A1 = sigmoid(Z1); Z2 = A1 * W2 + b2; A2 = softmax(Z2); % 计算损失和梯度 loss = -sum(sum(Y_batch .* log(A2))) / size(X_batch, 1); dZ2 = A2 - Y_batch; dW2 = A1' * dZ2 / size(X_batch, 1); db2 = sum(dZ2, 1) / size(X_batch, 1); dZ1 = (dZ2 * W2') .* sigmoid_gradient(Z1); dW1 = X_batch' * dZ1 / size(X_batch, 1); db1 = sum(dZ1, 1) / size(X_batch, 1); % 更新参数 W1 = W1 - learning_rate * dW1; b1 = b1 - learning_rate * db1; W2 = W2 - learning_rate * dW2; b2 = b2 - learning_rate * db2; end % 输出每个epoch的损失 fprintf('Epoch %d, Loss: %f\n', epoch, loss); end ``` 4. 测试模型 ```matlab % 前向传播 Z1 = X_test * W1 + b1; A1 = sigmoid(Z1); Z2 = A1 * W2 + b2; A2 = softmax(Z2); % 计算准确率 [~, predict_test] = max(A2, [], 2); accuracy = sum(predict_test-1 == y_test) / size(X_test, 1); fprintf('Test Accuracy: %f\n', accuracy); ``` 完整代码如下: ```matlab load('mnist_train.mat'); load('mnist_test.mat'); % 转换成二维数组 X_train = reshape(X_train, [28*28, 60000])'; X_test = reshape(X_test, [28*28, 10000])'; % 标准化 mean_train = mean(X_train); std_train = std(X_train); X_train = (X_train - mean_train) ./ std_train; X_test = (X_test - mean_train) ./ std_train; % 转换为分类问题 Y_train = zeros(size(X_train, 1), 10); for i = 1:size(X_train, 1) Y_train(i, y_train(i)+1) = 1; end input_size = 28*28; hidden_size = 25; output_size = 10; W1 = randn(input_size, hidden_size) * 0.01; b1 = zeros(1, hidden_size); W2 = randn(hidden_size, output_size) * 0.01; b2 = zeros(1, output_size); num_epochs = 100; learning_rate = 0.1; batch_size = 100; for epoch = 1:num_epochs % 随机打乱数据 shuffle_index = randperm(size(X_train, 1)); X_train = X_train(shuffle_index, :); Y_train = Y_train(shuffle_index, :); % 分批处理 for batch_start = 1:batch_size:size(X_train, 1) batch_end = min(batch_start+batch_size-1, size(X_train, 1)); X_batch = X_train(batch_start:batch_end, :); Y_batch = Y_train(batch_start:batch_end, :); % 前向传播 Z1 = X_batch * W1 + b1; A1 = sigmoid(Z1); Z2 = A1 * W2 + b2; A2 = softmax(Z2); % 计算损失和梯度 loss = -sum(sum(Y_batch .* log(A2))) / size(X_batch, 1); dZ2 = A2 - Y_batch; dW2 = A1' * dZ2 / size(X_batch, 1); db2 = sum(dZ2, 1) / size(X_batch, 1); dZ1 = (dZ2 * W2') .* sigmoid_gradient(Z1); dW1 = X_batch' * dZ1 / size(X_batch, 1); db1 = sum(dZ1, 1) / size(X_batch, 1); % 更新参数 W1 = W1 - learning_rate * dW1; b1 = b1 - learning_rate * db1; W2 = W2 - learning_rate * dW2; b2 = b2 - learning_rate * db2; end % 输出每个epoch的损失 fprintf('Epoch %d, Loss: %f\n', epoch, loss); end % 前向传播 Z1 = X_test * W1 + b1; A1 = sigmoid(Z1); Z2 = A1 * W2 + b2; A2 = softmax(Z2); % 计算准确率 [~, predict_test] = max(A2, [], 2); accuracy = sum(predict_test-1 == y_test) / size(X_test, 1); fprintf('Test Accuracy: %f\n', accuracy); function y = sigmoid(x) y = 1 ./ (1 + exp(-x)); end function y = sigmoid_gradient(x) y = sigmoid(x) .* (1 - sigmoid(x)); end function y = softmax(x) x = exp(x - max(x, [], 2)); y = x ./ sum(x, 2); end ```
评论 26
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值