sowilo ᛋ
OpenCV's algorithms. torchvision's autodiff. OCaml's reliability.
why sowilo?
differentiable vision
Every operation supports automatic differentiation. Train neural networks with classical CV in the loop.
pure functional
No global state, no side effects. Image processing operations that compose like functions should.
type-safe images
Images are just tensors with known shapes. The compiler catches dimension mismatches.
jit ready
Built on Rune's tensor operations. When JIT lands, your filters compile to GPU kernels automatically.
show me the code
OpenCV
import cv2 import numpy as np # Load and process img = cv2.imread('photo.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) blurred = cv2.GaussianBlur(gray, (5, 5), 1.0) edges = cv2.Canny(blurred, 100, 200) # Not differentiable!
SOWILO
open Sowilo (* Load and process *) let img = Nx_io.load_image "photo.jpg" |> Rune.of_bigarray let processed = img |> to_grayscale |> gaussian_blur ~ksize:5 ~sigma:1.0 |> canny ~low:100. ~high:200. (* Fully differentiable! *)
image processing operations
(* Filters *) gaussian_blur img ~ksize:5 ~sigma:1.0 median_blur img ~ksize:3 box_filter img ~ksize:3 (* Edge detection *) let grad_x, grad_y = sobel img ~dx:1 ~dy:0 ~ksize:3 let edges = canny img ~low:50. ~high:150. (* Morphology *) let kernel = get_structuring_element Rect ~ksize:3 let eroded = erode img kernel let dilated = dilate img kernel (* Thresholding *) threshold img ~thresh:128. ~maxval:255. ~typ:Binary
differentiable augmentations
Train neural networks with classical CV operations in the forward pass:
(* Augmentation pipeline *) let augment img = img |> random_crop ~size:(224, 224) |> random_flip ~p:0.5 |> adjust_brightness ~factor:(random 0.8 1.2) |> gaussian_blur ~ksize:3 ~sigma:(random 0. 1.) (* Use in training - gradients flow through! *) let loss model img label = let augmented = augment img in let features = extract_features augmented in let pred = Model.forward model features in cross_entropy pred label
what's implemented
core operations
- ✓ Color space conversions
- ✓ Gaussian, median, box filters
- ✓ Sobel gradients, Canny edges
- ✓ Morphological operations
- ✓ Thresholding functions
- ✓ Image resizing (nearest, bilinear)
coming soon
- ⏳ Feature detection (SIFT, ORB)
- ⏳ Optical flow
- ⏳ Semantic segmentation ops
- ⏳ Video processing
- ⏳ 3D vision primitives
design philosophy
Images are tensors. No special image type - just 3D arrays with shape [H; W; C]. This means any tensor operation works on images.
Everything differentiates. Unlike traditional CV libraries, every operation in sowilo can be differentiated. This enables new techniques like learnable image processing.
Functional composition. Operations are pure functions that compose naturally. No global state, no side effects.
get started
Sowilo isn't released yet. For now, check out the documentation to learn more.
When it's ready:
# Install opam install sowilo # Try it open Sowilo (* Edge detection example *) let () = let img = Nx_io.load_image "input.jpg" in let edges = Rune.of_bigarray (Nx.to_bigarray img) |> to_grayscale |> canny ~low:50. ~high:150. |> Rune.to_bigarray |> Nx.of_bigarray in Nx_io.save_image edges "edges.png"