-
Notifications
You must be signed in to change notification settings - Fork 0
/
extractor.py
46 lines (39 loc) · 1.59 KB
/
extractor.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import cv2
import numpy as np
from skimage.measure import ransac
from skimage.transform import FundamentalMatrixTransform
class Extractor(object):
def __init__(self):
self.orb = cv2.ORB_create()
self.bf = cv2.BFMatcher.create(cv2.NORM_HAMMING)
self.last = None
def extract(self, img):
# preprocessing
# temporaly disabled because of np.float32() required for the followirng steps
#gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# detection
feats = cv2.goodFeaturesToTrack(np.mean(img, axis=2).astype(np.uint8), maxCorners=300, qualityLevel=0.01, minDistance=3)
# extraction
kps = [cv2.KeyPoint(x=f[0][0], y=f[0][1], _size=20) for f in feats]
kps, des = self.orb.compute(img, kps)
# matching
ret = []
if self.last is not None:
matches = self.bf.knnMatch(des, self.last['des'], k=2)
for m,n in matches:
if m.distance < 0.75*n.distance:
kp1 = kps[m.queryIdx].pt
kp2 = self.last['kps'][m.trainIdx].pt
ret.append((kp1, kp2))
# filter
if len(ret) > 0:
ret = np.array(ret)
model, inliers = ransac((ret[:, 0], ret[:, 1]),
FundamentalMatrixTransform,
min_samples=8,
residual_threshold=1,
max_trials=100)
ret = ret[inliers]
# return
self.last = {'kps': kps, 'des': des}
return ret