Как я могу получить golang read jpegs и получить те же значения unit8, что и в Python/C?
У меня есть тестовый JPEG, который я использую для некоторого кода обработки изображений, и я пытаюсь получить тот же массив значений uint8, что и opencv в Python и C и Pillow (через scipy) в Python, которые все соответствуют значениям, которые я получаю, когда Я открываю JPEG с помощью GIMP.
Я пытался сместить значения цвета на 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
}
но это все равно не совпадает. Как я могу получить те же результаты?
1 ответ
Спецификация JPEG не имеет точного определения пикселя для декодера, поэтому у разных реализаций будет немного различный вывод. Даже сам по себе libjpeg имеет 4 различных реализации дискретного косинусного преобразования с использованием математики целых чисел или чисел с плавающей запятой.
Что касается вашего кода, если img
уже image.RGBA
все значения сохраняются как uint8
и вы просто перемещаете биты назад и вперед, ничего не делая. Если изображение image.YCbCr
то вы также зависите от алгоритма преобразования цвета и YCbCr.RGBA()
метод немного отличается от color.YCbCrToRGB
функция. Первый пытается сохранить большую точность, и вам нужно правильно округлять значения, а не обрезать их простым сдвигом вправо. Последнее ближе к спецификации спецификации, но не использует константы с плавающей запятой, которые также могут отличаться от других реализаций.
Наконец, само изображение может иметь встроенный профиль ICC, и в зависимости от программного обеспечения, используемого для декодирования изображения, профиль может применяться или не применяться при просмотре необработанных данных пикселей.