【邮政编码识别】基于matlab灰度二值化邮政编码识别【含Matlab源码788期】

一、简介

1 灰度化 (grayscale)

将彩色图像转化为灰度图像的过程称为图像灰度化。彩色图像中的像素值由RGB三个分量决定,每个分量都有0-255(256种)选择,这样一个像素点的像素值可以有1600万种可能(256256256),而灰度图的像素点的像素值是RGB三个分量值相同的一种特殊的彩色图像, 只有256种可能。所以在图像处理中,往往将各种图像首先灰度化成灰度图像以便后续处理,降低计算量。灰度是指只含亮度信息,不含色彩信息的图像。黑白照片就是灰度图,特点是亮度由暗到明,变化是连续的。灰度图像的描述与彩色图像一样仍然反映了整幅图像的整体和局部的色度和亮度等级的分布和特征,

使用灰度图的好处:
① RGB的值都一样。
② 图像数据即调色板索引值,就是实际的RGB值,也就是亮度值。
③ 因为是256色调色板,所以图像数据中一个字节代表一个像素,很整齐。
所以,做图像处理时一般都采用灰度图。
要表示灰度图,就需要把亮度值进行量化,有四种方法:

(1)分量法
将彩色图像中的三分量的亮度作为三个灰度图像的灰度值,可根据应用需要选取一种灰度图像。
(2)最大值法
将彩色图像中的三分量亮度的最大值作为灰度图的灰度值。
(3)均值法
将彩色图像中的三分量亮度求平均得到灰度图的灰度值。
(4)加权平均法
根据重要性及其它指标,将三个分量以不同的权值进行加权平均。由于人眼对绿色的敏感最高,对蓝色敏感最低,因此,按下式对RGB三分量进行加权平均能得到较合理的灰度图像,f(i,j)=0.30R(i,j)+0.59G(i,j)+0.11B(i,j))。

2 二值化(binaryzation)

图像的二值化是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的黑白效果。将256个亮度等级的灰度图像通过适当的阀值选取而获得仍然可以反映图像整体和局部特征的二值化图像。所有灰度大于或等于阀值的像素被判定为属于特定物体,其灰度值为255,否则这些像素点被排除在物体区域以外,灰度值为0,表示背景或者例外的物体区域。在数字图像处理中,二值图像占有非常重要的地位,首先,图像的二值化有利于图像的进一步处理,使图像变得简单,而且数据量减小,能凸显出感兴趣的目标的轮廓。其次,要进行二值图像的处理与分析,首先要把灰度图像二值化,得到二值化图像。
二值化的常用算法有:

全局二值化: 一幅图像包括目标物体、背景还有噪声,要想从多值的数字图像中直接提取出目标物体,最常用的方法就是设定一个全局的阈值T,用T将图像的数据分成两部分:大于T的像素群和小于T的像素群。将大于T的像素群的像素值设定为白色(或者黑色),小于T的像素群的像素值设定为黑色(或者白色)。全局二值化,在表现图像细节方面存在很大缺陷。为了弥补这个缺陷,出现了局部二值化方法。

局部二值化:按照一定的规则将整幅图像划分为N个窗口,对这N个窗口中的每一个窗口再按照一个统一的阈值T将该窗口内的像素划分为两部分,进行二值化处理。局部二值化也有一个缺陷。这个缺陷存在于那个统一阈值的选定。这个阈值是没有经过合理的运算得来,一般是取该窗口的平局值。这就导致在每一个窗口内仍然出现的是全局二值化的缺陷。为了解决这个问题,就出现了局部自适应二值化方法。

局部自适应二值化:在局部二值化的基础之上,将阈值的设定更加合理化。该方法的阈值是通过对该窗口像素的平均值E,像素之间的差平方P,像素之间的均方根值Q等各种局部特征,设定一个参数方程进行阈值的计算,例如:T=aE+bP+c*Q,其中a,b,c是自由参数。这样得出来的二值化图像就更能表现出二值化图像中的细节。

3 反色(inverse)
反色的实际含义是将R、G、B值反转。若颜色的量化级别是256,则新图的R、G、B值为255减去原图的R、G、B值。这里针对的是所有图,包括真彩图、带调色板的彩色图(又称为伪彩色图)、和灰度图。真彩图不带调色板,每个象素用3个字节,表示R、G、B三个分量。所以处理很简单,把反转后的R、G、B值写入新图即可,比如一个点的颜色为(0,0,0),反色后为(255,255,255)。带调色板的彩色图,其位图中的数据只是对应调色板中的一个索引值,我们只需要将调色板中的颜色反转,形成新调色板,而位图数据不用动,就能够实现反转。

二、源代码

clc, clear, close all

number_Image = 1; %用于处理的原图像编号.
mkdir image; %新建子文件夹.
addpath(genpath(pwd)); %将所有子文件夹添加到路径中.

OriginalImage = imread(['image',num2str(number_Image),'.png']);
figure
subplot(211),imshow(OriginalImage),title('OriginalImage');
hsvImage = rgb2hsv(OriginalImage);  %彩色图像转HSV以消除亮度和背景的影响.
subplot(212),imshow(hsvImage),title('HsvImage');
hsv1 = hsvImage(:,:,1);
hsv2 = hsvImage(:,:,2);
hsv3 = hsvImage(:,:,3);
figure  %显示HSV三层图像
subplot(311),imshow(hsv1),title('Hsv1');
subplot(312),imshow(hsv2),title('Hsv2');
subplot(313),imshow(hsv3),title('Hsv3');
[m, n] = size(hsv1);
d1 = zeros(m, n); 
d2 = zeros(m, n);
for i = 1:m
    for j = 1:n
        if hsv3(i, j)<0.7  %hsv3层用来提取数字
            d1(i, j) = 1;
        else 
            d1(i, j) = 0;
        end
        if hsv2(i, j)>0.7  %hsv2层用来提取方格
            d2(i, j) = 1;
        else 
            d2(i, j) = 0;
        end
    end
end
figure
% subplot(211),imshow(d2);
bw1 = logical(d1);%double转logical型.
thinImage = bwmorph(bw1, 'thin', Inf); %提取骨架.
cleanImage = bwmorph(thinImage, 'clean', Inf); %去除孤立点.
subplot(311),imshow(bw1),title('logicalImage of hsv2');
subplot(312),imshow(thinImage),title('thinImage');
subplot(313),imshow(cleanImage),title('cleanImage');
% SpurImage = bwmorph(g,'spur',3); %去毛刺.
% figure 
% imshow(SpurImage);
sum_rows = zeros(m,1);
sum_columns = zeros(1,n);
for i = 1:m
    for j = 1:n
        if d2(i,j)==1
            sum_rows(i) = sum_rows(i) + 1;
        end
    end
end
boundary_rows_up = find(sum_rows>0, 1, 'first'); %上边界行标.
boundary_rows_down = find(sum_rows>0, 1, 'last' ); %下边界行标.
height = boundary_rows_down - boundary_rows_up +1; %方格高度.

for i = 1:n
    for j = 1:m
        if d2(j,i)==1
            sum_columns(i) = sum_columns(i) + 1;
        end
    end
end
boundary = zeros(m,n); %粗提左右边框
for i = boundary_rows_up:boundary_rows_down
    for j = 1:n
        if sum_columns(j)>m/2
            boundary(i,j) = 1;
        end
    end
end
thinImage_boundary = bwmorph(boundary, 'thin', Inf); %提取左右边框骨架.

n_boundary_c = zeros(1,n); %设立零矩阵存放图像每列的和.
for i = 1:n
    for j = 1:m
        if thinImage_boundary(j,i)==1
            n_boundary_c(i) =  n_boundary_c(i) + 1;
        end
    end
end
boundary_columns = find(n_boundary_c>0);  %提取方格左右边界.
% len = size(boundary_columns); %必有12条边界
sum_boundary = 0; %求方格宽度.
for i = 1:12
    if mod(i,2)==0
        sum_boundary = sum_boundary + boundary_columns(i) - boundary_columns(i-1);
    end
end
width = ceil(sum_boundary/6); %求平均宽度并向上取整.
    
%提取每个方格并显示.
figure
for i = 1:12 %从原图中提取每个方格数据.
    if mod(i,2)==1
        ExtractImage(:, :, (i+1)/2) = OriginalImage(boundary_rows_up:boundary_rows_down, boundary_columns(i):boundary_columns(i)+width);   
    end
end
for i = 1:6
    subplot(3,2,i); imshow(ExtractImage(:, :, i)); title(['number',num2str(i)]);
    BwImage_etc = ~im2bw(ExtractImage(:, :, i),0.7); %灰度图像二值化.
    ThinImage_etc = bwmorph(BwImage_etc, 'thin', Inf); %提取骨架.
%     SpurImage_etc = bwmorph(ThinImage_etc,'spur',4); %去毛刺.
    CleanImage_etc(:,:,i) = bwmorph(ThinImage_etc, 'clean'); %移除孤立点,若去毛刺则将ThinImage_etc改为SpurImage_etc.
    imwrite(CleanImage_etc(:,:,i), ['image/n',num2str(i),'.tif']);
end
function [dir,n] = connex(x1,x2) %x1为数字图,x2为端点图
[end_r,end_c] = find(x2==1); %看端点位置.
n = length(end_r);
dir = zeros(1,n);
for i=1:n %求各端点方向数
    if x1(end_r(i),end_c(i)+1)==1
        dir(i) = 0;
    elseif x1(end_r(i)-1,end_c(i)+1)==1
        dir(i) = 1;
    elseif x1(end_r(i)-1,end_c(i))==1
        dir(i) = 2;
    elseif x1(end_r(i)-1,end_c(i)-1)==1
        dir(i) = 3;
    elseif x1(end_r(i),end_c(i)-1)==1
        dir(i) = 4;
    elseif x1(end_r(i)+1,end_c(i)-1)==1
        dir(i) = 5;
    elseif x1(end_r(i)+1,end_c(i))==1
        dir(i) = 6;
    elseif x1(end_r(i)+1,end_c(i)+1)==1
        dir(i) = 7;
    end
end
end

三、运行结果

【邮政编码识别】基于matlab灰度二值化邮政编码识别【含Matlab源码788期】_第1张图片
【邮政编码识别】基于matlab灰度二值化邮政编码识别【含Matlab源码788期】_第2张图片
【邮政编码识别】基于matlab灰度二值化邮政编码识别【含Matlab源码788期】_第3张图片
【邮政编码识别】基于matlab灰度二值化邮政编码识别【含Matlab源码788期】_第4张图片

四、备注

完整代码或者代写添加QQ 1564658423

你可能感兴趣的:(matlab,图像处理)