butteraugli

package module
v0.0.0-...-0fc85ae Latest Latest
Warning

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

Go to latest
Published: May 29, 2016 License: Apache-2.0 Imports: 5 Imported by: 0

README

go-butteraugli

This is a direct port of the butteraugli (https://github.com/google/butteraugli) library for measuring the psychovisual similarity between two images.

This port was mostly a line-by-line translation from c++ to go.  The key difference is that float64 was used for both double and float.  This allowed for simpler code and did not affect the resulting diff value.

Example diff value:
butteraugli:    1.071696
go-butteraugli: 1.0716956373428894

This library is currently in parity with commit https://github.com/google/butteraugli/commit/88897aba.  Since 88897aba the authors have chosen to roll back roughly 1000 changelines (https://github.com/google/butteraugli/compare/26d3d9b8110499fa767673c1f713eacdf306aba5...master).  I'm going to wait until the library stabilizes to update this port.  Until then this port is out of parity and is producing very different numbers.

Tools:
A command-line tool for measuring the butteraugli diff value between two images is included in `cmd/compare_images`.  It serves as an example for how to use this library.

Contributing:

Pull requests are welcome that fix bugs or port updates to the butteraugli library to this code.  Changes that make the code more idiomatic to the go language are not welcome.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrTooSmall       = errors.New("Butteraugli is undefined for small images")
	ErrDifferentSizes = errors.New("Images are not the same size")
)
View Source
var GammaDerivativeTable = func() []GammaDerivativeTableEntry {
	var kTable [256]GammaDerivativeTableEntry
	var prev float64 = GammaDerivativeRaw(0)
	for i := 0; i < 255; i++ {
		var (
			fi       float64 = float64(i)
			next     float64 = GammaDerivativeRaw(fi + 1)
			slope    float64 = next - prev
			constant float64 = prev - slope*fi
		)
		kTable[i].slope = slope
		kTable[i].constant = constant
		prev = next
	}
	kTable[255].slope = 0.0
	kTable[255].constant = prev
	return kTable[:]
}()

Functions

func ApplyErrorClustering

func ApplyErrorClustering(xsize, ysize, step int, distmap *[]float64)

Making a cluster of local errors to be more impactful than just a single error.

func Average5x5

func Average5x5(xsize, ysize int, diffs []float64)

===== Functions used by Suppression() only =====

func Butteraugli8x8CornerEdgeDetectorDiff

func Butteraugli8x8CornerEdgeDetectorDiff(pos_x, pos_y, xsize, ysize int, blurred0, blurred1 [][]float64, gamma, diff_xyz *[3]float64)

Direct model with low frequency edge detectors. Two edge detectors are applied in each corner of the 8x8 square. The squared 3-dimensional error vector is added to diff_xyz.

func ButteraugliAdaptiveQuantization

func ButteraugliAdaptiveQuantization(xsize, ysize int, rgb [][]float64, quant *[]float64) bool

Returns a map which can be used for adaptive quantization. Values can typically range from kButteraugliQuantLow to kButteraugliQuantHigh. Low values require coarse quantization (e.g. near random noise), high values require fine quantization (e.g. in smooth bright areas).

func ButteraugliDctd8x8

func ButteraugliDctd8x8(m *[64]float64)

The Dct computation used in butteraugli.

func ButteraugliDctd8x8RgbDiff

func ButteraugliDctd8x8RgbDiff(gamma *[3]float64, rgb0, rgb1 [192]float64, diff_xyz_dc, diff_xyz_ac *[3]float64)

Rgbdiff for one 8x8 block. The Dct computation used in butteraugli. Computes 8x8 DCT (with corner mixing) of each channel of rgb0 and rgb1 and adds the total squared 3-dimensional rgbdiff of the two blocks to diff_xyz. making copies of rgb0, rgb1

func ButteraugliDctd8x8Vertical

func ButteraugliDctd8x8Vertical(data *[64]float64)

Perform a DCT on each of the 8 columns. Results is scaled. The Dct computation used in butteraugli.

func ButteraugliDistanceFromMap

func ButteraugliDistanceFromMap(xsize, ysize int, distmap []float64) float64

func ButteraugliFuzzyClass

func ButteraugliFuzzyClass(score float64) float64

Converts the butteraugli score into fuzzy class values that are continuous at the class boundary. The class boundary location is based on human raters, but the slope is arbitrary. Particularly, it does not reflect the expectation value of probabilities of the human raters. It is just expected that a smoother class boundary will allow for higher-level optimization algorithms to work faster.

Returns 2.0 for a perfect match, and 1.0 for 'ok', 0.0 for bad. Because the scoring is fuzzy, a butteraugli score of 0.96 would return a class of around 1.9.

func ButteraugliInterface

func ButteraugliInterface(xsize, ysize int, rgb0, rgb1 [][]float64, diffmap []float64) (float64, error)

func ButteraugliMap

func ButteraugliMap(xsize, ysize int, rgb0, rgb1 [][]float64, result *[]float64)

func ButteraugliMixCorners

func ButteraugliMixCorners(m *[64]float64)

Mix a little bit of neighbouring pixels into the corners.

func ButteraugliQuadraticBlockDiffCoeffsXyz

func ButteraugliQuadraticBlockDiffCoeffsXyz(scale, gamma *[3]float64, rgb_copy [192]float64, coeffs *[192]float64)

Fills in coeffs[0..191] vector in such a way that if d[0..191] is the difference vector of the XYZ-color space DCT coefficients of an 8x8 block, then the butteraugli block error can be approximated with the

SUM(coeffs[i] * d[i]^2; i in 0..191)

quadratic function.

func CompareImages

func CompareImages(img1, img2 image.Image) (float64, error)

func Convolution

func Convolution(xsize, ysize, xstep, length, offset int, multipliers, inp, result []float64)

Computes a horizontal convolution and transposes the result.

func DiffPrecompute

func DiffPrecompute(rgb [][]float64, xsize, ysize int, suppression *[][]float64)

func DotProduct

func DotProduct(u [3]float64, v [3]float64) float64

func DotProductWithMax

func DotProductWithMax(u [3]float64, v [3]float64) float64

func GammaDerivativeLut

func GammaDerivativeLut(v float64) float64

func GammaDerivativeRaw

func GammaDerivativeRaw(v float64) float64

Model of the gamma derivative in the human eye.

func GammaDerivativeWeightedAvg

func GammaDerivativeWeightedAvg(m0, m1 *[64]float64) float64

func GaussBlurApproximation

func GaussBlurApproximation(xsize, ysize int, channel []float64, sigma float64)

func GetContrastSensitivityMatrix

func GetContrastSensitivityMatrix() []float64

Contrast sensitivity related weights.

func GetHighFreqColorDiffDx

func GetHighFreqColorDiffDx() []float64

func GetHighFreqColorDiffDy

func GetHighFreqColorDiffDy() []float64

func GetHighFreqColorDiffDz

func GetHighFreqColorDiffDz() []float64

func GetLowFreqColorDiff

func GetLowFreqColorDiff() []float64

func ImageToLinearOnBlack

func ImageToLinearOnBlack(img image.Image) ([][]float64, bool)

Translate R, G, B channels from sRGB to linear space. If an alpha channel is present, overlay the image over a black or white background. Overlaying is done in the sRGB space; while technically incorrect, this is aligned with many other software (web browsers, WebP near lossless).

func ImageToLinearOnWhite

func ImageToLinearOnWhite(img image.Image) [][]float64

func Interpolate

func Interpolate(array []float64, size int, sx float64) float64

func MinSquareVal

func MinSquareVal(square_size, offset, xsize, ysize int, values []float64)

Replaces values[x + y * xsize] with the minimum of the values in the square_size square with coordinates

x - offset .. x + square_size - offset - 1,
y - offset .. y + square_size - offset - 1.

func MixGamma

func MixGamma(gamma *[3]float64)

func MultiplyScalarImage

func MultiplyScalarImage(xsize, ysize, offset int, scale, result []float64)

func RadialWeights

func RadialWeights(output []float64) float64

func RgbDiff

func RgbDiff(r0, g0, b0, r1, g1, b1 float64) float64

Color difference evaluation for 'high frequency' color changes.

Color difference is computed between two color pairs: (r0, g0, b0) and (r1, g1, b1).

Values are expected to be between 0 and 255, but gamma corrected, i.e., a linear amount of photons is modulated with a fixed amount of change in these values.

func RgbDiffGamma

func RgbDiffGamma(ave_r, ave_g, ave_b, r0, g0, b0, r1, g1, b1 float64) float64

Version of rgb diff that applies gamma correction to the diffs. The rgb "background" values where the diffs occur are given as ave_r, ave_g, ave_b.

func RgbDiffGammaLowFreq

func RgbDiffGammaLowFreq(ave_r, ave_g, ave_b, r0, g0, b0, r1, g1, b1 float64) float64

func RgbDiffLowFreq

func RgbDiffLowFreq(r0, g0, b0, r1, g1, b1 float64) float64

func RgbDiffLowFreqScaledSquared

func RgbDiffLowFreqScaledSquared(r0, g0, b0, r1, g1, b1 float64, scale [3]float64) float64

func RgbDiffLowFreqSquared

func RgbDiffLowFreqSquared(r0, g0, b0, r1, g1, b1 float64) float64

Same as RgbDiffLowFreq^2. Avoids unnecessary square root.

func RgbDiffLowFreqSquaredXyzAccumulate

func RgbDiffLowFreqSquaredXyzAccumulate(r0, g0, b0, r1, g1, b1, factor float64, res *[3]float64)

func RgbDiffScaledSquared

func RgbDiffScaledSquared(r0, g0, b0, r1, g1, b1 float64, scale [3]float64) float64

Function to estimate the psychovisual impact of a high frequency difference.

func RgbDiffSquared

func RgbDiffSquared(r0, g0, b0, r1, g1, b1 float64) float64

Function to estimate the psychovisual impact of a high frequency difference. Same as RgbDiff^2. Avoids unnecessary square root.

func RgbDiffSquaredXyzAccumulate

func RgbDiffSquaredXyzAccumulate(r0, g0, b0, r1, g1, b1, factor float64, res *[3]float64)

func RgbLowFreqToVals

func RgbLowFreqToVals(r, g, b float64, valx, valy, valz *float64)

Rough psychovisual distance to gray for low frequency colors.

func RgbToVals

func RgbToVals(r, g, b float64, valx, valy, valz *float64)

func RgbToXyz

func RgbToXyz(r, g, b float64, valx, valy, valz *float64)

The high frequency color model used by RgbDiff().

func ScaleImage

func ScaleImage(scale float64, result []float64)

func SoftClampHighValues

func SoftClampHighValues(v float64) float64

func SuppressionBlue

func SuppressionBlue(delta float64) float64

func SuppressionRedMinusGreen

func SuppressionRedMinusGreen(delta float64) float64

func SuppressionRedPlusGreen

func SuppressionRedPlusGreen(delta float64) float64

Non-linearities for component-based suppression.

func SuppressionRgb

func SuppressionRgb(rgb [][]float64, xsize, ysize int, suppression *[][]float64)

Compute values of local frequency masking based on the activity in the argb image.

func Transpose8x8

func Transpose8x8(data *[64]float64)

func XyzToVals

func XyzToVals(x, y, z float64, valx, valy, valz *float64)

Types

type ButteraugliComparator

type ButteraugliComparator struct {
	// contains filtered or unexported fields
}

Allows incremental computation of the butteraugli map by keeping some intermediate results.

func NewButteraugliComparator

func NewButteraugliComparator(xsize, ysize, step int) *ButteraugliComparator

func (*ButteraugliComparator) CombineChannels

func (bc *ButteraugliComparator) CombineChannels(result *[]float64)

func (*ButteraugliComparator) Dct8x8mapIncremental

func (bc *ButteraugliComparator) Dct8x8mapIncremental(rgb0, rgb1 [][]float64, changed []bool)

func (ButteraugliComparator) DistanceMap

func (bc ButteraugliComparator) DistanceMap(rgb0, rgb1 [][]float64, result *[]float64)

Computes the butteraugli map from scratch, updates all intermediate results.

func (*ButteraugliComparator) DistanceMapIncremental

func (bc *ButteraugliComparator) DistanceMapIncremental(rgb0, rgb1 [][]float64, changed []bool, result *[]float64)

Computes the butteraugli map by resuing some intermediate results from the previous run.

Must be called with the same rgb0 image as in the last DistanceMap() call.

If changed[res_y * res_xsize_ + res_x] is false, it assumes that rgb1 did not change compared to the previous calls of this function or of DistanceMap() anywhere within an 8x8 block with upper-left corner in (step_ * res_x, step_ * res_y).

func (*ButteraugliComparator) EdgeDetectorMap

func (bc *ButteraugliComparator) EdgeDetectorMap(rgb0, rgb1 [][]float64)

func (*ButteraugliComparator) FinalizeDistanceMap

func (bc *ButteraugliComparator) FinalizeDistanceMap(result *[]float64)

func (*ButteraugliComparator) GetSuppressionMap

func (bc *ButteraugliComparator) GetSuppressionMap(suppression *[][]float64)

Copies the suppression map computed by the previous call to DistanceMap() or DistanceMapIncremental() to *suppression.

func (*ButteraugliComparator) SuppressionMap

func (bc *ButteraugliComparator) SuppressionMap(rgb0, rgb1 [][]float64)

type GammaDerivativeTableEntry

type GammaDerivativeTableEntry struct {
	// contains filtered or unexported fields
}

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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