FPGA实现车牌识别 四.MATLAB车牌字符分割
笔者大二学了数电,结合之前学习的一些机器学习的基础知识,决定用FPGA实现一个车牌识别系统,由于能力有限可能更新进度较慢,希望理解。这是第四部分的内容MATLAB车牌字符分割
前言
这一篇文章依旧是FPGA实现前的算法验证。在上一篇文章中,已经得到了车牌的四个角落上的坐标,在这一篇文章将根据坐标将车牌从原图像中分割出来,在从车牌图像中分割出每一个字符。
一、车牌分割
这一步是根据四个坐标点从原始图像中分割出车牌 这里向内多切了几个像素,以去除部分字符外的蓝色边缘
二、字符分割
1.二值化
这里需要区分的是蓝色的背景与白色的字符,在这里我们可以采用红色通道分离两者。 得到红色通道的图像: 选取合适阈值,将其二值化得到图像:
2.水平方向投影
可以看到图像左右两侧存在数值较低的区域对应车牌区域最上方与最下方的空白区域 可以看出图像明显存在七个低谷,因此可将其分为八个字符
3.字符提取
分别对水平方向与竖直方向的投影结果设定阈值,当阈值超过阈值代表在字符范围内,以此找到每个字符的上下边界与左右边界。 提取得到的字符为
三、完整代码
function [img_out,exist] = cutting(img_in,x1,x2,y1,y2)
char_x1 = [];
char_x2 = [];
char_y1 = 0;
char_y2 = 0;
x_size = x2-x1+1-10;
y_size = y2-y1+1-10;
plate = zeros(y_size,x_size,3);
for i = y1+5:y2-5
for j = x1+5:x2-5
plate(i-y1+1,j-x1+1,:) = img_in(i,j,:);
end
end
plate = uint8(plate);
%figure(4)
%image(plate);
%imwrite(plate,'17.bmp');
r = plate(:,:,1);%红色通道
img_r(:,:,1) = r;
img_r(:,:,2) = 0;
img_r(:,:,3) = 0;
%figure(5)
%image(img_r);
%imwrite(img_r,'18.bmp');
%对红色通道进行二值化
for i = 1:y_size
for j = 1:x_size
if(r(i,j)>100)
r_bz(i,j) = 255;
else
r_bz(i,j) = 0;
end
end
end
img_bz(:,:,1) = r_bz;
img_bz(:,:,2) = r_bz;
img_bz(:,:,3) = r_bz;
img_bz = uint8(img_bz);
%figure(6)
%image(img_r_bz);
%imwrite(img_r_bz,'19.bmp');
%垂直投影
%水平投影
cnt_x = zeros(1,x_size);
cnt_y = zeros(1,y_size);
for i = 1:y_size
for j = 1:x_size
if(r_bz(i,j) == 255)
cnt_y(i) = cnt_y(i)+1;
end
end
end
figure(1);
plot(cnt_y);
%水平方向
cnt_img = 0;
edge_flag = 0;%为0时下一个边界为上边界,为1时下一个边界为下边界
y_threshold = 30;%大于该阈值时认为在字符内部
for i = 1:y_size
if((cnt_img == 1)&&(edge_flag == 0))%找到所有字符是退出
break;
end
if((i==1))
if(cnt_y(1)>=y_threshold)%如果第一个字符从上边界开始
cnt_img = 1;
char_y1 = 1;
edge_flag = 1;
end
elseif((i == y_size)&&(edge_flag == 1))%如果最后一个字符到下边界结束
char_y2 = i;
edge_flag = 0;
elseif((cnt_y(i-1)<=y_threshold)&&(cnt_y(i)>y_threshold)&&(edge_flag==0))
cnt_img = cnt_img+1;
char_y1 = i;
edge_flag=1;
elseif((cnt_y(i-1)>=y_threshold)&&(cnt_y(i)<y_threshold)&&(edge_flag==1))
char_y2 = i;
edge_flag = 0;
end
end
for i = char_y1:char_y2
for j = 1:x_size
img_y_finish(i-char_y1+1,j,:) = img_bz(i,j,:);
end
end
y_size = char_y2-char_y1+1;
image(img_y_finish);
for i = 1:y_size
for j = 1:x_size
if(img_y_finish(i,j,1) == 255)
cnt_x(j) = cnt_x(j)+1;
end
end
end
figure(2);
plot(cnt_x);
%x方向
cnt_img = 0;
edge_flag = 0;%为0时下一个边界为左边界,为1时下一个边界为右边界
x_threshold = 5;%大于该阈值时认为在字符内部
for i = 1:x_size
%找到所有字符是退出
if((cnt_img == 8)&&(edge_flag == 0))
break;
end
if(i==1)
if(cnt_x(1)>=x_threshold)%如果第一个字符从左边界开始
cnt_img = 1;
char_x1(1) = 1;
edge_flag = 1;
end
elseif((i == x_size)&&(edge_flag == 1))%如果最后一个字符到右边界结束
char_x2(cnt_img) = i;
edge_flag = 0;
elseif((cnt_x(i-1)<=x_threshold)&&(cnt_x(i)>x_threshold)&&(edge_flag==0))%为左边界时
cnt_img = cnt_img+1;
char_x1(cnt_img) = i;
edge_flag=1;
elseif((cnt_x(i-1)>=x_threshold)&&(cnt_x(i)<x_threshold)&&(edge_flag==1))%为右边界时
char_x2(cnt_img) = i;
edge_flag = 0;
end
end
if(cnt_img == 8 )
exist = 1;
else
exist =0;
img_out = 0;
return;
end
for i = 1:8
for k = char_x1(i) : char_x2(i)
img_out(:,k-char_x1(i)+1,:,i) = img_y_finish(:,k,:);
end
imwrite(img_out(:,:,:,i),['char',num2str(i),'.bmp']);
end
end
总结
这里已经完成了每个字符的分割,在下一篇文章中将使用简单的神经网网络对字符进行识别。
|