package imageutils import ( "image" "image/color" "math" ) type ImageAnalyzer struct { image.Image } // Calculate the energy using the dual-gradient energy function func getEnergy( firstPixel color.Color, secondPixel color.Color, ) float64 { firstRed, firstGreen, firstBlue, _ := firstPixel.RGBA() firstRed, firstGreen, firstBlue = firstRed >> 8, firstGreen >> 8, firstBlue >> 8 secondRed, secondGreen, secondBlue, _ := secondPixel.RGBA() secondRed, secondGreen, secondBlue = secondRed >> 8, secondGreen >> 8, secondBlue >> 8 return float64( math.Abs(float64(firstRed - secondRed)) + math.Abs(float64(firstGreen - secondGreen)) + math.Abs(float64(firstBlue - secondBlue)), ) } // Calculate a 0-255 grayscale value from a color using the NTSC formula func colorToGray(color color.Color) float64 { red, green, blue, _ := color.RGBA() red, green, blue = red >> 8, green >> 8, blue >> 8 return 0.299 * float64(red) + 0.587 * float64(green) + 0.114 * float64(blue) } func sumSlice(slice []float64) float64 { var sum float64 for _, value := range slice { sum += value } return sum } func (image *ImageAnalyzer) CalculateEnergyAt(x int, y int) float64 { northPixel := image.At( x, max(0, y - 1), ) northEastPixel := image.At( min(image.Bounds().Max.X, x + 1), max(0, y - 1), ) eastPixel := image.At( min(image.Bounds().Max.X, x + 1), y, ) southEastPixel := image.At( min(image.Bounds().Max.X, x + 1), min(image.Bounds().Max.Y, y + 1), ) southPixel := image.At( x, min(image.Bounds().Max.Y, y + 1), ) southWestPixel := image.At( max(0, x - 1), min(image.Bounds().Max.Y, y + 1), ) westPixel := image.At( max(0, x - 1), y, ) northWestPixel := image.At( max(0, x - 1), max(0, y - 1), ) thisPixel := image.At( x, y, ) _ = thisPixel _ = northPixel _ = northEastPixel _ = southPixel horizontalMatrix := []float64{ colorToGray(northWestPixel), 0, -colorToGray(northEastPixel), 2 * colorToGray(westPixel), 0, -2 * colorToGray(eastPixel), colorToGray(southWestPixel), 0, -colorToGray(southEastPixel), } verticalMatrix := []float64{ colorToGray(northWestPixel), 2 * colorToGray(northPixel), colorToGray(northEastPixel), 0, 0, 0, -colorToGray(southWestPixel), -2 * colorToGray(southPixel), -colorToGray(southEastPixel), } g_x := sumSlice(horizontalMatrix) g_y := sumSlice(verticalMatrix) return math.Sqrt( math.Pow(g_x, 2) + math.Pow(g_y, 2), ) }