Sau khi nhận dạng được ký tự trên biển số xe ra, chương trình sẽ tiến hành so sánh chuỗi ký tự đĩ với dữ liệu biển số xe vào được lưu từ trước. Máy tính sẽ truyền tín hiệu xuống vi điều khiển 89S52 làm sáng led, nếu đúng thì led green sáng, nếu sai thì led blue sáng.
Tín hiệu từ chân số 2 của cổng COM vào chân 8 của Max232, sau đĩ tín hiệu từ chân 9 của Max232 vào chân 10 của vi điều khiển 89S52.
Vi điều khiển sẽ kiểm tra tín hiệu truyền xuống. Nếu là đúng thì sẽ sáng led green, cịn sai thì sáng led blue.
Khi led green sáng, tín hiệu truyền xuống, làm quay động cơ. 4s sau, đèn Green tắt, động cơ trở về vị trí ban đầu.
KẾT LUẬN
Độ chính xác của chương trình nhận dạng biển số xe phụ thuộc vào ánh sáng mơi trường. Tuy nhiên yếu tố này ta cĩ thể điều chỉnh được.
Việc nhận dạng ký tự cịn nhiều sai sĩt do khơng cĩ được một tập mẫu hồn chỉnh.
Chương trình được viết bằng MATLAB đã giải quyết được bài tốn nhận dạng với dung lượng lớn trong thực tế, qua đĩ giải quyết được yêu cầu của đề tài.
Để giải quyết các khĩ khăn của đề tài, người thực hiện xin đề xuất 1 số ý kiến sau đây:
Sử dụng camera chuyên dụng.
Thiết lập mơi trường ổn định xung quanh để làm tăng độ chính xác của ảnh chụp ( xác định 1 vị trí cố định để chụp ảnh).
Thu thập nhiều mẫu ký tự để tăng tập mẫu qua đĩ tăng độ chính xác của chương trình.
Sử dụng thẻ mã vạch để làm vé giữ xe. 48
TÀI LIỆU THAM KHẢO
[1] Amin Sarafraz (2004), “Detects lines in a binary image using common computer vision operation known as the Hough Transform”, University of Tehran, Iran. [2] [Beal72] Beale, E. M. L., "A derivation of conjugate gradients," in F. A. Lootsma, ed.,
Numerical methods for nonlinear optimization, London: Academic Press, 1972.
[3] [Caud89] Caudill, M., Neural Networks Primer, San Francisco, CA: Miller Freeman Publications, 1989.
[4] [Cabu92] Caudill, M., and C.Butler, Understanding Neural Networks: Computer Explorations, vols. 1 and 2, cambridge, ma: the mit press, 1992.
[5] Ondrej martinsky, “Algorithmic and mathematical principles of automatic number plate recognition systems ”, brno 2007.
[6] Otsu, N. (1979), “A Threshold Selection Method from Gray-Level Histograms”, IEEE Transactions on Systems, Man, and Cybernetics, Vol. 9, No. 1, pp. 62-66.
Phụ lục 1: Code của chương trình MATLAB
1.CHỤP VÀ LƯU ẢNH TỪ WEBCAM:
obj = videoinput('winvideo', 1,'YUY2_640x480'); set(obj,'ReturnedColorSpace','rgb');
src_obj = getselectedsource(obj); get(src_obj);
vidRes = get(obj, 'VideoResolution'); nBands = get(obj, 'NumberOfBands');
hImage = image( zeros(vidRes(2), vidRes(1), nBands) ); preview(obj, hImage); pause(2); x=getsnapshot(obj); x=imresize(x,[480 640]); imwrite(x,'D:\NCKH\bai lam\x.jpg','Quality', 100); 2.CHƯƠNG TRÌNH TÁCH BIỂN SỐ: function [bienso,biensomau]=laybiensohoanchinh(pic1); XSIZE = 50; YSIZE = 150; white_pic=laybienso(pic1); [r]=lp_area_extraction_lap(white_pic,30); n=length(r)/4 for i=1:n x=r(4*i-3); x2=r(4*i-2); y=r(4*i-1); y2=r(4*i); lp_area = pic1(y:y2, x:x2, :); angle = find_angle(lp_area);
pic = imrotate(white_pic(y:y2, x:x2), angle, 'bilinear');
[small_pic, xx, xx2, yy, yy2] = improved_lp_area(pic, angle);
[image, RECTx, RECTy] = crop_lp(small_pic, lp_area, xx, xx2, yy, yy2, angle);
end
image = imrotate(lp_area, angle, 'bilinear'); image=image(yy:yy2,xx:xx2,:);
cao = length(image(:,1,1)) ; rong=length(image(1,:,1));
if cao > rong
image = imrotate(image, -90, 'bilinear');
end
biensomau = image;
[grayImage, quantImage, bw] = quantizeImage(image);
quantImage = imadjust(grayImage, stretchlim(grayImage), [0 1]); bienso=bw;
return
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [vungbienso]=laybienso(x) %CẮT THƠ mucxam=rgb2gray(x); mucxam=medfilt2(mucxam,[3 3]); threshold=graythresh(mucxam); bw = im2bw(mucxam,threshold); bw = bwareaopen(bw,5000); vungbienso = bw; return %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [angle] = find_angle(rgb_image); %TÌM GĨC XOAY gray_image = rgb2gray(rgb_image);
theta = (0:179)';
[R, xp] = radon(edge(gray_image), theta); i = find(R > (max(R(:)) - 25));
[foo, ind] = sort(-R(i)); [y, x] = ind2sub(size(R), i); t = -theta(x)*pi/180; r = xp(y); [r,c] = find(R == max(R(:))); thetap = theta(c(1)); angle = 90 - thetap; return; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [pic, x1, x2, y1, y2] = improved_lp_area(image, angle); [x1,x2,y1,y2] = detect_lp_area(image, 0);
pic = image(y1:y2, x1:x2);
return;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [x, x2, y, y2] = detect_lp_area (white_pic, spacing); LP_MIN_AREA = 15000;
LP_MAX_AREA=74200; LP_MAX_RATIO = 0.8; LP_MIN_RATIO = 0.7;
dilated_pic = imdilate(white_pic, strel('diamond', 5)); stat = imfeature(bwlabel(dilated_pic));
depth = -1;
for i = 1 : length([stat.Area])
if stat(i).BoundingBox(2) >= depth && stat(i).Area > LP_MIN_AREA && ...
stat(i).BoundingBox(4) <= LP_MAX_RATIO*stat(i).BoundingBox(3) && ...
stat(i).BoundingBox(4) >= (LP_MIN_RATIO)*stat(i).BoundingBox(3) && stat(i).Area >= max([stat.Area])/3.5
depth = stat(i).BoundingBox(2);
end;
r = [];
for i = 1 : length([stat.Area])
if stat(i).BoundingBox(2) == depth && stat(i).Area > LP_MIN_AREA && ...
stat(i).BoundingBox(4) <= LP_MAX_RATIO*stat(i).BoundingBox(3) && ...
stat(i).BoundingBox(4) >= (LP_MIN_RATIO)*stat(i).BoundingBox(3) && stat(i).Area >= max([stat.Area])/3.5
r = [r stat(i).Area];
end;
end;
if(length(r) == 0)
index = (find([stat.Area] == max([stat.Area])));
else
index = (find([stat.Area] == max(r)));
end;
x = max(floor(stat(index).BoundingBox(1) - spacing), 1); y = max(floor(stat(index).BoundingBox(2) - spacing), 1); width = ceil(stat(index).BoundingBox(3) + 2*spacing); height = ceil(stat(index).BoundingBox(4) + 2*spacing); y2 = min(y + height, size(white_pic, 1));
x2 = min(x + width, size(white_pic, 2));
return;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [image, RECTx, RECTy] = crop_lp(pic, lp_area, x1, x2, y1, y2, angle); rec = find_lp_location(pic);
image = imrotate(lp_area, angle, 'bilinear'); image = image(y1:y2, x1:x2, :);
RECTy = [rec(2), rec(2), rec(2) + rec(4), rec(2) + rec(4)]; RECTx = [rec(1), rec(1) + rec(3), rec(1) + rec(3), rec(1)]; image = imcrop(image, rec);
return;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [rec] = find_lp_location(im); p1 = sum(im);
[x1, x2] = find_contours(p1); p2 = sum(im');
[y1, y2] = find_contours(p2); rec = [x1, y1, x2-x1, y2-y1];
return;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [index1, index2] = find_contours(vec); avg = mean(vec); for j = 1 : length(vec) if(vec(1,j) <= avg) continue; end; index1 = j - 1; break;
end; for j = length(vec) : -1 : 1 if(vec(1,j) <= avg) continue; end; index2 = j + 1; break; end; return; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [grayImage, quantImage, bw] = quantizeImage(rgbImage); grayImage = rgb2gray(rgbImage);
quantImage = imadjust(grayImage, stretchlim(grayImage), [0 1]); quantImage = im2double(quantImage);
op = find_optimal_threshold(quantImage); bw = im2bw(quantImage, op);
return;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [im] = normalized_lp_contour(bwImage, dimension); im=imcomplement(bwImage); im = imresize(im, dimension); im=im(3:48,11:140); im = imresize(im, dimension); return; 3.PHÂN VÙNG BIỂN SỐ:
function [hang1,hang2] = phanvungchu(bienso); bit_cuoi=50; bit_giua=bit_cuoi/2; hang1 = bienso(1:bit_giua,:); hang2 = bienso((bit_giua+1):bit_cuoi,:); return %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [seg] = character_segmentation(bw); DIGIT_WIDTH =28;
MIN_AREA = 200;
seg = phanvung(bw, DIGIT_WIDTH, MIN_AREA); [x y] = size(seg);
if x < 4
for i = 1 : x
bw(:,seg(i,2))=0;
end;
seg = phanvung(bw, DIGIT_WIDTH, MIN_AREA);
end; area = [];
pic = bw(:, seg(i,1) : seg(i,2), :); area(i) = bwarea(pic); end; area1 = sort(area); seg = seg'; for j = 1:(length(area1)-4) i = find(area == area1(j)); len = length(area); if i == 1 area = [area(2:len)]; seg = [seg(:,2:len)]; elseif i == len area = [area(1:i-1)]; seg = [seg(:,1:i-1)]; else
area = [area(1:i-1) area(i+1:len)]; seg = [seg(:,1:i-1) seg(:,i+1:len)];
end;
end; seg = seg';
return;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [segmentation] = phanvung(im, digit_width, min_area); segmentation = [];
t = sum(im);
seg = clean(vitricuctieu(t, 2, 1, digit_width), 3); j = 1;
for i = 1 : (length(seg) - 1)
band_width = seg(i+1) - seg(i); maxi = max(t(1, seg(i):seg(i+1)));
if(maxi * band_width > min_area) segmentation(j, 1) = seg(i); segmentation(j, 2) = seg(i+1); j = j + 1; end; end; return; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [s] = vitricuctieu(t, val, offset, digit_width); s = find(t < val);
if(length(s) < 2)
s = vitricuctieu(t, val + 1, offset, digit_width);
return;
end;
if((t(1,1) >= val) && s(1) ~= 1) s = [1 s];
end;
if((t(1, length(t)) >= val) && s(length(s)) ~= length(t)) s = [s length(t)];
end;
s = add(s, offset - 1); s = clean(s, 3);
while bad_digit(s, digit_width) == 1
for i = 1: (length(s) - 1)
if (s(i + 1) - s(i)) > digit_width
sub_vec = t(1, s(i) - offset + 1 : s(i+1) - offset + 1);
s = [s(1 : i) vitricuctieu(sub_vec, val + 1, s(i), digit_width) s(i+1 : length(s))];
end;
end;
end;
return;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [bool] = bad_digit(s, digit_width);
if length(s) == 0 bool = 0; return; end; tmp = s(1); bool = 0; for i = 2 : length(s) if(s(i) - tmp) > digit_width bool = 1; return; end; tmp = s(i); end; return; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [t] = clean(s, val); t = [];
len = length(s); i = 2;
j = 1;
while i <= len
while(s(i) - s(i-1) <= val) i = i + 1; if(i > len) return; end; end; if j == 1||s(i-1)-t(j-1) > val t(j) = s(i-1);
j = j + 1; end; t(j) = s(i); j = j + 1; i = i + 1; end; return; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [t] = add(s, val); len = length(s);
t = [];
for i = 1:len t(i) = s(i) + val;
end;
return;
4.NHẬN DẠNG KÝ TỰ:
function number2 = nhandangsonoron2(hang2, seg2, netso) load 'netso.mat';
number2 = [];
for i = 1:size(seg2, 1)
input = hang2(:, seg2(i,1) : seg2(i,2), :); rec = nhandangsonoron(netso, input); number2 = strcat(number2, rec);
end return;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function so = nhandangsonoron(net,input ) matranmau=[35 20];
input = imresize(input, matranmau, 'nearest'); input=bwareaopen(input,60);
vec = double(im2col(input, size(input), 'distinct')); rslt = sim(net, vec);
[Y,I] = max(rslt); num = I-1;
so = char('0' + num);
Phụ lục 2: Code của vi điều khiển 89S52 RS BIT P2.3 RW BIT P2.4 EN BIT P2.5 ORG 0000H LJMP MAIN ORG 0023H LJMP INT_SERIAL ORG 0030H MAIN: MOV IE,#10010000B MOV TMOD,#00100001B MOV PCON,#00000000B MOV SCON,#01010000B MOV TH1,#-3 SETB TR1 MOV R1,#0 MOV R0,#"D" MOV P2,#0FFh INT_SERIAL: JNB RI,EXIT_SERIAL MOV A,SBUF CJNE A,#"A",TTO CPL p2.2 LCALL TRANF LCALL DELAYHT CPL p2.2 CLR RI RETI TTO: CJNE A,#"B",EXIT_SERIAL CPL p2.3
LCALL LCALL TRANF DELAYHT CPL p2.3 CLR RI RETI EXIT_SERIAL: CLR TI RETI TRANF: CPL p2.4 CLR ES MOV SBUF,A JNB TI,$ CLR TI CPL p2.4 SETB ES RET DELAY: MOV 77H,#255 DJNZ 77H,$ RET DELAYHT: MOV 7CH,#16 K: MOV 7EH,#255 L: LCALL DELAY DJNZ 7EH,L DJNZ 7CH,K RET END