colorsim

package module
v0.0.0-...-3813304 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 20, 2026 License: MIT Imports: 10 Imported by: 0

README

go-colorsim

go-colorsim is a small, dependency-light Go library and CLI for background-robust image color similarity.

It is designed as a practical addon to go-phash: use phash for structure, and go-colorsim to distinguish images that look structurally similar but differ by color.

Why this approach

The algorithm builds a Gaussian center-weighted HSV histogram:

  • Uses H (hue) and S (saturation) only.
  • Ignores V (value/brightness), which improves robustness to white/black backgrounds and lighting shifts.

Comparison applies a center-focused Gaussian weight, so foreground regions contribute more than edge/background regions. This works best for studio-style images where the garment is centered and the background is mostly around the edges.

Distance is computed with Bhattacharyya distance:

  • 0 means identical color distributions.
  • Larger values mean less color similarity.
  • 1 means no histogram overlap at all.

By default, use colorsim.DefaultSimilarityThreshold (0.35) as a practical split:

  • distance < 0.35 -> close
  • distance > 0.35 -> distinct

Features

  • Robust decode from io.Reader with DecodeAny.
  • Reads full input bytes first (works with non-seekable readers).
  • Support JPEG, PNG, GIF, BMP and WebP.
  • No CGO.
  • Minimal dependencies.

Install

go get github.com/enot-style/go-colorsim

Library usage

package main

import (
	"fmt"
	"os"

	colorsim "github.com/enot-style/go-colorsim"
)

func main() {
	fa, _ := os.Open("a.jpg")
	defer fa.Close()
	fb, _ := os.Open("b.webp")
	defer fb.Close()

	imgA, _, _ := colorsim.DecodeAny(fa)
	imgB, _, _ := colorsim.DecodeAny(fb)

	// Uses defaults: 36x16 bins, sigma=0.55, minWeight=0.05
	d := colorsim.ColorDistance(imgA, imgB)
	fmt.Printf("distance=%.4f\n", d)
}
Tunable histogram API
histA := colorsim.ColorHist(imgA, 36, 16, 0.55, 0.05)
histB := colorsim.ColorHist(imgB, 36, 16, 0.55, 0.05)
d, _ := colorsim.BhattacharyyaDistance(histA, histB)

CLI

Usage:

go run ./cmd/imgsim <imageA> <imageB>

Example:

go run ./cmd/imgsim ./test_data/kblue.webp ./test_data/kyellow.jpeg
# 0.1834

Optional flags:

imgsim -sigma 0.45 -hbins 48 -sbins 20 -minw 0.02 <imageA> <imageB>
  • -sigma: normalized Gaussian sigma (> 0)
  • -hbins: hue bins (> 0)
  • -sbins: saturation bins (> 0)
  • -minw: minimum per-pixel weight (>= 0)

Documentation

Overview

Package colorsim provides background-robust image color similarity based on Gaussian center-weighted HSV histograms.

Index

Constants

View Source
const (
	// DefaultSigma is normalized Gaussian sigma, independent of image size.
	DefaultSigma = 0.55
	// DefaultHBins is the default number of hue bins.
	DefaultHBins = 36
	// DefaultSBins is the default number of saturation bins.
	DefaultSBins = 16
	// DefaultMinWeight is the floor for per-pixel Gaussian weight.
	DefaultMinWeight = 0.05
	// DefaultSimilarityThreshold is a practical default split:
	// distance < threshold -> close, distance >= threshold -> distinct.
	DefaultSimilarityThreshold = 0.35
)

Variables

View Source
var (
	// ErrHistogramLengthMismatch indicates two histograms have different sizes.
	ErrHistogramLengthMismatch = errors.New("histograms must have the same length")
	// ErrEmptyHistogram indicates an empty histogram input.
	ErrEmptyHistogram = errors.New("histograms must not be empty")
	// ErrNilReader indicates a nil input reader.
	ErrNilReader = errors.New("reader must not be nil")
	// ErrEmptyInput indicates an empty byte stream.
	ErrEmptyInput = errors.New("input is empty")
	// ErrUnsupportedFormat indicates data is not in a supported image format.
	ErrUnsupportedFormat = errors.New("unsupported image format")
)

Functions

func BhattacharyyaDistance

func BhattacharyyaDistance(a, b []float64) (float64, error)

BhattacharyyaDistance computes the Bhattacharyya distance between two normalized histograms.

BC = sum_i sqrt(p[i] * q[i]) D = sqrt(max(0, 1 - BC))

func ColorDistance

func ColorDistance(imgA, imgB image.Image) float64

ColorDistance computes color distance using default parameters.

func ColorHist

func ColorHist(img image.Image, hBins, sBins int, sigma, minWeight float64) []float64

ColorHist computes a Gaussian center-weighted 2D HSV histogram (H,S only) and normalizes it so the sum equals 1.

func DecodeAny

func DecodeAny(r io.Reader) (image.Image, string, error)

DecodeAny decodes image bytes from any supported format.

Supported formats:

  • JPEG, PNG, GIF (standard library)
  • BMP (golang.org/x/image/bmp)
  • WebP (golang.org/x/image/webp)

It reads all bytes first to support non-seekable readers.

func RGBToHSV

func RGBToHSV(r, g, b uint8) (h, s, v float64)

RGBToHSV converts 8-bit RGB values to HSV.

Output ranges:

  • H in [0, 360)
  • S in [0, 1]
  • V in [0, 1]

For grayscale pixels (delta == 0), H and S are both 0.

Types

This section is empty.

Directories

Path Synopsis
cmd
imgsim command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL