Пользователь
0,0
рейтинг
15 июля 2012 в 18:39

Разработка → Восстановление расфокусированных и смазанных изображений. Практика

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

В дополнение к этому я написал демонстрационную программу, в которой реализованы основные алгоритмы по устранению расфокусировки и смаза. Программа выложена на GitHub вместе с исходниками и дистрибутивами.

Ниже показан результат обработки реального размытого изображения (не с синтетическим размытием). Исходное изображение было получено камерой Canon 500D с объективом EF 85mm/1.8. Фокусировка была выставлена вручную, чтобы получить размытие. Как видно, текст совершенно не читается, лишь угадывается диалоговое окно Windows 7.



И вот результат обработки:



Практически весь текст читается достаточно хорошо, хотя и появились некоторые характерные искажения.

Под катом подробное описание проблем деконволюции, способов их решения, а также множество примеров и сравнений. Осторожно, много картинок!

Вспомним теорию


Подробное описание теории было в первой части, но все же напомню вкратце основные моменты. В процессе искажения из каждого пикселя исходного изображения получается некоторое пятно в случае расфокусировки и отрезок для случая обычного смаза. Все это друг на друга накладывается и в результате мы получаем искаженное изображение — это называется сверткой изображения или конволюцией. То, по какому закону размазывается один пиксель и называется функцией искажения. Другие синонимы – PSF (Point spread function, т.е. функция распределения точки), ядро искажающего оператора, kernel и другие.

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

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

image (1),
где все элементы — это фурье-образы соответствующих функций:
G(u,v) – результат искажения, т.е. то, что мы наблюдаем в результате (смазанное или расфокусированное изображение)
H(u,v) – искажающая функция, PSF
F(u,v) – исходное неискаженное изображение
N(u,v) – аддитивный шум

Итак, нам нужно восстановить максимальное приближение к исходному изображению F(u,v). Просто поделить правую и левую часть на H(u,v) не получится, т.к. при наличии даже совсем небольшого шума (а он всегда есть на реальных изображениях) слагаемое N(u,v)/H(u,v), будет доминировать, что приведет к тому, что исходное изображение будет целиком скрыто под шумом.

Чтобы решить эту проблему, были разработаны более устойчивые методы, одним из которых являтся фильтр Винера (Wiener). Он рассматривает изображение и шум как случайные процессы и находит такую оценку f' для неискаженного изображения f, чтобы среднеквадратическое отклонение этих величин было минимальным:

image (2)

Функцией S здесь обозначаются энергетические спектры шума и исходного изображения соответственно – поскольку, эти величины редко бывают известны, то дробь Sn / Sf заменяют на некоторую константу K, которую можно приблизительно охарактеризовать как соотношение сигнал-шум.

Способы получения PSF


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

Основная задача — получить оценку функции распределения точки (PSF). Это можно сделать несколькими способами:
1. Моделирование. Очень непросто и трудоемко, т.к. современные объективы состоят из десятка, другого различных линз и оптических элементов, часть из которых имеет асферическую форму, каждый сорт стекла имеет свои уникальные характеристики преломления лучей с той или иной длиной волны. В итоге задача корректного расчета распространение света в такой сложнейшей оптической системе с учетом влияния диафрагмы, переотражений и т.п. становится практически невозможной. И решение ее, пожалуй, доступно только разработчикам современных объективов.
2. Непосредственное наблюдение. Вспомним, что PSF — это то, во что превращается каждая точка изображения. Т.е. если мы сформируем черный фон и одну белую точку на нем, а затем сфотографируем это с нужным значением расфокусировки, то мы получим непосредственно вид PSF. Кажется просто, но есть много нюансов и тонкостей.
3. Вычисление или косвенное наблюдение. Присмотримся к формуле (1) процесса искажение и подумаем, как можно получить H(u,v)? Решение приходит сразу — нужно иметь исходное F(u,v) и искаженное G(u,v) изображения. Тогда поделив фурье-образ искаженного изображения на фурье-образ исходного изображения мы получим искомую PSF.

Про боке


Перед тем как перейдем к деталям, расскажу немного теории расфокусировки применительно к оптике. Идеальный объектив имеет PSF в виде круга, соответственно каждая точка превращается в круг некоторого диаметра. Кстати, это для многих неожиданность, т.к. с первого взгляда кажется, что дефокус просто растушевывает все изображение. Это же объясняет и то, почему фотошоповское размытие Гаусса совсем не похоже на тот рисунок фона (его еще называют боке), который мы видим у объективов. На самом деле это два разных типа размытия — по Гауссу каждая точка превращается в нечеткое пятно (колокол Гаусса), а дефокус каждую точку превращает в круг. Соответственно и разные результаты.

Но идеальных объективов у нас нет и в реальности мы получаем то или иное отклонение от идеального круга. Именно это и формирует неповторимый рисунок боке каждого объектива, заставляя фотографов тратить кучу денег на объективы с красивым боке :) Боке можно условно разделить на три типа:
— Нейтральное. Это максимальное приближение к кругу
— Мягкое. Когда края имеют меньшую яркость, чем центр
— Жесткое. Когда края имеют большую яркость, чем центр.

Рисунок ниже иллюстрирует это:



Более того, тип боке — мягкое или жесткое зависит еще и от того, передний это фокус или задний. Т.е. фотоаппарат сфокусирован перед объектом или же за ним. К примеру, если объектив имеет мягкий рисунок боке в переднем фокусе (когда, скажем, фокус на лице, а задний план размыт), то в заднем фокусе боке того же объектива будет жестким. И наоборот. Только нейтральное боке не меняется от вида фокуса.

Но и это еще не все — поскольку каждому объективу присущи те или иные геометрические искажения, то вид PSF зависит еще и от положения. В центре — близко к кругу, по краям — эллипсы и другие сплюснутые фигуры. Это хорошо видно на следующем фото — обратите внимание на правый нижний угол:



А теперь рассмотрим подробнее два последних метода получения PSF.

PSF — Непосредственное наблюдение


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

Для этого я распечатал черный квадрат Малевича (да, тонера много ушло, но чего не сделаешь ради науки!), наложил с другой стороны фольгу, т.к. лист бумаги все же неплохо просвечивает и иголкой проколол маленькую дырочку. Затем соорудил нехитрую конструкцию из 200-ваттной лампы и сэндвича из черного листа и фольги. Выглядело это вот так:



Далее включил лампу, закрыл ее листом, выключил общий свет и сделал несколько фоток используя два объектива — китовый Canon EF 18-55 и портретник Canon EF 85mm/1.8. Из получившихся фоток я вырезал PSF и затем построил графики профилей.
Вот что получилось для китового объектива:



И для портретника Canon EF 85mm/1.8:



Хорошо видно как меняется характер боке с жествкого на мягкий для одного и того же объектива в случае переднего и заднего фокуса. Также видно, какую непростую форму имеет PSF — она весьма далека от идеального круга. Для портретника также видны большие хроматические аберрации из-за большой светосилы объектива и малой диафрагмы 1.8.

И вот еще пара снимков при диафрагме 14 — на нем видно, как поменялась форма с круга на правильный шестиугольник:



PSF — Вычисление или косвенное наблюдение


Следующий подход — косвенное наблюдение. Для этого, как писалось выше, нам нужно иметь исходное F(u,v) и искаженное G(u,v) изображения. Как их получить? Очень просто — необходимо поставить фотоаппарат на штатив и сделать один резкий и один размытый снимок одного и того изображения. Далее с помощью деления фурье-образа искаженного изображения на фурье-образ исходного изображения мы получим фурье-образ нашей искомой PSF. После чего применив обратное преобразование Фурье получим PSF в прямом виде.
Я сделал два снимка:





И в результате получил вот такую PSF:



На горизонтальную линию не обращайте внимания, это артефакт после преобразования Фурье в матлабе. Результат, скажем так, средненький — очень много шумов и детали PSF видны не так хорошо. Тем не менее, метод имеет право на существование.

Описанные методы можно и нужно использовать для построения PSF при восстановлении размытых изображений. Т.к. от того, насколько эта функция приближена к реальной напрямую зависит качество восстановления исходного изображения. При несовпадении предполагаемой и реальной PSF будут наблюдаться многочисленные артефакты в виде «звона», ореолов и снижения четкости. В большинстве случаев предполагается форма PSF в виде круга, тем не менее для достижения максимальной степени восстановления рекомендуется поиграться с формой этой функции, попробовав несколько вариантов от распространенных объективов — как мы видели, форма PSF может варьироваться в значительной степени в зависимости от диафрагмы, объектива и прочих условий.

Краевые эффекты


Следующая проблема заключается в том, что если напрямую применить фильтр Винера, то на краях изображения будет своеобразный «звон». Его причина, если объяснять на пальцах, заключается в следующем — когда делается деконволюция для тех точек, которые расположены на краях, то при сборке не хватает пикселей, которые находятся за краями изображения и они принимаются либо равным нулю, либо берутся с противоположной стороны (зависит от реализации фильтра Винера и преобразования Фурье). Выглядит это так:



Одно из решений, чтобы избежать этого состоит предобработке краев изображения. Они размываются с помощью той же самой PSF. На практике это реализуется следующем образом — берется входное изображение F(x,y), размывается с помощью PSF и получается F'(x,y), затем итоговое входное изображение F''(x,y) формируется суммированием F(x,y) и F'(x,y) с использованием весовой функции, которая на краях принимает значение 1 (точка целиком берется из размытого F'(x,y)), а на расстоянии равном (или большем) радиусу PSF от края изображения принимает значение 0. Результат получается такой — звон на краях исчез:



Практическая реализация


Я сделал программу, демонстрирующую восстановление смазанных и расфокусированных изображений. Написана она на C++ с использованием Qt. В качестве реализации преобразования Фурье я выбрал библиотеку FFTW, как самую быструю из опен-соурсных реализаций. Называется моя программа SmartDeblur, скачать ее можно на странице github.com/Y-Vladimir/SmartDeblur, все исходники открыты под лицензией GPL v3.
Скриншот главного окна:



Основные функции:
— Высокая скорость. Обработка изображения размером 2048*1500 пикселей занимает около 300мс в режиме Preview (когда перемещаются ползунки настроек) и 1.5 секунды в чистовом режиме (когда отпустили ползунки настроек).
— Подбор параметров в Real-time режиме. Нет необходимости нажимать кнопки Preview, все делается автоматически, нужно лишь двигать ползунки настроек искажения
— Вся обработка идет для изображения в полном разрешении. Т.е. нет никакого маленького окошка предпросмотра и кнопок Apply.
— Поддержка восстановления смазанных и расфокусированных изображений
— Возможность подстройки вида PSF

Основной упор при разработке был сделан на скорость. В итоге она получилась такая, что превосходит коммерческие аналоги в десятки раз. Вся обработка сделана по-взрослому, в отдельном потоке. За 300 мс программа успевает сгенерить новую PSF, сделать 3 преобразования Фурье, сделать деконволюцию по Винеру и отобразить результат — и все это для изображения размером 2048*1500 пикселей. В чистовом режиме делается 12 преобразований Фурье (3 для каждого канала, плюс одно для каждого канала для подавления краевых эффектов) — это занимает около 1.5 секунд. Все времена указаны для процессора Core i7.

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

Ну и в целом в процессе разработки пришлось обходить множество скрытых проблем как в FFTW (например не поддерживаются изображения с нечетным размером одной из сторон, типа 423*440.). Были проблемы и с Qt — выяснилось, что рендеринг линии со включенным Antialiasing работает не совсем точно. При некоторых значениях углов линия перескакивала на доли пикселя, что давало артефакты в виде сильной ряби. Для обхода этой проблемы добавил строчки:

    // Workarround to have high accuracy, otherwise drawLine method has some micro-mistakes in the rendering
    QPen pen = kernelPainter.pen();
    pen.setWidthF(1.01);
    kernelPainter.setPen(pen);


Сравнение


Осталось сравнить качество обработки с коммерческими аналогами.
Я выбрал 2 самые известные программы
1. Topaz InFocus — www.topazlabs.com/infocus
2. Focus Magic — www.focusmagic.com

Для чистоты эксперимента будем брать те рекламные изображения, которые приведены на официальных сайтах — так гарантируется, что параметры тех программ выбраны оптимальными (т.к. думаю, разработчики тщательно отбирали изображения и подбирали параметры перед публикацией в рекламе на сайте).
Итак, поехали — восстановление смаза:
Берем пример с сайта Topaz InFocus:

www.topazlabs.com/infocus/_images/licenseplate_compare.jpg


Обрабатываем с вот такими параметрами:


и получаем такой результат:


Результат с сайта Topaz InFocus:



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

Примеров сильно дефокусировки на сайте этой программы найти не удалось, да и она не предназначена для этого (максимальный радиус размытия составляет всего несколько пикселей).
Можно отметить еще один момент — угол наклона оказался ровно 45 градусов, а длина смаза 10 пикселей. Это наводит на мысль о том, что изображение смазано искусственно. В пользу этого факта говорит и то, что качество восстановления очень хорошее.

Пример номер два — восстановление дефокусировки. Для этого возьмем пример с сайта Focus Magic: www.focusmagic.com/focusing-examples.htm



Получили вот такой результат:

Результат SmartDeblur Результат Focus Magic

Тут уже не так очевидно, что лучше.

Заключение


На этом я хотел бы закончить эту статью. Хотя и много чего еще хотелось написать, но и так уже длинный текст получился. Буду очень признателен, если попробуете скачать SmartDeblur и потестировать на реальных изображениях — у меня, к сожалению, не так много расфокусированных и смазанных изображений, все поудалял.
И буду особо признателен, если пришлете мне (мыло есть в профиле) свой фидбек и примеры удачных/неудачных восстановлений. Ну и просьба сообщать о всех багах, замечаниях, предложениях — т.к. приложение еще пока местами сыроватое и немного нестабильное.
P.S. Исходники пока не очень чистые в плане стиля — там пока куча утечек памяти, еще не успел перевести на смарт-поинтеры, поэтому после нескольких изображений может перестать открывать файлы. Но в целом работает.

Ссылка на SmartDeblur: github.com/Y-Vladimir/SmartDeblur

UPD: Ссылка на продолжение

--
Vladimir Yuzhikov
Vladimir Yuzhikov @YUVladimir
карма
325,2
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

Комментарии (141)

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

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

        люблю KDE и linux

        Как-то одно противоречит другому, не находите?
        • +23
          Он к одной конкретной платформе не любит привязанность, очевидно.
        • –10
          Не нахожу.
        • +9
          Как-то одно противоречит другому, не находите?

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

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

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

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

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

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

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

                      Пахнет снобизмом, но:
                      Что раньше было трудолюбием — сейчас трудоголизм.
                      Что раньше было верностью — сейчас глупость.
                      Что раньше было вежливостью — сейчас снобизм…
                      • 0
                        Напускное и акцентированное «Вы» может задеть не меньше чем «ты».
                        Потому надо забивать, как к тебе обращаються и принимать оба варианта.
                        О чём я и сказал в первом сообщении ветки.
                        • –1
                          В английском поступили мудро — выпилили и оставили только один вариант.
                          • 0
                            Thoy?
                            • 0
                              Google Translate не знает такого слова.
                              • 0
                                Наверное, потому что «thou».
                                PS вроде известное же «So I dub thee unforgiven»
          • 0
            «Вы» нужно заслужить. Учите русский язык.
            • –3
              Еще один дотнетер учит меня жизни.
            • 0
              namespace заслужил уважение, я считаю. Это видно из комментариев его статей.
              • +1
                Уважение тех кто читал его статьи и посчитал их полезными — да. Для остальных — он просто человек, который грубо себя повел в комментариях (например как я в своем предыдущем комментарии, за что извиняюсь).

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

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

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

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

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

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

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

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

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

    upload.wikimedia.org/wikipedia/commons/c/c9/Dyatlov_Pass_incident_03.jpeg
    • +1
      Сделал.

      • 0
        Тут по идее надо еще больший радиус выставлять и менять PSF на восьмиугольник, тогда будет какой-то стоящий результат. Вообще с таким сильным размытием требуется, как правило, весьма кропотливая работа с подбором PSF и параметров.
      • 0
        Чёрт, так это пришельцы!
        • +6
          Черт, это сиськи!
    • 0
      Может быть кому интересно будет
      ru.wikipedia.org/wiki/Гибель_тургруппы_Дятлова
      • 0
        Да, известная история — насчет того размытого снимка, думаю что-то можно из него вытянуть ручным формированием PSF (Там он в виде правильного восьмиугольника с чуть скругленными краями.
  • 0
    А если в алгоритме обрезать края изображения, используя их только для этапа восстановления, то поможет ли это от ряби избавиться?
    • 0
      Надо не обрезать, а, наоборот, расширять.
      • 0
        Если задача — восстановить центр, то относительно центра картинка и расширяется.
        Относительно же целой картинки, восстановленная часть обрезается.
    • 0
      Изменять размер изображения очень дорого — требуется переинициализация всех массивов и FFTW. Сейчас в программе после загрузки изображения читается размер, инициализируется преобразование фурье этим размером, формируются полноразмерные входные и промежуточные буферы. Менять все это займет около секунды.
      На практике гораздо проще размыть края описанным в статье способом — звон на краях исчезает полностью
      • 0
        Владимир, а как насчет аподизации до ближайшей степени двойки?
        Расширяем картинку, за счет зеркалирования краевых пикселей.

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

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

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

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

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

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

            взяли маску
            посмотрели в какой прямоугольник вписались
            если вылезли за края исходной картинки то дополнили данными с противоположной стороны.
            получили результат наложили исходную непрямоугольную маску
  • 0
    коллеги, а в чем смысл? Качество восстановленных изображений сиииильно далеко от приемлемого для печати… только для анализа на предмет каких-то данных?
    • 0
      Именно. Это же точно не для фотопечати, а вот для определения виновника происшествия или для получения косвенной информации для аналитики — отличный инструмент!
    • 0
      Очень даже есть смысл. Например, в качестве предобработки для последующего оптического распознавания.
    • 0
      Смысл уже есть — техническое восстановление изображения в случае сильного размытия для чтения надписей, знаков. Для среднего и малого размытия уже можно говорить и о качестве приемлемом для печати. Посмотрите последние примеры с машиной или лицом — после небольшой постобработки качество вполне.
      Ну и главный смысл — практический опен-соурсный прогресс в решении задачи восстановления изображений.
    • 0
      Первые фотоаппараты выдавали изображение немногим лучше приведенных в статье, а хороший художник рисовал качественный эскиз быстрее, чем проявлялись первые фотопластинки и с меньшим числом неудач.
    • +1
      Научный интерес.
  • +1
    Фарш невозможно провернуть назад…
    Поется на мотив известной песни.
    • +3
      Фарш почти невозможно провернуть назад…
      Поётся на мотив топика ;)
  • +1
    Молодец! Нечто подобное было на конференции Adobe, и там подобная технология вызвала фурор: www.gizmag.com/official-adobe-deblur-video/20185/

    p.s. Мы круче дельцов из кремниевой долины :)
    • +4
      Да нет, они сделали очень крутую вещь — автоматический поиск матрицы деконволюции. Если приведенная в статье методика — это просто реализация «в лоб» нескольких математических формул, то решение от адоба — это уже научная работа, притом доведенная до коммерческого применения. А вообще это очень интересная задача, поиск матрицы деконволюции уже втречался мне в одной задаче из области теории управления, но опенсорсных решений так и не нашел, да и просто нормальных теоретических исследований в открытом доступе мало.
      • +1
        но почему?

        Статьи, тех парней есть в открытом доступе.
        вполне себе нормальный итеративный процесс описан.

        www.juew.org/publication/publications.htm
  • 0
    А фильтр для AviSynth есть? :-)
    • +1
      Если кто-то напишет, то будет )
  • 0
    Отличная статья, спасибо
    В свое время пытался заморочиться с этой тематикой, но не хватило трудолюбия довести дело до конца
    Я пробовал реализовать некоторые алгоритмы, основанные на регуляризации Тихонова.
    Вы не пробовали эти методы?
    • +1
      В первой части статьи пробовал и показывал результаты фильтра Винера, Тихонова, Люси-Ричардсона, слепую деконволюцию.
      • 0
        Да, есть, это я пропустил, спасибо
        Насколько я помню ту книгу, которую я использовал как источник знаний, там строились интегральные уравнения
        У вас довольно подробно описан сам алгоритм, это снижает немного порог вхождения
        Года два назад весь инет перерыл в поисках русскоязычных статей на эту тему
  • +1
    Надо камрадам с www.irfanview.com/ отписаться, дабы плагин для программы соответствующий сделали — сама реализация просто чудесная. Автору спасибо!
    • +3
      Уж лучше для GIMP плагин сделать ;)
      • +1
        Такой есть уже — refocus называется
        • 0
          Refocus с 2003-02-03 не развивается. А refocus-it с 2004-07-19.
          • 0
            Ну тогда можно портировать SmartBlur'овские исходники под GIMP-плагин :)
  • 0
    YUVladimir, а вы случайно в КГУ не преподавали? Вроде как у меня первая семестровая про обработку изображений от вас была :)
    • +1
      Да, было дело — в КГУ что-то преподавал :)
  • 0
    Будет интересно попробовать воспроизвести что-то подобное с помощью встроенных средств ImageMagick. Благо, фурье (точнее — получение спектра) и некоторые матричные операции над изображениями у него встроены.
    • 0
      Да, чуть покопался и нашёл на сайте ImageMagick статью с примерами:
      www.imagemagick.org/Usage/fourier/fft_math/

      В общем, всё можно делать, так сказать, «штатными» средствами :).
      • 0
        Да, такие вещи легко делаются любыми тулами, которые поддерживают преобразование Фурье. На FFTW это можно тоже в несколько строчек сделать — собственно умножить одну матрицу на другую.
        Основные сложности появляются при обработке реальных иображений — вот там и вылезают влияние шума, краевые эффекты, необходимость подстраивать PSF. Ну и плюс обеспечение высокой скорости.
        По факту SmartDeblur — это реализация одной весьма простой формулы фильтра Винера, которая известна уже 70 лет, но вот качественно и удобно реализовать, учесть все подводные камни, это уже сложнее.
        • +1
          А еще выскакивает квантование при делении на малые числа: float оказывается совершенно недостаточно, а double многовато памяти жрет. Но даже double вблизи нулей ОПФ дает при делении хорошие такие выбросы.
          • 0
            В век когда доступно более 4гб «double жрётмноговато памяти»?
            Да хоть в long double можно считать если это добавит качество.
            • 0
              > В век когда доступно более 4гб «double жрётмноговато памяти»?

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

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

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

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

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

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

    Qt 4.6.2 не катит?
    • 0
      Я собирал под Qt 4.8, похоже в 4.6 еще не было constScanLine
  • 0
    Интересно, а к видео это можно как-нибудь применить?
    • +1
      Можно, только вопрос чего хочется добиться.
      Нужно каким-то образом разделять регионы с плохим фокусом или смазом, а потом определять параметры и делать деконволюцию.
      Таких работ тоже довольно много, в качестве примера можно взять MSU Dblur

      ДО:
      image

      ПОСЛЕ:
      image

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

      ДО:
      image

      ПОСЛЕ:
      image

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