Disabled image quality patch
This commit is contained in:
parent
1f0adabde2
commit
4f6078943c
@ -1,287 +1,289 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
func main() {}
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"image"
|
|
||||||
"image/color"
|
|
||||||
_ "image/jpeg"
|
|
||||||
"image/png"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
// import (
|
||||||
data, err := ioutil.ReadFile("input.jpg")
|
// "bytes"
|
||||||
|
// "fmt"
|
||||||
|
// "image"
|
||||||
|
// "image/color"
|
||||||
|
// _ "image/jpeg"
|
||||||
|
// "image/png"
|
||||||
|
// "io/ioutil"
|
||||||
|
// "os"
|
||||||
|
// )
|
||||||
|
|
||||||
if err != nil {
|
// func main() {
|
||||||
panic(err)
|
// data, err := ioutil.ReadFile("input.jpg")
|
||||||
}
|
|
||||||
|
|
||||||
img, _, err := image.Decode(bytes.NewReader(data))
|
// if err != nil {
|
||||||
|
// panic(err)
|
||||||
|
// }
|
||||||
|
|
||||||
if err != nil {
|
// img, _, err := image.Decode(bytes.NewReader(data))
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
improved := ImproveQuality(img)
|
// if err != nil {
|
||||||
f, err := os.Create("output.png")
|
// panic(err)
|
||||||
|
// }
|
||||||
|
|
||||||
if err != nil {
|
// improved := ImproveQuality(img)
|
||||||
panic(err)
|
// f, err := os.Create("output.png")
|
||||||
}
|
|
||||||
|
|
||||||
defer f.Close()
|
// if err != nil {
|
||||||
png.Encode(f, improved)
|
// panic(err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Pixel ...
|
// defer f.Close()
|
||||||
type Pixel struct {
|
// png.Encode(f, improved)
|
||||||
X int
|
// }
|
||||||
Y int
|
|
||||||
}
|
|
||||||
|
|
||||||
// Area ...
|
// // Pixel ...
|
||||||
type Area struct {
|
// type Pixel struct {
|
||||||
Pixels []Pixel
|
// X int
|
||||||
totalR uint64
|
// Y int
|
||||||
totalG uint64
|
// }
|
||||||
totalB uint64
|
|
||||||
totalA uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add ...
|
// // Area ...
|
||||||
func (area *Area) Add(x, y int, r, g, b, a uint32) {
|
// type Area struct {
|
||||||
area.Pixels = append(area.Pixels, Pixel{
|
// Pixels []Pixel
|
||||||
X: x,
|
// totalR uint64
|
||||||
Y: y,
|
// totalG uint64
|
||||||
})
|
// totalB uint64
|
||||||
|
// totalA uint64
|
||||||
|
// }
|
||||||
|
|
||||||
area.totalR += uint64(r)
|
// // Add ...
|
||||||
area.totalG += uint64(g)
|
// func (area *Area) Add(x, y int, r, g, b, a uint32) {
|
||||||
area.totalB += uint64(b)
|
// area.Pixels = append(area.Pixels, Pixel{
|
||||||
area.totalA += uint64(a)
|
// X: x,
|
||||||
}
|
// Y: y,
|
||||||
|
// })
|
||||||
|
|
||||||
// AverageColor ...
|
// area.totalR += uint64(r)
|
||||||
func (area *Area) AverageColor() color.Color {
|
// area.totalG += uint64(g)
|
||||||
if len(area.Pixels) == 0 {
|
// area.totalB += uint64(b)
|
||||||
return color.Transparent
|
// area.totalA += uint64(a)
|
||||||
}
|
// }
|
||||||
|
|
||||||
return color.RGBA64{
|
// // AverageColor ...
|
||||||
R: uint16(area.totalR / uint64(len(area.Pixels))),
|
// func (area *Area) AverageColor() color.Color {
|
||||||
G: uint16(area.totalG / uint64(len(area.Pixels))),
|
// if len(area.Pixels) == 0 {
|
||||||
B: uint16(area.totalB / uint64(len(area.Pixels))),
|
// return color.Transparent
|
||||||
A: uint16(area.totalA / uint64(len(area.Pixels))),
|
// }
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
// return color.RGBA64{
|
||||||
tolerance = uint32(3000)
|
// R: uint16(area.totalR / uint64(len(area.Pixels))),
|
||||||
)
|
// G: uint16(area.totalG / uint64(len(area.Pixels))),
|
||||||
|
// B: uint16(area.totalB / uint64(len(area.Pixels))),
|
||||||
|
// A: uint16(area.totalA / uint64(len(area.Pixels))),
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
func diffAbs(a uint32, b uint32) uint32 {
|
// const (
|
||||||
if a > b {
|
// tolerance = uint32(3000)
|
||||||
return a - b
|
// )
|
||||||
}
|
|
||||||
|
|
||||||
return b - a
|
// func diffAbs(a uint32, b uint32) uint32 {
|
||||||
}
|
// if a > b {
|
||||||
|
// return a - b
|
||||||
|
// }
|
||||||
|
|
||||||
// ImproveQuality returns the average color of an image in HSL format.
|
// return b - a
|
||||||
func ImproveQuality(img image.Image) *image.NRGBA {
|
// }
|
||||||
width := img.Bounds().Dx()
|
|
||||||
height := img.Bounds().Dy()
|
|
||||||
clone := image.NewNRGBA(image.Rect(0, 0, width, height))
|
|
||||||
areas := []*Area{}
|
|
||||||
areaIndexMap := make([]int, width*height)
|
|
||||||
|
|
||||||
for x := 0; x < width; x++ {
|
// // ImproveQuality returns the average color of an image in HSL format.
|
||||||
for y := 0; y < height; y++ {
|
// func ImproveQuality(img image.Image) *image.NRGBA {
|
||||||
color := img.At(x, y)
|
// width := img.Bounds().Dx()
|
||||||
r, g, b, a := color.RGBA()
|
// height := img.Bounds().Dy()
|
||||||
areaIndex := -1
|
// clone := image.NewNRGBA(image.Rect(0, 0, width, height))
|
||||||
|
// areas := []*Area{}
|
||||||
|
// areaIndexMap := make([]int, width*height)
|
||||||
|
|
||||||
// Find similar area
|
// for x := 0; x < width; x++ {
|
||||||
for i := 0; i < len(areas); i++ {
|
// for y := 0; y < height; y++ {
|
||||||
area := areas[i]
|
// color := img.At(x, y)
|
||||||
avgR, avgG, avgB, _ := area.AverageColor().RGBA()
|
// r, g, b, a := color.RGBA()
|
||||||
|
// areaIndex := -1
|
||||||
|
|
||||||
// Is the color similar?
|
// // Find similar area
|
||||||
if diffAbs(r, avgR) <= tolerance && diffAbs(g, avgG) <= tolerance && diffAbs(b, avgB) <= tolerance {
|
// for i := 0; i < len(areas); i++ {
|
||||||
areaIndex = i
|
// area := areas[i]
|
||||||
break
|
// avgR, avgG, avgB, _ := area.AverageColor().RGBA()
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert new area
|
// // Is the color similar?
|
||||||
if areaIndex == -1 {
|
// if diffAbs(r, avgR) <= tolerance && diffAbs(g, avgG) <= tolerance && diffAbs(b, avgB) <= tolerance {
|
||||||
areaIndex = len(areas)
|
// areaIndex = i
|
||||||
areas = append(areas, &Area{})
|
// break
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
areaIndexMap[y*width+x] = areaIndex
|
// // Insert new area
|
||||||
areas[areaIndex].Add(x, y, r, g, b, a)
|
// if areaIndex == -1 {
|
||||||
}
|
// areaIndex = len(areas)
|
||||||
}
|
// areas = append(areas, &Area{})
|
||||||
|
// }
|
||||||
|
|
||||||
fmt.Println(len(areas), "areas")
|
// areaIndexMap[y*width+x] = areaIndex
|
||||||
|
// areas[areaIndex].Add(x, y, r, g, b, a)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
// Reduce noise
|
// fmt.Println(len(areas), "areas")
|
||||||
noiseCount := 0
|
|
||||||
|
|
||||||
for areaIndex, area := range areas {
|
// // Reduce noise
|
||||||
noisePixelIndices := []int{}
|
// noiseCount := 0
|
||||||
areaSurroundedBy := map[int]int{}
|
|
||||||
|
|
||||||
for i := 0; i < len(area.Pixels); i++ {
|
// for areaIndex, area := range areas {
|
||||||
// If pixel is surrounded by 4 different areas, remove it
|
// noisePixelIndices := []int{}
|
||||||
pixel := area.Pixels[i]
|
// areaSurroundedBy := map[int]int{}
|
||||||
x := pixel.X
|
|
||||||
y := pixel.Y
|
|
||||||
left := areaIndex
|
|
||||||
right := areaIndex
|
|
||||||
top := areaIndex
|
|
||||||
bottom := areaIndex
|
|
||||||
|
|
||||||
if x > 0 {
|
// for i := 0; i < len(area.Pixels); i++ {
|
||||||
left = areaIndexMap[y*width+(x-1)]
|
// // If pixel is surrounded by 4 different areas, remove it
|
||||||
}
|
// pixel := area.Pixels[i]
|
||||||
|
// x := pixel.X
|
||||||
|
// y := pixel.Y
|
||||||
|
// left := areaIndex
|
||||||
|
// right := areaIndex
|
||||||
|
// top := areaIndex
|
||||||
|
// bottom := areaIndex
|
||||||
|
|
||||||
if x < width-1 {
|
// if x > 0 {
|
||||||
right = areaIndexMap[y*width+(x+1)]
|
// left = areaIndexMap[y*width+(x-1)]
|
||||||
}
|
// }
|
||||||
|
|
||||||
if y > 0 {
|
// if x < width-1 {
|
||||||
top = areaIndexMap[(y-1)*width+x]
|
// right = areaIndexMap[y*width+(x+1)]
|
||||||
}
|
// }
|
||||||
|
|
||||||
if y < height-1 {
|
// if y > 0 {
|
||||||
bottom = areaIndexMap[(y+1)*width+x]
|
// top = areaIndexMap[(y-1)*width+x]
|
||||||
}
|
// }
|
||||||
|
|
||||||
differentNeighbors := 0
|
// if y < height-1 {
|
||||||
|
// bottom = areaIndexMap[(y+1)*width+x]
|
||||||
|
// }
|
||||||
|
|
||||||
if left != areaIndex {
|
// differentNeighbors := 0
|
||||||
differentNeighbors++
|
|
||||||
}
|
|
||||||
|
|
||||||
if right != areaIndex {
|
// if left != areaIndex {
|
||||||
differentNeighbors++
|
// differentNeighbors++
|
||||||
}
|
// }
|
||||||
|
|
||||||
if top != areaIndex {
|
// if right != areaIndex {
|
||||||
differentNeighbors++
|
// differentNeighbors++
|
||||||
}
|
// }
|
||||||
|
|
||||||
if bottom != areaIndex {
|
// if top != areaIndex {
|
||||||
differentNeighbors++
|
// differentNeighbors++
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Determine surrounding area
|
// if bottom != areaIndex {
|
||||||
areaIndexScore := map[int]int{}
|
// differentNeighbors++
|
||||||
|
// }
|
||||||
|
|
||||||
areaIndexScore[left]++
|
// // Determine surrounding area
|
||||||
areaIndexScore[right]++
|
// areaIndexScore := map[int]int{}
|
||||||
areaIndexScore[top]++
|
|
||||||
areaIndexScore[bottom]++
|
|
||||||
|
|
||||||
areaSurroundedBy[left]++
|
// areaIndexScore[left]++
|
||||||
areaSurroundedBy[right]++
|
// areaIndexScore[right]++
|
||||||
areaSurroundedBy[top]++
|
// areaIndexScore[top]++
|
||||||
areaSurroundedBy[bottom]++
|
// areaIndexScore[bottom]++
|
||||||
|
|
||||||
newAreaIndex := -1
|
// areaSurroundedBy[left]++
|
||||||
bestScore := 0
|
// areaSurroundedBy[right]++
|
||||||
|
// areaSurroundedBy[top]++
|
||||||
|
// areaSurroundedBy[bottom]++
|
||||||
|
|
||||||
for checkIndex, score := range areaIndexScore {
|
// newAreaIndex := -1
|
||||||
if score > bestScore {
|
// bestScore := 0
|
||||||
bestScore = score
|
|
||||||
newAreaIndex = checkIndex
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if differentNeighbors >= 3 && bestScore >= 3 {
|
// for checkIndex, score := range areaIndexScore {
|
||||||
noiseCount++
|
// if score > bestScore {
|
||||||
noisePixelIndices = append(noisePixelIndices, i)
|
// bestScore = score
|
||||||
|
// newAreaIndex = checkIndex
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
// Add to surrounding area
|
// if differentNeighbors >= 3 && bestScore >= 3 {
|
||||||
r, g, b, a := img.At(x, y).RGBA()
|
// noiseCount++
|
||||||
areas[newAreaIndex].Add(x, y, r, g, b, a)
|
// noisePixelIndices = append(noisePixelIndices, i)
|
||||||
|
|
||||||
area.totalR -= uint64(r)
|
// // Add to surrounding area
|
||||||
area.totalG -= uint64(g)
|
// r, g, b, a := img.At(x, y).RGBA()
|
||||||
area.totalB -= uint64(b)
|
// areas[newAreaIndex].Add(x, y, r, g, b, a)
|
||||||
area.totalA -= uint64(a)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove noise pixels
|
// area.totalR -= uint64(r)
|
||||||
offset := 0
|
// area.totalG -= uint64(g)
|
||||||
|
// area.totalB -= uint64(b)
|
||||||
|
// area.totalA -= uint64(a)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
for _, removal := range noisePixelIndices {
|
// // Remove noise pixels
|
||||||
index := removal - offset
|
// offset := 0
|
||||||
area.Pixels = append(area.Pixels[:index], area.Pixels[index+1:]...)
|
|
||||||
offset++
|
|
||||||
}
|
|
||||||
|
|
||||||
// // Determine surrounding area
|
// for _, removal := range noisePixelIndices {
|
||||||
// surroundingAreaIndex := -1
|
// index := removal - offset
|
||||||
// bestScore := 0
|
// area.Pixels = append(area.Pixels[:index], area.Pixels[index+1:]...)
|
||||||
|
// offset++
|
||||||
|
// }
|
||||||
|
|
||||||
// for checkIndex, score := range areaSurroundedBy {
|
// // // Determine surrounding area
|
||||||
// if score > bestScore && checkIndex != areaIndex {
|
// // surroundingAreaIndex := -1
|
||||||
// bestScore = score
|
// // bestScore := 0
|
||||||
// surroundingAreaIndex = checkIndex
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// surroundingArea := areas[surroundingAreaIndex]
|
// // for checkIndex, score := range areaSurroundedBy {
|
||||||
|
// // if score > bestScore && checkIndex != areaIndex {
|
||||||
|
// // bestScore = score
|
||||||
|
// // surroundingAreaIndex = checkIndex
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
|
||||||
// if areaIndex != surroundingAreaIndex && len(surroundingArea.Pixels) > len(area.Pixels)*2 {
|
// // surroundingArea := areas[surroundingAreaIndex]
|
||||||
// // const surroundTolerance = 5000
|
|
||||||
|
|
||||||
// // r1, g1, b1, a1 := area.AverageColor().RGBA()
|
// // if areaIndex != surroundingAreaIndex && len(surroundingArea.Pixels) > len(area.Pixels)*2 {
|
||||||
// // r2, g2, b2, a2 := surroundingArea.AverageColor().RGBA()
|
// // // const surroundTolerance = 5000
|
||||||
|
|
||||||
// // if diffAbs(r1, r2) < surroundTolerance && diffAbs(g1, g2) < surroundTolerance && diffAbs(b1, b2) < surroundTolerance && diffAbs(a1, a2) < surroundTolerance {
|
// // // r1, g1, b1, a1 := area.AverageColor().RGBA()
|
||||||
// // // fmt.Println(areaIndex, "surrounded by", surroundingAreaIndex, "|", len(area.Pixels), len(surroundingArea.Pixels))
|
// // // r2, g2, b2, a2 := surroundingArea.AverageColor().RGBA()
|
||||||
|
|
||||||
// // // Add pixels to surrounding area
|
// // // if diffAbs(r1, r2) < surroundTolerance && diffAbs(g1, g2) < surroundTolerance && diffAbs(b1, b2) < surroundTolerance && diffAbs(a1, a2) < surroundTolerance {
|
||||||
// // for _, pixel := range area.Pixels {
|
// // // // fmt.Println(areaIndex, "surrounded by", surroundingAreaIndex, "|", len(area.Pixels), len(surroundingArea.Pixels))
|
||||||
// // r, g, b, a := img.At(pixel.X, pixel.Y).RGBA()
|
|
||||||
// // surroundingArea.Add(pixel.X, pixel.Y, r, g, b, a)
|
|
||||||
// // }
|
|
||||||
|
|
||||||
// // // Remove this area
|
// // // // Add pixels to surrounding area
|
||||||
// // area.Pixels = nil
|
// // // for _, pixel := range area.Pixels {
|
||||||
// // area.totalR = 0
|
// // // r, g, b, a := img.At(pixel.X, pixel.Y).RGBA()
|
||||||
// // area.totalG = 0
|
// // // surroundingArea.Add(pixel.X, pixel.Y, r, g, b, a)
|
||||||
// // area.totalB = 0
|
// // // }
|
||||||
// // area.totalA = 0
|
|
||||||
// // }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println(noiseCount, "noise pixels")
|
// // // // Remove this area
|
||||||
|
// // // area.Pixels = nil
|
||||||
|
// // // area.totalR = 0
|
||||||
|
// // // area.totalG = 0
|
||||||
|
// // // area.totalB = 0
|
||||||
|
// // // area.totalA = 0
|
||||||
|
// // // }
|
||||||
|
// // }
|
||||||
|
// }
|
||||||
|
|
||||||
pixelCount := 0
|
// fmt.Println(noiseCount, "noise pixels")
|
||||||
|
|
||||||
for _, area := range areas {
|
// pixelCount := 0
|
||||||
pixelCount += len(area.Pixels)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println(pixelCount, "pixels", width*height)
|
// for _, area := range areas {
|
||||||
|
// pixelCount += len(area.Pixels)
|
||||||
|
// }
|
||||||
|
|
||||||
// Build image from areas
|
// fmt.Println(pixelCount, "pixels", width*height)
|
||||||
for _, area := range areas {
|
|
||||||
avgColor := area.AverageColor()
|
|
||||||
|
|
||||||
for _, pixel := range area.Pixels {
|
// // Build image from areas
|
||||||
clone.Set(pixel.X, pixel.Y, avgColor)
|
// for _, area := range areas {
|
||||||
}
|
// avgColor := area.AverageColor()
|
||||||
}
|
|
||||||
|
|
||||||
return clone
|
// for _, pixel := range area.Pixels {
|
||||||
}
|
// clone.Set(pixel.X, pixel.Y, avgColor)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return clone
|
||||||
|
// }
|
||||||
|
Loading…
Reference in New Issue
Block a user