Как я могу получить 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, и в зависимости от программного обеспечения, используемого для декодирования изображения, профиль может применяться или не применяться при просмотре необработанных данных пикселей.

Другие вопросы по тегам