Skip to main content

Python bindings for SPHORB feature detector

Project description

PySPHORB

Python bindings for SPHORB (Spherical ORB), a fast and robust binary feature detector optimized for spherical and panoramic images.

About

SPHORB is a feature detection and description method designed specifically for 360° panoramic images using a geodesic grid representation. It provides scale and rotation invariance while avoiding expensive spherical harmonics calculations.

This package provides Python bindings for the original C++ implementation, enabling easy integration with modern computer vision workflows using NumPy and OpenCV.

Installation

From PyPI (Recommended)

pip install pysphorb

Pre-built wheels are available for:

  • Python 3.11, 3.12, 3.13, 3.14
  • Linux x86_64 (manylinux_2_35)

From Source

For other platforms or custom builds:

pip install git+https://github.com/cshyundev/py_sphorb.git

Or clone and install locally:

git clone https://github.com/cshyundev/py_sphorb.git
cd py_sphorb
pip install .

Build Requirements

  • Python >= 3.11
  • NumPy >= 2.0
  • OpenCV >= 4.0
  • CMake >= 3.15
  • C++17 compatible compiler

Quick Start

import cv2
import pysphorb

# Initialize detector
detector = pysphorb.SPHORB()

# Load panoramic image
img = cv2.imread("panorama.jpg")

# Detect keypoints and compute descriptors
keypoints, descriptors = detector.detectAndCompute(img)

print(f"Detected {len(keypoints)} keypoints")
print(f"Descriptor shape: {descriptors.shape}")  # (N, 32)

Usage Example

Feature Matching

import cv2
import pysphorb

# Initialize detector with custom parameters
detector = pysphorb.SPHORB(nfeatures=500, nlevels=7, b=20)

# Load two panoramic images
img1 = cv2.imread("pano1.jpg")
img2 = cv2.imread("pano2.jpg")

# Detect and compute descriptors
kp1, desc1 = detector.detectAndCompute(img1)
kp2, desc2 = detector.detectAndCompute(img2)

# Match using BFMatcher with Hamming distance
matcher = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=False)
matches = matcher.knnMatch(desc1, desc2, k=2)

# Apply Lowe's ratio test
good_matches = []
for m_n in matches:
    if len(m_n) == 2:
        m, n = m_n
        if m.distance < 0.75 * n.distance:
            good_matches.append(m)

print(f"Found {len(good_matches)} good matches")

Visualization

# Convert keypoints to cv2.KeyPoint format for visualization
cv_kp1 = [cv2.KeyPoint(x=kp[0], y=kp[1], size=kp[2], angle=kp[3],
                        response=kp[4], octave=kp[5]) for kp in kp1]
cv_kp2 = [cv2.KeyPoint(x=kp[0], y=kp[1], size=kp[2], angle=kp[3],
                        response=kp[4], octave=kp[5]) for kp in kp2]

# Draw matches
result = cv2.drawMatches(img1, cv_kp1, img2, cv_kp2, good_matches, None,
                         flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
cv2.imwrite("matches.jpg", result)

API Reference

SPHORB(nfeatures=500, nlevels=7, b=20)

Initialize SPHORB detector.

Parameters:

  • nfeatures (int): Maximum number of features to detect (default: 500)
  • nlevels (int): Number of pyramid levels (default: 7)
  • b (int): Barrier threshold for feature detection (default: 20)

detectAndCompute(image)

Detect keypoints and compute descriptors.

Parameters:

  • image (numpy.ndarray): Input image (grayscale or BGR)

Returns:

  • keypoints (list): List of tuples (x, y, size, angle, response, octave)
  • descriptors (numpy.ndarray): Binary descriptors of shape (N, 32)

detect(image)

Detect keypoints only (no descriptors).

Parameters:

  • image (numpy.ndarray): Input image (grayscale or BGR)

Returns:

  • keypoints (list): List of tuples (x, y, size, angle, response, octave)

descriptorSize()

Returns the descriptor size in bytes (always 32 for SPHORB).

descriptorType()

Returns the OpenCV descriptor type code.

Improvements Over Original Implementation

This Python binding includes several enhancements to the original C++ implementation:

1. Coordinate Scaling Fix

Issue: Original code returned keypoint coordinates in fixed internal resolution (1280x640), not matching input image size.

Fix: Keypoints now correctly scaled to match input image dimensions, enabling seamless integration with OpenCV workflows.

2. Adaptive Resolution Processing

Issue: All images were resized to 1280x640, causing unnecessary upscaling for smaller images (e.g., 640x320 → 1280x640).

Fix: Automatically selects appropriate pyramid start level based on input size:

  • Small images (e.g., 320x160): Processes at native resolution without upscaling
  • Large images (≥1280x640): Behavior unchanged

Benefits:

  • ~10% faster processing for small images
  • Eliminates upscaling artifacts
  • Better feature quality on native resolution images

Usage Notes

Unlike OpenCV's ORB which works directly on input images, SPHORB:

  • Uses pre-computed lookup tables for specific resolutions (64-256 cell geodesic grids)
  • Maximum effective resolution: 1280x640 (larger images are downsampled)
  • Designed for spherical/panoramic images with 2:1 aspect ratio

For best results, use panoramic images around 1280x640 to 2560x1280 resolution.

Original Paper

This implementation is based on the following paper:

SPHORB: A Fast and Robust Binary Feature on the Sphere Qiang Zhao, Wei Feng, Liang Wan, Jiawan Zhang International Journal of Computer Vision, Volume 113, Number 2, Pages 143-159, June 2015

Links:

Citation

If you use this code in your research, please cite:

@article{zhao2015sphorb,
  title={SPHORB: A Fast and Robust Binary Feature on the Sphere},
  author={Zhao, Qiang and Feng, Wei and Wan, Liang and Zhang, Jiawan},
  journal={International Journal of Computer Vision},
  volume={113},
  number={2},
  pages={143--159},
  year={2015},
  publisher={Springer}
}

License

This project inherits the GNU General Public License from the original SPHORB implementation. For commercial licensing inquiries, please contact the original authors.

Credits

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pysphorb-0.1.5.tar.gz (23.0 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

pysphorb-0.1.5-cp314-cp314-manylinux_2_35_x86_64.whl (88.4 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.35+ x86-64

pysphorb-0.1.5-cp313-cp313-manylinux_2_35_x86_64.whl (88.4 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.35+ x86-64

pysphorb-0.1.5-cp312-cp312-manylinux_2_35_x86_64.whl (88.4 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.35+ x86-64

pysphorb-0.1.5-cp311-cp311-manylinux_2_35_x86_64.whl (88.4 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.35+ x86-64

File details

Details for the file pysphorb-0.1.5.tar.gz.

File metadata

  • Download URL: pysphorb-0.1.5.tar.gz
  • Upload date:
  • Size: 23.0 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for pysphorb-0.1.5.tar.gz
Algorithm Hash digest
SHA256 9a108382dc34f511d7a38f2d3de83034f99c9cd39b492a4d61e2f2d4173f7202
MD5 30debcfac7171f6d3f5fa3e25fdcb6c0
BLAKE2b-256 bdb45142e75a8e8dd8474812dbbfd9f82e2d093639667cb15fc362c33eb00e47

See more details on using hashes here.

File details

Details for the file pysphorb-0.1.5-cp314-cp314-manylinux_2_35_x86_64.whl.

File metadata

File hashes

Hashes for pysphorb-0.1.5-cp314-cp314-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 f0db455c8487a01f5b99a09fcc232d717d22d3ee270177737a776a7c50d19084
MD5 410b471798ed8f20258081f120af67b5
BLAKE2b-256 e8e221c570e5e88d060310afb6e28a52857241f3b791c6a372d7b9bb246504f6

See more details on using hashes here.

File details

Details for the file pysphorb-0.1.5-cp313-cp313-manylinux_2_35_x86_64.whl.

File metadata

File hashes

Hashes for pysphorb-0.1.5-cp313-cp313-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 2e9b5f96fa4ca2ee6ca58de3e79934018b306251f0fc48aae900f4356326f46c
MD5 7da09eeb3592c2f7835298d3735ea911
BLAKE2b-256 4af277c872a5d617c6558d2b5e7b0879fb1b9ed0b6223d5adb6f0de30ee3cd78

See more details on using hashes here.

File details

Details for the file pysphorb-0.1.5-cp312-cp312-manylinux_2_35_x86_64.whl.

File metadata

File hashes

Hashes for pysphorb-0.1.5-cp312-cp312-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 c0a6ef674f4f97340a0533a50b980fe80057411fa57403e90e6dd18b4b1f3ed7
MD5 c35850349261304b3f0e89160918e60f
BLAKE2b-256 f287fb3d0aee3f696f803e2a10e379ade40f2b6eb00154e2c179f70ffa9b98b7

See more details on using hashes here.

File details

Details for the file pysphorb-0.1.5-cp311-cp311-manylinux_2_35_x86_64.whl.

File metadata

File hashes

Hashes for pysphorb-0.1.5-cp311-cp311-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 417d62841c7057d9ed66fd880cb3b8e3819a3394ec5f0530719504fab77215be
MD5 eafb6625ebc00db98782670b2dc6323a
BLAKE2b-256 58efe407542aabfd284ee952c89e5a005f770dd0771e48f7d3ccc1c237847538

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page