上一篇文章中利用Harris角点算子提取了图像中的角点。这一篇文章将利用NCC(归一化互相关匹配算法)对两张不同角度的图像的角点进行匹配。本文代码是基于《python计算机视觉》改写的。首先介绍NCC匹配方法。该方法原理较为简单,如下图所示,即计算主图像中每个角点周围窗口与辅图像中每个角点周围窗口的互相关指数。
# -*- coding:utf-8 -*-
import numpy
from PIL import Image
from pylab import *
import testharris1
import pickle
import testpkl
#图1
I=array(Image.open('ukbench00641.jpg').convert('L'))
c_coords1,c_coords2=testharris1.testharris1(I,threshold=0.1)
c_coords=vstack((array(c_coords1).T,array(c_coords2).T))
#图2
I1=array(Image.open('ukbench00642.jpg').convert('L'))
c_coords1_1,c_coords2_1=testharris1.testharris1(I1,threshold=0.1)
c_coords_1=vstack((array(c_coords1_1).T,array(c_coords2_1).T))
def get_widvalue(I,c_coords1,c_coords2,wid=5):#获取角点周围点信息存进desc
desc1 = []
for i in range(len(c_coords1)):
patch=I[c_coords1[i]-wid:c_coords1[i]+wid+1,c_coords2[i]-wid:c_coords2[i]+wid+1]
desc1.append(patch)
return desc1
desc1=get_widvalue(I,c_coords1,c_coords2,wid=10)
desc2=get_widvalue(I1,c_coords1_1,c_coords2_1,wid=10)
def match(desc1,desc2,threshold=0.5):
n=len(desc1)
d = -ones([len(desc1),len(desc2)])
for i in range(len(desc1)):
for j in range(len(desc2)):
d1 = (desc1[i] - mean(desc1[i])) / std(desc1[i])
d2 = (desc2[j] - mean(desc2[j])) / std(desc2[j])
ncc_value=sum(d1*d2)/(n-1)
if ncc_value>threshold:
d[i,j]=ncc_value
ndx=argsort(-d)
matchscores=ndx[:,0]
return matchscores,d
mat,d=match(desc1,desc2,threshold=1.2)
mat1,d1=match(desc2,desc1,threshold=1.2)
output=open('mat.pkl','wb')
pickle.dump(mat,output)
output.close()
output1=open('mat1.pkl','wb')
pickle.dump(mat1,output1)
mat_total=testpkl.testpkl(mat,mat1)
output1.close()
output2=open('mat_t.pkl','wb')
pickle.dump(mat_total,output2)
output2.close()
def appendimages(I,I1):
rows=I.shape[0]
rows_1=I1.shape[0]
if rowsrows_1:
I1=concatenate((I1,zeros((rows-rows_1,I1.shape(0)))),axis=0)
return concatenate((I,I1),axis=1)
I_12=appendimages(I,I1)
c_total1=[]
c_total2=[]
c_total1_1=[]
c_total2_1=[]
for i in range(len(mat_total[0])):
c_total1.append(c_coords1[mat_total[0,i]])
c_total2.append(c_coords2[mat_total[0,i]])
c_total1_1.append(c_coords1_1[mat_total[1,i]])
c_total2_1.append(c_coords2_1[mat_total[1,i]])
c_total2_1_1=[k+I.shape[1] for k in c_total2_1]
figure()
imshow(I_12,cmap='gray')
plot(c_total2,c_total1,'r*')
plot(c_total2_1_1,c_total1_1,'b*')
c_total2=array(c_total2)
c_total1=array(c_total1)
c_total1_1=array(c_total1_1)
c_total2_1_1=array(c_total2_1_1)
X=[c_total2[:],c_total2_1_1[:]]
Y=[c_total1[:],c_total1_1[:]]
plot(X,Y)
axis('off')
show()
主函数的代码如上所示。结果如下图所示。从结果来看,图像存在许多错误点。这与harris算子本身的缺陷和NCC算子的缺陷有关。因此尺度不变的SIFT算子是更好的选择。