images4/custom.go
2024-01-30 01:18:45 +01:00

66 lines
2.1 KiB
Go

package images4
// Threshold multiplication coefficients for func CustomSimilar.
// When all values equal 1.0 func CustomSimilar is equivalent
// to func Similar. By setting those values less than 1, similarity
// comparison becomes stricter (more precise). Values larger than 1
// will generalize more and show more false positives. When uncertain,
// setting all coefficients to 1.0 is the safe starting point.
type CustomCoefficients struct {
Y float64 // Luma (grayscale information).
Cb float64 // Chrominance b (color information).
Cr float64 // Chrominance r (color information).
Prop float64 // Proportion tolerance (how similar are image borders).
}
// CustomSimilar is like Similar, except it allows changing default
// thresholds by multiplying them. The practically useful range of
// the coefficients is [0, 1.0), but can be equal or larger than 1
// if necessary. All coefficients set to 0 correspond to identical images,
// for example an image file copy. All coefficients equal to 1 make func
// CustomSimilar equivalent to func Similar.
func CustomSimilar(iconA, iconB IconT, coeff CustomCoefficients) bool {
if !customPropSimilar(iconA, iconB, coeff) {
return false
}
if !customEucSimilar(iconA, iconB, coeff) {
return false
}
return true
}
func customPropSimilar(iconA, iconB IconT, coeff CustomCoefficients) bool {
return PropMetric(iconA, iconB) <= thProp*coeff.Prop
}
func customEucSimilar(iconA, iconB IconT, coeff CustomCoefficients) bool {
m1, m2, m3 := EucMetric(iconA, iconB)
return m1 <= thY*coeff.Y &&
m2 <= thCbCr*coeff.Cb &&
m3 <= thCbCr*coeff.Cr
}
// Similar90270 works like Similar, but also considers rotations of ±90°.
// Those are rotations users might reasonably often do.
func CustomSimilar90270(iconA, iconB IconT, coeff CustomCoefficients) bool {
if CustomSimilar(iconA, iconB, coeff) {
return true
}
// iconB rotated 90 degrees.
if CustomSimilar(iconA, Rotate90(iconB), coeff) {
return true
}
// As if iconB was rotated 270 degrees.
if CustomSimilar(Rotate90(iconA), iconB, coeff) {
return true
}
return false
}