|
| 1 | +package processing |
| 2 | + |
| 3 | +import ( |
| 4 | + "image/color" |
| 5 | + |
| 6 | + "github.com/julyskies/brille/utilities" |
| 7 | +) |
| 8 | + |
| 9 | +func getAperture(axisValue, axisMax, apertureMin, apertureMax int) (int, int) { |
| 10 | + start, end := 0, axisMax |
| 11 | + if axisValue+apertureMin > 0 { |
| 12 | + start = axisValue + apertureMin |
| 13 | + } |
| 14 | + if axisValue+apertureMax < axisMax { |
| 15 | + end = axisValue + apertureMax |
| 16 | + } |
| 17 | + return start, end |
| 18 | +} |
| 19 | + |
| 20 | +func KuwaharaFilter(source [][]color.Color, aperture uint) [][]color.Color { |
| 21 | + width, height := len(source), len(source[0]) |
| 22 | + destination := utilities.CreateGrid(width, height) |
| 23 | + apertureHalf := int(aperture / 2) |
| 24 | + apertureMinX := [4]int{-apertureHalf, 0, -apertureHalf, 0} |
| 25 | + apertureMaxX := [4]int{0, apertureHalf, 0, apertureHalf} |
| 26 | + apertureMinY := [4]int{-apertureHalf, -apertureHalf, 0, 0} |
| 27 | + apertureMaxY := [4]int{0, 0, apertureHalf, apertureHalf} |
| 28 | + for x := 0; x < width; x += 1 { |
| 29 | + for y := 0; y < height; y += 1 { |
| 30 | + pixelCount := [4]int{0, 0, 0, 0} |
| 31 | + rValues := [4]int{0, 0, 0, 0} |
| 32 | + gValues := [4]int{0, 0, 0, 0} |
| 33 | + bValues := [4]int{0, 0, 0, 0} |
| 34 | + maxRValue := [4]int{0, 0, 0, 0} |
| 35 | + maxGValue := [4]int{0, 0, 0, 0} |
| 36 | + maxBValue := [4]int{0, 0, 0, 0} |
| 37 | + minRValue := [4]int{255, 255, 255, 255} |
| 38 | + minGValue := [4]int{255, 255, 255, 255} |
| 39 | + minBValue := [4]int{255, 255, 255, 255} |
| 40 | + for i := 0; i < 4; i += 1 { |
| 41 | + x2start, x2end := getAperture(x, width, apertureMinX[i], apertureMaxX[i]) |
| 42 | + y2start, y2end := getAperture(y, height, apertureMinY[i], apertureMaxY[i]) |
| 43 | + for x2 := x2start; x2 < x2end; x2 += 1 { |
| 44 | + for y2 := y2start; y2 < y2end; y2 += 1 { |
| 45 | + r, g, b, _ := utilities.RGBA(source[x2][y2]) |
| 46 | + rValues[i] += int(r) |
| 47 | + gValues[i] += int(g) |
| 48 | + bValues[i] += int(b) |
| 49 | + if int(r) > maxRValue[i] { |
| 50 | + maxRValue[i] = int(r) |
| 51 | + } else if int(r) < minRValue[i] { |
| 52 | + minRValue[i] = int(r) |
| 53 | + } |
| 54 | + if int(g) > maxGValue[i] { |
| 55 | + maxGValue[i] = int(g) |
| 56 | + } else if int(g) < minGValue[i] { |
| 57 | + minGValue[i] = int(g) |
| 58 | + } |
| 59 | + if int(b) > maxBValue[i] { |
| 60 | + maxBValue[i] = int(b) |
| 61 | + } else if int(b) < minBValue[i] { |
| 62 | + minBValue[i] = int(b) |
| 63 | + } |
| 64 | + pixelCount[i] += 1 |
| 65 | + } |
| 66 | + } |
| 67 | + } |
| 68 | + j := 0 |
| 69 | + MinDifference := 10000 |
| 70 | + for i := 0; i < 4; i += 1 { |
| 71 | + cdR := maxRValue[i] - minRValue[i] |
| 72 | + cdG := maxGValue[i] - minGValue[i] |
| 73 | + cdB := maxBValue[i] - minBValue[i] |
| 74 | + CurrentDifference := cdR + cdG + cdB |
| 75 | + if CurrentDifference < MinDifference && pixelCount[i] > 0 { |
| 76 | + j = i |
| 77 | + MinDifference = CurrentDifference |
| 78 | + } |
| 79 | + } |
| 80 | + cR := uint8(rValues[j] / pixelCount[j]) |
| 81 | + cG := uint8(gValues[j] / pixelCount[j]) |
| 82 | + cB := uint8(bValues[j] / pixelCount[j]) |
| 83 | + destination[x][y] = color.RGBA{cR, cG, cB, 255} |
| 84 | + } |
| 85 | + } |
| 86 | + return destination |
| 87 | +} |
0 commit comments