package module
v1.0.0 Latest Latest

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

Go to latest
Published: May 10, 2019 License: BSD-3-Clause Imports: 13 Imported by: 18


Go Report Card GoDoc


Find the K most dominant colors in an image

The Kmeans function returns the K most dominant colors in the image, ordered in the order of dominance.

To execute it with the default values, call

func Kmeans(orgimg image.Image) (centroids []ColorItem)

which takes an image and returns the K dominant colors, sorted by the most frequent one first.

It uses Kmeans++ to pick K initial centroid values, and goes through all pixels to re-calculate the centroids used.

As default function Kmeans uses these settings:

  • K=3
  • crops the center of the image before resizing (removing 25% on all sides)
  • resizes to 80 pixels
  • uses Kmeans++
  • uses median value to find the color for the centroid
  • mask out white, black or green backgrounds

To have more control, call KmeansWithArgs or KmeansWithAll. Below are the parameters that can be tweaked when calling those functions.


As default it has got K=3.

If set to high, it will get too detailed and would separate nuances of the same color in different centroids.


As default it resizes the image to 80 pixels wide (and whatever height to preserve aspect ratio).

The higher value, the more time it will take to process since it goes through all pixels.


ArgumentSeedRandom : Kmeans++ vs Random

As default it uses Kmeans++.

Kmeans++ will take K points that are as far away from each other as possible, to avoid that the points might be too close to each other and really could be in the same cluster. Hence the initial step takes slightly longer than just randomly picking the initial K starting points.

ArgumentAverageMean : Median vs mean for picking color

As default it uses median.

When the colors are being lumped together in the K clusters, it can pick the mean value, meaning adding all values together and dividing by the number of colors in that cluster. This will make the centroid color to be close to the color of the majority of the pixels in that cluster. Median will take the median value, i.e. just take the one in the middle of all colors in the cluster.

ArgumentNoCropping : Crop to center of image vs not cropping

As default, it crops the center of the image (removing 25% on all sides).

The theory being that the most relevant area in the image is in the middle, so even if the most dominant color in that area is not the most dominant color in the whole image, it might be what the user percieve as most dominant.

The image below contains mostly green color, but since the flower is in the center of the image, we might be interested in perceiving that as the dominant color. When cropping (default) it finds pink to be most dominant, without cropping (by setting ArgumentNoCropping), green is most dominant.

Using cropCenter

ArgumentLAB : RGB vs LAB

As default it uses RGB.

LAB is experimental atm, hence RGB is default.

ArgumentDebugImage : Save temporary image

Saves an image in /tmp/ where the pixels that have been masked out are colored pink. Useful when modifying the values of the masks, so you can observe the result.

Masking; removing background colours

GetDefaultMasks is the function containing the masks used as default, they can be used as a starting point when passing other masks to the function. As default it filters white, black or green backgrounds.

To handle items that are shot against white/black/green background ("isolated" objects / clipart / green screen images), the image is pre-processed to disregard the white/black/green background: If the four corners are in that same color (or close to it), the code will take those as starting points for the areas to be removed.

In the image below, it removes much of the white (the pink pixels are the pixels that have been removed). By removing those areas, "white" will have less of a chance of becoming the dominant color.

Ignoring backgrounds

Sample code

See example/example.go and example2/example2.go for sample calls with different parameters.

The sample images in example/ comes from flickr and are all Public Domain

The images used:


Carl Asman (

BSD License




Package prominentcolor finds the K most dominant/prominent colors in an image



View Source
const (
	// ArgumentDefault default settings
	ArgumentDefault int = 0
	// ArgumentSeedRandom randomly pick initial values (instead of K-means++)
	ArgumentSeedRandom = 1 << iota
	// ArgumentAverageMean take the mean value when determining the centroid color (instead of median)
	// ArgumentNoCropping do not crop background that is considered "white"
	// ArgumentLAB (experimental, it seems to be buggy in some cases): uses LAB instead of RGB when measuring distance
	// ArgumentDebugImage saves a tmp file in /tmp/ where the area that has been cut away by the mask is marked pink
	// useful when figuring out what values to pick for the masks
View Source
const (
	// DefaultK is the k used as default
	DefaultK = 3
	// DefaultSize is the default size images are re-sized to
	DefaultSize = 80


View Source
var (
	// MaskWhite "constant" for white mask (for ease of re-use for other mask arrays)
	MaskWhite = ColorBackgroundMask{R: true, G: true, B: true, Treshold: uint32(0xc000)}
	// MaskBlack "constant" for black mask (for ease of re-use for other mask arrays)
	MaskBlack = ColorBackgroundMask{R: false, G: false, B: false, Treshold: uint32(0x5000)}
	// MaskGreen "constant" for green mask (for ease of re-use for other mask arrays)
	MaskGreen = ColorBackgroundMask{R: false, G: true, B: false, PercDiff: 0.9}


func IsBitSet

func IsBitSet(bitset int, lookingfor int) bool

IsBitSet check if "lookingfor" is set in "bitset"

func ProcessImg

func ProcessImg(arguments int, bgmasks []ColorBackgroundMask, img image.Image) draw.Image

ProcessImg process the image and mark unwanted pixels transparent. It checks the corners, if not all of them match the mask, we conclude it's not a clipart/solid background and do nothing

func ProcessImgOutline

func ProcessImgOutline(bgmask ColorBackgroundMask, imgDraw *draw.Image)

ProcessImgOutline follow the outline of the image and mark all "white" pixels as transparent


type ColorBackgroundMask

type ColorBackgroundMask struct {
	// Setting them all to true or all to false; Treshold is used, otherwise PercDiff
	R, G, B bool

	// Treshold is the lower limit to check against for each r,g,b value, when all R,G,B that has true set should be above to be ignored (upper if all set to false)
	Treshold uint32

	// PercDiff if any of R,G,B is true (but not all), any of the other colors divided by the color value that is true, must be below PercDiff
	PercDiff float32

ColorBackgroundMask defines which color channels to look for color to ignore

func GetDefaultMasks

func GetDefaultMasks() []ColorBackgroundMask

GetDefaultMasks returns the masks that are used for the default settings

type ColorItem

type ColorItem struct {
	Color ColorRGB
	Cnt   int

ColorItem contains color and have many occurrences of this color found

func Kmeans

func Kmeans(orgimg image.Image) (centroids []ColorItem, err error)

Kmeans uses the default: k=3, Kmeans++, Median, crop center, resize to 80 pixels, mask out white/black/green backgrounds It returns an array of ColorItem which are three centroids, sorted according to dominance (most frequent first).

func KmeansWithAll

func KmeansWithAll(k int, orgimg image.Image, arguments int, imageReSize uint, bgmasks []ColorBackgroundMask) ([]ColorItem, error)

KmeansWithAll takes additional arguments to define k, arguments (see constants Argument*), size to resize and masks to use

func KmeansWithArgs

func KmeansWithArgs(arguments int, orgimg image.Image) (centroids []ColorItem, err error)

KmeansWithArgs takes arguments which consists of the bits, see constants Argument*

func (*ColorItem) AsString

func (c *ColorItem) AsString() string

AsString gives back the color in hex as 6 character string

type ColorRGB

type ColorRGB struct {
	R, G, B uint32

ColorRGB contains the color values


Path Synopsis

Jump to

Keyboard shortcuts

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