现在的位置: 首页 > 综合 > 正文

基于边缘的模板匹配

2018年04月10日 ⁄ 综合 ⁄ 共 5292字 ⁄ 字号 评论关闭
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                          %
%   a: model RGB image                                     %
%   b: target RGB image                                    %
%   c: output the match image                              %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [ c ] = edge_match( a,b)
%UNTITLED2 Summary of this function goes here
%   Detailed explanation goes here
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%用sobel掩膜提取边缘并保留边缘点的梯度方向与ang数组中%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
ma=im2double(rgb2gray(a)); %样本图像
mb=im2double(rgb2gray(b)); %模板

%水平与竖直方向的sobel掩膜
mask_Ver= fspecial('sobel');     %垂直方向上的掩膜
mask_Lev=  mask_Ver';              %水平方向掩膜
%图像在水平方向和垂直方向上对sobel算子的响应
imgSobel_Lev=imfilter(ma,double(mask_Lev),'corr','replicate','same');
imgSobel_Ver=imfilter(ma,double(mask_Ver),'corr','replicate','same');
%imwrite(imgSobel_Ver,'Ver.jpg');
%imwrite(imgSobel_Lev,'Lev.jpg');
%%
%计算模板特征点角度
[Row,Col]=size(ma);
for i=1:Row
    for j=1:Col
      imgEdge(i,j)=sqrt(imgSobel_Ver(i,j)*imgSobel_Ver(i,j)+imgSobel_Lev(i,j)*imgSobel_Lev(i,j));       
        if(imgSobel_Lev(i,j)==0)
              temp=0;
          elseif(imgSobel_Ver(i,j)==0)
              temp=90.0;
          else
              temp =atan(imgSobel_Lev(i,j)/imgSobel_Ver(i,j));
        end       
        if(temp<0)
             temp=180*(pi+temp)/(pi);
          else
              temp=180*temp/(pi);
        end
     
%将角度归为0,45,90,135,四个方向
if((temp<22.5)||(temp>157.5))
    ang(i,j)=0;
elseif(temp>=22.5&&temp<=67.5)
    ang(i,j)=45;
elseif(temp>67.5&&temp<112.5)
    ang(i,j)=90;
elseif(temp>=112.5&&temp<=157.5)
    ang(i,j)=135;
end

    end
end 
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%非最大抑制法% && %孤立点删除%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
avg=0;%边缘点强度的平局值
count=0;%边缘点个数
%摒弃图像边缘点 
for i=1:Row
    for j=1:Col
         if(i==1 || i==Row || j==1 || j==Col )
            imgEdge(i,j)=0;
       else
        %最大抑制法
        if(imgEdge(i,j)~=0)%是边缘点
            switch ang(i,j)
                case 0
                  ptLeft=imgEdge(i,j-1);
                  ptRight=imgEdge(i,j+1);
                case 45
                  ptLeft=imgEdge(i-1,j+1);
                  ptRight=imgEdge(i+1,j-1);
                case 90
                  ptLeft=imgEdge(i-1,j);
                  ptRight=imgEdge(i+1,j);
                case 135
                  ptLeft=imgEdge(i-1,j-1);
                  ptRight=imgEdge(i+1,j+1);
            end %switch
                    if(imgEdge(i,j)<ptLeft||imgEdge(i,j)<ptRight)
                        imgEdge(i,j)=0;
                        imgSobel_Ver(i,j)=0;
                        imgSobel_Lev(i,j)=0;
                    else
                         avg=avg+imgEdge(i,j);
                         count=count+1;
                    end
        end %if(imgEdge(i,j)~=0)
         end %end of if(i==1)
    end %end of Col
end%end of Row
%%
%对比度抑制
avg=avg/count;
%重心坐标
gravity_x=0;
gravity_y=0;
MagG=0;
count=0; 
maxContrast = avg*0.8;%满足最大的肯定是边缘点
minContrast = avg*0.5;%低于最小的肯定不是
for i=2:Row-1
    for j=2:Col-1
        %上下门限删除孤立点
        tl=imgEdge(i-1,j-1);
        tp=imgEdge(i-1,j);
        tr=imgEdge(i-1,j+1);
        lt=imgEdge(i,j-1);
        rt=imgEdge(i,j+1);
        bl=imgEdge(i+1,j-1);
        bt=imgEdge(i+1,j);
        br=imgEdge(i+1,j+1);
        if(imgEdge(i,j)~=0 && imgEdge(i,j)<maxContrast)
            %删除对比度过小的边缘点
            if(imgEdge(i,j)<minContrast)        
                imgEdge(i,j)=0;
                imgSobel_Ver(i,j)=0;
                imgSobel_Lev(i,j)=0;
            %如果八邻域都没有绝对边缘点,认为是孤立点,删除    
            elseif(tl<maxContrast&&tp<maxContrast&&tr<maxContrast&&...
                   lt<maxContrast&&rt<maxContrast&&...
                   bl<maxContrast&&bt<maxContrast&&br<maxContrast)
                imgEdge(i,j)=0;
                imgSobel_Ver(i,j)=0;
                imgSobel_Lev(i,j)=0;
            end   %if(imgEdge(i,j)<minContrast)
        end   %if(imgEdge(i,j)<maxContrast)     
 %%
        %求重心
        if(imgEdge(i,j)~=0)%((imgSobel_Ver(i,j)~=0||imgSobel_Lev(i,j)~=0&&imgEdge(i,j)~=0))            
            gravity_x=gravity_x+i*imgEdge(i,j);
            gravity_y=gravity_y+j*imgEdge(i,j);
            MagG=MagG+imgEdge(i,j);
                 %记录模板特征描述符
                  count=count+1;
                  Model_mag(count)= 1/imgEdge(i,j);
                  Model_y(count)=j;
                  Model_x(count)=i;
                  ModDerivative_Ver(count)=imgSobel_Ver(i,j);
                  ModDerivative_Lev(count)=imgSobel_Lev(i,j);
       end % end of (imgEdge(i,j)~=0
    end    % end of col
end        % end of row
%  imwrite(imgEdge,'edge3.jpg');   
%  imwrite(imgSobel_Ver,'imgSobel_Ver.jpg');  
%  imwrite(imgSobel_Lev,'imgSobel_Lev.jpg');  
%%%%%%%%%%%%%%%%%%计算模板特征描述%%%%%%%%%%%%%%%%%%%%%
%%
gravity_x=int32(gravity_x/MagG);
gravity_y=int32(gravity_y/MagG);

ModFeatNo=count;%模板的特征点数量

%将特征点位置描述改为以重心为原心

for k=1:ModFeatNo
Model_x(k)=Model_x(k)-gravity_x;
Model_y(k)=Model_y(k)-gravity_y;
end
 
%%%%%%%%%%%%%%%%%%匹配算法%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
[Row,Col]=size(mb);%待测目标
%图像在水平方向和垂直方向上对sobel算子的响应
tagSobel_Lev=imfilter(mb,double(mask_Lev),'corr','replicate','same');
tagSobel_Ver=imfilter(mb,double(mask_Ver),'corr','replicate','same');

targDeriv_Ver=0;
targDeriv_Lev=0;
modDeriv_Ver=0;
modDeriv_Lev=0;
score=0;%匹配得分
BestScore=0;
location=[-1,-1];%模板重心在目标图像的位置
minScore =0.1 ;%最低匹配得分,低于最低认为匹配失败
normMinScore=minScore/ModFeatNo;
greediness=0.01;%模板的梯度指数,
normGreediness=(1-greediness*minScore)/(1-greediness);

patialSum=0;%局部最大值
for i=1:Row
    for j=1:Col
  for k=1:ModFeatNo
   CurX=Model_x(k)+i;
   CurY=Model_y(k)+j;
   %游标位置限制,待测目标的搜索起始和结束位置不会使得模板越界
   if(CurX<1 || CurY<1 || CurX> Row || CurY> Col)
       continue;
   else
       %相似性判别
       targDeriv_Ver=tagSobel_Ver(CurX,CurY);
       targDeriv_Lev=tagSobel_Lev(CurX,CurY);
       if((targDeriv_Ver~=0 || targDeriv_Lev~=0))
       modDeriv_Ver=ModDerivative_Ver(k);
       modDeriv_Lev=ModDerivative_Lev(k);  
       
       targMag=sqrt(targDeriv_Ver*targDeriv_Ver+targDeriv_Lev*targDeriv_Lev);
       if(targMag~=0)
       targMag=1/targMag;    
       end;
       %余弦向量相似性度量
       patialSum =patialSum +((modDeriv_Ver*targDeriv_Ver) +...
           (modDeriv_Lev*targDeriv_Lev))*(Model_mag(k)*targMag);
       end        
       %退出判断
       thres=[(minScore-1)+normGreediness*k,normMinScore*k];
       threshold=min(thres);
       score=patialSum;
           if(score<threshold)
           break;
           end
   end   %if(CurX<1 || CurY<1)
   end    %for k=1:ModFeatNo
   score=patialSum/ModFeatNo;
   patialSum=0;
   if(score>=BestScore)
       BestScore=score;
       location(1)=i;
       location(2)=j;
   end   %   if(score>=BestScore)
    end    %for j=1:Col
end       %for i=1:Row
%%
%模板在目标图像中的坐标
[Row,Col]=size(ma);
countt=1;
location(1);
location(2);
 for i=1:Row;
     for j=1:Col;
         if(imgEdge(i,j)~=0)
        x1(countt)=location(1)+i-gravity_x;
        y1(countt)=location(2)+j-gravity_y;
        countt=countt+1;
         end
 end
 end
%%
%画出输出图像
figure
hold on;
image(b);
plot(y1,x1,'o','LineWidth',2,...             %设置圆圈的线粗
                'MarkerEdgeColor','r',...      %边界设置为黑色
                'MarkerFaceColor','r',...      %内部设置白色
                'MarkerSize',2)                 %大小设置
            hold off;
c=b;

             %%%%%%%最后一个end
end

模板:

目标:

结果:

抱歉!评论已关闭.