蓝色区域切割
继续使用上节的Pre_Process来获得蓝色区域,并对蓝色区域进行判断。
流程如下
- 获得蓝色区域
- 对蓝色区域进行Hough直线检测并进行校正
- 分析蓝色区域
- 分析失败则返回第一步,并将此蓝色区域置为0。
我们先模拟一下如果第一次获取失败,进行第二次的过程。
hsv = rgb2hsv(f);
v = hsv(:, :, 3);
v = imfilter(v, fspecial('gaussian', [5 5], 0.2));
f = hsv2rgb(cat(3, hsv(:, :, 1), hsv(:, :, 2), adapthisteq(v)));
f = imread('车牌2.jpg');
[P B L] = Pre_Process(f);
g = f(L.row(1):L.row(2), L.col(1):L.col(2), :);
subplot(1, 2, 1), imshow(g), title('第一次分割');
f(L.row(1):L.row(2), L.col(1):L.col(2), :) = 0;
[P B L] = Pre_Process(f);
g = f(L.row(1):L.row(2), L.col(1):L.col(2), :);
subplot(1, 2, 2), imshow(g), title('第二次分割');
结果是可行的。
接着,我们进行校正,这里先假设第二次成功找到。
f = imread('车牌2.jpg');
[P B L] = Pre_Process(f);
f(L.row(1):L.row(2), L.col(1):L.col(2), :) = 0;
[P B L] = Pre_Process(f);
area = f(L.row(1):L.row(2), L.col(1):L.col(2), :);
g = rgb2gray(area);
g = adapthisteq(g); % 对比度增强
h = edge(g,'canny', 0.25); % 使用sobel算子进行边缘检测
h = bwmorph(h, 'dilate', 1);
subplot(1, 2, 1), imshow(h), hold on;
[H theta rho] = hough(h);
peaks = houghpeaks(H, 1);
lines = houghlines(h, theta , rho, peaks, 'FillGap', 25, 'MinLength', 25);
for i = 1 : length(lines)
xy = [lines(i).point1; lines(i).point2];
plot(xy(:, 1), xy(:, 2), 'LineWidth', 2, 'Color', 'red');
x1 = xy(:, 1);
y1 = xy(:, 2);
K1 = (x1(2)-x1(1))/(y1(2)-y1(1));
angle = atan(K1)*180/pi;
area = imrotate(area, 90 - angle, 'bilinear');
end
subplot(1, 2, 2), imshow(area);
接着在进行字符提取
f = imread('车牌2.jpg');
[P B L] = Pre_Process(f);
f(L.row(1):L.row(2), L.col(1):L.col(2), :) = 0;
[P B L] = Pre_Process(f);
area = f(L.row(1):L.row(2), L.col(1):L.col(2), :);
g = rgb2gray(area);
g = adapthisteq(g); % 对比度增强
h = edge(g,'canny', 0.25); % 使用sobel算子进行边缘检测
h = bwmorph(h, 'dilate', 1);
[H theta rho] = hough(h);
peaks = houghpeaks(H, 1);
lines = houghlines(h, theta , rho, peaks, 'FillGap', 25, 'MinLength', 25);
for i = 1 : length(lines)
xy = [lines(i).point1; lines(i).point2];
x1 = xy(:, 1);
y1 = xy(:, 2);
K1 = (x1(2)-x1(1))/(y1(2)-y1(1));
angle = atan(K1)*180/pi;
area = imrotate(area, 90 - angle, 'bilinear');
end
area = rgb2gray(area);
g_max=double(max(max(area)));
g_min=double(min(min(area)));
T=round(g_max-(g_max-g_min)/3);
area = im2bw(area, T/256);
area = bwareaopen(area, 20);
[H theta rho] = hough(area);
peaks = houghpeaks(H, 1);
lines = houghlines(area, theta , rho, peaks, 'FillGap', 25, 'MinLength', 25);
for i = 1 : length(lines)
xy = [lines(i).point1; lines(i).point2];
x1 = xy(:, 1);
y1 = xy(:, 2);
area(y1(1) : y1(2), x1(1):x1(2)) = 0;
end
area2 = imfill(area, 'holes'); % 先将空洞删除
X=[];
z=0;
flag=0;
for j=1:size(area ,2)
sum_y=sum(area(:,j));
if logical(sum_y)~=flag %列和有变化时,记录下此列
if(j-z > 3)
X=[X j];
flag=logical(sum_y);
z=j; %用z记录上一个j的值,防止两个列坐标间隔太小
end
end
end
[y x] = size(area2);
X = [X y];
for n=1:7
res = area(:, X(2 * n - 1):X(2 * n)); %进行粗分割
for i=1:size(res,1) %这两个for循环对分割字符的上下进行裁剪
if sum(res(i,:))~=0
top=i;
break
end
end
for i=1:size(res,1)
if sum(res(size(res,1)-i,:))~=0
bottom=size(res,1)-i;
break
end
end
res=res(top:bottom,:);
subplot(2, 4, n), imshow(res);
end
接着对字符进行分析。
获取传入的二维图的车牌信息
function rec = getCarPlate(g)
g = adapthisteq(g); % 对比度增强
h = edge(g,'canny', 0.25); % 使用sobel算子进行边缘检测
h = bwmorph(h, 'dilate', 1);
[H theta rho] = hough(h);
peaks = houghpeaks(H, 1);
lines = houghlines(h, theta , rho, peaks, 'FillGap', 25, 'MinLength', 25);
for i = 1 : length(lines)
xy = [lines(i).point1; lines(i).point2];
x1 = xy(:, 1);
y1 = xy(:, 2);
K1 = (x1(2)-x1(1))/(y1(2)-y1(1));
angle = atan(K1)*180/pi;
area = imrotate(area, 90 - angle, 'bilinear');
end
area = rgb2gray(area);
g_max=double(max(max(area)));
g_min=double(min(min(area)));
T=round(g_max-(g_max-g_min)/3);
area = im2bw(area, T/256);
area = bwareaopen(area, 20);
area2 = imfill(area, 'holes'); % 先将空洞删除
X=[];
z=0;
flag=0;
for j=1:size(area ,2)
sum_y=sum(area(:,j));
if logical(sum_y)~=flag %列和有变化时,记录下此列
if(j-z > 3)
X=[X j];
flag=logical(sum_y);
z=j; %用z记录上一个j的值,防止两个列坐标间隔太小
end
end
end
[y x] = size(area2);
X = [X y];
for n=1:7
res = area(:, X(2 * n - 1):X(2 * n)); %进行粗分割
for i=1:size(res,1) %这两个for循环对分割字符的上下进行裁剪
if sum(res(i,:))~=0
top=i;
break
end
end
for i=1:size(res,1)
if sum(res(size(res,1)-i,:))~=0
bottom=size(res,1)-i;
break
end
end
res=res(top:bottom,:);
res = imresize(res,[40,20],'nearest'); %归一化为40*20的大小,以便模板匹配
imgchar{n}=res;
end
res=[];
store1=strcat('贵','豫','粤','湘','鄂','皖','鲁','藏','京','苏','黑','吉','冀','晋','辽','浙','津','闽','云','陕','琼'); %创建汉字识别模板库
for j=1:21
Im=imgchar{1};
Template=imread(strcat('车牌汉字库\',num2str(j),'.jpg'));
Template=im2bw(Template);
Differ=Im-Template;
Compare(j)=sum(sum(abs(Differ)));
end
index=find(Compare==(min(Compare)));
res=[res store1(index)];
store2=strcat('A','B','C','D','E','F','G','H','J','K','L','M','N','P','Q','R','S','T','U','V','W','X','Y','Z','0','1','2','3','4','5','6','7','8','9'); %创建字母与数字识别模板库
for i=2:7
for j=1:34
Im=imgchar{i};
Template=imread(strcat('车牌字符库\',num2str(j),'.jpg'));
Template=im2bw(Template);
Differ=Im-Template;
Compare(j)=sum(sum(abs(Differ)));
end
index=find(Compare==(min(Compare)));
res=[res store2(index)];
end
end
主函数
clear;
clear all;
f = imread('车牌.jpg');
real = f;
n = 1;
while n < 5
[P B L] = Pre_Process(f);
area = f(L.row(1):L.row(2), L.col(1):L.col(2), :);
try
res = getCarPlate(area);
n = 999;
catch err
disp(err);
disp('截取失败,进行下一次截取');
f(L.row(1):L.row(2), L.col(1):L.col(2), :) = 0;
figure, imshow(f);
n = n + 1;
end
end
imshow(real), title(res);
我们还需要去除一些因为反光而白色的线。
h = imread('车牌8.jpg');
subplot(1, 2, 1), imshow(h), hold on;
[H theta rho] = hough(h);
peaks = houghpeaks(H, 1);
lines = houghlines(h, theta , rho, peaks, 'FillGap', 25, 'MinLength', 25);
for i = 1 : length(lines)
xy = [lines(i).point1; lines(i).point2];
plot(xy(:, 1), xy(:, 2), 'LineWidth', 2, 'Color', 'red');
x1 = xy(:, 1);
y1 = xy(:, 2);
h(y1(1) : y1(2), x1(1):x1(2)) = 0;
end
subplot(1, 2, 2), imshow(h);
接着再按照上面的过程执行即可。
传说中的人形大宝宝今天来看我打码了- -