Comments 141
Ссылку бы еще в конце страницы, что бы потом п длинному посту не искать, заранее спасибо :)
А так, результат поражает.
Но ведь тогда нечем их будет троллить, сударь. Такого допустить нельзя.
Интересно было бы скрестить такую программу с [телефоном с] камерой и акселлерометром.
В момент фотографирования записывать возможные движения и применять фильтр для улучшения качества фото.
Такое уже пробовали:
Эффективный метод стабилизации изображений от Microsoft
Во время открытия затвора пишется траектория движения/дрожания камеры с помощью трехосого гироскопа и акселерометра. Дальше восстанавливаем исходное изображение, используя эту информацию
Да-да, я это и имел в виду. А вы не хотите написать приложение под Android/iOS/WP? Под Win, вроде неплохо получилось.
Просто то что по ссылке — не слишком «готово к употреблению».
Под мобильные пока не планировал писать, т.к. самое сложное — найти нормальную библиотеку для преобразования Фурье, чтобы работала быстро и надежно. FFTW-то еле прикрутил, да и то баги остались.
Ну а так исходники открыты, как говориться — welcome :)
Ну можно сделать гибридную версию :) Чтобы снимала и записывала смещение камеры на телефоне, сохраняя снимок + «маршрут» а нужные преобразования потом можно было сделать в отдельном приложении на ПК
В теории можно, но не уверен что получится, т.к. в телефонах гироскопы и акселерометры очень шумящие. Не думаю что из них можно будет выцепить такие мелкие перемещения при смазе.
Вот оптические стабилизаторы в объективах — это другое дело, акселерометры в них очень чуткие. Конечно если есть возможно получать эти данные со стабилизатора.
Если кто-то напишет тестовое приложение, которое будет писать все отклонения во время съемки кадра — то можно будет попробовать использовать эти данные в офф-лайн режиме для деконволюции.
Насколько мне известно, только у Шарпа есть телефон с оптическим стабилизатором, да и тот продаётся только в Японии.
Здесь я больше имел ввиду фотоаппараты, нежели мобильные телефоны — там почти у всех есть оптические стабилизаторы. Возможно у каких-то экземпляров есть доступ к сырым данным с датчиков стабилизатора.
Под iOS написать такую программу точно не получится — нет низкоуровневых API для камеры. Думаю, что и под остальные платформы тоже.
Спасибо за статью. Единственный момент, который, наверное, стоит пояснить: свёртка — это не только деградация изображения, в общем случае это просто операция над двумя функциями (изображение — частный случай функции двух аргументов), которая может использоваться в том числе и для улучшения изображения (например, для увеличения контраста).
Частично я об этом писал в первой части — там подробно рассматривалась операция свертки
Скоро, чувствую, перестанем смеяться над фильмами, где поэтапно увеличивают расплывчатую картинку с камеры видеонаблюдения, с увеличением четкости на каждой итерации, и в итоге в отражении на головке какого-нибудь винтика видят фото убийцы.
жалко только что увеличение != восстановление фокуса/размытости )
В принципе, да, это возможно — если видеонаблюдение вести комплексом, где камера пишет видео на локальный диск в полном разрешении матрицы. И матрица ставится на 100500Мп. В целом, смысл таких программ я вижу в устранении необходимости предварительной фокусировки — для видеонаблюдения это большая проблема, и сейчас её обычно решают толпами операторов, что не есть хорошо.
Здесь должна была быть ссылка на статью про технологию бесфокусного фото, но я ее не нашел.
Я предполагаю, это http://habrahabr.ru/post/147172/ и http://habrahabr.ru/post/146136/ — сводится всё к той же очень большой матрице, и математике, которая делает картинку хорошей. Метод из статьи хорош тем, что применим к «мыльницам» — аппаратам с огромным разрешением матрицы, и практически отсутствующей оптикой — то есть, не требует ставить оптику в стиле Lytro.
Вот именно, что сейчас они разные. Разные ценовые диапазоны, разные возможности. Но технологии восстановления изображения позволяют им потихоньку сближаться — к примеру, повысить качество картинки китайского автомобильного видеорегистратора, использовать в качестве устройства видеонаблюдения мобильник… Тот же google glass от таких технологий только выиграет. Сейчас в профессиональных системах видеонаблюдения морщат ум над местом установки каждой камеры, а можно будет поставить десятки «мыльных китайских» за ту же цену. В конце концов, большая матрица в современных условиях дешевле, проще в изготовлении и занимает меньше места, чем хороший объектив.
Интересно, чем может быть обусловлен такой результат?
Radius 3.6, Smooth 40%, Correction Strength -2%, Edge Feather 51%.
Есть некоторые баги такого рода — пока точно не понял с чем они связаны. Возможно с особенностиями работы преобразования Фурье в библиотеке FFTW. В некоторых положениях ползунков наблюдаются такие проблемы — для решения обычно достаточно сдвинуть один из ползунков на деление влево или вправо
Впечетляет. Даешь неделю статей про обработку изображений на хабре.

Еще радует, что написано на моем любимом Qt. А то постоянно эти дотнетики, windows, б-р-рр.
Я так понял что минусуют .NET'щики? Если что — ничего личного, я просто не люблю привязанность к конкретной платформе, люблю KDE и linux. Что поделаешь…
просто не люблю привязанность к конкретной платформе

люблю KDE и linux

Как-то одно противоречит другому, не находите?
Он к одной конкретной платформе не любит привязанность, очевидно.
Как-то одно противоречит другому, не находите?

Человек не любит привязанность к одной конкретной платформе, потому что сам сидит на другой — всё логично.
Да нет же. Это к слову. Я обожаю кросс-платформенность. Но при этом люблю KDE и linux — там все завязано на Qt — который кроссплатформенен. Так что все логично.

И не надо хамить, пожалуйста. Прошу обращаться ко мне на «вы», ок?
Мне вот всегда было интересно — а какая разница, как к Вам обращаются — на «вы» или на «ты»? Ну идея сообщения ведь понятна — так ли важна одна эта буква, чтобы за неё цепляться?
«Вы» указывает на уважительное отношение, «ты» — на небрежное. Это что касается общение в сети, стереотипы.

Вот например, мне имманентно воспринимать обращение на «ты», как хамство и преступление.
Знаете, в жизни я обращаюсь на «ты» к людям, к которым я отношусь очень уважительно и, даже, с любовью — родители, близкие друзья. А на «Вы» обращаюсь обычно к людям, на которых мне абсолютно однобоко — когда прошу деньги в маршрутке передать или хлеб покупаю.
Как по мне обращение на «вы» попахивает снобизмом и искуственным увеличением психологической дистанции, но никак не уважением.
Ко всем людям, которых я уважаю я обращаюсь на «ты».
Уважительное обращение — является не уважением, а скорее этикетом. Я тоже с большинством людей, которых уважаю, говорю на «ты». Тут все хорошо и правильно.
Но представьте, в маршрутке:
1. Уважительное «Передайте пожалуйста за проезд.»
2. Хамское: «Передай за проезд».

Первое — просьба, даже без «пожалуйста». Второе — приказ (ну я бы его воспринял как приказ).

В сети тоже самое.
В маршрутке сказать своему ровеснику/ровеснице «передай за проезд, пожалуйста»? Да запросто! И ни один вменяемый человек не посчитает это хамством.
Тут еще от интонации зависит, и от наличия преступной внешности у автора просьбы :).

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

А коль так, следует обращаться к незнакомцам на Вы, что повысит вероятность отсутствия конфликтов и недоразумений на этой почве.

Пахнет снобизмом, но:
Что раньше было трудолюбием — сейчас трудоголизм.
Что раньше было верностью — сейчас глупость.
Что раньше было вежливостью — сейчас снобизм…
Напускное и акцентированное «Вы» может задеть не меньше чем «ты».
Потому надо забивать, как к тебе обращаються и принимать оба варианта.
О чём я и сказал в первом сообщении ветки.
В английском поступили мудро — выпилили и оставили только один вариант.
Уважение тех кто читал его статьи и посчитал их полезными — да. Для остальных — он просто человек, который грубо себя повел в комментариях (например как я в своем предыдущем комментарии, за что извиняюсь).

Вы ведь не идете домой к продавщице выяснять насколько она хороший человек, только для того, чтобы понять как ей отвечать на её грубость? Вы её можете заочно знать и знать её как очень порядочного человека, который просто сегодня не в духе. А можете не знать и ответить то что считаете нужным.
Звучит убедительно, я с вами согласен. Но, в данном случае, узнать кем является автор комментария, можно за пару минут (в общих чертах).
А многим ли оно нужно, если автор комментария не потрудился не хамить другим? Такое поведение просто раздражает и находит свою оценку.
PS а ещё сильно уводит комментарии в сторону от темы статьи. При том, что статья интересная и обсуждение деталей — куда лучше, чем «партизанские священные войны».
Я же говорил, что минусуют дотнетчики. Только вот самые активные из них, GrigoryPerepechko и LionSoft — выступают, если можно так сказать.

Можете объяснить, за что я получил минусы? Я всего лишь поблагодарил автора поста за его выбор фреймворка, так как категорически не одобряю .NET в качестве фреймворка для разработки такого рода ПО.

П.С. На 90% уверен что этот комментарий ни на что не повлияет и он будет заминусован.
Не минусовал предыдущие комментарии(т.к. побоку на .Net, кеды и ваше к ним отношение), но этот минусану по следующей причине: большАя часть комментария посвящена жалобам на вселенскую несправедливость, я зря потратил время на чтение.
Так я ведь не могу ставить оценки (тут нужен ресурс-который-нельзя-называть-всуе). А вот ВЫ меня явно заминусовали :) Но раз это столь приятно для ВАС — милости прошу.

А насчёт ты/вы:
Вы же в профиле поставили 13 лет. Откуда столько гонору для такого возраста? Детям несвойственны глупые фамильярности и экивоки. Давайте жить дружно :)
Хочу подметить, что я не говорил что вы меня минусували. А я вас не минусовал, кстати. Конкретно вам я минус не ставил (пруф).

Но я считаю что вы его заслужили — «Ну так люби :) Зачем тут об этом знать? Для любви есть личные блоги и твиттер» звучало для меня как минимум неприятно

А насчёт ты/вы:
Когда вы писали первый комментарий — вы не смотрели мой профиль. Сейчас вы говорите что мне 13 лет. Пускай мне 13 лет, но я тоже хочу хоть элементарного уважения в свою сторону. Или вам сложно к незнакомым людям, даже младше вас обращатся на «вы», хотя бы по той причине — что незнакомым?
Да что ж такое)
Вы умудрились развить холивар на абсолютно пустом месте))
Кстати, мою карму весь день дрыгают (от +18 до +21) — было утром около 80 голосов, сейчас 102. Пока дотнетеры выигрывают, но кутешники не сдаются)).
UPD: если это кого-то интересует — кутешники приняли поражение (.NET заминусовали до +15).
Я не участвую, но предположу, что к «дотнетерам» присоединились еще и нелюбители холиваров на ровном месте.
Ну вы и похоливарить, господа :)
Добрая половина коментов статьи посвящена этому.
Реально пожалел что недостаточно кармы, т.к. изложение прекрасное, a наличие кода вообще класс.
Я не силён в математике, но как обычному обывателю с помощью вашей программы добиться результатов как в первом примере с окошком Windows? Я взял исходную заблюренную картинку и начал играться с параметрами. Но ничего даже близкого к второй картинке не получил…

У меня хобби фотография и с фотосессий частенько попадаются снимки с промахами фокусировки. Чуть чуть это исправить было бы крайне полезно!
Хотя, простите, я наврал — примерные параметры: Radius: 13.3, Smooth 30%, Cor. Strength: 17%, Feather: 43%. Гениально, нет слов.
А я всегда был уверен, что это киношный трюк, А ВОТ ОНО КАК ОКАЗЫВАЕТСЯ...
Боюсь с реально-расфокусированными изображениями это не будет корректно работать. Сейчас можно задать только радиус размытия на всё изображение, но такого не бывает на реальной фотографии — радиус расфокусировки зависит от удаленности от точки фокусировки.

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

А вот смазанные изображения восстанавливает хорошо.
Задача-то некорректная! Понятное дело, что успех ее реализации очень сильно зависит от вида изображения.
В реальности superresolution требует подготовки серии снимков. Либо — эталонного снимка, полученного при тех же условиях съемки (что зачастую просто невозможно).
Собственно в том и сложность восстановления расфокусировки — очень много подводных камней. Но даже сейчас вполне успешно восстанавливаются фотки с общей равномерной расфокусировкой — типа снимали пейзаж и фокус промахнулся.
Также можно восстановить фотки типа «лицо не в фокусе, зато задний план в фокусе» — правда нужен ряд приседаний в виде предварительного вырезания фона, чтобы звон с четкого фона на влиял на лицо.
Кстати, а можно как-то вытащить PSF засчёт зеркальности шума. Ведь качественые объективы симметричны по обоим осям?
Увы, шум не коррелирован с изображением, а накладывается сверху (складывается)
Интересно! А откуда на первом скрине появляется цветной шум? Вроде изначально его нет или это края после Фурье дают о себе знать?
При деконволюции имеющийся на фотографии шум многократно усиливается — и вылезают все дефекты. Например при радиусе 10 один пиксел собирается из 314 окружающих пикселей, причем шум и ошибки накапливаются, отсюда и результат.
Благодарю за отличный пост. Быстрое преобразование Фурье обычно работает с изображениями, размеры которых кратны степени 2. Например 1024х512, 2048х2048 и т. д. Скорее всего исходные фотографии нужно кадрировать до этих размеров.
FFTW позволяет работать с любыми размерами, правда производительность существенно снижается.
Тут по идее надо еще больший радиус выставлять и менять PSF на восьмиугольник, тогда будет какой-то стоящий результат. Вообще с таким сильным размытием требуется, как правило, весьма кропотливая работа с подбором PSF и параметров.
Да, известная история — насчет того размытого снимка, думаю что-то можно из него вытянуть ручным формированием PSF (Там он в виде правильного восьмиугольника с чуть скругленными краями.
А если в алгоритме обрезать края изображения, используя их только для этапа восстановления, то поможет ли это от ряби избавиться?
Если задача — восстановить центр, то относительно центра картинка и расширяется.
Относительно же целой картинки, восстановленная часть обрезается.
Изменять размер изображения очень дорого — требуется переинициализация всех массивов и FFTW. Сейчас в программе после загрузки изображения читается размер, инициализируется преобразование фурье этим размером, формируются полноразмерные входные и промежуточные буферы. Менять все это займет около секунды.
На практике гораздо проще размыть края описанным в статье способом — звон на краях исчезает полностью
Владимир, а как насчет аподизации до ближайшей степени двойки?
Расширяем картинку, за счет зеркалирования краевых пикселей.

;) Да, и по поводу краевых эффектов.
Если изображение имеет размеры по степени двойки, то дребезг заметно меньше.
Это и есть специфика преобразования фурье…

img-service.com/overview/image_restoration_deblurring.html
> Владимир, а как насчет аподизации до ближайшей степени двойки?

Этим всем как раз и занимается FFTW — в этом и ее суть, предоставить удобный интерфейс для выполнения преобразования Фурье.

> Если изображение имеет размеры по степени двойки, то дребезг заметно меньше

C предобработкой краев дребезг и так нулевой получается (если вы имеете ввиду дребезг от краев). Да и в любом случае нужен алгоритм который позволит вырезать любой участок изображения произвольной формы без эффекта «звона» — например когда мы хотим обработать по маске.
С маской эт вообще легко ;)
Разложения Фурье инварианты к сдвигу.
Этим можно и нужно пользоваться.

а любую маску накладывать апостериори.

взяли маску
посмотрели в какой прямоугольник вписались
если вылезли за края исходной картинки то дополнили данными с противоположной стороны.
получили результат наложили исходную непрямоугольную маску
коллеги, а в чем смысл? Качество восстановленных изображений сиииильно далеко от приемлемого для печати… только для анализа на предмет каких-то данных?
Именно. Это же точно не для фотопечати, а вот для определения виновника происшествия или для получения косвенной информации для аналитики — отличный инструмент!
Очень даже есть смысл. Например, в качестве предобработки для последующего оптического распознавания.
Смысл уже есть — техническое восстановление изображения в случае сильного размытия для чтения надписей, знаков. Для среднего и малого размытия уже можно говорить и о качестве приемлемом для печати. Посмотрите последние примеры с машиной или лицом — после небольшой постобработки качество вполне.
Ну и главный смысл — практический опен-соурсный прогресс в решении задачи восстановления изображений.
Первые фотоаппараты выдавали изображение немногим лучше приведенных в статье, а хороший художник рисовал качественный эскиз быстрее, чем проявлялись первые фотопластинки и с меньшим числом неудач.
Фарш невозможно провернуть назад…
Поется на мотив известной песни.
Фарш почти невозможно провернуть назад…
Поётся на мотив топика ;)
Да нет, они сделали очень крутую вещь — автоматический поиск матрицы деконволюции. Если приведенная в статье методика — это просто реализация «в лоб» нескольких математических формул, то решение от адоба — это уже научная работа, притом доведенная до коммерческого применения. А вообще это очень интересная задача, поиск матрицы деконволюции уже втречался мне в одной задаче из области теории управления, но опенсорсных решений так и не нашел, да и просто нормальных теоретических исследований в открытом доступе мало.
Отличная статья, спасибо
В свое время пытался заморочиться с этой тематикой, но не хватило трудолюбия довести дело до конца
Я пробовал реализовать некоторые алгоритмы, основанные на регуляризации Тихонова.
Вы не пробовали эти методы?
В первой части статьи пробовал и показывал результаты фильтра Винера, Тихонова, Люси-Ричардсона, слепую деконволюцию.
Да, есть, это я пропустил, спасибо
Насколько я помню ту книгу, которую я использовал как источник знаний, там строились интегральные уравнения
У вас довольно подробно описан сам алгоритм, это снижает немного порог вхождения
Года два назад весь инет перерыл в поисках русскоязычных статей на эту тему
Надо камрадам с www.irfanview.com/ отписаться, дабы плагин для программы соответствующий сделали — сама реализация просто чудесная. Автору спасибо!
YUVladimir, а вы случайно в КГУ не преподавали? Вроде как у меня первая семестровая про обработку изображений от вас была :)
Будет интересно попробовать воспроизвести что-то подобное с помощью встроенных средств ImageMagick. Благо, фурье (точнее — получение спектра) и некоторые матричные операции над изображениями у него встроены.
Да, такие вещи легко делаются любыми тулами, которые поддерживают преобразование Фурье. На FFTW это можно тоже в несколько строчек сделать — собственно умножить одну матрицу на другую.
Основные сложности появляются при обработке реальных иображений — вот там и вылезают влияние шума, краевые эффекты, необходимость подстраивать PSF. Ну и плюс обеспечение высокой скорости.
По факту SmartDeblur — это реализация одной весьма простой формулы фильтра Винера, которая известна уже 70 лет, но вот качественно и удобно реализовать, учесть все подводные камни, это уже сложнее.
А еще выскакивает квантование при делении на малые числа: float оказывается совершенно недостаточно, а double многовато памяти жрет. Но даже double вблизи нулей ОПФ дает при делении хорошие такие выбросы.
В век когда доступно более 4гб «double жрётмноговато памяти»?
Да хоть в long double можно считать если это добавит качество.
> В век когда доступно более 4гб «double жрётмноговато памяти»?

Я как-то раз столкнулся с нехваткой памяти, когда БПФ с помощью CUDA делал. Картинка маленькая, кстати, была: всего-то 3000х3000. Но и оперативки в моей видеокарте было лишь 512МБ. Все руки не дойдут разрулить это дело: чтобы в случае нехватки ресурсов видеокарты софтинка считала на CPU, а не матюгалась.
О, я с нехваткой памяти столкнулся в полный рост при тестировании SmartDeblur. В итоге пришлось жертвовать производительностью. А все дело в преобразовании Фурье — он есть кучу памяти.
Поясню на примере: допустим у нас есть картинка 15 мегапикселей

15 миллионов пикселей * 3 канала * 16 (это два дабла на пиксель во входной матрице преобразования Фурье, т.к. комплексные числа) * 2 (это выходная матрица со спектром, тоже в комплексном виде) = 1440 мегабайт

И это только самый минимум для матриц, а еще там надо полноразмерную матрицу под PSF (также комплексный вход и выход), промежуточную матрицу для обработки краев. Можно конечно оптимизировать типа переиспользования матриц для каждого канала, но тогда теряем в производительности в три раза за счет невозможности в три потока считать три канала.

И если не применять разные трюки, то и в 4 гига не влезем.
Я, кстати, из-за нехватки ресурсов подумываю реализовать свертку все-таки не через Фурье, а именно в виде свертки. На GPU по идее производительность не сильно пострадает.
Надо будет проверить. Да лень…
Речь как раз о реальных изображениях. Просто Ваше достаточно подробное описание действий — гораздо ценнее чем любая готовая программа. Как раз потому, что эти действия можно повторить с помощью других инструментов и получить тот же результат.
На платформе win — там да, на любой чих модно писать свой бинарь. А вот в unix-way — уже есть все готовые «блоки», остаётся только подобрать подходящий «клей» и собрать скрипт. Это в любом случае гораздо удобнее, чем когда есть некая программа-«чёрный ящик».

Единственный затык — в последней ubuntu штатный пакет IM собран без поддержки fftw, но эта проблема решается за несколько минут путём установки пакета libfftw3-dev и последующей пересборки пакета imagemagick из его же собственных исходников (никаких модификаций этих самых исходников не нужно; его configure-скрипт сам определяет наличие fftw, просто в оригинальном пакете мэйнтэйнер забыл явно прописать её в список зависимостей пакета, и поэтому в оригинале на «стерильной» сборочной платформе fftw туда не попадает).

А дальше всё работает, как у вас в статье. Я попробовал на ваших изображениях.
А вашим скриптом не поделитесь? К примеру тем, который обрабатывает смазанную машину.
Ну и результатом тоже.
Очень интересно было бы взглянуть на это.
Отладить алгоритм можно и в octave. Я ее частенько использую не только для сиюминутных расчетов, но и для отладки какого-нибудь алгоритма, который потом на C перенесу. Для просмотра промежуточных результатов лучше использовать MathGL + feh, нежели тормознутый gnuplot.
Сколько сложностей на ровном месте из-за несовершенства текущей одиночной картинки.
Давно бы уже все выпускали стерео-фотоаппараты с сильно зажатой диафрагмой, резкой картинкой, где воссоздав карту глубины можно было бы менять фокус и боке как хочешь и сколько хочешь при постпроцессинге (как в Lytro)
Да, я знаю что расход в памяти упадет в два раза, но специально оставил классическое complex-to-complex преобразование. Сделано это было с целью упрощения отладки — получается сразу полноразмерный спектр, который просто выводить в файл для анализа, просто и наглядно умножать без вычисления границ половины и пр. Вообщем на этапе разработки гораздо проще — и так было много проблем с симметрией (где точно центр фурье-преобразования, т.к. любое отклонение от него давало сильную рябь и т.д.).
После отработки алгоритмов можно перейти на real-to-complex. Расход памяти сократится, насчет скорости не уверен — в теории быстрее, но судя по бенчмаркам чуть ли не наоборот.
Не собирается на Ubuntu 10.04. Пишет что: ImageUtils.cpp:98: error: ‘const class QImage’ has no member named ‘constScanLine’

Qt 4.6.2 не катит?
Можно, только вопрос чего хочется добиться.
Нужно каким-то образом разделять регионы с плохим фокусом или смазом, а потом определять параметры и делать деконволюцию.
Таких работ тоже довольно много, в качестве примера можно взять MSU Dblur

ДО:
image

ПОСЛЕ:
image

Или вот другая работа:
http://videoprocessing.ucsd.edu/~stanleychan/deconvtv_folder/deconvtv_video.html

ДО:
image

ПОСЛЕ:
image
Only those users with full accounts are able to leave comments. Log in, please.