Zamin Docs

OpenCV Guide

Image processing and computer vision powered by OpenCV 4/5.

Overview

The opencv module wraps OpenCV 4/5 to give Zamin programs access to image I/O, color conversion, filtering, transforms, object detection, drawing, and more. It is available behind a feature flag and requires system-level OpenCV development libraries.

Build with the opencv feature enabled:

cargo build --release --features opencv

Install OpenCV development libraries on your system:

# Debian / Ubuntu
sudo apt install libopencv-dev

# Fedora
sudo dnf install opencv-devel

# macOS (Homebrew)
brew install opencv

Quick Start

Read an image, convert it to grayscale, apply edge detection, and save the result:

let img = opencv.imread("photo.jpg")
let gray = opencv.grayscale(img)
let edges = opencv.canny(gray, 50.0, 150.0)
opencv.imwrite("edges.png", edges)

Run it:

$ zamin run detect.zamin

Image I/O

FunctionDescription
imread(path) Read an image from disk. Returns a BGR image matrix.
imwrite(path, image) Write an image to disk. Format inferred from extension.
imread_gray(path) Read an image directly as grayscale.
shape(image) Returns [rows, cols, channels] for the image.
copy(image) Return a deep copy of the image matrix.
let img = opencv.imread("photo.jpg")
print(opencv.shape(img))  // [480, 640, 3]

let clone = opencv.copy(img)
opencv.imwrite("copy.jpg", clone)

Color Conversion

FunctionDescription
cvt_color(image, code) Convert color space using a code constant (e.g. opencv.BGR2GRAY).
grayscale(image) Auto-detect channel count and convert to single-channel grayscale.
let img = opencv.imread("photo.jpg")
let gray = opencv.grayscale(img)
let rgb = opencv.cvt_color(img, opencv.COLOR_BGR2RGB)

Resize and Transform

FunctionDescription
resize(image, width, height) Resize using linear interpolation.
resize_fast(image, width, height) Resize using nearest-neighbor interpolation (faster, lower quality).
thumbnail(image, max_size) Resize preserving aspect ratio so the longest side equals max_size.
flip(image, code) Flip the image. Use FLIP_HORIZONTAL, FLIP_VERTICAL, or FLIP_BOTH.
rotate(image, code) Rotate 90° increments. Use ROTATE_90_CLOCKWISE, ROTATE_180, or ROTATE_90_COUNTERCLOCKWISE.
crop(image, x, y, w, h) Crop a rectangular region starting at pixel (x, y).
letterbox(image, target_w, target_h, bg_r?, bg_g?, bg_b?) Resize and pad to fill the target dimensions, adding a background color (default black).
let img = opencv.imread("photo.jpg")
let small = opencv.resize(img, 320, 240)
let thumb = opencv.thumbnail(img, 128)
let flipped = opencv.flip(img, opencv.FLIP_HORIZONTAL)
let rotated = opencv.rotate(img, opencv.ROTATE_90_CLOCKWISE)
let cropped = opencv.crop(img, 100, 50, 200, 200)
let padded = opencv.letterbox(img, 640, 640, 114, 114, 114)

Filters and Effects

FunctionDescription
gaussian_blur(image, kx, ky, sigma) Apply Gaussian blur with kernel size (kx, ky) and sigma.
blur(image, ksize) Apply a simple box blur with the given kernel size.
canny(image, low, high) Canny edge detection with low and high thresholds.
edges(image) Canny edge detection with automatically computed thresholds.
threshold(image, thresh, maxval, type) Apply binary thresholding. Use constants like THRESH_BINARY.
brightness(image, delta) Adjust brightness by adding delta to every pixel.
contrast(image, alpha) Adjust contrast. alpha > 1.0 increases, alpha < 1.0 decreases.
invert(image) Invert all pixel values (negative image).
sepia(image) Apply a sepia tone effect.
pixelate(image, block) Pixelate the image using blocks of the given size.
equalize_hist(image) Equalize the histogram to improve contrast on grayscale images.
normalize(image, alpha?, beta?, norm_type?) Normalize pixel values. Defaults to 0-1 range with L2 norm.
let img = opencv.imread("photo.jpg")
let blurred = opencv.gaussian_blur(img, 15, 15, 0)
let edges = opencv.edges(img)
let bright = opencv.brightness(img, 30)
let dark = opencv.contrast(img, 0.5)
let inv = opencv.invert(img)
let sep = opencv.sepia(img)
let pix = opencv.pixelate(img, 8)

Object Detection

FunctionDescription
detect_cascade(image, cascade_path, ...) Detect objects using a Haar cascade classifier XML file. Returns a list of bounding rectangles [x, y, w, h].
detect_people(image, ...) Detect people using the HOG pedestrian detector. Returns bounding rectangles.
detect_dnn(image, model_path, ...) Detect objects using a DNN model (e.g. YOLO, MobileNet). Returns bounding rectangles with confidence scores.
let img = opencv.imread("street.jpg")

// Haar cascade face detection
let faces = opencv.detect_cascade(img, "haarcascade_frontalface.xml")
for face in faces {
    opencv.draw_rect(img, face[0], face[1], face[2], face[3], 0, 255, 0, 2);
    print("Face at: {face}");
}

// HOG people detection
let people = opencv.detect_people(img)
for p in people {
    opencv.draw_rect(img, p[0], p[1], p[2], p[3], 255, 0, 0, 2);
}

opencv.imwrite("detected.jpg", img)

Drawing and Annotation

FunctionDescription
draw_rect(image, x, y, w, h, r?, g?, b?, thickness?) Draw a rectangle. Defaults: color green, thickness 1.
draw_text(image, text, x, y, scale?, r?, g?, b?, thickness?) Draw text at position (x, y). Defaults: scale 1.0, color white, thickness 1.
let img = opencv.imread("photo.jpg")
opencv.draw_rect(img, 50, 50, 200, 150, 0, 255, 0, 3)
opencv.draw_text(img, "Detected!", 60, 45, 1.2, 0, 255, 0, 2)
opencv.imwrite("annotated.jpg", img)

Template Matching

FunctionDescription
match_template(image, template, method?) Search for a template within an image. Returns the best match location and confidence. Method defaults to TM_CCOEFF_NORMED.
let img = opencv.imread("screenshot.png")
let icon = opencv.imread("icon.png")
let result = opencv.match_template(img, icon)
print("Best match at: {result.location}, score: {result.score}")

Display (GUI)

For quick visualization, the opencv module provides display functions that use OpenCV's highgui module.

FunctionDescription
imshow(name, image) Display an image in a named window.
wait_key(delay) Wait for a key press for delay milliseconds. Pass 0 to wait indefinitely.
destroy_all_windows() Close all open display windows.
let img = opencv.imread("photo.jpg")
opencv.imshow("Preview", img)
opencv.wait_key(0)
opencv.destroy_all_windows()

ASCII Art

Convert images to ASCII art for terminal output or creative effects.

FunctionDescription
to_ascii(image, width?) Convert an image to ASCII art. Optional width controls output width (default 80).
read_ascii(path, width?) Read an image from disk and convert to ASCII in one step.
let img = opencv.imread("photo.jpg")
let art = opencv.to_ascii(img, 100)
print(art)

// Or in one step:
let art2 = opencv.read_ascii("photo.jpg", 80)
print(art2)

Complete Example

A full working example that creates a synthetic image, applies multiple operations, saves results, and prints ASCII art:

let opencv = require("opencv")

// Create a synthetic 400x300 image with color gradient
print("Creating synthetic image...")
let img = opencv.zeros(300, 400, 3)
for y in 0..300 {
    for x in 0..400 {
        let r = (float(x) / 400.0 * 255.0).int();
        let g = (float(y) / 300.0 * 255.0).int();
        img.set(y, x, [r, g, 128]);
    }
}

opencv.imwrite("gradient.png", img)
print("Saved gradient.png")

// Grayscale conversion
let gray = opencv.grayscale(img)
opencv.imwrite("gradient_gray.png", gray)
print("Saved gradient_gray.png")

// Gaussian blur
let blurred = opencv.gaussian_blur(img, 21, 21, 0)
opencv.imwrite("gradient_blur.png", blurred)
print("Saved gradient_blur.png")

// Edge detection
let edges = opencv.canny(gray, 50.0, 150.0)
opencv.imwrite("gradient_edges.png", edges)
print("Saved gradient_edges.png")

// Threshold
let thresh = opencv.threshold(gray, 128.0, 255.0, opencv.THRESH_BINARY)
opencv.imwrite("gradient_thresh.png", thresh)
print("Saved gradient_thresh.png")

// Sepia effect
let sep = opencv.sepia(img)
opencv.imwrite("gradient_sepia.png", sep)
print("Saved gradient_sepia.png")

// Pixelate
let pix = opencv.pixelate(img, 16)
opencv.imwrite("gradient_pixel.png", pix)
print("Saved gradient_pixel.png")

// Flip and rotate
let flipped = opencv.flip(img, opencv.FLIP_BOTH)
opencv.imwrite("gradient_flipped.png", flipped)
print("Saved gradient_flipped.png")

// Draw annotations
let annotated = opencv.copy(img)
opencv.draw_rect(annotated, 50, 50, 300, 200, 0, 255, 0, 3)
opencv.draw_text(annotated, "Zamin OpenCV", 80, 140, 2.0, 255, 255, 255, 3)
opencv.imwrite("gradient_annotated.png", annotated)
print("Saved gradient_annotated.png")

// Print ASCII art
print("\nASCII art preview:")
let art = opencv.to_ascii(gray, 60)
print(art)

// Print image info
print("\nImage shape: {opencv.shape(img)}")
print("Done!")

Constants Reference

Color Conversion Codes

ConstantDescription
opencv.BGR2GRAYConvert BGR to grayscale
opencv.COLOR_BGR2RGBConvert BGR to RGB
opencv.COLOR_RGB2BGRConvert RGB to BGR
opencv.COLOR_BGR2HSVConvert BGR to HSV
opencv.COLOR_BGR2LABConvert BGR to CIE Lab
opencv.COLOR_GRAY2BGRConvert grayscale to 3-channel BGR

Threshold Types

ConstantDescription
opencv.THRESH_BINARYPixels > threshold set to maxval, else 0
opencv.THRESH_BINARY_INVInverse of THRESH_BINARY
opencv.THRESH_TRUNCPixels > threshold set to threshold, else unchanged
opencv.THRESH_TOZEROPixels > threshold unchanged, else set to 0
opencv.THRESH_TOZERO_INVPixels > threshold set to 0, else unchanged

Flip Codes

ConstantDescription
opencv.FLIP_HORIZONTALFlip left-to-right (code 1)
opencv.FLIP_VERTICALFlip top-to-bottom (code 0)
opencv.FLIP_BOTHFlip both axes (code -1)

Rotation Codes

ConstantDescription
opencv.ROTATE_90_CLOCKWISERotate 90° clockwise
opencv.ROTATE_180Rotate 180°
opencv.ROTATE_90_COUNTERCLOCKWISERotate 90° counter-clockwise

Template Matching Methods

ConstantDescription
opencv.TM_SQDIFFSquared difference
opencv.TM_SQDIFF_NORMEDNormalized squared difference
opencv.TM_CCORRCross-correlation
opencv.TM_CCORR_NORMEDNormalized cross-correlation
opencv.TM_CCOEFFCross-correlation coefficient
opencv.TM_CCOEFF_NORMEDNormalized cross-correlation coefficient (default)
Edit this page on GitHub Last updated: July 2026