в двух словах: я не могу извлечь значимые значения интенсивности света из значений RGB из фотографий JPEG, и попытка учесть гамма-коррекцию или sRGB только ухудшает ситуацию.
Я занимаюсь игрушечным проектом, который включает обработку множества фотоизображений, снятых с помощью интервометра. По сути, я хочу сделать из них промежуток времени с некоторыми исправлениями, чтобы клипы были более аккуратными. Я использую Canon dSLR.
Мне нужна функция, которая, учитывая файл JPEG, вычисляет «среднюю яркость сцены». Результат должен быть простым числом; Не нужно выражать какие-либо абсолютные фотометрические единицы, я делаю только относительные сравнения. Так, например, вы делаете снимок какой-то комнаты, и функция возвращает, скажем, «5.0». Затем вы добавляете вторую лампочку к источнику, точно такого же типа, как и первая, расположенную рядом с ней, и снова снимаете. Функция должна теперь дать вам «10.0».
Итак, моя текущая реализация этой функции сочетает в себе несколько вещей: чувствительность ISO, выдержку, диафрагму (извлеченную из EXIF) и среднюю яркость изображения. Материал Exif, очевидно, важнее, потому что в автоматических режимах камера будет пытаться использовать такие-то и такие-то настройки, поэтому яркость изображения приближается к средней серой точке.
Тем не менее, все настройки ISO / Затвора / Апертуры имеют разрешение 1/3 ступени или меньше, поэтому определение яркости изображения важно для «тонкой настройки».
Пока я делал это, я получал некоторые явно фиктивные результаты, и чем больше я копался, тем больше удивлялся. В итоге я поставил «почти серьезный» эксперимент:
Тестовая настройка:
Простая стена в комнате, освещенная лампой накаливания, освещенность довольно ровная.
Для сравнения результатов использовали две камеры: 5D с 50-миллиметровым основным, 350D с 35-миллиметровым основным.
Расстояние до стены: около 3 метров.
Все фотографии сняты с выдержкой 1/10 с.
Настройки камеры: ручной, «точный режим» (без улучшений, без насыщенности или контрастности), Tungsten WB, без пользовательских функций, JPEG-Fine, цветовое пространство sRGB. Линзы не имеют фильтров. Подсветка не меняется, меняются только настройки ISO и диафрагмы.
Вот результаты, которые я получил:
Avg Spd ISO Aperture
1. 0.3507, 0.10, 100, f/2.8
2. 0.5382, 0.10, 200, f/2.8
3. 0.3557, 0.10, 200, f/4.0
4. 0.2709, 0.10, 200, f/5.0
5. 0.2118, 0.10, 200, f/5.6
6. 0.1718, 0.10, 200, f/6.3
7. 0.1459, 0.10, 200, f/7.1
8. 0.1112, 0.10, 200, f/8.0
9. 0.0883, 0.10, 200, f/9.0
Первый столбец - это среднее значение пикселя (прямо из JPEG), усредненное по всему изображению, с преобразованием в оттенки серого как (R + G + B) / 3. Цвета нормализуются в диапазоне [0..1] путем деления диапазона [0..255] на 255.
Таким образом, между 1) и 2) я только меняю настройки ISO, изображение должно стать в два раза ярче, но среднее значение пикселя увеличивается только на 53% (переэкспонированных областей нет).
2..3: диафрагма на одну ступень вниз, поэтому изображение должно стать наполовину менее ярким, поэтому 1) и 3) согласуются (дополнительная яркость, вероятно, связана с уменьшением виньетирования)
3..5: Опять же, один стоп вниз, 5) должен быть наполовину таким же ярким, как 3)
5..8: То же самое, должно быть наполовину (хотя в принципе это нормально).
Все это очень, очень странно. Кстати, результаты между двумя камерами согласуются, что позволяет предположить, что это не просто особенность конкретной модели.
Это без применения гамма-коррекции. Код для чтения JPEG написан на C ++ и в основном соответствует примеру кода IJG (утилита djpeg
). Теперь JPEG сохраняет значения с гамма-коррекцией, поэтому значения пикселей следует рассматривать как значения в цветовом пространстве sRGB (получить исходные пиксели, преобразовать в [0..1] и применить sRGB-> линейное преобразование RGB . Давайте попробуем это:
Avg Spd ISO Aperture
1. 0.1140, 0.10, 100, f/2.8
2. 0.2746, 0.10, 200, f/2.8
3. 0.1175, 0.10, 200, f/4.0
4. 0.0682, 0.10, 200, f/5.0
5. 0.0424, 0.10, 200, f/5.6
6. 0.0287, 0.10, 200, f/6.3
7. 0.0213, 0.10, 200, f/7.1
8. 0.0133, 0.10, 200, f/8.0
9. 0.0092, 0.10, 200, f/9.0
Я также попробовал «простую» гамма-коррекцию (гамма = 2,2), результаты очень похожи на случай коррекции sRGB.
Так что я очень, очень озадачен.
Может кто-нибудь объяснить, как интенсивность RGB от JPEG с камеры должна действительно интерпретироваться как, так как у меня нет идей:)