基于 matlab 的三种面值人民币的自动识别
摘 要
本文通过分析第五版人民币自身特征,分别利用主色调提取、长宽比提取、中值滤波特征图像提取、特征数字提取等四种方法,通过
matlab 软件来实现对第五套人民币 100 元、50 元、和 20 元这三个不同面值的纸币进行自动识别。大致思路如下:通过纸币图像特征区域内,不同面值人民币颜色分量比值数不同;不同面值纸币的长宽比不同;不同面值纸币左下角特征图案不同;纸币中间部分面额数字不同, 利用不同的数字特征来分别区分出不同面额的纸币。
关键词:第五套人民币 主色调 长宽比 特征图案 自动识别
前言:随着科技的发展,很多行业都出现了基于人民币纸币识别技术的智能化无人收费系统,节省大量人力资源。人民币纸币的识别技术不仅可以应用在自动售货售票上,也可以应用到银行的自动存取款机,手机营业厅的自动交费机等。目前已有的识别方法主要是利用统计方法进行识别,如尺寸比较法、模板匹配、人工神经网络等。以不同面值人民币自动识别方法的应用日益广泛为背景,本小组提出多种通过利用matlab 软件、图像处理技术,实现对第五版人民币 20 元、
50 元、100 元这三个不同面值纸币,进行简易、快速的自动识别方法, 并能够在保证识别准确率的情况下,实现对纸币的快速自动识别。本小组四名成员刘光冉、邵爱刚、杨秋怡、刘红丹同学,经过共同商讨, 确立了特征区域图像主色调不同、纸币长宽比不同、特征图像不同、不同币值特征数字这四个方向。并分别从四种不同方向入手,查阅大量相关资料,明确各种方法的实现步骤,共同努力实现程序编写及论文和答辩的准备。
本文主要介绍通过 matlab 软件对所采集的图像进行四种不同方法处理,利用不同面值人民币的特征点,分别实现对第五套人民币
20 元、50 元、100 元这三个不同面值纸币进行准确的识别的方法。纸币识别具体过程如下:
1、读取图像,将所需的图像放在一定的文件中储存以备所用。
2、滤波降噪,为了减少图像噪点,为了便于以后的图像的相关处理, 便于区分与识别。
3、纸币摆正,针对纸币可能出现的不同的情况需要对纸币进行校正处理,如若倾斜则进行校正处理,如若不倾斜直接进行下一步。
4、采用相应的方法剔除背景,只提取纸币部分,避免背景造成的相关的干扰,便于准确快速的识别纸币的不同面值。
5、具体的实施思路有四种方法,分别是主色调、图像轮廓长宽比、特征部位(左下角)、特征数字(中间部位),具体部位如下图(1)
(2)(3)(4)所示,然后针对不同的思路设计出相应的程序并分别进行处理比对,最后准确快速的识别出不同的纸币面值。
(一)、主色调识别
首先将纸币的图像从相应的背景下提取出来,然后找到一个色调集中的部分,如图(1)所示。分别提取该部分图像的 RGB 三色分量。以面值为 100 的为例,该部分面积比较大且容易提取与区分。图像的相应的该部分提取出来后,利用 R、G、B 分量灰度值累加后的R/G 比值确定某一个范围,并通过多次实验确定区间阈值,以此来区分 100、
50、20 的面值,具体程序代码以及相应的结果分析如下:
图(1)
% 颜色判别
% 只取头像部分
function [val_color,IM_pic_real_head] = yanse(IM_pic,left,right,up,down)
% 提取彩色纸币部分
IM_pic_real = IM_pic(up:down,left:right,:);
% 提取头像部分
[h,l,g] = size(IM_pic_real);
IM_pic_real_head =
IM_pic_real(round(0.07*h):round(0.87*h),round(0.6*l):round(0.8*l),:); IM_rgb = squeeze(sum(sum(IM_pic_real_head,1),2));
r_g = IM_rgb(1) / IM_rgb(2); if r_g >= 1.41
val_color = 100; elseif r_g <= 0.94
val_color = 50; else
val_color = 20;
end
% | 100 | |
% | 3892554 | |
% | 2519328 | |
% | 2810818 | |
% | r/g = 1.5451[1.41, ] | |
% | 50 | |
% | 10232415 | |
% | 11418984 | |
% | 9625793 | |
% | r/g = 0.8961[ ,0.94] | |
% | 20 |
% 12417005
% 10030369
% 7692525
% r/g = 1.2379[0.95,1.40]
(二)、基于边缘提取的长宽比例识别
首先必须将图像读入,进行滤波处理。依据边缘提取原理依次将100、50、20 的相关的边缘即整个图像的整体轮廓提取出来。以面值为 100 的为例如图(2),计算出长度与宽度的比值,以此相应的三个值,设置相应阈值为判断面值的依据。来区分 100、50、 20 的不同的面值。具体程序代码以及相应的结果分析如下:
图(2)
%长宽比确定币值
function [val_ckb] = changkuanbi(left,right,up,down)
%确定图片的长宽比例
A = (right-left) / (down-up); if A < 2.0000
val_ckb = 100;% 1.9796 1.9778 1.9796 1.9796 1.9796
elseif A < 2.0600
val_ckb = 20;% 2.0421 2.0368 2.0368 2.0286 2.0421
elseif A < 2.2000
val_ckb = 50;% 2.0919 2.0948 2.0919 2.0909 2.0948
else
val_ckb = 0;
end
(三)、基于中值滤波的特征部位(左下角)的图像识别
本方法是基于左下角图示区域的图案差别来区分。100 和 50 的分别为相应的阿拉伯数字,而 20 则为一定的图案。根据实物所对应
的图案位置进行计算,确定出各面值纸币所对应的位置区域,将上述三种面值纸币的取并集,以确保提取特征信息无丢失,如图所示。其次进行中值滤波降噪,然后锁定左下角的位置,二值化,将区域灰度值沿X 坐标向下投影,确定图案对应的投影的左右起点和终点横坐标差值即为图案的长度,以图案的长度除以提取区域的长度为特征值, 设定相应的阈值,以此来辨别不同的面值。具体程序代码以及相应的结果分析如下:
图 (3) function [val_left,FFv_bw] = zuoxia(FF,m,n)
%提取纸币特定部位(左下角)
FFv = FF(round(0.80*m):round(0.94*m),round(0.03*n):round(0.15*n));
FFv=medfilt2(FFv,[4,4]);%进行中值滤波; FFv = FFv(2:(end-4),2:(end-4));
FFv_bw = im2bw(FFv,0.6);%二值化[mt1,nt1] = size(FFv);
Ty = find((sum(FFv_bw) <= (mt1-2)) == 1); try
rat1 = (Ty(end) - Ty(1)) / nt1; if rat1 >= 0.75
val_left = 100; elseif rat1 >= 0.4
val_left = 50; else
val_left = 20;
end catch
val_left = end | 20; | ||
% 100 0.8226 | 0.8226 0.8095 | 0.8095 | 0.8000 |
% 50 0.6735 | 0.6667 0.6923 | 0.6909 | 0.6724 |
% 20 0.0263 0.0351
(四)、基于中值滤波的特征数字(中间部位)的识别
本方法是基于中央位置,即数字部分来进行区分。首先提取出纸币图像,然后确定中央带有特征数字的区域,然后进行中值滤波即降噪处理。其次,将提取的部分进行二值化处理,使其成为只具有黑白两色的图像,将此图像显示出来。从数字的最左边及最右边分别开始以第一个黑点为界计算出数字的宽度,然后计算出此宽度占截取部分比例的大小,中央数字宽度最大的图片即为面值为 100 的人民币,实
现将 100 元纸币首先区分出来。因 50 和 20 的宽度相当,进一步选取
特征数字 5 和 2 左上角区域,从左向右取五列图像的宽度,计算出每
列图像黑点与白点的比值,进而实现对 20 元和 50 元两个面值人民币的区分。体程序代码以及相应的结果分析如下:
图 (4) function [val_mid,FFv2_bw] = zhongyang(FF,m,n)
% 提取纸币特殊部位(中央数字)
FFv2 = FF(round(0.24*m):round(0.50*m),round(0.25*n):round(0.52*n));
FFv2=medfilt2(FFv2,[4,4]);%进行中值滤波; FFv2 = FFv2(2:(end-4),2:(end-4));
[mt2,nt2] = size(FFv2);
FFv2_bw = im2bw(FFv2,0.5);%二值化
% 判断是否为 100
Ty_100 = logical(sum(FFv2_bw) <= (mt2-2)); Ty_100_l = find((Ty_100 == 1));
rat_100 = (Ty_100_l(end) - Ty_100_l(1)) / nt2; if rat_100 >= 0.8
val_mid = 100; else
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%↓(下面求取 20 50)
% 求取第二象限,出现黑点的列(下面求取 20 50)
lie_f = 0;
for j = 1:(nt2/2)
for i = 1:(mt2/2)
if ~(FFv2_bw(i,j) + lie_f) lie = j;
lie_f = 1;
end
end
end
% 向当前列后 2——6 共 5 列,取黑白行数FFv2_bw_f = FFv2_bw(:,(lie+2):(lie+6)); hang(3,:) = mt2;
for j = 1:5
for i = 1:(mt2-2)
if ~(FFv2_bw_f(i,j) + FFv2_bw_f(i+1,j) + FFv2_bw_f(i+2,j)) hang(1,j) = i;%第一行记录首次黑点行数
for k = (i+2):(mt2-2)
if (FFv2_bw_f(k,j) + FFv2_bw_f(k+1,j) + FFv2_bw_f(k+2,j))>=2
hang(2,j) = k+1;%第二行记录二次白点for l = (k+2):mt2
if ~(FFv2_bw_f(l,j))
hang(3,j) = l;%第三行记录二次黑点break
end
end
end
end
break
end
end
end
break
[hang_m,hang_n] = size(hang);
hang_new = round(sum(hang,2) / hang_n); hang_black = hang_new(2) - hang_new(1); hang_white = hang_new(3) - hang_new(2); if hang_black >= hang_white
val_mid = 50; else
val_mid = 20;
end
end
结论:
% 人民币识别
clc; clear all; close all;
I = imread('207.jpg');% 图像输入IM_pic = ceshi(I);% 摆正校正 返回 I1
[left,right,up,down,FF] = bianyuan(IM_pic);% 剔除边缘 提取纸币 FF FF_real = IM_pic(up:down,left:right,:);
[m,n] = size(FF);
[val_color,IM_pic_real_head] = yanse(IM_pic,left,right,up,down);% 色调识别
[val_ckb] = changkuanbi(left,right,up,down);% 长宽比识别[val_left,FFv_bw] = zuoxia(FF,m,n);% 左下角特征识别[val_mid,FFv2_bw] = zhongyang(FF,m,n);% 中央特征识别subplot(2, 3, 1); imshow(I); title('原图像');
subplot(2, 3, 2); imshow(IM_pic); title('摆正图像');
subplot(2, 3, 3); imshow(FF_real); title('纸币部分');xlabel(val_ckb) subplot(2, 3, 4); imshow(IM_pic_real_head); title(' 色 调 识 别 区 域');xlabel(val_color);
subplot(2, 3, 5); imshow(FFv_bw); title('左下角特征');xlabel(val_left); subplot(2, 3, 6); imshow(FFv2_bw); title(' 中 央 特 征 识 别');xlabel(val_mid);
五、结论
在进行该项目研究时,首先分别对第五版人民币 20 元、
50 元和 100 元,这三个不同面值的人民币的图像进行了详细的分析和讨论。经过本小组成员的共同商讨,选择出特征区域主色调、长宽比、特征图像和特征数字这四个特征点作为完成本项目的切入点。并对这四个切入点的实现,进行了清晰的步骤分析。
接下来,我们小组成员分别从这四个切入点入手,在查阅了大量资料后,实际动手编写程序,最终实现了从所采集图像主色调、长宽比、特征图像和特征数字这四个特征点,利用 matlab 软件对三个不同面值的人民币进行自动识别。
通过对这四种方法的分别运行,我们发现通过主色调不同对于不同面值的纸币进行识别,是可靠度最高、运行速度最快,但却也是受背景图像干扰很严重的的一种方法。通过对中央特征数值的提取来实
现对不同面值的识别,是最有效可靠的方法。
通过此次三级项目的研究学习,让我们对matlab 软件有了更加深入的学习和了解。通过自己动手设计编写程序,并从中发现问题、解决问题,增强了我们实际应用这门学科的能力和分析处理问题的能力。另一方面,也增强了我们的团队协作能力,让我们通过结组讨论、共同解决问题的形式,互补学习、共同进步。
通过对这一项目的研究,我们发现不同面值的人民币上,盲文也可以作为重要的区分标志,而且本程序还无法实现对于有污损和褶皱的人民币识别。因此,在接下来的工作中,我们还准备对于不同面值人民币左下角的盲文信息进行进一步的分析处理,用以实现对第五版人民币 20 元、50 元及 100 元的崭新人民币,甚至对于有污损、褶皱的人民币利进行面值的自动识别。使识别方法具有更高的准确性、稳定性,推广其应用范围。
参考文献:
- 范立南,韩晓微,张广渊.图像处理与模式识别 [M].北京:科学出版 2007,3.
- [ 美 ]Rafael C Gonzalez, Richard E Woods, Steven L Eddins. 阮 秋 琦译 . 数 字 图 像 处 理 (MATLAB 版)[M].北京: 电子工业出版社, 2005. [3] 范立南,韩晓微,张广渊.图像处理与模式识别 [M].北京:科学出版社 007,3.
[4] [ 美 ]Rafael C Gonzalez, Richard E Woods, Steven L Eddins. 阮 秋 琦译 . 数 字 图 像 处 理 (MATLAB 版)[M].北京: 电子工业出版社, 2005. [5] 杜选,高明峰.人工神经网络在数字识别中的应用[J].计算机系统与应用 2007.
[6]陈慧鹏,杨亮亮,李鸿.模糊集识别法在纸币清分中的应用研究[J].华中科技大学国家数控工,2004. [7]宋铭利.关于去除图像噪音的中值滤波算法 [J].洛阳师范学院院报,2002. [8]韩贺磊.人民币纸币面额的机器视觉识别方法研究[D].大连理工大学,2007.
[9]张国华.一种基于模板匹配的人民币纸币面额识别方法 [J].沈阳工业大学学报,2005.
附件:
1、%此程序用作图像的摆正function [I1] = ceshi(I)
bw = im2bw(I);
bw = imclose(bw, strel('disk', 5)); [r, c]=find(bw==1);
[rectx, recty, area, perimeter] = minboundrect(c, r, 'a');
% 'a'是按面积算的最小矩形,如果按边长用'p' for i = 1 : length(rectx)-1
len = norm([rectx(i+1)-rectx(i) recty(i+1)-recty(i)]); Len(i) = len;
end
[MaxLen, ind] = max(Len);
x1 = [rectx(ind) rectx(ind+1)]; y1 = [recty(ind) recty(ind+1)];
% 求得线段的斜率
K1 = -(y1(1)-y1(2))/(x1(1)-x1(2));
angle = atan(K1)*180/pi;
I1 = imrotate(I, -angle, 'bilinear');% imrotate 是逆时针的所以取一个负号
如果不倾斜则直接进行背景剔除及图像整体轮廓的提取,即边缘提取处理,具体程序如下:
% 背景剔除 边缘提取
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%↓
function [left,right,up,down,FF] = bianyuan(IM_pic) IM_g = rgb2gray(IM_pic);
% 低通滤波
n=1;
H=1/(n*n)*ones(n,n); IM_g=imfilter(IM_g,H);
% 边缘
F = edge(IM_g,'sobel'); [m n] = size(F);
F = double(F);
% ground =0;%取背景
k = 0;l = 0;%取左右边缘for i1 = 1:m
for j1 = 1:n
if F(i1,j1) ~= 0 k = k + 1; left(k) = j1;
for j2 = n:-1:j1
if F(i1,j2) ~= 0 l = l + 1;
right(l) = j2; break
end end break
end
end
end
left = mode(left); right = mode(right);
k = 0;l = 0;%取上下边缘for j1 = 1:n
for i1 = 1:m
if F(i1,j1) ~= 0 k = k + 1; up(k) = i1;
for i2 = m:-1:i1
if F(i2,j1) ~= 0 l = l + 1; down(l) = i2; break
end end break
end
end
end
up = mode(up); down = mode(down);
% 已知纸币的上下左右
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%↑
% 剔除背景,提取纸币部分
FF = IM_g(up:down,left:right);
% title('纸币部分提取')
2、以上程序涉及的函数如下所示:
function [rectx,recty,area,perimeter] = minboundrect(x,y,metric)
% default for metric
if (nargin<3) || isempty(metric) metric = 'a';
elseif ~ischar(metric)
error 'metric must be a character flag if it is supplied.' else
% check for 'a' or 'p' metric = lower(metric(:)');
ind = strmatch(metric,{'area','perimeter'}); if isempty(ind)
error 'metric does not match either ''area'' or ''perimeter''' end
% just keep the first letter. metric = metric(1);
end
% preprocess data x=x(:);
y=y(:);
% not many error checks to worry about n = length(x);
if n~=length(y)
error 'x and y must be the same sizes' end
% start out with the convex hull of the points to
% reduce the problem dramatically. Note that any
% points in the interior of the convex hull are
% never needed, so we drop them. if n>3
edges = convhull(x,y,{'Qt'}); % 'Pp' will silence the warnings
% exclude those points inside the hull as not relevant
% also sorts the points into their convex hull as a
% closed polygon
x = x(edges); y = y(edges);
% probably fewer points now, unless the points are fully convex nedges = length(x) - 1;
elseif n>1
% n must be 2 or 3 nedges = n; x(end+1) = x(1);
y(end+1) = y(1); else
% n must be 0 or 1 nedges = n;
end
% now we must find the bounding rectangle of those
% that remain.
% special case small numbers of points. If we trip any
% of these cases, then we are done, so return. switch nedges
case 0
% empty begets empty rectx = [];
recty = [];
area = []; perimeter = []; return
case 1
% with one point, the rect is simple. rectx = repmat(x,1,5);
recty = repmat(y,1,5); area = 0;
perimeter = 0; return
case 2
% only two points. also simple. rectx = x([1 2 2 1 1]);
recty = y([1 2 2 1 1]);
area = 0;
perimeter = 2*sqrt(diff(x).^2 + diff(y).^2); return
end
% 3 or more points.
% will need a 2x2 rotation matrix through an angle theta
Rmat = @(theta) [cos(theta) sin(theta);-sin(theta) cos(theta)];
% get the angle of each edge of the hull polygon. ind = 1:(length(x)-1);
edgeangles = atan2(y(ind+1) - y(ind),x(ind+1) - x(ind));
% move the angle into the first quadrant. edgeangles = unique(mod(edgeangles,pi/2));
% now just check each edge of the hull nang = length(edgeangles);
area = inf; perimeter = inf; met = inf;
xy = [x,y]; for i = 1:nang
% rotate the data through -theta rot = Rmat(-edgeangles(i));
xyr = xy*rot;
xymin = min(xyr,[],1);
xymax = max(xyr,[],1);
% The area is simple, as is the perimeter A_i = prod(xymax - xymin);
P_i = 2*sum(xymax-xymin); if metric=='a'
M_i = A_i; else
M_i = P_i; end
% new metric value for the current interval. Is it better? if M_i<met
% keep this one met = M_i;
area = A_i;
perimeter = P_i; rect =
[xymin;[xymax(1),xymin(2)];xymax;[xymin(1),xymax(2)];xymin]; rect = rect*rot';
rectx = rect(:,1);
recty = rect(:,2); end
end
% get the final rect
% all done
end % mainline end