php-Redakteur Yuzai wies darauf hin, dass die Gaußsche Unschärfe eine gängige Bildverarbeitungstechnik ist, die Bilder verwischen kann und häufig zum Verschönern von Fotos oder zum Erzielen von Spezialeffekten verwendet wird. Wenn der Gaußsche Unschärfealgorithmus jedoch nicht korrekt implementiert wird, kann es zu seltsamen Ergebnissen kommen. Dazu können Probleme wie Bildverzerrungen, unscharfe Kanten oder Farbverschiebungen gehören. Daher muss bei der Verwendung der Gaußschen Unschärfetechnologie auf die korrekte Implementierung des Algorithmus geachtet werden, um den erwarteten Ausgabeeffekt sicherzustellen.
Ich versuche, Gaußsche Unschärfe auf Golang-Objekten zu implementieren. Für die folgenden Bilder: image.image
Wie man sehen kann, enthält das Ausgabebild einige unverarbeitete Grenzen, die der aktuellen Implementierungsentscheidung entsprechen, Kanten nicht zu verarbeiten, was mich denken lässt, dass ich die Berechnung irgendwie durcheinander gebracht habe (ich meine, dieser Teil der Implementierung funktioniert). sodass ich den einzelnen Fehler beim Durchlaufen von Bildpixeln verwerfen kann. Ich habe diesen Code mehrmals überprüft, kann meinen Fehler jedoch nicht finden. Ich würde mich sehr über Hilfe und Überlegungen bei der Implementierung freuen, die mir bei der Lösung meines Problems helfen könnten. Der Code ist unten enthalten. Wenn Änderungen oder Klarstellungen erforderlich sind, lassen Sie es mich bitte wissen!
package main import ( "image" "image/color" "image/draw" "image/jpeg" "math" "os" ) func main() { f, err := os.Open("dog.jpeg") if err != nil { panic(err) } img, err := jpeg.Decode(f) if err != nil { panic(err) } newImg := gaussianBlur(img, 3) out, err := os.Create("dog-blurred.jpeg") if err != nil { panic(err) } err = jpeg.Encode(out, newImg, nil) if err != nil { panic(err) } } func applyGaussianFunction(x, y, stdDev float64) float64 { // eFactor := 1 / (2 * math.Pi * stdDev*stdDev); ePowNominator := -(x*x + y*y); ePowDenominator := 2 * stdDev*stdDev; return math.Pow(math.E, (ePowNominator/ePowDenominator)); } func generateKernel(radius int) [][]float64 { size := 1 + (radius * 2); kernel := make([][]float64, size); stdDev := math.Max(float64(radius / 2), 1); sum := float64(0); for i := 0; i < size; i++ { kernel[i] = make([]float64, size); } for i := -radius; i < radius + 1; i++ { for j := -radius; j < radius + 1; j++ { val := applyGaussianFunction(float64(j), float64(i), stdDev); kernel[i + radius][j + radius] = val; sum += val; } } for i := 0; i < size; i++ { for j := 0; j < size; j++ { kernel[i][j] /= sum; } } return kernel; } func makeImageRGBA(src image.Image) *image.RGBA { b := src.Bounds().Size(); rgba := image.NewRGBA(image.Rect(0, 0, b.X, b.Y)); draw.Draw(rgba, rgba.Bounds(), src, image.Pt(0, 0), draw.Src); return rgba; } func gaussianBlur(img image.Image, radius int) image.Image { size := img.Bounds().Size(); rgbaImg := image.NewRGBA(image.Rect(0, 0, size.X, size.Y)); kernel := generateKernel(radius); for y := radius; y < size.Y - radius; y++ { for x := radius; x < size.X - radius; x++ { var nr, ng, nb, na float64 = 0, 0, 0, 0; for i := -radius; i < radius + 1; i++ { for j := -radius; j < radius + 1; j++ { // NEW: Get pixels from original Image pr, pg, pb, pa := img.At(x - j, y - i).RGBA(); nr += float64(pr) * kernel[i + radius][j + radius]; ng += float64(pg) * kernel[i + radius][j + radius]; nb += float64(pb) * kernel[i + radius][j + radius]; na += float64(pa) * kernel[i + radius][j + radius]; } } // Handle overflow by using 64-bit alphapremultiplied values rgbaImg.Set(x, y, color.RGBA64{uint16(nr), uint16(ng), uint16(nb), uint16(na)}); } } return rgbaImg; }
Bearbeiten
rgbaimg
liest
applygaussianfunction
函数注释了 efactor
,因为我已经使用 sum
normalisiert
.set
Diese schwarzen Ränder lassen sich leicht reparieren, ich bin bereits dabei, sie zu reparieren. Das ist nicht mehr Teil des Problems. WorkaroundSie lesen aus demselben Bild, an das Sie schreiben. Sie sollten vom Originalbild lesen:
pr, pg, pb, pa := img.at(x+j, y+i).rgba()
Herausgeber:
Außerdem : image.at
返回 color.rgba
,而 func (color.rgba) rgba
返回0 到 0xffff 范围。然而 color.rgba
构造函数期望它们在 0 到 255 范围内。在写入结果时,您可能需要使用 color.rgba64
rgbaImg.Set(x, y, color.RGBA64{uint16(nr), uint16(ng), uint16(nb), uint16(na)});
Das obige ist der detaillierte Inhalt vonDie Implementierung der Gaußschen Unschärfe führt zu einer seltsamen Ausgabe. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!