Documentation
¶
Overview ¶
Package images is a pure-Go (cgo-free) image-processing library in the style of scikit-image, built on the Go standard library's image, image/color, image/png and image/jpeg packages.
Unlike the established options in the Ruby world — ruby-vips (libvips) and RMagick (ImageMagick) — and unlike cgo-backed Go wrappers, this library has no native C dependency: it is CGO=0 and builds and runs identically on every Go target. That makes it trivially cross-compilable and embeddable (for example inside go-embedded-ruby), at the cost — for now — of the hand-tuned SIMD that libvips/ImageMagick rely on. A later phase will close that gap with SIMD kernels generated by go-asmgen across the six supported 64-bit targets. See docs/plan-images.md for the roadmap and an honest comparison with the existing pure-Go libraries (bild, disintegration/imaging).
Operations are pure functions: each takes an image and returns a freshly allocated *image.RGBA, never mutating its input. Use ToRGBA to convert an arbitrary image.Image to the *image.RGBA the operations consume, and the I/O helpers (Load, Save, Decode, Encode) for PNG and JPEG.
Phase 0 implements Grayscale, Invert, Resize (nearest-neighbour and bilinear), Convolve (arbitrary odd-sized kernels with edge clamping), GaussianBlur (separable), AdjustBrightness and AdjustContrast.
Phase 1 adds edge detection — Sobel (gradient magnitude) with SobelX/SobelY directional responses, the normalised Prewitt, Scharr and SobelMag operators and the Laplacian (matching skimage.filters.{prewitt,scharr,sobel,laplace}), and the full Canny detector (Gaussian, Sobel, bilinear non-maximum suppression, hysteresis); the filters BoxBlur (separable running-sum mean, matching scipy.ndimage.uniform_filter), Median (square median, matching scipy.ndimage.median_filter), and UnsharpMask/Sharpen (matching skimage.filters.unsharp_mask); the geometric transforms FlipHorizontal, FlipVertical, Rotate90/Rotate180/Rotate270 (numpy.fliplr/flipud/rot90) and Crop; the colour conversions RGBToHSV/HSVToRGB; and thresholding via OtsuThreshold/Threshold/Otsu (matching skimage.filters.threshold_otsu).
Phase 2 adds grayscale morphology over a square structuring element: Erode and Dilate (per-channel local min/max, matching scipy.ndimage.grey_erosion and grey_dilation) and the derived Open and Close. On binary 0/255 images these reduce to ordinary binary morphology.
docs/perf.md reports honest go-images-vs-scikit-image/SciPy benchmarks and correctness checks for the hot operations.
Index ¶
- func AdjustBrightness(img image.Image, delta float64) *image.RGBA
- func AdjustContrast(img image.Image, factor float64) *image.RGBA
- func BoxBlur(img image.Image, radius int) (*image.RGBA, error)
- func Canny(img image.Image, sigma, low, high float64) (*image.RGBA, error)
- func Close(img image.Image, radius int) (*image.RGBA, error)
- func Convolve(img image.Image, k Kernel) (*image.RGBA, error)
- func Crop(img image.Image, r image.Rectangle) (*image.RGBA, error)
- func Decode(r io.Reader) (*image.RGBA, error)
- func Dilate(img image.Image, radius int) (*image.RGBA, error)
- func Encode(w io.Writer, img image.Image, format Format) error
- func Erode(img image.Image, radius int) (*image.RGBA, error)
- func FlipHorizontal(img image.Image) *image.RGBA
- func FlipVertical(img image.Image) *image.RGBA
- func GaussianBlur(img image.Image, sigma float64) (*image.RGBA, error)
- func Grayscale(img image.Image) *image.RGBA
- func HSVToRGB(img image.Image) *image.RGBA
- func Invert(img image.Image) *image.RGBA
- func Laplacian(img image.Image) *image.RGBA
- func Load(path string) (*image.RGBA, error)
- func Median(img image.Image, radius int) (*image.RGBA, error)
- func Open(img image.Image, radius int) (*image.RGBA, error)
- func Otsu(img image.Image) *image.RGBA
- func OtsuThreshold(img image.Image) uint8
- func Prewitt(img image.Image) *image.RGBA
- func RGBToHSV(img image.Image) *image.RGBA
- func Resize(img image.Image, w, h int, mode ResizeMode) (*image.RGBA, error)
- func Rotate90(img image.Image) *image.RGBA
- func Rotate180(img image.Image) *image.RGBA
- func Rotate270(img image.Image) *image.RGBA
- func Save(path string, img image.Image) error
- func Scharr(img image.Image) *image.RGBA
- func Sharpen(img image.Image) *image.RGBA
- func Sobel(img image.Image) *image.RGBA
- func SobelMag(img image.Image) *image.RGBA
- func SobelX(img image.Image) *image.RGBA
- func SobelY(img image.Image) *image.RGBA
- func Threshold(img image.Image, t uint8) *image.RGBA
- func ToRGBA(img image.Image) *image.RGBA
- func UnsharpMask(img image.Image, radius, amount float64) (*image.RGBA, error)
- type Format
- type Kernel
- type ResizeMode
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AdjustBrightness ¶
AdjustBrightness returns a copy of img with delta added to the R, G and B channels, clamped to [0, 255]. Alpha is preserved.
func AdjustContrast ¶
AdjustContrast returns a copy of img with the R, G and B channels scaled about the mid-point (128) by factor, clamped to [0, 255]. A factor of 1 leaves the image unchanged; values above 1 increase contrast, values in [0, 1) reduce it. Alpha is preserved.
func BoxBlur ¶
BoxBlur returns img blurred by a square averaging filter of the given radius: every output pixel is the mean of the (2*radius+1) by (2*radius+1) source neighbourhood centred on it, computed independently per R, G and B channel (alpha preserved). Borders use clamp-to-edge addressing, matching scipy.ndimage.uniform_filter with mode="nearest" and size 2*radius+1. The filter is separable and evaluated with a running window sum, so its cost is independent of the radius. It returns an error if radius is not positive.
func Canny ¶
Canny returns the binary Canny edge map of img: white (255,255,255) edges on an opaque black background. It implements the classic Canny pipeline, matching the algorithm of skimage.feature.canny:
- smooth the Rec. 601 luminance with a Gaussian of standard deviation sigma (clamp-to-edge borders);
- estimate gradients with the Sobel operator; the edge strength is the gradient norm;
- thin to 1-pixel ridges by non-maximum suppression with bilinear interpolation along the gradient direction;
- link edges by hysteresis: keep every ridge pixel with magnitude >= high, plus every ridge pixel with magnitude >= low that is 8-connected to a kept one.
low and high are absolute thresholds on the Sobel gradient magnitude (the smoothed luminance is in [0,255], so the magnitudes are on that scale). It returns an error if sigma is not positive, if either threshold is negative, or if high < low.
func Close ¶
Close returns the morphological closing of img (dilation followed by erosion). Closing fills small dark features smaller than the structuring element. It returns an error if radius is not positive.
func Convolve ¶
Convolve returns img convolved with k, using clamp-to-edge addressing at the borders. The R, G and B channels are convolved and clamped to [0, 255]; alpha is preserved. It returns an error if k has non-positive or even dimensions, or if the length of k.Weights does not match Width*Height.
func Crop ¶
Crop returns the rectangular region r of img as a new image anchored at the origin. r is interpreted in the coordinate system of img converted to RGBA (origin at the top-left). It returns an error if r is empty or extends outside the image bounds.
func Decode ¶
Decode reads an image from r, auto-detecting the format among the registered decoders (PNG and JPEG). It returns the decoded image converted to *image.RGBA.
func Dilate ¶
Dilate returns the grayscale morphological dilation of img: the per-channel local maximum over a square structuring element. See Erode for borders, alpha and the radius rule.
func Erode ¶
Erode returns the grayscale morphological erosion of img with a square structuring element of the given radius: every output channel is the minimum of the (2*radius+1) by (2*radius+1) source neighbourhood. Borders use clamp-to-edge addressing; alpha is preserved. The operation is separable (matching a square footprint in scipy.ndimage.grey_erosion). On a binary image (0/255) this is ordinary binary erosion. It returns an error if radius is not positive.
func FlipHorizontal ¶
FlipHorizontal returns a copy of img mirrored left-to-right (column x of the width-w source becomes column w-1-x). It matches numpy.fliplr.
func FlipVertical ¶
FlipVertical returns a copy of img mirrored top-to-bottom (row y of the height-h source becomes row h-1-y). It matches numpy.flipud.
func GaussianBlur ¶
GaussianBlur returns img blurred by a Gaussian of standard deviation sigma, implemented as a separable convolution with clamp-to-edge borders. It returns an error if sigma is not positive.
func Grayscale ¶
Grayscale returns a copy of img with every pixel replaced by its luminance-weighted gray value (Rec. 601 coefficients). Alpha is preserved.
func HSVToRGB ¶
HSVToRGB inverts RGBToHSV: it interprets each pixel's first three channels as byte-encoded H, S, V and returns the corresponding R, G, B. Alpha is preserved.
func Invert ¶
Invert returns a copy of img with the R, G and B channels negated. Alpha is preserved.
func Laplacian ¶
Laplacian returns the discrete Laplacian edge map of img, matching skimage.filters.laplace with ksize=3 (the kernel [0,-1,0; -1,4,-1; 0,-1,0] applied to the luminance plane). The signed second-derivative response is offset by 128 so a flat region is mid-grey, written to R, G and B and clamped to [0,255]; alpha is preserved and borders use clamp-to-edge addressing. Being a second-derivative operator it highlights intensity curvature (lines, spots, zero-crossings) rather than step edges.
func Load ¶
Load reads and decodes the image at path, returning it as *image.RGBA. The format is auto-detected from the file contents.
func Median ¶
Median returns img filtered by a square median of the given radius: every output channel is the median of the (2*radius+1) by (2*radius+1) source neighbourhood, computed independently per R, G and B (alpha preserved), with clamp-to-edge addressing. It matches scipy.ndimage.median_filter with a (2*radius+1)-square footprint and mode="nearest". The median is robust to outliers, so it removes salt-and-pepper noise while preserving edges far better than a linear blur. It returns an error if radius is not positive.
func Open ¶
Open returns the morphological opening of img (erosion followed by dilation with the same square structuring element). Opening removes small bright features smaller than the element while preserving overall shape. It returns an error if radius is not positive.
func Otsu ¶
Otsu is a convenience wrapper that thresholds img at the level chosen by Otsu's method (equivalent to Threshold(img, OtsuThreshold(img))).
func OtsuThreshold ¶
OtsuThreshold returns the gray level in [0, 255] computed by Otsu's method on img's Rec. 601 luminance histogram: the level that maximises the between-class variance of the two pixel populations split at it. It matches the value returned by skimage.filters.threshold_otsu on a 256-bin histogram. Pass the result to Threshold (foreground = luminance strictly greater than it).
func Prewitt ¶
Prewitt returns the Prewitt gradient-magnitude edge map of img. The operator is the separable 3x3 Prewitt kernel applied to each pixel's Rec. 601 luminance; the magnitude sqrt((gx^2+gy^2)/2) is written to the R, G and B channels as a grayscale edge image (alpha preserved). It mirrors skimage.filters.prewitt: the directional kernels are normalised so each axis kernel's absolute weights sum to one, and clamp-to-edge addressing reproduces skimage's default reflect border for a 3-tap kernel.
func RGBToHSV ¶
RGBToHSV returns a copy of img with each pixel's R, G, B replaced by a byte-encoded H, S, V triple: H is the hue mapped from [0,360) to [0,255], S and V are mapped from [0,1] to [0,255]. Alpha is preserved. HSVToRGB inverts the mapping (within rounding). The encoding keeps the result inside the same RGBA-backed representation the rest of the pipeline uses.
func Resize ¶
Resize returns img scaled to w by h pixels using the given mode. It returns an error if w or h is not positive.
func Rotate90 ¶
Rotate90 returns img rotated 90 degrees counter-clockwise (matching numpy.rot90 with k=1). A w-by-h image becomes h-by-w.
func Rotate180 ¶
Rotate180 returns img rotated 180 degrees (numpy.rot90 with k=2). The dimensions are unchanged.
func Rotate270 ¶
Rotate270 returns img rotated 90 degrees clockwise, i.e. 270 degrees counter-clockwise (numpy.rot90 with k=3). A w-by-h image becomes h-by-w.
func Save ¶
Save encodes img and writes it to path, choosing the format from the file extension: ".png" for PNG and ".jpg" or ".jpeg" for JPEG (case-insensitive). It returns an error for any other extension.
func Scharr ¶
Scharr returns the Scharr gradient-magnitude edge map of img, matching skimage.filters.scharr. The Scharr smoothing triple (0.1875, 0.625, 0.1875) gives the best rotational symmetry of the Sobel/Prewitt/Scharr family. See Prewitt for the luminance, magnitude and border conventions.
func Sharpen ¶
Sharpen returns a sharpened copy of img with sensible defaults: an unsharp mask with radius 1.0 and amount 1.0, i.e. it adds back the full single-pixel- scale detail layer. For finer control over the scale or strength use UnsharpMask directly.
func Sobel ¶
Sobel returns the Sobel gradient-magnitude edge map of img. The operator is applied to each pixel's Rec. 601 luminance with clamp-to-edge borders; the magnitude is clamped to [0, 255] and written to the R, G and B channels, producing a grayscale edge image. Alpha is preserved. Strong intensity transitions appear bright, flat regions dark.
func SobelMag ¶
SobelMag returns the normalised Sobel gradient-magnitude edge map of img using the scikit-image convention (sqrt((gx^2+gy^2)/2) on luminance scaled to [0,1]), matching skimage.filters.sobel. It differs from Sobel, which uses the classic integer kernels and the unnormalised magnitude sqrt(gx^2+gy^2); SobelMag shares the one definition used by Prewitt and Scharr so the edge family is directly comparable to scikit-image.
func SobelX ¶
SobelX returns the horizontal Sobel response of img: an estimate of the left-to-right intensity derivative of each pixel's luminance. The signed response is scaled and offset so a zero gradient is mid-grey (128), a rising edge brighter and a falling edge darker, clamped to [0, 255] and written to R, G and B. Alpha is preserved; borders use clamp-to-edge addressing.
func SobelY ¶
SobelY returns the vertical Sobel response of img: an estimate of the top-to-bottom intensity derivative of each pixel's luminance, with the same scaling, offset and addressing conventions as SobelX. Alpha is preserved.
func Threshold ¶
Threshold returns a binary image: every pixel of img whose Rec. 601 luminance is strictly greater than t becomes white, every other pixel black. Alpha is preserved. Combine with OtsuThreshold for an automatically chosen level.
func ToRGBA ¶
ToRGBA returns img as an *image.RGBA. If img is already an *image.RGBA whose bounds start at the origin, it is returned unchanged; otherwise the pixels are copied (and, when necessary, colour-converted) into a freshly allocated origin-anchored *image.RGBA of the same dimensions.
func UnsharpMask ¶
UnsharpMask returns a sharpened copy of img using the unsharp-masking technique: dst = clamp(src + amount*(src - blurred)), where blurred is the Gaussian blur of img with standard deviation radius. The R, G and B channels are processed independently and alpha is preserved. It matches skimage.filters.unsharp_mask applied per channel.
radius controls the scale of the detail recovered (the Gaussian sigma) and must be positive; amount scales how strongly that detail is added back: 0 leaves the image unchanged, typical sharpening uses values around 0.5–2, and negative values soften. It returns an error if radius is not positive.
Types ¶
type Kernel ¶
Kernel is a 2-D convolution kernel: Weights is a row-major slice of length Width*Height, and both Width and Height must be odd.
type ResizeMode ¶
type ResizeMode int
ResizeMode selects the interpolation used by Resize.
const ( // NearestNeighbor selects the source pixel nearest to each destination // pixel. It is fast and exact for integer scale factors but blocky. NearestNeighbor ResizeMode = iota // Bilinear linearly interpolates the four nearest source pixels. It is // smoother than nearest-neighbour at the cost of more arithmetic. Bilinear )
