在Golang中的卷积操作

huangapple go评论83阅读模式
英文:

Convolution in Golang

问题

我想在一张图像上执行卷积运算。

原始图像如下:

在Golang中的卷积操作

所以我用GIMP测试了卷积运算。使用以下矩阵:

1 1 1

1 1 1

1 1 1

和除数9

我得到了以下结果:

在Golang中的卷积操作

当我执行我的算法时,得到了以下结果:

在Golang中的卷积操作

我的算法是:

func Convolution(img *image.Image, matrice [][]int) *image.NRGBA {
    imageRGBA := image.NewNRGBA((*img).Bounds())
    w := (*img).Bounds().Dx()
    h := (*img).Bounds().Dy()
    sumR := 0
    sumB := 0
    sumG := 0
    var r uint32
    var g uint32
    var b uint32
    for y := 0; y < h; y++ {
        for x := 0; x < w; x++ {

            for i := -1; i <= 1; i++ {
                for j := -1; j <= 1; j++ {

                    var imageX int
                    var imageY int

                    imageX = x + i
                    imageY = y + j
                
                    r, g, b, _ = (*img).At(imageX, imageY).RGBA()
                    sumG = (sumG + (int(g) * matrice[i+1][j+1]))
                    sumR = (sumR + (int(r) * matrice[i+1][j+1]))
                    sumB = (sumB + (int(b) * matrice[i+1][j+1]))
                }
            }

            imageRGBA.Set(x, y, color.NRGBA{
                uint8(min(sumR/9, 255)),
                uint8(min(sumG/9, 255)),
                uint8(min(sumB/9, 255)),
                255,
            })

            sumR = 0
            sumB = 0
            sumG = 0

        }
    }

    return imageRGBA

}

哪里出错了?
谢谢你的帮助。

英文:

I want execute a convolution product on an image.

The original image is:

在Golang中的卷积操作

So I test the convolution with gimp. With this matrix:

1 1 1

1 1 1

1 1 1

and the divider 9

I obtain

在Golang中的卷积操作

When I execute my algorithm I obtain:

在Golang中的卷积操作

My algorithm is:

func Convolution(img *image.Image, matrice [][]int) *image.NRGBA {
	imageRGBA := image.NewNRGBA((*img).Bounds())
	w := (*img).Bounds().Dx()
	h := (*img).Bounds().Dy()
	sumR := 0
	sumB := 0
	sumG := 0
	var r uint32
	var g uint32
	var b uint32
	for y := 0; y &lt; h; y++ {
		for x := 0; x &lt; w; x++ {

			for i := -1; i &lt;= 1; i++ {
				for j := -1; j &lt;= 1; j++ {

					var imageX int
					var imageY int

					imageX = x + i
					imageY = y + j
				
					r, g, b, _ = (*img).At(imageX, imageY).RGBA()
					sumG = (sumG + (int(g) * matrice[i+1][j+1]))
					sumR = (sumR + (int(r) * matrice[i+1][j+1]))
					sumB = (sumB + (int(b) * matrice[i+1][j+1]))
				}
			}

			imageRGBA.Set(x, y, color.NRGBA{
				uint8(min(sumR/9, 255)),
				uint8(min(sumG/9, 255)),
				uint8(min(sumB/9, 255)),
				255,
			})

			sumR = 0
			sumB = 0
			sumG = 0

		}
	}

	return imageRGBA

}

Where are the error ?
Thank you for your help.

答案1

得分: 2

rgbuint32类型的值,它们包含16位的颜色信息,如果以非零的8位值开始,它们的值总是大于255。

因此,你不能对RGBA值进行操作并将它们截断为uint8类型,因为这样会得到一个无用的结果,因为最低有效位只是8位值的小数部分。

将候选整数值与最大的16位值65535进行比较,并在截断之前将其向左移动8位,以获取8个最高有效位。

uint8(min(sumR/9, 0xffff) >> 8),
uint8(min(sumG/9, 0xffff) >> 8),
uint8(min(sumB/9, 0xffff) >> 8),
英文:

r, g, and b are uint32 values, and they contain 16bits of color information which is always greater than 255 if started as a non-zero 8 bit value.

You then can't operate on the RGBA values and truncate them to a uint8; that gives you a useless result because the least significant bits are just fractional parts of the 8bit values.

Compare the candidate integer value with the max 16bit value 65535, and shift it 8 bits before truncating it to get the 8 most significant bits.

uint8(min(sumR/9, 0xffff) &gt;&gt; 8),
uint8(min(sumG/9, 0xffff) &gt;&gt; 8),
uint8(min(sumB/9, 0xffff) &gt;&gt; 8),

huangapple
  • 本文由 发表于 2017年3月9日 00:50:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/42677196.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定