Developer
2026
Computer Vision, Geometry, 3D Reconstruction
Python, NumPy, OpenCV, SciPy, Viser
Individual project
Built a sparse Structure from Motion pipeline that estimates image correspondences, camera motion, and 3D scene points from two staff-provided iPhone 15 Pro living-room images.
Settings: random seed 42; 8,000 maximum SIFT features; NNDR threshold 0.8; 2,000 RANSAC iterations; and a Sampson-distance inlier threshold of 0.001.
Computed the intrinsic matrix from a 6.765 mm focal length, 9.757 mm sensor width, and 1280×960 image dimensions: f = 6.765 × (1280 / 9.757) ≈ 887.49 px, with principal point (640, 480). The height calculation produced 887.46 px, supporting the square-pixel assumption.
Used OpenCV SIFT because it is robust to the pair's rotation and translation. The detector produced 7,807 features in image one and 7,372 in image two, using default SIFT parameters except an 8,000 feature cap.


OpenCV's BFMatcher compares SIFT descriptors with L2 distance. An NNDR threshold of 0.8 retained 617 candidate correspondence pairs; it is intentionally permissive because geometry-based RANSAC removes outliers downstream.
Each RANSAC iteration samples eight correspondences, estimates an Essential matrix with the 8-point algorithm, decomposes it into four candidate poses, and uses a cheirality check to select the pose with the most positive-depth triangulations. All correspondences are scored with Sampson distance, then the best model is refined using every inlier.
The final model retained 469/617 inliers (76.01%). Tightening epsilon from 0.01 to 0.001 corrected an initially incorrect pose by excluding geometrically inconsistent matches.








Inlier pairs are triangulated with Direct Linear Transform, then filtered by positive depth and reprojection error. The final sparse reconstruction contains 469 points, with mean depth 1.6068 and depth range [0.5960, 20.5436].
The recovered rotation has Euler angles roll 21.36°, pitch 22.08°, yaw 12.40°; the normalized translation is [-0.73835, 0.55234, 0.38698]. The final point cloud can be explored through the generated Viser scene data.






