Previous Entry Share Next Entry
Сканер и фотошоп подложили новую свинью
ook
nabbla1
Вот "сырой скан":
grayscale0001.png
сделанный на сканере OpticBook 3800 с настройкой гаммы 2.2 (по умолчанию такая и стоит).

Его гистограмма при открытии в фотошопе:
LyingHist.png
Хорошая такая гистограмма, гладкая.

Но тут я наконец-то решил поиграться со способами преобразования изображений в 1-битный ч/б, чтобы текст хорошо пропечатывался, а фон стал бы белым, и всё на полном автомате, и там чуть ли не первое, что нужно сделать - построить гистограмму, после чего, к примеру, найти самый левый и самый правый пики и провести порог ровно посерёдке. Так вот, у меня гистограмма вышла такой:
RealHist.png

Отдельные пики и множество провалов - как же так!?


Перепроверил свою библиотеку - да, она показывает именно "сырые" значения пикселей без всяческих профилей и гамм, ровно те, что туда положил сканер. У фотошопа, как я помню, тоже должны были отображаться именно "сырые" значения, так что же за нафиг?

Начал я щелкать в фотошопе на всё, что щелкается, в том числе на значок "обновить" справа сверху гистограммы. Чисто от безысходности, ведь зачем обновлять, если я только-только загрузил файл. Тем не менее, вот что получилось:

RealPhotoshopHist.png

Нифига себе обновил!

Навел курсор на этот значок "обновить", там всплыла подсказка - Uncached refresh. Полез искать, что это значит, оказалось: по умолчанию фотошоп строит гистограмму не от исходного здоровенного изображения, а от уменьшенной копии - кэша, с которой он проделывает все операции во время пред. просмотра и которую он отображает на экране. А уменьшает он её довольно качественно, с усреднением пикселей, из-за чего различных значений серого становится больше, чем было в оригинале.

Ну а такие пики на оригинале - это явный признак, что сканер присылает на компьютер линейные 8-битные отсчеты, и лишь после этого на стороне драйвера выполняется гамма-коррекция, "растягивающая" область малых яркостей, тупо заменяя val на gamma[val]. Поскольку исходных отсчетов всего 256, как и преобразованных, то при растяжении образуются прорехи, их-то мы и видим.

Отсюда мораль:
1. Уважающая себя программа для сканирования тоже должна показывать реальную гистограмму (я обязательно её встрою в свой CaesarScan), и если там начинаются такие чудеса, то нужно гамму поставить в 1, да и в регулировке яркости и контрастности тоже смысла нет - всё это делает драйвер и делает ничуть не лучше любой другой программы - он принимает те же самые линейные 8 бит... Только вот если у нас есть "сырые сканы", то мы можем поиграться по-всякому, а если драйвер решил самостоятельно всё настроить, то отменить его действия невозможно, преобразование необратимо.

2. Вот не зря мне хотелось заполучить со сканера 16 бит Grayscale или 48 бит RGB! Да, наверное сколько-нибудь хороший фотографический сканер и 8 бит даст качественные, но вот линейные 8 бит - это маловато будет! Причем ладно бы если Mustek так сделал, на него я давно махнул рукой, самый дешевый сканер A3, что с него возьмёшь... У него даже ручка переноски отвалилась, пока я его тащил. Но от Plustek'а не ожидал такого - весьма серьёзная вещь должна была быть...

3. Впрочем, один недостаток сканера компенсируется другим его недостатком - довольно сильные шумы изображения производят естественный dithering, да и запас по разрешению имеется, благодаря чему сканы всё-таки получаются неплохие.

  • 1
Левая колонка - яркость пикселя (0-черный, 255-белый), в правой - количество пикселей в изображении, имеющие такую яркость.

Да, исходное "линейное" значение X заменяется на (X/255)^(1/2.2) * 255, т.е 0 остаётся нулём, 255 остаётся 255, но вместо линейного отклика у нас квадратичный, даже чуть сильнее. Проверяем: (1/255)^(1/2.2) * 255 = 20,54. Всё верно: ноль остаётся нулём, 1 превращается в 21, 2 превращается в 28, в этой части значения расползаются, зато на больших яркостях, напротив, сливаются воедино.

А зачем такое преобразование? Понятно, что оно и раздвигает палки, ведь ему нечего вставить в промежутки.

Преобразование - чтобы к стандартному представлению прийти. Почти всегда, когда кодируется цвет, будь то градации серого или RGB, там отклик нелинейный. 0 означает черный, 255 - белый, а 128 - внезапно не 1/2 яркости, а почти что 1/4. Во времена ЭЛТ-мониторов это удобно было тем, что такой сигнал можно усилить и подавать между катодом и модулятором трубки и получить наконец-то линейный отклик по току и соотв. по яркости. Потом подумали было - давайте к линейному представлению перейдём, но оказалось - тогда 8 бит будет мало, человек отчетливо видит отдельные градации на малой яркости, нужно 10, а лучше 12 бит! А при нелинейном отображении вполне хватало и 8 бит - там малые яркости с меньшим шагом идут, чем большие, что соответствует человеческому восприятию - если у нас было 0 люкс, а стало вдруг 1, это очень заметно. А если было 99, а стало 100 - вообще не заметим ничего!

Вот и оказалось - у сканера АЦП линейный, даёт он всего 8 бит, а потом только делает гамма-преобразование. Правильно было бы иметь на входе не 8 бит, а те самые 10-12 бит, тогда никаких промежутков не было бы.

  • 1
?

Log in