Rumah > Artikel > pembangunan bahagian belakang > Pelaksanaan kabur Gaussian menghasilkan output pelik
editor php Yuzai menegaskan bahawa Gaussian blur ialah teknik pemprosesan imej biasa yang boleh mengaburkan imej dan sering digunakan untuk mencantikkan foto atau mencapai kesan khas. Walau bagaimanapun, jika algoritma kabur Gaussian tidak dilaksanakan dengan betul, ia boleh menghasilkan output yang pelik. Ini mungkin termasuk isu seperti herotan imej, tepi kabur atau peralihan warna. Oleh itu, apabila menggunakan teknologi kabur Gaussian, perhatian mesti diberikan kepada pelaksanaan algoritma yang betul untuk memastikan kesan output yang dijangkakan.
Saya cuba melaksanakan Gaussian blur pada objek golang image.image
. Untuk gambar berikut:
Imej keluaran yang dihasilkan ialah:
Seperti yang dapat dilihat, imej output mengandungi beberapa sempadan yang tidak diproses yang sepadan dengan keputusan pelaksanaan semasa untuk tidak memproses tepi, yang membuatkan saya berfikir bahawa saya mungkin telah mengacaukan pengiraan dalam beberapa cara (maksud saya, Bahagian pelaksanaan ini berfungsi jadi saya boleh membuang ralat satu demi satu apabila melelaran pada piksel imej). Saya telah menyemak kod ini beberapa kali tetapi saya tidak menemui ralat saya. Saya amat menghargai bantuan dan pertimbangan mengenai pelaksanaan, yang boleh membantu saya menyelesaikan masalah saya. Kod disertakan di bawah. Jika sebarang suntingan atau penjelasan diperlukan, sila beritahu saya!
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; }
Edit
rgbaimg
applygaussianfunction
函数注释了 efactor
,因为我已经使用 sum
pembolehubah.set
kaedah untuk menggunakan struktur rgba 64-bitIni ialah imej yang baru dijana
Sempadan hitam itu mudah dibaiki, saya sudah membetulkannya. Ini bukan lagi sebahagian daripada masalah.
Anda membaca dari imej yang sama yang anda tulis. Anda harus membaca dari imej asal:
pr, pg, pb, pa := img.at(x+j, y+i).rgba()
Editor:
Selain itu, 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)});
Atas ialah kandungan terperinci Pelaksanaan kabur Gaussian menghasilkan output pelik. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!