L'éditeur php Yuzai a souligné que le flou gaussien est une technologie de traitement d'image courante qui peut rendre les images floues et est souvent utilisée pour embellir des photos ou obtenir des effets spéciaux. Cependant, si l’algorithme de flou gaussien n’est pas implémenté correctement, il peut produire un résultat étrange. Cela peut inclure des problèmes tels qu'une distorsion de l'image, des bords flous ou des changements de couleur. Par conséquent, lors de l’utilisation de la technologie du flou gaussien, il faut prêter attention à la mise en œuvre correcte de l’algorithme pour garantir l’effet de sortie attendu.
J'essaie d'implémenter le flou gaussien sur des objets Golang image.image
. Pour les images suivantes :
L'image de sortie générée est :
Comme on peut le voir, l'image de sortie contient des limites non traitées qui correspondent à la décision actuelle d'implémentation de ne pas traiter les bords, ce qui me fait penser que j'ai peut-être gâché le calcul d'une manière ou d'une autre (je veux dire, cette partie de l'implémentation fonctionne afin que je puisse supprimer l'erreur une par une lors de l'itération sur les pixels de l'image). J'ai vérifié ce code plusieurs fois mais je ne trouve pas mon erreur. J'apprécierais vraiment de l'aide et de la considération sur la mise en œuvre, ce qui pourrait m'aider à résoudre mon problème. Le code est inclus ci-dessous. Si des modifications ou des clarifications sont nécessaires, faites-le-moi savoir !
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; }
Modifier
rgbaimg
applygaussianfunction
函数注释了 efactor
,因为我已经使用 sum
variables.set
modifiée pour utiliser la structure rgba 64 bitsVoici l'image nouvellement générée
Ces bordures noires sont faciles à corriger, je suis déjà en train de les réparer. Cela ne fait plus partie du problème.
Vous lisez à partir de la même image sur laquelle vous écrivez. Vous devriez lire à partir de l'image originale :
pr, pg, pb, pa := img.at(x+j, y+i).rgba()
Éditeur :
De plus, 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)});
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!