归一化交叉相关Normalization cross correlation (NCC)

归一化交叉相关Normalization cross correlation (NCC)

NCC正如其名字,是用来描述两个目标的相关程度的,也就是说可以用来刻画目标间的相似性。一般NCC也会被用来进行图像匹配,即在一个图像中搜索与一小块已知区域的NCC最高的区域作为对应匹配,然后对准整幅图像。

假设两幅图像,那么其NCC可如下计算:

其中表示点乘运算。

比如下面两幅图像,我们想对齐

enter description here

part1.jpg

enter description here

part2.jpg

首先在一幅图像中选取两个图像都有的区域作为templete

enter description here

templete.jpg

然后在另一幅图像中选取包含templete的区域

enter description here

region.jpg

最终对齐的结果如下

enter description here

result.jpg

  1. function NCC 
  2. close all 
  3. part2 =imread('part1.png'); 
  4. part1 = imread('part2.png'); 
  5.  
  6. imshow(part2);title('part2'
  7. figure, imshow(part1);title('part1'); 
  8. % 选取template和搜索区域region. Note:template的大小必须小于region 
  9. figure, 
  10. [sub_part2,rect_part2]=imcrop(part2);% template 
  11. [sub_part1,rect_part1]=imcrop(part1);% region 
  12.  
  13. figure, imshow(sub_part2) 
  14. figure, imshow(sub_part1); 
  15.  
  16. [x,y,z] = normcorr2(double(sub_part2(:,:,1)),double(sub_part1(:,:,1))); 
  17. figure,surf(x,y,z),shading flat 
  18. %% 寻找偏置 
  19. [~,imax]=max(z(:));% 
  20. [yoffset,xoffset]=ind2sub(size(z),imax(1)); 
  21. %% 图像对齐 
  22. % 配对点在第一幅图像中到边界的距离 
  23.  
  24. rect_part1=floor(rect_part1); 
  25. left1=rect_part1(1)+xoffset; 
  26. right1=size(part1,2)-left1; 
  27. up1=rect_part1(2)+yoffset; 
  28. down1 = size(part1,1)-left1; 
  29. % 配对点在第二幅图像中到边界的距离 
  30. rect_part2=floor(rect_part2); 
  31. left2=rect_part2(1); 
  32. right2=size(part2,2)-left2; 
  33. up2=rect_part2(2); 
  34. down2 = size(part2,1)-up2; 
  35.  
  36. img=zeros(max(up1,up2)+max(down1,down2)+1,max(left1,left2)+max(right1,right2)+1,size(part1,3)); 
  37. sx=max(left1,left2)+1
  38. sy=max(up1,up2)+1
  39. img(sy-up1+1:sy-up1+size(part1,1),sx-left1+1:sx-left1+size(part1,2),:)=part1; 
  40. img(sy-up2+1:sy-up2+size(part2,1),sx-left2+1:sx-left2+size(part2,2),:)=part2; 
  41. imshow(uint8(img)); 
  42. end 
  43.  
  44.  
  45.  
  46. function [x,y,z]=normcorr2(I1,I2) 
  47. % I1,I2是单通道图像,即矩阵 
  48. % I1 is template 
  49. % I2 is the region where match pairs are searched 
  50. [m1,n1]=size(I1); 
  51. [m2,n2]=size(I2); 
  52. z=conv2(I2,rot90(I1,2),'valid'); 
  53. im2=cumsum(I2.^2,1); 
  54. im2=cumsum(im2,2); 
  55. sum1=sum(sum(I1.^2,1),2); 
  56. % nz=zeros(m2-m1+1,n2-n1+1); 
  57. wrapIm2=zeros(1+m2,1+n2); 
  58. wrapIm2(2:end,2:end)=im2; 
  59. nz=(wrapIm2(m1+1:m2+1,n1+1:n2+1)+wrapIm2(1:m2-m1+1,1:n2-n1+1)-wrapIm2(1:m2-m1+1,n1+1:n2+1)-wrapIm2(m1+1:m2+1,1:n2-n1+1))*sum1; 
  60. nz=sqrt(nz); 
  61. z=z./nz; 
  62. [x,y]=meshgrid(1:n2-n1+1,1:m2-m1+1); 
  63. end 

enter description here

1477398865849.jpg

enter description here

1477398880386.jpg

enter description here

1477398892560.jpg

enter description here

1477398906100.jpg

enter description here

1477398924878.jpg

有些文献在计算卷积的时候,总说要把矩阵逆排序之后再对应相乘,包括conv2这个函数也是这么计算的。但实际上我们有一个templete和region,直接就是对应位置乘积之后作为卷积结果,也只有这样才能保证在匹配的位置处NCC系数最大,所以在代码里,我先对templete进行了逆序操作,在使用conv2卷积。

另外matlab2016添加了image registration 工具箱,里面可以直接计算NCC系数了,具体参见
http://cn.mathworks.com/help/images/examples/registering-an-image-using-normalized-cross-correlation.html.

原文地址:https://www.cnblogs.com/YiXiaoZhou/p/5998153.html