1
+ # -*- coding: utf-8 -*-
2
+ # @Time : 2017年7月13日 下午6:57
3
+ # @Author : play4fun
4
+ # @File : code.py
5
+ # @Software: PyCharm
6
+
7
+ """
8
+ code.py:多视角几何基础,极点 极线 对极约束 对极平面
9
+
10
+ 在我们使用针孔相机时 我们会丢失大量重要的信息
11
+ 比如 图像的深度 或者 图像上的点和摄像机的距离
12
+ 因为这是一个从 3D 到 2D 的转换。
13
+ 重要的问题:
14
+ 使用这样的摄像机我们能否计算出深度信息呢?
15
+ 答案 就是使用多个相机。
16
+ 我们的眼睛就是这样工作的 使用两个摄像机 两个眼睛
17
+ 称为立体视角
18
+
19
+ 三角测量
20
+
21
+ 本征矩阵 E 和基础矩阵 F
22
+
23
+ 点越多越好 可以使用 RANSAC 算法得到更加稳定的结果
24
+
25
+ 使用 SIFT 描述符 FLANN 匹配器和比值检测
26
+ """
27
+
28
+ import cv2
29
+ import numpy as np
30
+ from matplotlib import pyplot as plt
31
+
32
+
33
+ # 找到极线
34
+ def drawlines (img1 , img2 , lines , pts1 , pts2 ):
35
+ ''' img1 - image on which we draw the epilines for the points in img2
36
+ lines - corresponding epilines '''
37
+ r , c = img1 .shape
38
+ img1 = cv2 .cvtColor (img1 , cv2 .COLOR_GRAY2BGR )
39
+ img2 = cv2 .cvtColor (img2 , cv2 .COLOR_GRAY2BGR )
40
+ for r , pt1 , pt2 in zip (lines , pts1 , pts2 ):
41
+ color = tuple (np .random .randint (0 , 255 , 3 ).tolist ())
42
+ x0 , y0 = map (int , [0 , - r [2 ] / r [1 ]])
43
+ x1 , y1 = map (int , [c , - (r [2 ] + r [0 ] * c ) / r [1 ]])
44
+ img1 = cv2 .line (img1 , (x0 , y0 ), (x1 , y1 ), color , 1 )
45
+ img1 = cv2 .circle (img1 , tuple (pt1 ), 5 , color , - 1 )
46
+ img2 = cv2 .circle (img2 , tuple (pt2 ), 5 , color , - 1 )
47
+ return img1 , img2
48
+
49
+
50
+ img1 = cv2 .imread ('myleft.jpg' , 0 ) # queryimage # left image
51
+ img2 = cv2 .imread ('myright.jpg' , 0 ) # trainimage # right image
52
+ sift = cv2 .SIFT ()
53
+ # find the keypoints and descriptors with SIFT
54
+ kp1 , des1 = sift .detectAndCompute (img1 , None )
55
+ kp2 , des2 = sift .detectAndCompute (img2 , None )
56
+ # FLANN parameters
57
+ FLANN_INDEX_KDTREE = 0
58
+ index_params = dict (algorithm = FLANN_INDEX_KDTREE , trees = 5 )
59
+ search_params = dict (checks = 50 )
60
+ flann = cv2 .FlannBasedMatcher (index_params , search_params )
61
+ matches = flann .knnMatch (des1 , des2 , k = 2 )
62
+ good = []
63
+ pts1 = []
64
+ pts2 = []
65
+ # ratio test as per Lowe's paper
66
+ for i , (m , n ) in enumerate (matches ):
67
+ if m .distance < 0.8 * n .distance :
68
+ good .append (m )
69
+ pts2 .append (kp2 [m .trainIdx ].pt )
70
+ pts1 .append (kp1 [m .queryIdx ].pt )
71
+ # 匹配点列表,用它来计算【基础矩阵】
72
+ pts1 = np .int32 (pts1 )
73
+ pts2 = np .int32 (pts2 )
74
+ F , mask = cv2 .findFundamentalMat (pts1 , pts2 , cv2 .FM_LMEDS )
75
+ # We select only inlier points
76
+ pts1 = pts1 [mask .ravel () == 1 ]
77
+ pts2 = pts2 [mask .ravel () == 1 ]
78
+ # 从两幅图像中计算并绘制极线
79
+ # Find epilines corresponding to points in right image (second image) and
80
+ # drawing its lines on left image
81
+ lines1 = cv2 .computeCorrespondEpilines (pts2 .reshape (- 1 , 1 , 2 ), 2 , F )
82
+ lines1 = lines1 .reshape (- 1 , 3 )
83
+ img5 , img6 = drawlines (img1 , img2 , lines1 , pts1 , pts2 )
84
+ # Find epilines corresponding to points in left image (first image) and
85
+ # drawing its lines on right image
86
+ lines2 = cv2 .computeCorrespondEpilines (pts1 .reshape (- 1 , 1 , 2 ), 1 , F )
87
+ lines2 = lines2 .reshape (- 1 , 3 )
88
+ img3 , img4 = drawlines (img2 , img1 , lines2 , pts2 , pts1 )
89
+ plt .subplot (121 ), plt .imshow (img5 )
90
+ plt .subplot (122 ), plt .imshow (img3 )
91
+ plt .show ()
92
+
93
+ #从上图可以看出所有的极线都汇聚以图像外的一点 这个点就是极点。
94
+ # 为了得到更好的结果 我们应 使用分辨率比较高的图像和 non-planar 点
0 commit comments