我如何让golang读取jpeg并获得与Python/C相同的unit8值?



我有一个测试jpeg,我正在使用一些图像处理代码&我试图获得与python中的opencv和C以及python中的Pillow(通过scipy)相同的uint8值数组,这些值都与我使用gimp打开jpeg时获得的值相匹配。

我尝试将颜色值移动8位,但这并不能准确地转换值-看起来好像有一些我不太理解的舍入。我知道gimp和opencv和Pillow/scipy都使用libjpeg,所以我尝试使用https://github.com/pixiv/go-libjpeg并使用

将图像转换为8位
func Convert(img image.Image) *image.RGBA {
   b := img.Bounds()
    rgba := image.NewRGBA(b)
    for y := b.Min.Y; y < b.Max.Y; y++ {
        for x := b.Min.X; x < b.Max.X; x++ {
            r32, g32, b32, _ := img.At(x, y).RGBA()
            c := color.RGBA{uint8(r32>>8), uint8(g32>>8), uint8(b32>>8), 255}
            rgba.SetRGBA(x, y, c)
        }
    }
    return rgba
}

,但这仍然不匹配。我怎样才能得到同样的结果?

JPEG规范没有对解码器的像素精确定义,因此不同的实现将有略微不同的输出。甚至libjpeg本身也有4种不同的离散余弦变换实现,使用整数或浮点数学。

至于你的代码,如果img已经是image.RGBA,那么这些值都存储为uint8,你只是来回移动比特,什么都不做。如果图像是image.YCbCr,那么还依赖于颜色转换算法,并且YCbCr.RGBA()方法与color.YCbCrToRGB函数略有不同。前者试图保持更高的精度,您需要正确地四舍五入值,而不是通过简单的右移截断它们。后者更接近规范建议,但不使用浮点常量,这可能与其他实现有所不同。

最后,图像本身可能有一个嵌入的ICC配置文件,并且根据用于解码图像的软件,在查看原始像素数据时可能已经或可能没有应用该配置文件。

最新更新