代码语言:javascript复制
import numpy as np
import cv2
from matplotlib import pyplot as plt
def drawlines(img1,img2,lines,pts1,pts2):
r,c=img1.shape
img1=cv2.cvtColor(img1,cv2.COLOR_GRAY2BGR)
img2=cv2.cvtColor(img2,cv2.COLOR_GRAY2BGR)
for r,pt1,pt2 in zip(lines,pts1,pts2):
color=tuple(np.random.randint(0,255,3).tolist())
x0,y0=map(int,[0,-r[2]/r[1]])
x1,y1=map(int,[c,-(r[2] r[0]*c)/r[1]])
img1=cv2.line(img1,(x0,y0),(x1,y1),color,1)
img1=cv2.circle(img1,tuple(pt1),5,color,-1)
img2=cv2.circle(img2,tuple(pt2),5,color,-1)
return img1,img2
img1=cv2.imread('C:/Users/xpp/Desktop/Lena.png',0)
img2=cv2.imread('C:/Users/xpp/Desktop/Lena.png',0)
sift=cv2.xfeatures2d.SIFT_create()
#使用SIFT查找关键点和描述符
kp1,des1=sift.detectAndCompute(img1,None)
kp2,des2=sift.detectAndCompute(img2,None)
FLANN_INDEX_KDTREE=1
index_params=dict(algorithm=FLANN_INDEX_KDTREE,trees=5)
search_params=dict(checks=50)
flann=cv2.FlannBasedMatcher(index_params,search_params)
matches=flann.knnMatch(des1,des2,k=2)
good=[]
pts1=[]
pts2=[]
for i,(m,n) in enumerate(matches):
if m.distance<0.8*n.distance:
good.append(m)
pts2.append(kp2[m.trainIdx].pt)
pts1.append(kp1[m.queryIdx].pt)
pts1=np.int32(pts1)
pts2=np.int32(pts2)
F,mask=cv2.findFundamentalMat(pts1,pts2,cv2.FM_LMEDS)
pts1=pts1[mask.ravel()==1]
pts2=pts2[mask.ravel()==1]
#找到与右图像(第二幅图像)中的点对应的外轮廓线并在左侧图像上绘制其线条
lines1=cv2.computeCorrespondEpilines(pts2.reshape(-1,1,2),2,F)
lines1=lines1.reshape(-1,3)
img5,img6=drawlines(img1,img2,lines1,pts1,pts2)
#找到与左图像(第一幅图像)中的点对应的外轮廓线并在右图上绘制其线条
lines2=cv2.computeCorrespondEpilines(pts1.reshape(-1,1,2),1,F)
lines2=lines2.reshape(-1,3)
img3, img4=drawlines(img2,img1,lines2,pts2,pts1)
plt.subplot(121),plt.imshow(img5)
plt.subplot(122),plt.imshow(img3)
plt.show()
算法:对极几何是是“两幅图像之间的对极几何”,图像平面与以基线为轴的平面束的交的几何(基线是指连接摄像机中心的直线)。
链接:https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_calib3d/py_epipolar_geometry/py_epipolar_geometry.html#epipolar-geometry