我正在尝试匹配在CT和MRI扫描中检测到的哈里斯角点。 但是,当我尝试使用归一化互相关和NMI匹配那些点时,却显示出意外的结果。 我无法确定原因。 由于图像是多峰的,我是否需要使用某种技术对输入图像进行预处理?
import numpy as np
import cv2
from matplotlib import pyplot as plt
from skimage import exposure
import scipy.ndimage as ndimage
import time
from skimage.feature import corner_harris, corner_subpix, corner_peaks
from sklearn.metrics.cluster import normalized_mutual_info_score
start_time = time.time()
EPS = np.finfo(float).eps
plt.rcParams['image.cmap'] = 'gray'
plt.rcParams['image.interpolation'] = 'nearest'
plt.close('all')
def extract_keypoints(keypoints):
i = 0
temp_array=np.zeros((500,2),dtype=np.int)
for point in keypoints:
temp=point.pt
temp_array[i][0]=temp[0]
temp_array[i][1]=temp[1]
i=i+1
return temp_array
def correlation_coefficient(patch1, patch2):
product = np.mean((patch1 - patch1.mean()) * (patch2 - patch2.mean()))
stds = patch1.std() * patch2.std()
if stds == 0:
return 0
else:
product /= stds
return product
def get_descriptors(image,filtered_coords,wid=5):
""" For each point return pixel values around the point
using a neighbourhood of width 2*wid+1. (Assume points are
extracted with min_distance > wid). """
desc = []
for coords in filtered_coords:
patch = image[coords[0]-wid:coords[0]+wid+1,
coords[1]-wid:coords[1]+wid+1].flatten()
desc.append(patch)
return desc
def match(desc1,desc2,threshold=0.1):
""" For each corner point descriptor in the first image,
select its match to second image using
normalized cross correlation. """
n = len(desc1[0])
# pair-wise distances
d = -np.ones((len(desc1),len(desc2)))
for i in range(len(desc1)):
for j in range(len(desc2)):
d1 = (desc1[i] - np.mean(desc1[i])) / np.std(desc1[i])
d2 = (desc2[j] - np.mean(desc2[j])) / np.std(desc2[j])
ncc_value = sum(d1 * d2) / (n-1)
if ncc_value > threshold:
d[i,j] = ncc_value
ndx = np.argsort(-d)
matchscores = ndx[:,0]
return matchscores
def match_twosided(desc1,desc2,threshold=0.1):
""" Two-sided symmetric version of match(). """
matches_12 = match(desc1,desc2,threshold)
matches_21 = match(desc2,desc1,threshold)
ndx_12 = np.where(matches_12 >= 0)[0]
# remove matches that are not symmetric
for n in ndx_12:
if matches_21[matches_12[n]] != n:
matches_12[n] = -1
return matches_12
def match_MI(desc1,desc2,threshold=0.001):
""" For each corner point descriptor in the first image,
select its match to second image using
normalized cross correlation. """
# pair-wise distances
d = -np.ones((len(desc1),len(desc2)))
for i in range(len(desc1)):
for j in range(len(desc2)):
MI_value = normalized_mutual_info_score(desc1[i],desc2[j])
if MI_value > threshold:
d[i,j] = MI_value
ndx = np.argsort(-d)
matchscores = ndx[:,0]
return matchscores
def match_twosided_MI(desc1,desc2,threshold=0.001):
""" Two-sided symmetric version of match(). """
matches_12 = match_MI(desc1,desc2,threshold)
matches_21 = match_MI(desc2,desc1,threshold)
ndx_12 = np.where(matches_12 >= 0)[0]
# remove matches that are not symmetric
for n in ndx_12:
if matches_21[matches_12[n]] != n:
matches_12[n] = -1
return matches_12
def appendimages(im1,im2):
""" Return a new image that appends the two images side-by-side. """
# select the image with the fewest rows and fill in enough empty rows
rows1 = im1.shape[0]
rows2 = im2.shape[0]
if rows1 < rows2:
im1 = np.concatenate((im1,np.zeros((rows2-rows1,im1.shape[1]))),axis=0)
elif rows1 > rows2:
im2 = np.concatenate((im2,np.zeros((rows1-rows2,im2.shape[1]))),axis=0)
# if none of these cases they are equal, no filling needed.
return np.concatenate((im1,im2), axis=1)
def plot_matches(im1,im2,locs1,locs2,matchscores,show_below=True):
""" Show a figure with lines joining the accepted matches
input: im1,im2 (images as arrays), locs1,locs2 (feature locations),
matchscores (as output from 'match()'),
show_below (if images should be shown below matches). """
im3 = appendimages(im1,im2)
if show_below:
im3 = np.vstack((im3,im3))
plt.show(im3)
cols1 = im1.shape[1]
for i,m in enumerate(matchscores):
if m>0:
plt.plot([locs1[i][1],locs2[m][1]+cols1],[locs1[i][0],locs2[m][0]],'c')
plt.axis('off')
CT= cv2.imread('F:\MyTransforms_HP\DataSet1\CT.jpg')
MR= cv2.imread('F:\MyTransforms_HP\DataSet1\MR.jpg')
img1= cv2.imread('F:\MyTransforms_HP\DataSet1\CT.jpg',0)
img2= cv2.imread('F:\MyTransforms_HP\DataSet1\MR.jpg',0)
#img1=cv2.resize(img,(10,10),0,0)
CT_size=img1.shape
MR_size=img2.shape
#img11 = exposure.adjust_gamma(img1, 0.6)
p2, p98 = np.percentile(img2, (2, 60))
img21 = exposure.rescale_intensity(img2, in_range=(p2, p98))
coords1 = corner_peaks(corner_harris(img1), min_distance=10)
coords2 = corner_peaks(corner_harris(img21), min_distance=10)
NoCT_Corners=len(coords1)
NoMR_Corners=len(coords2)
print("Harris Corners detetcted--- %s seconds ---" % (time.time() - start_time))
print("No. of Corners in CT : %s" %NoCT_Corners)
print("No. of Corners in MR : %s" %NoMR_Corners)
des1=get_descriptors(img1,coords1)
des2=get_descriptors(img2,coords2)
matches_NCC=match_twosided(des1,des2)
des2=get_descriptors(img21,coords2)
matches_MI=match_twosided_MI(des1,des2)
#plot_matches(img1, img2, coords1, coords2, matches_12)
FinalMatch_NCC=np.zeros(shape=(36,2),dtype=np.int64)
k1=0
for i in range (0,NoCT_Corners):
if (matches_NCC[i]!=-1):
FinalMatch_NCC[k1][0]=i
FinalMatch_NCC[k1][1]=matches_NCC[i]
k1=k1+1
FinalMatch_MI=np.zeros(shape=(36,2),dtype=np.int64)
k2=0
for i in range (0,NoCT_Corners):
if (matches_MI[i]!=-1):
FinalMatch_MI[k2][0]=i
FinalMatch_MI[k2][1]=matches_MI[i]
k2=k2+1
im3 = appendimages(img1,img2)
im4 = appendimages(img1,img2)
#Draw lines
count = 0
for i in range (0,k1):
x1=coords1[FinalMatch_NCC[i][0]][1]
y1=coords1[FinalMatch_NCC[i][0]][0]
x2=coords2[FinalMatch_NCC[i][1]][1]+512
y2=coords2[FinalMatch_NCC[i][1]][0]
cv2.line(im3,(x1,y1),(x2,y2),(255,0,0),2)
cv2.circle(im3,(x1,y1),3,(255,255,255), -1)
cv2.circle(im3,(x2,y2),3,(255,255,255), -1)
#plt.close('all')
for i in range (0,k2):
x1=coords1[FinalMatch_MI[i][0]][1]
y1=coords1[FinalMatch_MI[i][0]][0]
x2=coords2[FinalMatch_MI[i][1]][1]+512
y2=coords2[FinalMatch_MI[i][1]][0]
cv2.line(im4,(x1,y1),(x2,y2),(255,0,0),1)
cv2.circle(im4,(x1,y1),3,(255,255,255), -1)
cv2.circle(im4,(x2,y2),3,(255,255,255), -1)
fig1, ax = plt.subplots(1,2)
ax[0].imshow(CT, interpolation='nearest', cmap=plt.cm.gray)
ax[0].plot(coords1[:, 1], coords1[:, 0], '.r', markersize=3)
ax[0].axis((0, 512,512, 0))
ax[1].imshow(MR, interpolation='nearest', cmap=plt.cm.gray)
ax[1].plot(coords2[:, 1], coords2[:, 0], '.r', markersize=3)
ax[1].axis((0, 512,512, 0))
plt.show()
plt.figure(2);
plt.imshow(im3);
plt.show();
plt.figure(3);
plt.imshow(im4);
plt.show();
[Harris Corners][1]