О высоких ISO и о дырках: Sony A77

Возьмем, к примеру, Sony A77. Самой камеры у меня нету, поэтому возьмем самплы с Imaging Resource. Я взял те, где есть большое серое поле (как на картинке в заставке этого поста) для разных ISO: 50, 100, 800, 1600, 6400, 16000.

А дальше выберем кусочек на сером поле размером, скажем, 450x200 пикселов и построим по нему гистограмму. Прямо вот по RAW-данным.

И вот что получается:

ISO 100

Это - обычная гистограмма. По горизонтальной оси - значения пикселов, по вертикальной - их количество.

Вертикальная палочка EV0 проведена довольно волюнтаристски: уровень белого имеет значения в зеленом канале в райне 1700-1750, ну значит проведем "уровень серого" на уровне в 7 раз ниже, как раз будет 14% от серого. Это только для ориентировки.

Второй зеленый канал не показан ибо от первого он ничем не отличается.

Мы видим "дырки в гистограмме", что свидетельствует о том, что сигнал подвергался какой-то обработке в целых числах, на что-то некратное 2.0 поделили или умножили. Если посмотреть на гистограмму всего кадра, видно что дырки проходят по уровням 8,23, 38, 53, 68... т.е. через 15. Я поподбирал, похоже на умножение на 1.0667 по всем каналам одинаково, но тут легко ошибиться. Возможно, конечно, что базовое ISO у камеры - в районе 93, а чтобы получить 100 - данные с АЦП домножают, но думать так я не хочу.

В остальном же - нормальная такая гистограмма.

ISO 50

Как видим, все значения сместились примерно на 0.7 стопа, максимум в зеленом был на 390, стал на 635, в остальных каналах - аналогичный сдвиг.

Таким образом, ISO50 - это на 0.7 стопа - передержка, а еще на 0.3 стопа - не знаю что, но скорее всего не умножение на другую константу, ибо дырки в гистограмме - в тех же местах и с тем же шагом. Возможно, это регулируется аналоговым усилением до АЦП, о чем мы поговорим ниже.

ISO800

Среднее вернулось туда же, где было на ISO100, дырки там же, за счет шума колокола на гистограммах стали пошире, отчего дырок мы видим больше.

ISO 1600

На ISO 1600 начинаются чудеса (картинка не влезает, поэтому в посте уменьшенная, а чудеса в полный размер открываются по клику):
Чудеса заключаются в том, что не хватает более чем трети уровней. Скажем, в диапазоне 128-149 из 22 уровней реально имеются 14.

ISO 6400

По клику откроется полноразмер:
Вакханалия продолжается. В диапазоне 100-149 вместо 50 уровней имеем только 16. Грабят!

ISO 16000

Вообще, мы на весь стоп от EV-1 до EV0 (от 128 до 255 включительно) видим 8 пиков. Вместо 128 "полноценных" уровней, которые там имеются на низких ISO.

Обсуждение результатов

Изначально я был сторонником той идеи, что высокие ISO получаются на этой камере цифровым способом, домножением на какую-то константу. Допустим, самое высокое "настоящее" ISO в камере - 1000 (как нам пишут в форумах dpreview), тогда ISO 16000 получается умножением "настоящих" данных на 16 и мы получим ряд значений 0,16,32,48,64,80 и так далее. Но эти пики будут единичной ширины, тогда как мы видим пики шириной 3-5 значений.

Более разумное объяснение - это наличие малошумящего усилителя перед АЦП.

Чудес не бывает: если мы на ISO100 заполняем колодец полностью и емкость колодца, скажем, 20000 электронов (цифра примерная, исходя из того что у 20Mpix full-frame - 60-80k электронов), то при экспозиции в 160 раз меньше (ISO 16000) у нас полному диапазону соответствует 125 электронов, а уровню EV-1 - в 16 раз (минус 4 стопа) меньше т.е. 8 электронов. Усилив их в 16 раз мы и получим уровни в районе 128, а за счет шума усилителя - пики не единичной ширины.

Таким образом, ожидать каких-то чудес от камеры со схожим объемом пикселя (в электронах) - невозможно, неоткуда им взяться. Улучшение может быть только от увеличения площади пикселя, тогда при той же экспозиции (и близкой квантовой эффективности) образуется бОльшее количество электронов и их можно будет усиливать в меньшее число раз.

При этом, обсуждая новые камеры Sony, необходимо помнить, что dcraw/LibRaw (при построении гистограмм использовалась вторая) распаковывают RAW по следующей процедуре:

value = table[value_from_raw << 1] >> 2;
Таблицу мы уже обсуждали, а вот деление результата на 4 (сдвиг на 2) - еще нет. За счет этого деления у Sony получается "почти 12-битный" выходной диапазон (максимальное значение в таблице - 17220, после деления/сдвига будет 4305), что может вводить в заблуждение при сравнении с камерами других производителей (у Canon серое поле имеет значение ~1000, а у Sony - около 400 в зеленом канале), такое сравнение без поправки на полный диапазон делать бессмысленно.

В обсуждаемом случае исходные пики на ISO16000 имели, очевидно, бОльшую ширину, не 3-5, а 12-20, а удаление младших двух битов их сузило.

Чешутся руки запатчить LibRaw и это деление на 4 оторвать.

Comments

а кто из производителей по итогам честнее выдаёт картинку на высоких исо?

Нужен FF и пиксель покрупнее. Т.е. мой кандидат - Nikon D3 или Canon 5D (не mark II). Но в эти файлы на этот предмет я не смотрел.

Все же просто - максимальная емкость пикселя достигается на минимальном "честном ISO". Скажем 80к электронов и ISO100 (Canon 5D). Значит на ISO 10000 будет использована 1/100 емкости пикселя т.е. 800 разных значений (количеств электронов)
Из них 400 - на самый верхний стоп, 200 - на следующий, 100 - на диапазон EV0-EV1 (считая EV0 как 3 стопа вниз от насыщения), 50 - на 3-ю зону, EV-1-EV0.

а что не так с mark ii? пикселей больше?
вроде не настолько их и больше.

и, КМК, при прочих равных из матрицы, "побитой" на бОльшее число пикселей, можно вытянуть больше деталей (а понизить разрешение софтово - дело нехитрое).

Ну их практически вдвое больше. Значит, при прочих равных, "глубина колодца" будет вдвое меньше. Равные не равны, поэтому разница там меньше.

У 5D MarkII ситуация "1 электрон на один отсчет АЦП" имеется при ISO400 (впрочем, дробные я не мерял). То есть при ISO6400 1 электрон будет приходиться на 16 отсчетов и будут пики "через 16". В зависимости от способа усиления, или единичной ширины (цифровое умножение или нешумящий вовсе усилитель), или размазанные, как у соньки в этом посте. По ширине, кстати, можно шум усилителя оценить.

EV0 (по экспонометру) у 5D2 - на 3.7 стопа ниже насыщения, грубо - в 12 раз. Т.е. стоп от EV-1 до EV0 - это 500 значений (от 500 до 1000) /все приблизительно/. То есть у вас будет ~30 разных значений в этом стопе, примерно вдвое лучше чем у рассмативаемой соньки (тоже на 6400).

Что касается деталей, то померять то несложно

Возьмите газетку, поставьте высокое ISO, поснимайте с недодержкой и все будет понятно.

я про то, что на мой взгляд называть высокое разрешение злом неправильно - если софтово снизить разрешение скажем в 4 раза (в два по горизонтали и два по вертикали), то мы получим практически ту же картинку, что и на матрице с вчетверо более "крупными" пикселями.

Красные-синие идут через 1, поэтому уменьшая в 2 раза по линейному размеру - того же самого не получишь.

Вместе с тем, я вовсе не называю высокое разрешение злом. У меня много хорошей оптики и я думаю что 40-50-60Mpix для FullFrame было бы в самый раз, оптикой я бы не был ограничен. Ну было бы 1ADU/e не на ISO400, а на 200 или 100 - мне нормально.

Я пишу про *особенности* высоких ISO. Про то, что чудес там никаких нет и банальная недодержка на чувствительности 1ADU/e не будет сильно хуже (с точностью до шумодавов, конечно).

Я как то брал посмотреть PhaseOne IQ180, на сегодня это самый дорогой и высокоразрещающий цифробэк с уникальными характеристиками - 80Мпикс и гигантского размера матрицей в три раза большей чем у "пятерки" :)))).
Так вот у него есть режим Sensor+.
Эврика, подумал я, как раз это иногда и бывает необходимо в работе.
Однако на деле, по просмотру съемки, увеличения полезной светочувствительности даже на ступень, при работе 4х пикселов как один - не обнаружил. Реальное улучшение светочувствительности от его прямого соседа и конкурента не обладающего такими 4хпиксельными технологиями (Aptus 12) - менее ступени.

> Возможно, конечно, что базовое ISO у камеры - в районе 93,

Ну что-то подобное на форумах бормочут:

=== cut ===
From published results it would appear that the peak dynamic range is at an indicated 50 ISO which, when measured, is actually 63 ISO. Of course that's after the SLT mirror, which acts as a very mild ND filter taking about 1/3rd of the light. Correct for that, and the base ISO of the "native" sensor is about 95 ISO, which is what it should be on the NEX-7.
=== cut ===

Но зачем стулья то ломать? Ну оставили бы как есть, ну было бы на 0.1 или сколько там стопов в светах больше.

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

Э. У вас есть, к примеру, 8 электронов. Коэффициент усиления - 16. Усиливаем и шумим....
Ну на самом деле, с учетом деления на 4, 32 электрона, коэффициент усиления 16, результат после АЦП делим на 4.

И, наоборот, не представляю себе математику, которая умножая на 16 ошиблась бы больше чем на единичку :)

А я вот не могу понять зеленый канал на iso 800, значения 375 и выше. Это проблема мишени?

Не-не. Это выступление группы "Несчастный случай" :)

Раскручиваем фарш назад: прибавляем 128 (уровень черного) и умножаем на 4. Получаем 2000 и больше. Это уже область действия нелинейной тоновой кривой

А кривая такая в этом месте:

2000 2000
2001 2002
2002 2004
2003 2006
2004 2008
2005 2010
2006 2012
2007 2014
2008 2016
2009 2018
2010 2020
и так далее....

Ну а дальше - неудачное округление при делении на 4, четных вдвое больше чем нечетных.

Аха. Спасибо.
А на ISO 100 мы на эту кривую просто не попали? Экспозиция другая? Или масштаб графиков разный.
Про нелинейные кривые читал и пока не понимаю, чего здесь больше плюсов или минусов. Это надо набраться желания и времени и эти равы покрутить.

Да по идее - должны были попасть.
Значит на 800 уже неудачное распределение данных. Надо посмотреть до кривой и до деления, а для этого надо LibRaw попатчить :)

Алексей, возможно это оффтопик, но как сейчас сделано SSE и OpenMP в libraw?

С OpenMP, вижу, она дружит.

А вот про __m128, __m128i, и __m128d, через emmintrin.h?

Кроме того. Есть такая штука, как оптимизация деления на константу, http://libdivide.com/ можно ли её включить в библиотеку? Я не слишком большой спец по лицензиям, но, по-моему, она свободная донельзя.

В libraw - SSE никак не сделано.

Алексей, я обещал сделать, и, можно сказать, сделал дебандинг, который с радостью бы включил в libraw

Сейчас из такого изображения

_MG_2391.default.jpg, 5Mb

делает автоматом такое

_MG_2391.debanded.jpg, 5Mb

На вход - четыре порога (по каналам). Делает для камер с бауером 2х2, умеет обрабатывать зелёный как один канал или как два независимых. Обработка идёт до дебауризации.

Сейчас работает не очень быстро (в два-три раза медленнее, чем дебауризация), памяти жрёт - дополнительно x2 относительно размера изображения. Но, всё-таки, это алгоритмы шумоподавления.

Реализовано всё через добавления ряда private функций и одной public, также глобальных переменных (для порогов) и изменения кода dcraw_emu.

В принципе, в будущем можно будет попробовать подружить с OpenMP, ну, а остальные пожелания я уже написал, которые тоже могут повлиять на увеличение скорости.

Ну, за вами слово :-)

Ну так если варианты лицензирования из трех
- triple (libraw)
- gpl2+
- gpl3+
устраивают, так говорите куда включать - и включим. Но это будет в 0.15, которая еще почти не началась.

Лицензия меня не очень волнует. Насколько я понимаю, GPL3+ посвободнее, потому что не даёт возможности писать на неё закрытые прошивки? А GPL2+ даёт право на вообще почти всё? Ну, я не жадный, пусть пишут закрытые прошивки.

Что такое triple?

Меня волнует, как это вообще технически реализовано?

Кроме того, а что с lib divide?

Libraw (основная, а не demosaic packs) лицензируется под тремя лицензиями сразу:
GNU Lesser General Public License, version 2.1
COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
LibRaw Software License
Либо можно влезть в какой-то из demosaic packs (GPL2, GPL3).
Только пожалуйста решите это сами, решить за вас я не могу. Самая строгая к писателям коммерческого софта - GPL3.

А с libdivide все просто - обязательной дополнительной зависимости не будет. Необязательная - пожалуйста.

Пусть будет под той же, что и основная libraw, в конце-концов, там весь код сильно заточен под структуры.

demosaic-pack-и работают с теми же структурами, тут разницы нет.

Но если нет какого-то желания "не дать противным коммерсантам это использовать", то основая LibRaw конечно лучше.

Не, нету такого желания. Есть желание внести некоторые вещи, которых мне весьма не хватает.

Так что с кодом-то делать :-) ?

Идеальный вариант - передать мне через github (т.е. сделать fork LibRaw, сверху налить свои изменения, покоммитить, прислать мне commit request).

Неидеальный вариант - просто прислать мне измененные/добавленные файлы и я их вставлю в.

Всё так и сделал. Проверяйте, пожалуйста.

Пока с lib divide, sse и openMP не стал морочиться, пусть будет хотя бы несколько подтверждений, что оно работает вообще, не вылетает.

Ну и вообще, посмотрите, как будет время. Там масса нерешенных вопросов есть, например, оно не интегрировано в систему статусов о времени.

Ваш fork вижу, pull request - не вижу.

Но так как я в любом случае буду это переделывать, вынося в отдельный исходник - пусть оно так и останется, я его всосу в 0.15 (которую тогда стартую прямо на днях) и творчески переработаю.

Чего мне не хватает для полноты счастья, это нормального "copyright message" копирайта для этого отдельного исходника. Так как он все едино станет известным (т.к. будет прямо там написан), то можно прямо тут ответить. Вот прямо что писать
"Copyright 2011 by ....."

А SSE и прочие OpenMP вставим потом по месту, пусть действительно сначала поработает.

"Copyright 2011 by Yan Vladimirovich"

Про творческую переработку - там комментарии нужно дать какие-то по ходу кода, что для чего ну и как вообще работает?

Как сделать pull request? Вот https://github.com/LibRaw/LibRaw/pulls вижу, ну и что тут жать, и зачем оно надо вообще?

Мне комментарии не нужны, от них только путаница обычно.

Про pull request не знаю, я их получаю. Как слать - написано тут: http://help.github.com/send-pull-requests/ и результаты этой работы обычно удобны для меня.

Но в данном случае я буду руками все делать.

Ок :-)

Ну, не слишком уж творчески перерабатывайте, чтобы там не всё полетело :-)

Да, а есть способ в VS получать код проекта простой c github?

Да я пальцем там не трону логику. Просто в отдельные файлы это вынесу и все.

Под win32 я пользуюсь msys-git А другого под винды вроде и нету.

Всосал в 0.15-unstable: https://github.com/LibRaw/LibRaw/tree/0.15-unstable
Файлс с собственно кодом - в internal/wf_filtering.cpp

При этом производимое вашим кодом (я попробовал -dbnd 100 100 100 100) и тем что я всосал - отличается бинарно (побитово), но не отличается визуально. Я пока забил т.к. визуальной разницы нет. Подозреваю

Всосать git-ом так:
git clone git://github.com/LibRaw/LibRaw.git
cd LibRaw
git checkout origin/0.15-unstable

Ну или склонировать к себе, а дальше как нравится.

Ваши изменения в dcb я не импортировал, все едино надо у автора свежую версию брать.

На каком файле пробовали?

Я сейчас как раз собираю файлы со сложными случаями, чтобы делал лучше, или, как минимум, не делал хуже.

Про WTF - ну, блин :-)

Файл - первый попавшийся (c 1D Mk 3 кажется). Бандинга там нету, 100(X4) его, наоборот, сделали. Мне было важно, что ваш неизмененный код и мой импортированный сделал визуально одно и то же

(побитовая разница может быть за счет того, что код вычитания черного с 14.0 которая у вас по 14.3 - немного менялся кажется)

Ну, я не понял зачем "100 100 100 100"

Кстати, я делаю дебандинг ДО вычитания черного (это важно!).

100x4 - просто чтобы попробовать.

А что вы делаете debanding до вычитания черного - это вам так кажется. Вычитание черного делает raw2image_ex, в той версии что вы правили - тоже.

Причем, влезть в это место просто - нельзя, сейчас копирование (из загашника) и вычитание черного - делаются одним проходом.

Я правил dcraw_emu

и мой код до вычитания черного был. По крайней мере, я специально всё проверял, 1023, что-ли, средний уровень был по черному.

dcraw_emu использует все едино dcraw_process() в который вы встроились.

Ну и?

Еще раз, я же пока писал - отлаживал кучу раз. Или рисовал "вымышленные данные для отладки", ну, фейковый raw, который потом "проявлял"

И неплохо помню, что уровень черного был не 0.

Теперь не так?

Это "теперь" наступило в июле.

Бля! ПРостите.

Но оно же работать будет реально хуже. Зачем? Я вообще считаю, что уровень черного нужно вычитать после дебауризации.

В смысле "хуже"?
Оно выдает результат, побитово эквивалентный dcraw с теми же опциями. Только быстрее.

Вот со встраиванием чего-то до subtract_black() но в существующий процессинг - настала жопа, да, которую впрочем можно легко полечить (я ниже написал как), ценой эффективности (особенно при кропе)

И, да, вычитать черный после дебайера вполне можно - нужно тогда его обнулить вовремя, а потом - вычесть самому.

То есть там несколько фаз процессинга:
- копирование raw-данных из заначки
- вычитание черного
- поворот для fuji
- кроп
были объединены с целью получения быстрого кропа (чтобы окошко под мышкой можно было показывать в реалтайме).

При этом все запчасти (кроме, возможно, кропа) остались т.е. теоретически можно для if(O.wf_debanding) их звать по частям и будет щастье. Но в случае кропа - медленное.

Ну, хорошо, можно сделать удаление черного только при флаге? И ставить этот флаг или сбрасывать?

Я, кстати, хотел попробывать написать удаление "по черной рамке", это реально может помочь).

Ну самый разумный вариант, на самом деле, это встроиться *до* raw2image_ex и ковыряться прямо в raw-буфере.

Ну то есть
- аллоцировать себе плоский буфер (а не 4 компонента)
- порезвиться там (и тогда вам все эти ужасы вроде своих макросов для байера не нужны), копируя данные из сохраненных raw
- подменить указатель на буфер перед raw2image_ex
- освободить буфер и вернуть указатель после raw2image_ex()

При этом черная рамка тоже доступн (в отличие от работы с image[]). Проблема в том, что для разных камер информативная часть там может быть сильно разной

У меня все функции работают с плоским буфером, просто нужно флаг поставить, так что тут переделок мало.

Ну, если архитектурно так можно, то пожалуйста, могу сделать и так.

Но у меня есть встречное предложение. Можно ли сделать эту функцию, чтобы она задавала выходной формат данных, и уровень предобработки (удалять черный/нет)? Скажем, тут же решается вопрос с float, пожалуйста, сиди пиши свой raw конвертер.

Никто из тех кто "позже" по списку вызовов - float не воспримет.

Т.е. я не вижу масс людей, бегущих писать float-конвертер (а для них у меня и так есть плоский буфер RAW, а дальше делай что хочешь)

Я тут специально написал письмо автору AMAZE, так он говорит "у меня давно всё на float"

Дело не в отдельных алгоритмах, а во всем пайплайне.

Там, на самом деле, и дела относительно немного (кроме, быть может, переноса всяких демозаик и demosaic packs) и дело само по себе - благородное.

Но. В свое время (давно) я попытался спроектировать библиотеку-raw-конвертор. Т.е всю из себя такую гибкую, чтобы в любую стадию можно было встроиться (а иначе нет смысла) - и получается что а) надо навязывать свою идеологию б) гибко и эффективно - антонимы.

Ну я поплакал в углу и зарекся постпроцессинг в dcraw трогать содержательно.
Т.е. тот же плоский RAW-буфер понадобился мне лично - ну я его и сделал совместимо с этим кодом. А в сам код - не полезу, хотя от контрибьюторов приму с удовольствием.

Ну, Алексей.

Давайте вы реализуете этот вывод с этим флагом.

А я вот, скажем, что-то сделаю, какой-то открытый код где-то найду, может.

Если будет неполный скелет пайплайна, то на него потом нарастёт мясо. Я же от вас прошу как раз архитектурных решений. Ну, да, нужно продумать всё. Скажем, в идеале можно там сделать какое-то наследование, чтобы был разный код для float и для int, или может какое-то наименование функций. Я не знаю, это вам решить.

Но на самом деле, мне кажется, контребьютеры (вроде меня) готовы писать "мясо", но нужен "скелет".

В смысле "реализуете"? Сделать плавающий пайплайн, пусть с одним видом дебайера?
Нет, я зарекся это место трогать.

Плавучка есть - кому надо - в darktable (кажется) и rawtherapee (точно), если интересует опенсорс.

Ну вот, раньше говорили "если кто сделает, я не против", а теперь вот

Ну, я могу написать попробовать, скажем, к версии 0.16. Там не так сложно, как кажется.

Если кто сделает - я конечно же с удовольствием всосу.

Я про то, что сам содержательно это место править не хочу.

У меня и так идей на core functionality (собственно, на распаковку raw) - с учетом других проектов, еще на полгода хватит.

А архитектурно можно как угодно, можно даже не убирать за собой, recycle() всю память выделенную через calloc/malloc подберет (но при последовательных вызовах с разными параметрами - не подберет и все распухнет)

Да, другой вариант:
- обнулить сохраненные копии black/cblack[]
- запустить raw2image_ex()
- запустить ваш код
- восстановить black/cblack в двух местах уже
- запустить subtract_black() (который в коде уже и так вызывается, другой вопрос что увидев что все вычтено - ничего не делает)

И пожалуй этот способ - более хакерский, но более простой.

Обнулять (сохранив значения) надо в rawdata.color.black/cblack[]
А восстанавливать после raw2image_ex - в rawdata.color и imgdata.color

То есть надо тогда плевать на эффективность и делать
raw2image() + wf_filtering() + subtract_black() + rotate_fuji_raw()
Но тогда отвалится кроп (или его придется тоже доделать).

Собственно raw2image_ex() появился ради очень быстрого кропа.

не понял. Кроп делается после удаления черного?

raw2image_ex() делает все сразу.

Насчет А77 и DPreview я перед первым выездом тоже это сообщение прочитал. Проверил - честно говоря - хотелось бы написавшему это долбодятлу прописать штативом по голове. На одном и том же объективе (CZ2470) в одном свете картинка снятая на ISO1000 темнее и шумнее на порядок. Вытянуть на тот же уровень яркости при сохранении того же уровня шумов что у фотографии с ISO 1600 просто в ACR нереально. НО при этом на дисплее камеры выглядело все очень презентабельно.

Про то как конверторы и прочие демозаики реагируют на эти ступеньки - я стараюсь не думать. Плохо, скорее всего, реагируют.

спасибо.
Будем знать. Что ж они так....

на одном форуме автор тестировал А77 с А580 в условия освещения комнаты настольной лампой,
так вот что интресно на всех ИСО А580 намного лучше,
зачем покупать новое в два раза дороже если оно значительно хуже ???
поэтому я тоже не сосем девряю буржуйсним тестам .

Ну конечно неподвижное зеркало отожрет изрядно света (стоп или порядка того).
Это цена за фазовую (т.е. быструю и без дерганий) фокусировку видео, платить ее или нет - каждый сам должен решить.

Ну и пикселей больше, значит каждому света достанется меньше.

Подвижный вращающийся на 180 градусом столик, у середин коротких сторон - горизонтальная ос с прецизионными микромоторчиками, внутри ос - шлейф с данными, по углам столика с его задней стороны - четыре микролифта для быстрой юстировки. С одной стороны столика - дневная матрица 36 мпикс для зайцев дистагонов-отусов, с другой стороны столика - ночная матрица 12 мпикс для high ISO, мыльнозумов и 8мпикс кропа по всей ширине для 4к видео. Как-будто пару ISO вверх можно будет улучшить.

Скорее всего, патент на подобное решение лет как 10-20 лежит в закромах одного из патентных троллей.

Add new comment