Skip to main content

A pure-NumPy image-processing library — filtering, transforms, feature extraction, drawing, and canvas operations — built from scratch without OpenCV.

Project description

RoboVision

Python Versions Version License Dependencies Platform

A pure-NumPy image-processing library — built from scratch without OpenCV.
Filtering · Transformations · Feature Extraction · Drawing · Canvas Operations


Overview

RoboVision is a lightweight, dependency-free computer vision library implemented entirely in Python and NumPy.
It covers the core image-processing pipeline from raw pixel manipulation all the way to feature extraction and drawing — without relying on OpenCV, PIL, or any compiled binary.

Built as part of CSE480: Machine Vision at Ain Shams University, Faculty of Engineering, Mechatronics Engineering Department — and structured to be a real, importable, maintainable Python package.


Why RoboVision?

Feature RoboVision OpenCV
Dependencies NumPy + Matplotlib only Large compiled C++ binary
Channel order RGB (natural) BGR (legacy)
Output dtype Always float32 [0,1] uint8 [0,255] by default
Error messages Specific, typed exceptions Silent None returns
Pure Python
Teachable internals ✅ Full math in docstrings ❌ Black box
Platform Any Python 3.9+ Platform-specific build

Installation

pip install robovision

Or install from source:

git clone https://github.com/omarmustafa/robovision.git
cd robovision
pip install -e .

Install with optional extras:

pip install robovision[notebook]   # Jupyter support
pip install robovision[dev]        # Testing + linting tools
pip install robovision[all]        # Everything

Quick Start

import numpy as np
from robovision.io.image_io import read_image, save_image, to_grayscale
from robovision.filters.filters import gaussian_filter, mean_filter
from robovision.filters.edge_detection import canny, sobel_gradients
from robovision.transforms.resize import resize
from robovision.features.hog import extract_hog
from robovision.utils.drawing_primitives import draw_rectangle, draw_text

# Load image
img = read_image("photo.jpg")           # → float32 [0,1], RGB
gray = to_grayscale(img)                # → (H, W) float32

# Filtering
blurred = gaussian_filter(img, size=5, sigma=1.0)
edges   = canny(gray, low_thresh=0.05, high_thresh=0.15)

# Feature extraction
hog_feat = extract_hog(gray, cell_size=8, n_bins=9)
print(f"HOG descriptor length: {hog_feat.shape[0]}")

# Drawing
canvas = img.copy()
draw_rectangle(canvas, 50, 50, 200, 150, color=(0, 1, 0), thickness=2)

# Save
save_image(canvas, "output.png")

Package Structure

robovision/
│
├── io/
│   └── image_io.py          ← read_image, save_image, to_grayscale, to_rgb
│
├── transforms/
│   ├── resize.py            ← nearest-neighbour & bilinear resize
│   ├── rotate.py            ← rotation with inverse mapping
│   ├── translate.py         ← pixel translation
│   ├── flip.py              ← horizontal / vertical / both
│   └── pyramid.py           ← Gaussian & Laplacian pyramids
│
├── filters/
│   ├── filters.py           ← pad_image, convolve2d, mean, gaussian, median
│   ├── thresholding.py      ← global, Otsu, adaptive thresholding
│   ├── edge_detection.py    ← Sobel, bit-plane slicing, Canny
│   └── histogram_ops.py     ← histogram, equalization, matching, gamma
│
├── features/
│   ├── hog.py               ← Histogram of Oriented Gradients
│   ├── sift.py              ← SIFT keypoints + 128-D descriptors
│   ├── color_histogram.py   ← per-channel & 2D joint histograms
│   ├── color_moments.py     ← mean, std, skewness (RGB + HSV)
│   └── spatial_pyramid.py   ← Spatial Pyramid Matching (SPM)
│
└── utils/
    ├── normalization.py     ← min-max, z-score, scale [0-1]/[0-255]
    ├── pixel_clipping.py    ← clip, percentile clip, sigma clip
    ├── padding.py           ← zero, reflect, replicate, constant, circular
    ├── convolution.py       ← convolve2d, filter2d, spatial_filter (3.5)
    ├── drawing_primitives.py← point, line (AA), rectangle, polygon, ellipse
    └── text_placement.py    ← bitmap font text rendering on NumPy arrays

API Reference

Image I/O

from robovision.io.image_io import read_image, save_image, to_grayscale, to_rgb, drop_alpha

img  = read_image("photo.png")                    # (H,W,3) float32 [0,1]
gray = read_image("photo.png", as_gray=True)      # (H,W)   float32 [0,1]
gray = to_grayscale(img)                          # BT.601 luminance weights
rgb  = to_rgb(gray)                               # (H,W) → (H,W,3)
img3 = drop_alpha(img)                            # (H,W,4) → (H,W,3)
save_image(img, "out.png")
save_image(img, "out.jpg", quality=90)

Transforms

from robovision.transforms.resize    import resize
from robovision.transforms.rotate    import rotate
from robovision.transforms.translate import translate
from robovision.transforms.flip      import flip
from robovision.transforms.pyramid   import gaussian_pyramid, laplacian_pyramid

small  = resize(img, (128, 128), method='bilinear')
rotated = rotate(img, angle=45, method='bilinear', expand=True)
shifted = translate(img, tx=50, ty=30)
flipped = flip(img, mode='horizontal')
gauss   = gaussian_pyramid(img, levels=4)
lap     = laplacian_pyramid(img, levels=4)

Filters

from robovision.filters.filters import mean_filter, gaussian_filter, median_filter, gaussian_kernel

k       = gaussian_kernel(size=5, sigma=1.0)   # normalised 2-D kernel
blurred = gaussian_filter(img, size=7, sigma=1.5)
box     = mean_filter(img, kernel_size=5)
clean   = median_filter(img, kernel_size=3)    # excellent for salt & pepper

Thresholding

from robovision.filters.thresholding import threshold_global, threshold_otsu, threshold_adaptive

binary        = threshold_global(gray, thresh=0.5)
auto, t       = threshold_otsu(gray, return_thresh=True)
local_mean    = threshold_adaptive(gray, block_size=11, C=0.02, method='mean')
local_gauss   = threshold_adaptive(gray, block_size=11, C=0.02, method='gaussian')

Edge Detection

from robovision.filters.edge_detection import sobel_gradients, canny, bit_plane_slice

grads  = sobel_gradients(gray)       # {'Gx', 'Gy', 'magnitude', 'angle'}
edges  = canny(gray, 0.05, 0.15)
msb    = bit_plane_slice(gray, plane=7)   # most significant bit plane

Histogram Operations

from robovision.filters.histogram_ops import (
    compute_histogram, histogram_equalization,
    histogram_matching, gamma_correction
)

hist, bins = compute_histogram(gray, n_bins=256)
enhanced   = histogram_equalization(gray)
matched    = histogram_matching(source, reference)
bright     = gamma_correction(img, gamma=0.5)    # γ < 1 → brighten
dark       = gamma_correction(img, gamma=2.2)    # γ > 1 → darken

Feature Extraction

from robovision.features.hog             import extract_hog
from robovision.features.sift            import extract_sift, sift_feature_vector
from robovision.features.color_histogram import extract_color_histogram
from robovision.features.color_moments   import extract_color_moments
from robovision.features.spatial_pyramid import extract_spatial_pyramid

hog   = extract_hog(gray, cell_size=8, block_size=2, n_bins=9)
kps, descs = extract_sift(gray, max_keypoints=500)
chist = extract_color_histogram(img, n_bins=32)    # 96-D for RGB
cmom  = extract_color_moments(img)                 # 9-D (mean,std,skew × 3ch)
spm   = extract_spatial_pyramid(img, levels=3, n_bins=16)   # 1008-D

Core Utilities

from robovision.utils.normalization    import normalize
from robovision.utils.pixel_clipping   import clip, clip_percentile
from robovision.utils.padding          import pad_image
from robovision.utils.convolution      import convolve2d, spatial_filter

norm   = normalize(img, mode='minmax')          # also: zscore, scale_01, scale_255
safe   = clip(img, 0.0, 1.0)
padded = pad_image(img, pad_width=5, mode='reflect')   # also: zero, replicate, constant, circular
out    = spatial_filter(img, kernel, rgb_strategy='per_channel')

Drawing & Text

from robovision.utils.drawing_primitives import (
    draw_point, draw_line, draw_line_aa,
    draw_rectangle, draw_polygon, draw_ellipse
)
from robovision.utils.text_placement import draw_text, get_text_size

canvas = np.zeros((400, 600, 3), dtype=np.float32)
draw_point(canvas, x=100, y=100, color=(1,0,0), radius=5)
draw_line(canvas, 0, 0, 599, 399, color=(0,1,0), thickness=2)
draw_line_aa(canvas, 10.5, 10.0, 300.5, 200.0, color=(1,1,0))   # anti-aliased
draw_rectangle(canvas, 50, 50, 250, 200, color=(0,0,1), filled=True)
draw_polygon(canvas, [(100,50),(200,20),(280,80),(240,160),(80,160)], color=(1,0.5,0), filled=True)
draw_ellipse(canvas, cx=300, cy=200, rx=80, ry=50, color=(0.8,0,0.8))
draw_text(canvas, "RoboVision 1.0", x=10, y=10, color=(1,1,1), scale=2)

Math & Algorithms

Each module contains a full docstring with the mathematical derivation.
Key algorithms implemented:

Algorithm Module Notes
BT.601 Luminance io/image_io.py Y = 0.2989R + 0.5870G + 0.1140B
Bilinear interpolation transforms/resize.py 4-neighbour weighted average
Inverse mapping rotation transforms/rotate.py Avoids holes in output
Gaussian kernel filters/filters.py G(x,y) = exp(-(x²+y²)/2σ²) normalised
Otsu's method filters/thresholding.py Maximises between-class variance
Adaptive threshold filters/thresholding.py Local mean/Gaussian − C
Canny 5-stage filters/edge_detection.py Gaussian → Sobel → NMS → Hysteresis
Histogram equalisation filters/histogram_ops.py CDF mapping out = CDF(in)
Histogram matching filters/histogram_ops.py Inverse CDF lookup
HOG descriptor features/hog.py Dalal & Triggs CVPR 2005
SIFT descriptor features/sift.py DoG + 128-D descriptor, Lowe 2004
Spatial Pyramid features/spatial_pyramid.py Lazebnik et al. CVPR 2006
Bresenham line utils/drawing_primitives.py Integer-only rasterisation
Wu anti-aliased line utils/drawing_primitives.py Sub-pixel alpha blending
Bresenham ellipse utils/drawing_primitives.py Midpoint algorithm, 4-fold symmetry
Scanline polygon fill utils/drawing_primitives.py Even-odd rule

Requirements

Package Minimum Version
Python 3.9
NumPy 1.24.0
Matplotlib 3.7.0

Development

# Clone and install in editable mode
git clone https://github.com/omarmustafa/robovision.git
cd robovision
pip install -e ".[dev]"

# Run tests
pytest

# Format code
black robovision/

# Lint
ruff check robovision/

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/new-filter)
  3. Commit your changes (git commit -m 'Add new filter')
  4. Push to the branch (git push origin feature/new-filter)
  5. Open a Pull Request

License

This project is licensed under the MIT License — see the LICENSE file for details.


Author

Omar Mustafa Mohammed
Mechatronics Engineering — Ain Shams University
CSE480: Machine Vision, Spring 2026


Acknowledgements

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

robovision_dr_gear-1.0.0.tar.gz (70.1 kB view details)

Uploaded Source

Built Distribution

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

robovision_dr_gear-1.0.0-py3-none-any.whl (79.1 kB view details)

Uploaded Python 3

File details

Details for the file robovision_dr_gear-1.0.0.tar.gz.

File metadata

  • Download URL: robovision_dr_gear-1.0.0.tar.gz
  • Upload date:
  • Size: 70.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.8

File hashes

Hashes for robovision_dr_gear-1.0.0.tar.gz
Algorithm Hash digest
SHA256 994e751c3b4ab57eabc6b6aef50fe83ee9d06856c8492ac1d9d6e4e55fbc23f5
MD5 04243a85eebcffa1b28240e3640a64e3
BLAKE2b-256 a39980c981b2f965f1ed4626511f74a8bf9f5846e3e6a31d03e2dd5c3d57e17e

See more details on using hashes here.

File details

Details for the file robovision_dr_gear-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for robovision_dr_gear-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4daaa4fee185993d8767925721b6e4605ee130e8ebe68f31e80b0ef86d358fdf
MD5 a74b50cb04ce4408c881017d9ad98e21
BLAKE2b-256 ee01cc5b563e68e59f7c2b162c9e21ab293fa041c406dcaecadf767b038688c2

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