Skip to content

Commit 3f2db32

Browse files
committed
Update README and docs
1 parent 0351741 commit 3f2db32

File tree

5 files changed

+45
-30
lines changed

5 files changed

+45
-30
lines changed

README.md

+9-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
## Monocular Visual Odometry
22

3-
### Pipeline
4-
To be described
3+
**DatasetReaderKITTI** is responsible for loading frames from [KITTI Visual Odometry Dataset](http://www.cvlibs.net/datasets/kitti/eval_odometry.php) (optionally scaling them to reduce processing time) and ground truth (camera matrix, camera position and scale).
54

6-
#### Dataset
7-
- [KITTI Visual Odometry Dataset](http://www.cvlibs.net/datasets/kitti/eval_odometry.php)
5+
In a processing loop I convert images to greyscale, run keypoint detection using GFTT and then track these keypoints with **FeatureTracker** that uses OpenCV optical flow. After finding feature tracks, I remove outliers (outside of image).
6+
7+
In the next step I estimate the essential matrix *E* to find relative pose *R*, *t* between consecutive frames. Calculating *E* matrix also allows to remove few outliers (found by RANSAC). Having that rotation and translation, I calculate absolute position and orientation of the camera and I use them to draw a trajectory.
8+
9+
To get better results, I rely on absolute scale provided as KITTI groundtruth when computing abs. pose.
810

911
#### Screenshots
12+
1013
<p align="center"> <img src="doc/tracking_1.png" alt="Tracking 1"/> </p>
14+
1115
<p align="center"> <img src="doc/tracking_2.png" alt="Tracking 2"/> </p>
16+
1217
<p align="center"> <img src="doc/trajectory.png" alt="Trajectory"/> </p>

slam/FeatureTracker.py renamed to source/feature_tracking.py

+24-12
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
import cv2
22
import numpy as np
33

4-
class FeatureTracker:
5-
# Finds indices of bad features (with status=0 or position outside the frame).
6-
# @param features Detected (or tracked) features.
7-
# @param frame Image matrix.
8-
# @param status Vector of status flags returned by optical flow.
9-
# @returns Vector containing indices that should be filtered out.
4+
class FeatureTracker:
5+
"""
6+
Finds indices of bad features (with status=0 or position outside the frame).
7+
8+
Args:
9+
features: Detected (or tracked) features.
10+
frame: Image matrix.
11+
status: Vector of status flags returned by optical flow.
12+
13+
Returns:
14+
Vector containing indices that should be filtered out.
15+
"""
1016
def calcWrongFeatureIndices(self, features, frame, status):
1117
status_ = status.copy()
1218
for idx, pt in enumerate(features):
@@ -15,12 +21,18 @@ def calcWrongFeatureIndices(self, features, frame, status):
1521
wrongIndices = np.where(status_ == 0)[0]
1622
return wrongIndices
1723

18-
# Tracks features using Lucas-Kanade optical flow and filters out bad features.
19-
# @param prevFrame Previous image.
20-
# @param currFrame Current (next) image.
21-
# @param prevPts Features detected on previous frame.
22-
# @param removeOutliers Set to true if you want to remove bad features after tracking.
23-
# @returns Features from previous and current frame (tracked), both filtered.
24+
"""
25+
Tracks features using Lucas-Kanade optical flow and filters out bad features.
26+
27+
Args:
28+
prevFrame: Previous image.
29+
currFrame: Current (next) image.
30+
prevPts: Features detected on previous frame.
31+
removeOutliers: Set to true if you want to remove bad features after tracking.
32+
33+
Returns:
34+
Features from previous and current frame (tracked), both filtered.
35+
"""
2436
def trackFeatures(self, prevFrame, currFrame, prevPts, removeOutliers=False):
2537
# Feature tracking on the 2nd frame
2638
currPts, status, _ = cv2.calcOpticalFlowPyrLK(prevFrame, currFrame, prevPts, None)

slam/DatasetReaderKITTI.py renamed to source/kitti_reader.py

-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ def readCameraMatrix(self):
3636
K[1, 1] = focal
3737
K[1, 2] = cy
3838
K[2, 2] = 1
39-
# print("Constructed camera matrix {}:\n{}".format(K.shape, K))
4039
return K
4140

4241
def readGroundtuthPosition(self, frameId):

slam/slam.py renamed to source/run.py

+3-12
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,9 @@
33
import numpy as np
44
import matplotlib.pyplot as plt
55

6-
from DatasetReaderKITTI import DatasetReaderKITTI
7-
from FeatureTracker import FeatureTracker
8-
from utils import drawFrameFeatures, updateTrajectoryDrawing
9-
10-
def savePly(points, colors, output_file):
11-
vertexes = [ (p[0], p[1], p[2], c[0], c[1], c[2]) for p, c in zip(points, colors)]
12-
vertexes = [ v for v in vertexes if v[2] >= 0 ] # Discard negative z
13-
dtypes = [('x', 'f8'), ('y', 'f8'), ('z', 'f8'), ('red', 'u1'), ('green', 'u1'), ('blue', 'u1')]
14-
array = np.array(vertexes, dtype=dtypes)
15-
element = plyfile.PlyElement.describe(array, "vertex")
16-
plyfile.PlyData([element]).write(output_file)
17-
6+
from kitti_reader import DatasetReaderKITTI
7+
from feature_tracking import FeatureTracker
8+
from utils import drawFrameFeatures, updateTrajectoryDrawing, savePly
189

1910
if __name__ == "__main__":
2011
tracker = FeatureTracker()

slam/utils.py renamed to source/utils.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,12 @@ def updateTrajectoryDrawing(trackedPoints, groundtruthPoints):
2424
plt.title("Trajectory")
2525
plt.legend()
2626
plt.draw()
27-
plt.pause(0.01)
27+
plt.pause(0.01)
28+
29+
def savePly(points, colors, output_file):
30+
vertexes = [ (p[0], p[1], p[2], c[0], c[1], c[2]) for p, c in zip(points, colors)]
31+
vertexes = [ v for v in vertexes if v[2] >= 0 ] # Discard negative z
32+
dtypes = [('x', 'f8'), ('y', 'f8'), ('z', 'f8'), ('red', 'u1'), ('green', 'u1'), ('blue', 'u1')]
33+
array = np.array(vertexes, dtype=dtypes)
34+
element = plyfile.PlyElement.describe(array, "vertex")
35+
plyfile.PlyData([element]).write(output_file)

0 commit comments

Comments
 (0)