Skip to content

Instantly share code, notes, and snippets.

@YoshiRi
Last active August 26, 2017 01:39
Show Gist options
  • Save YoshiRi/428e47c35bec96d72f13ff3be4d2481f to your computer and use it in GitHub Desktop.
Save YoshiRi/428e47c35bec96d72f13ff3be4d2481f to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Jun 24 22:45:15 2017
@author: yoshi
"""
import cv2
import numpy as np
from matplotlib import pyplot as plt
def drawlines(img1,img2,lines,pts1,pts2):
''' img1 - img2上の点に対応するエピポーラ線を描画する画像
lines - 対応するエピポーラ線 '''
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('0.jpg',0) #queryimage # left image
img2 = cv2.imread('1.jpg',0) #trainimage # right image
# load camera matrix and distort matrix
K = np.loadtxt("K.csv",delimiter=",")
dist_coef = np.loadtxt('d.csv',delimiter=",")
img1 = cv2.undistort(img1, K, dist_coef)
img2 = cv2.undistort(img2, K, dist_coef)
# ORB (Oriented FAST and Rotated BRIEF)
detector = cv2.ORB_create()
#detector = cv2.AKAZE_create()
# create BFMatcher object
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
kp1,des1 = detector.detectAndCompute(img1,None)
kp2,des2 = detector.detectAndCompute(img2,None)
# Match descriptors.
matches = bf.match(des1,des2)
good = []
pts1 = []
pts2 = []
# Sort them in the order of their distance.
matches = sorted(matches, key = lambda x:x.distance)
count = 0
for m in matches:
count+=1
if count < 60:
good.append([m])
pts2.append(kp2[m.trainIdx].pt)
pts1.append(kp1[m.queryIdx].pt)
pts1 = np.float32(pts1)
pts2 = np.float32(pts2)
F, mask = cv2.findFundamentalMat(pts1,pts2,cv2.FM_LMEDS)
#F, mask = cv2.findFundamentalMat(pts1,pts2,cv2.FM_RANSAC)
# 外れ値を取り除きます
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://stackoverflow.com/questions/33906111/how-do-i-estimate-positions-of-two-cameras-in-opencv
# Normalize for Esential Matrix calaculation
pts1_norm = cv2.undistortPoints(np.expand_dims(pts1, axis=1), cameraMatrix=K, distCoeffs=None)
pts2_norm = cv2.undistortPoints(np.expand_dims(pts2, axis=1), cameraMatrix=K, distCoeffs=None)
E, mask = cv2.findEssentialMat(pts1_norm, pts2_norm, focal=1.0, pp=(0., 0.), method=cv2.RANSAC, prob=0.999, threshold=3.0)
points, R, t, mask = cv2.recoverPose(E, pts1_norm, pts2_norm)
M_r = np.hstack((R, t))
M_l = np.hstack((np.eye(3, 3), np.zeros((3, 1))))
P_l = np.dot(K, M_l)
P_r = np.dot(K, M_r)
point_4d_hom = cv2.triangulatePoints(P_l, P_r, np.expand_dims(pts1, axis=1), np.expand_dims(pts2, axis=1))
point_4d = point_4d_hom / np.tile(point_4d_hom[-1, :], (4, 1))
point_4d = point_4d[:3, :].T
Kinv = np.linalg.inv(K)
Kinvt = np.transpose(Kinv)
F = np.dot(Kinvt,E,K)
# 右画像(二番目の画像)中の点に対応するエピポーラ線の計算
# 計算したエピポーラ線を左画像に描画
lines1 = cv2.computeCorrespondEpilines(pts2.reshape(-1,1,2), 2,F)
lines1 = lines1.reshape(-1,3)
img15,img16 = drawlines(img1,img2,lines1,pts1,pts2)
# 左画像(一番目の画像)中の点に対応するエピポーラ線の計算
# 計算したエピポーラ線を右画像に描画
lines2 = cv2.computeCorrespondEpilines(pts1.reshape(-1,1,2), 1,F)
lines2 = lines2.reshape(-1,3)
img13,img14 = drawlines(img2,img1,lines2,pts2,pts1)
# 結果の表示
plt.subplot(121),plt.imshow(img15)
plt.subplot(122),plt.imshow(img13)
plt.show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment