Коррекция искажений объективов и опен сорс

04.01.2013 21:45:59

Началось всё просто. Я в очередной раз включил режим «Только RAW» на фотике и отправился с ним смотреть гранд-макет России (надеюсь, отдельной записью ещё про это дело напишу). Оттуда притащил чуть менее двух сотен фоток, загрузил их, по привычке, в Digikam и начал глядеть. Digikam показал мне вот такое высокохудожественное произведение:

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

Открыл в дигикамовском же редакторе RAW и увидел уже вот такое:

В этом месте меня охватил ужас. Кривизна всех линий ударила в оба глаза и заставила зажмуриться. Повторное открытие глаз картину не изменило — кривизна осталась на месте.

«А чего горевать?» — подумал я, да и пошёл по меню «Улучшить»→«Объектив»→«Автокоррекция» дигикамовского редактора. Я уже когда-то однажды пытался ею воспользоваться и хорошо запомнил, что профилей под линзы Sony NEX там нет, однако это было когда-то однажды, а тут у меня уже openSUSE 12.2 и, возможно, что-то изменилось. Оказалось, не изменилось, профилей линз как не было, так и нет.

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

«openSUSE 12.2 это хорошо, но может быть всё-таки подпротухло что-то в ней, всё-таки ёпен сорс», — подумал я, да и пошёл на сайт lensfun, поскольку именно через него «Дигикам» и делает коррекции. На сайте обнаружилось, что, во-первых, моя версия 0.2.6 таки самая последняя из релизных, но, во-вторых, «New release is on its way!». И действительно, оказалось, что не зря там написали «many people send in calibration data for quite a lot of lenses and camera updates»: файлик профилей для Sony пополнился интересующими меня данными.

«Ура, вот он опен сорс!» — радостно кричал я, скачивая файл и размещая его в «/usr/share/lensfun/mil-sony.xml». Пакет RPM? Да ладно, бросьте, ради такого файлика морочиться с пакетами ещё… «Дигикам» быстренько подхватил новые данные, позволил выбрать нужный объектив, и… выдал в результате что-то несуразное. К сожалению, сохранить я это дело не успел, но кривизна настолько бросалась в глаза, что оставалось только вздыхать: «ох уж этот ёпен сорс…».

Появилось подозрение, что профиль кривой. Для китового объектива Sony NEX 18-55 на 18мм было прописано такое:

<distortion model="ptlens" focal="18" a="0.02897" b="-0.08920" c="0.03513" />

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

А на выходных был поставлен Hugin (в пакетах openSUSE он есть) и дело завертелось по новой.

Подумав над выбором качественной мишени я взял доску для го и сделал восемь снимков «а-ля панорама»:

Для всех последовательных пар аккуратно понавыбирал по 10-15 контрольных точек, процесс занимает существенное время, хотя должен отметить, что работа с контрольными точками в «Хугине» это одно удовольствие — после первой пары точку на втором снимке он ставит в полном автомате (а для первой пары в полуавтомате, на одном ставишь точно, на втором только успеваешь приблизительно ткнуть, как он тут же в увеличении даёт правильный результат). Работает очень хорошо, у меня на получившиеся более 90 точек было всего несколько, когда «Хугин» сказал, что коэффициент корреляции слабоват и надо бы проверить (при этом, в половине этих случаев он таки попал куда надо) и пара точек, с которыми он конкретно промахнулся, но здесь надо учитывать то, что это всё-таки сетка и в пересечениях (или, точнее, углах образуемых пересечениями) линий, которые я и использовал в качестве точек, запутаться несложно.

В итоге, после расчёта оптимизации «Хугин» выдал мне волшебные параметры и строка в описании у меня поменялась на

<distortion model="ptlens" focal="18" a="0.027" b="-0.103" c="0.051" />

«Вон оно как на самом-то деле!» — радостно кричал я, снова загружая «Дигикам». Снова попробовал откорректировать изначальный снимок в нём и… результат получился ещё более кривой, нежели был изначально. Крепко задумавшись я снова сходил к «Хугину» и исключил точки с самыми большими отклонениями, они там неплохо видны, после этого коэффициенты получились такие:

<distortion model="ptlens" focal="18" a="0.021" b="-0.076" c="0.022" />

Снова «Дигикам» и снова фэйл, результат был неимоверно далёк от того, который выдаёт камера при внутренних коррекциях. Где-то в этот момент надо было всё бросать, но меня зацепило, как же это так, вроде бы всё есть, а результат неправильный.

Начал копать дальше и наткнулся на альтернативный метод коррекции через «calibrate_lens_gui». Изначально загрузил в него те же картинки с доской, но, скорее всего, из-за высокой шумности (ISO 3200, да, было темно и я поджимал диафрагму до восьми, чтобы порезче) калибратор нашёл там буквально по три-пять линий на каждом из снимков и выдал вот такие коэффициенты:

<distortion model="ptlens" focal="18" a="-0.00334" b="0.02864" c="-0.09199" />

Если результаты предыдущего метода были ещё хоть сколько-то похожи на те, что были добавлены в базу «Ленсфана», то это уже было что-то новое. Однако, и это новое не дало в «Дигикаме» хоть сколь-нибудь внятного результата, скорее даже наоборот. Тогда было решено изготовить мишень:

На четырёх снимках с нормальной чувствительностью (ISO 800, да, для некса это нормально, F8, опять же) калибратор нашёл уже по 40-50 линий на каждом снимке и, подумав, выдал такие параметры:

<distortion model="ptlens" focal="18" a="0.01932" b="-0.06322" c="0.02422" />

С чувством большой гордости за проделанную работу я снова открыл «Дигикам» и снова попробовал откорректировать изначальный снимок с новыми параметрами. И… снова потерпел поражение, результат по прежнему был очень далёк от камерного. Напряжение усиливалось. Я сделал ещё одну серию на четыре снимка и получил для них такие результаты:

<distortion model="ptlens" focal="18" a="0.02218" b="-0.07281" c="0.0339" />

Снова «Дигикам» и снова фэйл. В попытке подавить нарастающую агрессию я сделал ещё одну серию, уже на восемь снимков, получил очередные коэффициенты и снова некорректный результат в дигикаме. Я начал пробовать доставать из архива снимки сделанные тем же объективом с тем же фокусным расстоянием и пихать их в тот же самый калибратор, я запихнул в него тот самый снимок из-за которого всё началось, получал всё новые и новые цифры и всё такие же отвратные результаты коррекции в «Дигикаме».

Тут у меня начало закрадываться подозрение, а уж нет ли проблем в самом «Ленсфане»? Всё-таки калибратор «Хугина» хоть и выдавал несколько разные результаты для разных наборов изображений, но они были довольно близки и у «Хугина» явно были основания считать их правильными. Здесь же обнаружилось, что в окошке просмотра линий можно не только линии посмотреть, но и откорректированную картинку:

И при добавлении оригинальной картинки с последующим просмотром обнаружилось Страшное: в калибраторе картинка выглядела отлично, а вот в «Дигикаме» с теми же коэффициентами паршиво. Привычно поругав ёпен сорс отправился смотреть, что да как в трекерах и исходниках lensfun. Довольно быстро обнаружил подозрительный баг, для которого даже есть патч. Суть бага проста: разработчики «ленсфана» зачем-то считали искажения по неправильным формулам, отличающимся от формул «Хугина». Ну а патч это всё исправляет.

«Вот оно!» — орал я, скачивая исходники пакета RPM для openSUSE. Вспомнил кун-фу по редактированию спек и сборке пакетов RPM, запатчил, собрал, поставил, ура, вот он опен сорс!

Надо ли говорить, что после этого результат был столь же крив, как и был? 😉

Но поскольку я уже не мог так просто отцепиться от этой темы, копания я продолжил. Была освоена коррекция фото «Хугином» в командной строке, это тривиально:

$ fulla -g $KA:$KB:$KC:1 $INFILE -o $OUTFILE

$KA, $KB, $KC — коэффициенты A, B и C, $INFILE и $OUTFILE — соответственно, входной и выходной файлы. На коэффициентах 0.0191, -0.06257 и 0.02286 хугин выдал такое:


Что вполне прилично. И вот дальше мне пришлось найти способ сделать коррекцию напрямую «Ленсфаном», без посредства «Дигикама». Как оказалось, это вполне реально, в исходниках самого «Ленсфана» есть маленькая софтинка «tmod», только вот она по умолчанию даже не собирается, поскольку никому особо не нужна. Мне — нужна и я её собрал, единственное что не стал заморачиваться с cmake и Правильной Сборкой, а сделал как-то так в каталоге «tests/tmod» исходников:

gcc -o tmod -I../../cmake_build/ -I../../include/auxfun/ -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -L/usr/lib64/ -lglib-2.0 -llensfun -lstdc++ -lpng12 -lm tmod.cpp ../../libs/auxfun/image.cpp

Собранный tmod работает только с форматом PNG, но для наших целей это уже были мелочи, исходник был нещадно отконвертирован и скормлен утилите так:

$ ./tmod -l "E 18-55mm F3.5-5.6 OSS" -C1,5 -F18 -d aaa.png -o aaac.png

tmod напрямую играться коэффициентами не даёт, берёт параметры для коррекции прямо из базы данных «Ленсфана» по имени объектива («-l»), используя указанный множитель фокусного расстояния («-C») и само фокусное расстояние («-F»). «-d» командует исправить искажения, ну а дальше вход и выход. Здорово, в базе у меня были забиты те же коэффициенты, которые я кормил руками «Хугину», и что же мы видим:

А видим мы, наконец-то, то, что и хотели увидеть. Уровень коррекции предельно близкий к тому, что делает сама камера, добротный и ровный результат. Замечу, что он отличается от результата самого «Хугина» через fulla, но в этом случае он мне даже больше нравится.

Стало понятно, что Счастье где-то рядом, но «Дигикам» продолжал выдавать плохой результат. Хотя используемая им библиотека явно была способна выдать результат корректный. Пришлось скачать репозиторий «Дигикама», там, конечно, обнаружились дикие ужасы и кошмары вроде внутренней версии библиотеки «Ленсфан», по счастью, не используемой в моей сборке (да-да, я изучил журнал сборки на OBS), но в остальном модуль коррекции смотрелся очень даже чистенько. Ну не видно навскидку каких-либо принципиальных отличий от tmod.

И тогда я занялся одним из любимых дел — начал придумывать проблему. Ну вот серьёзно, где может быть проблема, если библиотека есть, работает правильно, корми её параметрами, да получай результат. Коэффициенты «Дигикам» возмёт из профиля, с коэффициентами ошибка маловероятна, они либо есть и учитываются (при изменении результат меняется, значит, учитываются), либо их нет. ФР есть в фото и оно даже выставляется правильно на автомате, не должно быть проблем:

Из того, что ещё скармливается tmod остаётся только множитель ФР, хотя он-то тоже указывается в профилях. Но, с другой стороны, его в интерфейсе и не видно. Пробуем?

$ ./tmod -l "E 18-55mm F3.5-5.6 OSS" -C1 -F18 -d aaa.png -o aaac2.png

А вот и результат:

Результат вышел явно кривой, но получение именно этого результата заметило всё семейство по характерному победному вою и визгу из моего угла. Потому что точно такой же, хоть и кривой, но точно такой же, результат я видел в самом «Дигикаме». 🙂 А это значит, что проблема вполне понятна и решаема, сейчас я пробую разновсяко пропатчить это дело и собрать.

Не менее интересно было прогнать tmod с оригинальными значениями коэффициентов из базы данных ленсфана, получилось так:

Результат явно отличается от того, что получалось с моими коэффициентами, но также явно хорош. И также явно близок к тому, что даёт камера. Прикладывание линейки к монитору не позволило выбрать что-то лучшее из двух, есть подозрение, что если бы не история с кроп-фактором, я был бы счастлив откорректировав фотки по тем значениям. Впрочем, тогда я бы не познал кун-фу получения этих значений и не познакомился бы с «Хугином». Да и в бложик написать нечего было бы.

А пока, как говорится, ту би континуед, осталось запатчить до смерти «Дигикам» и, возможно, ещё поэкспериментировать с коэффициентами.

Много комментариев (3) к заметке “Коррекция искажений объективов и опен сорс”

  1. virens:

    Роман, я не понял этих рыданий в три ручья — дисторсия (barrel and pincushion) присуща всем оптическим объективам в той или иной степени. Джыпег из камеры уже пост-обработан, и я готов спорить на бутыль портвейна, что там коррекция на дисторсию уже применена. Поэтому ты её и не видишь. А в RAW ничего этого нет, там всё честно.

    Поскольку я считал коррекцию искажений дикой магией, профили для которой могут делать только специально обученные люди специальными шаманскими методами

    Ну, это ещё не рокетсаенс, ты зря. Немного почитав книжек по оптике, ты сможешь даже сам написать для этого программу. Или взять готовые тут или тут. Ничего особо сложного в них нет. Просветительская статейка в тему.

    Я просто в свю красноглазую молодость сам писал на MATLAB скрипты для устранения дисторсии.Ничего, жив-здоров.

    всё-таки ёпен сорс», — подумал я
    🙂

    У ёпен-сорса мозгов хватает только городить музыкальные плееры, текстовые редакторы и всякую хреновину типа пульсаудио и системд. Что-то большее типа GEGL и графических редакторов с CAD не осиливают.

    Для тех, кто не в теме (типа я): хто такие fulla и tmod и откуда они взялись? Это часть digikam или где?

    И ещё: можно пройтись поиском-заменой по тексту и убрать «хугин» на Hugin?

    P.S.> Роман, система комментирования у тебя на блоге — это боль в ж***, ты уж извини: OpenID не работает, других wordpress-юзеров не принимает. Северная Корея какая-то 🙂 Даёшь демократии!

  2. Роман:

    Джыпег из камеры уже пост-обработан… А в RAW ничего этого нет, там всё честно.
    Это-то я понимаю и это ожидаемо. Но также ожидаема была большая волшебная кнопка «сделай снимку хорошо», вот с этим возникли определённые сложности.

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

    Очень может быть, но поскольку я этой темой никогда не занимался, ощущение было именно такое.

    Для тех, кто не в теме (типа я): хто такие fulla и tmod и откуда они взялись? Это часть digikam или где?

    fulla — это хугин, tmod — ленсфан, ну там где-то написано было.

    P.S.> Роман, система комментирования у тебя на блоге – это боль в ж***, ты уж извини: OpenID не работает, других wordpress-юзеров не принимает. Северная Корея какая-то 🙂 Даёшь демократии!

    Раньше OpenID работал. Попробую посмотреть, сейчас хоть какое-то время на это есть, а то бложик совсем уже пылью покрылся.

  3. Роман Химов » Баги коррекции искажений линз в Digikam и lensfun:

    […] коррекции, на который я как бы и наткнулся по ходу мытарств с коррекцией, но как бы не совсем. После финта со сборкой […]

Закомментировать

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