playground/python/epipolar.py

91 lines
2.8 KiB
Python
Raw Normal View History

2024-09-21 21:50:07 -04:00
import numpy as np
import cv2
from matplotlib import pyplot as plt
# Load the left and right images
# in gray scale
imgLeft = cv2.imread('image_l.jpg', 0)
imgRight = cv2.imread('image_r.jpg', 0)
# Detect the SIFT key points and
# compute the descriptors for the
# two images
sift = cv2.SIFT_create()
keyPointsLeft, descriptorsLeft = sift.detectAndCompute(imgLeft, None)
keyPointsRight, descriptorsRight = sift.detectAndCompute(imgRight, None)
assert(len(keyPointsLeft) == len(descriptorsLeft))
assert(len(keyPointsRight) == len(descriptorsRight))
# Create FLANN matcher object
FLANN_INDEX_KDTREE = 0
indexParams = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
searchParams = dict(checks=50)
flann = cv2.FlannBasedMatcher(indexParams, searchParams)
matches = flann.knnMatch(descriptorsLeft, descriptorsRight, 2)
# Apply ratio test
goodMatches = []
ptsLeft = []
ptsRight = []
for m, n in matches:
if m.distance < 0.8 * n.distance:
goodMatches.append([m])
# ptsLeft.append(keyPointsLeft[m.trainIdx].pt)
# ptsRight.append(keyPointsRight[n.trainIdx].pt)
ptsLeft.append(keyPointsLeft[m.queryIdx].pt)
ptsRight.append(keyPointsRight[m.trainIdx].pt)
ptsLeft = np.int32(ptsLeft)
ptsRight = np.int32(ptsRight)
# r F l = 0 <- find f
F, mask = cv2.findFundamentalMat(ptsLeft,
ptsRight,
cv2.FM_LMEDS)
# We select only inlier points
ptsLeft = ptsLeft[mask.ravel() == 1]
ptsRight = ptsRight[mask.ravel() == 1]
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 i, (r, pt1, pt2) in enumerate(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
# Find epilines corresponding to points
# in right image (second image) and
# drawing its lines on left image
linesLeft = cv2.computeCorrespondEpilines(ptsRight.reshape(-1, 1, 2), 2, F)
linesLeft = linesLeft.reshape(-1, 3)
img5, img6 = drawlines(imgLeft, imgRight,
linesLeft, ptsLeft,
ptsRight)
# Find epilines corresponding to
# points in left image (first image) and
# drawing its lines on right image
linesRight = cv2.computeCorrespondEpilines(ptsLeft.reshape(-1, 1, 2), 1, F)
linesRight = linesRight.reshape(-1, 3)
img3, img4 = drawlines(imgRight, imgLeft,
linesRight, ptsRight,
ptsLeft)
plt.subplot(121), plt.imshow(img5)
plt.subplot(122), plt.imshow(img3)
plt.show()