【二维码图像矫正增强】基于MATLAB的二维码图像矫正增强处理仿真

1.软件版本

matlab2013b

2.算法流程概述

通过形态学处理获得二维码部分的图像区域及边界;

采用凸包算法来计算边界上的点集;

然后根据点集来寻找二维码的四个顶点,

然后透视变换矫正,二维码分割得到每个格子中的点。

进行二维码图像归一化。完成二维码修正。

然后做实验比较与其他采用边缘检测加hough变换进行矫正后图像的识别率。

在二值化操作之前进行光照增强,采用同态滤波和直方图均衡化结合的方式来做,然后采用ostu法进行二值化。

通过定位二维码三个角点的位置,然后通过膨胀处理,并进行连通区域。将不是这三个探测图元所在的连通区域删除,然后将剩下的连通区域腐蚀,进行边缘检测,将得到的边缘上的点集用凸包法进行连接,

大致确定二维码的边界,然后使用到四条外界直线距离最短的方式来确定四个顶点。

3.部分源码

clc;
clear all;
close all;
warning off;
addpath 'func\'


%filename ='1.jpg';
%filename ='2.jpg';
%filename ='3.jpg';
filename ='4.jpg';

X        = imread(filename);  
%获取图像相关信息
[R,C,K]  = size(X);
if K == 3
   f = rgb2gray(X);
else
   f = X;
end

%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%使用小波滤波+中值滤波的改进滤波方案
figure
subplot(141);
imshow(f);
title('原始图像');
f = imadjust(f,[0.1 0.8],[]);

f = func_wavelet_filter(f);
subplot(142);
imshow(f);
title('小波滤波和光线增强后图像');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%基于OSTU方法的二值提取
G   = f;
f   = func_ostu(f); 
f   =~f;
subplot(143);
imshow(f);
title('ostu二值化处理图像');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%
%形态学膨胀
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SE = strel('disk',8);
I  = imdilate(f,SE);
%删除小的区域
I  = bwareaopen(I,20000);
%求取整幅图的重心
subplot(144);
imshow(I);
title('形态学膨胀图像');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%




%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%标记连通域
[L,num]=bwlabel(I,8);
figure
subplot(141);
imshow(L);
%剔除无关连通域,这里改进了剔除措施,之前的方法很多测试图片没法正确处理
[R,C,K] = size(I);
L2      = zeros(R,C);
for i=1:num
    [r,c]=find(L==i); %计算坐标
    if isempty(r) == 0 & isempty(c) == 0 
       a2(i) = min(r);  %计算坐标
       a1(i) = max(r);  %计算坐标
       b2(i) = min(c);  %计算坐标
       b1(i) = max(c);  %计算坐标
       %根据面积进行判断是否是正确的区域
       Lss    = a1(i) - a2(i);
       Wss    = b1(i) - b2(i);
       if (Lss>=0.9*Wss & Lss<=1.1*Wss) | (Wss>=0.9*Lss & Wss<=1.1*Lss)
          for j = 1:length(r) 
              L2(r(j),c(j)) = L(r(j),c(j));
          end
       end
    end
end
SE = strel('disk',8);
T=imerode(L2,SE);
T=imfill(T,'holes');
subplot(142);
imshow(T);
title('形态学腐蚀');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%提取边缘
T2=edge(T,'prewitt');
subplot(143);
imshow(T2);
title('提取边缘');
%待判断凸包的点集,这个部分做了改进,原来的方法存在残缺问题,会无法检测边缘的问题
[y,x] = find(T2==1);
img   = ones(size(T2));
p     = [];
for i=1:length(x)
    img(y(i),x(i))=0; 
    p=[p;x(i),y(i)];     
end
subplot(144);
imshow(img);
%下面计算凸包
[t,index] = max(p(:,2));  
%找到y最大的点
tmp_p     = p(index,:);         
%设一个和y最大的点平行的点
tmp_heng  =[tmp_p(1)+100,tmp_p(2)];    
for i=1:length(p)           
    %求每个点和y最大的点的夹角,自己和自己夹角NAN
    Ang(i) = func_angle(tmp_heng,p(i,:),tmp_p);  
end
Ang   = Ang';
p     =[p,Ang];
%按第三列排序,第三列是夹角度数
p     = sortrows(p,3);    
%re相当于栈
re{1} = p(length(p),1:2);     
re{2} = p(1,1:2);
re{3} = p(2,1:2);
top   = 3; 
for i=3:length(p)-1
    while func_multi(p(i,1:2),re{top-1},re{top})>=eps      
        top=top-1;    
        if top<=1
           break;
        end
    end
    top=top+1;
    re{top}=p(i,1:2);
end
 
%下面是把找到的凸包上的点连线
for i=2:top   
    imgs = drawline(img,re{i-1}(1),re{i-1}(2),re{i}(1),re{i}(2));
end
imgs = drawline(img,re{1}(1),re{1}(2),re{top}(1),re{top}(2));

figure
subplot(231);
imshow(imgs)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%计算四个顶点
jiaodian2             = func_cal_point(imgs);
%这里使用相似度匹配措施对初始顶点进行顶点修正
[jiaodian3,jiaodian4] = func_cal_point_adjust(jiaodian2,G);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%校正
Z=func_adjust(jiaodian4,G);
subplot(232);
imshow(uint8(G))
hold on
for i = 1:4
    plot(jiaodian2(i,2),jiaodian2(i,1),'g.'); 
    hold on;
    text(jiaodian2(i,2),jiaodian2(i,1),num2str(i)); 
end

subplot(233);
imshow(uint8(G))
hold on
for i = 1:4
    plot(jiaodian4(i,2),jiaodian4(i,1),'r.'); 
    hold on;
    plot(jiaodian3(i,2),jiaodian3(i,1),'g.'); 
    hold on;
end

subplot(234);
imshow(uint8(G))
hold on
for i = 1:3
    line([jiaodian4(i,2),jiaodian4(i+1,2)],[jiaodian4(i,1),jiaodian4(i+1,1)],'Color',[0 1 0]); 
    hold on;
end
line([jiaodian4(end,2),jiaodian4(1,2)],[jiaodian4(end,1),jiaodian4(1,1)],'Color',[0 1 0]); 

subplot(235);
Z2 = histeq(uint8(Z));
imshow(Z2);

subplot(236);
thresh=graythresh(Z2);
f   = im2bw(Z2,thresh); 
imshow(f);
 

%%
%对最后的结果进行分割
[R,C] = size(Z2);

Z3    = edge(Z2,'canny');

%行扫描
tmp1  = 0;
tmp2  = 0;
for i = 2:R  
    tmp1    = f(i-1,:);
    tmp2    = f(i,:);
    diff1(i) = abs(mean(tmp1 - tmp2));
end
%搜索最小值
[pks1,locs1]=findpeaks(-1*diff1,'minpeakdistance',3); % Find peaks 



%列扫描
tmp1  = 0;
tmp2  = 0;
for i = 2:C  
    tmp1    = f(:,i-1);
    tmp2    = f(:,i);
    diff2(i) = abs(mean(tmp1 - tmp2));
end
%搜索最小值
[pks2,locs2]=findpeaks(-1*diff2,'minpeakdistance',3); % Find peaks 
locs1 = [locs1];
locs2 = [locs2];
%获得归一化二维码
QRcode = zeros(length(locs1),length(locs2));
for i = 1:length(locs1)
    for j = 1:length(locs2)
        QRcode(i,j) = f(locs1(i),locs2(j));
    end
end
%补偿
QRcode = QRcode; 


figure;
subplot(3,2,1);
imshow(Z2);
subplot(3,2,2);
imshow(Z3);
subplot(3,2,3);
plot(diff1);
hold on;
plot(locs1,diff1(locs1),'k^','markerfacecolor',[1 0 0]);
title('水平边缘投影');
subplot(3,2,4);
plot(diff2); 
hold on;
plot(locs2,diff2(locs2),'k^','markerfacecolor',[1 0 0]);
title('垂直边缘投影');

subplot(3,2,5);   
imshow(Z2,[]);
title('透视纠正后图像');
subplot(3,2,6);   
imshow(QRcode,[]);
title('归一化二维码');








4.仿真结果

 

 

 

 A10-38

猜你喜欢

转载自blog.csdn.net/ccsss22/article/details/125490457
今日推荐