Дымка на изображениях может стать настоящей проблемой, и не всегда для ее удаления нужны сложные алгоритмы или нейронные сети. Я хочу продемонстрировать реализацию метода удаления дымки Robust Single Image Haze Removal Using Dark Channel Prior and Optimal Transmission Map and Adaptive Atmospheric Light (Удаление дымки с использованием метода предварительного темного канала, карты пропускания и не однородного света) в .NET.

Преимущества подхода:

  1. Простота и эффективность: Метод, основанный на интуитивных принципах обработки изображений, легко воспринимается и прост в реализации. Использование только математических операций, и зная их параметры, в итоговом изображении никогда не будут присутствовать неизвестные артефакты или “фантомы”. Работа с изображением не будет выглядеть как копание в черном ящике с параметрами нейронной сети или библиотеки с закрытым алгоритмом.

  2. Отсутствие зависимости от обучающих данных: Не требует сложного обучающего набора данных, что сокращает затраты и упрощает процесс.

  3. Высокая скорость работы: Работает быстро и не требует значительных вычислительных ресурсов.

  4. Прозрачность и интерпретируемость: Легко понимаемый метод обработки изображений, что упрощает объяснение и обоснование результатов.

  5. Универсальность: Хорошо работает на различных типах изображений и условиях освещения без необходимости сложной перенастройки.

Используемые инструменты:

Для решения задачи удаления дымки мы используем библиотеку EmguCV, обертку для OpenCV в .NET. Этот инструмент обеспечивает удобный доступ к широкому спектру функций обработки изображений и видео, и матриц вообще. Причем синтаксис для работы с CPU и GPU примерно одинаковый new Mat() или new GpuMat(). Но есть отличие в вызове методов, которое унаследовано из OpenCV . И при работе с GpuMat требуется более тщательно следить за сборкой мусора, или реализовать свой интерфейс с GC, или придется постоянно использовать using. На github есть issue по очистке памяти GpuMat , но, пока оно не закрыто.

Схема атмосферного света была любезно предоставлена mirasnowfox

Основные компоненты этого метода включают:

  1. Оценка атмосферного света:

используя квадратное разложение

выберем область с наибольшей яркостью

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


private Mat ComputeDarkChannelPatch(Image<Bgr, float> srcImage, int patch)
        {
            var bgrChannels = srcImage.Clone().Mat.Split();
            var darkChannel = new Mat();
            CvInvoke.Min(bgrChannels[0], bgrChannels[1], darkChannel);
            CvInvoke.Min(darkChannel, bgrChannels[2], darkChannel);
            CvInvoke.Erode(darkChannel, darkChannel, null, new Point(-1, -1), patch, BorderType.Reflect101, default);
            return darkChannel;
        }

Формула d(x,y)=min(R(x,y),B(x,y),G(x,y)) где R(x,y) , B(x,y) и G(x,y) представляют интенсивность красного, зеленого и синего каналов для каждого пикселя соответственно. Сортируем и выбираем некоторый процент наиболее ярких пикселей, затем вычисляем для них среднее значения Ac по каждому каналу RGB.

  1. Построение оптимальной карты трансмиссии:

строим карту трансмиссии

по формуле t(x,y)=e^{-\beta*d(x,y)} где коэффициент ослабления атмосферы, которая оптимально отражает степень проникновения света через туман в каждой точке изображения. Хотя есть более простая альтернатива t(x,y)=1-{\omega}*d(x,y) где \omega количество дымки для удаления

  1. Уточнение карты трансмиссии:

к полученной карте трансмиссии применим Guided Filter, для

для смягчения краев у ярких мест изображения. Это могут быть источники света, места с сильным эффектом дымки, различные отражающие поверхности. Для GPU версии я использовал работу Kaiming He (kahe@microsoft.com) реализация в MATLAB http://research.microsoft.com/en-us/um/people/kahe/eccv10/guided-filter-code-v1.rar

  1. Восстановление изображения:

производится по формуле: J(x,y)=\frac{I(x,y)-A_c}{max(t(x,y),t_{min})}+A_c где I(x,y) - значение туманного пикселя, J(x,y) - значение безтуманного пикселя.

Для сравнение изображение перед обработкой

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

Ссылка на проект github

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


  1. mobi
    27.04.2024 04:46
    +4

    А почему работа ведется в RGB-пространстве? Мне кажется, было бы логичнее сначала перейти в любое цветовое пространство, где яркость является одним из компонентов, провести там коррекцию, а потом уже вернуться в RGB.


    1. maksim_sitnikov Автор
      27.04.2024 04:46

      Есть другой вариант дехейзинга где работа видеться не через RGB, и с использованием DCP, попробую описать его отдельно. Кстати хочу заметить что тут оно BGR, но это к сведению. В одном из вариантов, который попробую описать позже, можно будет заодно прикрутить пирамиды Гауса и Лапласа для вместо Guided Filter. Интересные штуки,но памяти жрут как не в себя.


      1. mobi
        27.04.2024 04:46
        +1

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

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


        1. maksim_sitnikov Автор
          27.04.2024 04:46

          Есть варианты и с учетом релеевского расселения, но судя по опытам в матлабе и публикациям на arxive.org супер эффекта это не дает, поиск поиск экстремумов по B и отдельно между R и G для вычисления величины атмосферного света, возможно на больших разрешениях, но это нужно пробовать.


  1. Lord_Ahriman
    27.04.2024 04:46

    Вы бы КДПВ сделали аккуратнее, а то изначально вообще в ленте показалось, что это два разных фото с разными ракурсами (в самой статье видно, что это не так),
    И присоединюсь к вопросу выше: почему бы не работать в пространстве, где яркость есть в явном виде?


    1. maksim_sitnikov Автор
      27.04.2024 04:46

      Ответил выше. И добавлю именно математика в варианте с RGB нагляднее и понятнее. Ну, мне так кажеться.


  1. Zara6502
    27.04.2024 04:46

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


    1. maksim_sitnikov Автор
      27.04.2024 04:46

      Конструктивно, а потом граммар-наци без него просто распнут.


      1. Zara6502
        27.04.2024 04:46
        +1

        "тся" сильно чаще встречается в тексте, так что шансы написать неправильно всё равно снизятся. Так же опустить "ь" можно списать на торопливость или еще какие-то причины, а вот сознательную печать - уже на безграмотность. Правило же безумно простое, вы перед отправкой разве не вычитываете то что людям пишете? Ну режет же безумно слух "Ну, мне так кажеться." - мне "что делаЕТ?" - кажеТСЯ. "где работа видеться" - "работа что делаЕТ?" - видиТСЯ. Не мог "что сделаТЬ?" - видеТЬСЯ с друзьями. Даже смысл другой.

        Ну и по классике:

        оно даже подчеркивается


        1. maksim_sitnikov Автор
          27.04.2024 04:46

          Я не нашелЪ этого мiста в стате. Можете помоч показат где в статье есть слово кажеться/кажется? Очень хочу исправить. И да, держу в курсе у меня дислексия, я иногда не только жышы могу написать у меня гласные печатаються раньше согласных. И , как мне показалось, будто вы чем то жизнью обижены? Показалось? Будьти позитивнее - улучшает настроение - продлевает жизнь.


          1. Vitimbo
            27.04.2024 04:46

            у меня дислексия

            Если это реально диагноз, то позвольте вопрос. Как с этим код пишется? С C# intellisense поможет, но в профиле вижу еще и питон. Можно словить интересных ошибок.


            1. maksim_sitnikov Автор
              27.04.2024 04:46

              Бывают сложности :(, главное не набирать быстро, ну и читать поправлять, ну и да иде помогает. И ещё меня поправили, не дислексия, дисграфия


              1. Zara6502
                27.04.2024 04:46

                главное не набирать быстро, ну и читать поправлять

                и что вам мешало поправить написанное ранее и не устраивать тут лекцию про ваш диагноз?


          1. Zara6502
            27.04.2024 04:46

            Я не нашелЪ этого мiста в стате

            А оно не в статье

            Можете помоч показат где в статье есть слово кажеться/кажется? Очень хочу исправить

            Вы даже читаете плохо, я нигде не писал про статью.

            И да, держу в курсе у меня дислексия

            Первое. Это не оправдание хотя бы потому, что я вам уже показал - в браузере есть проверка орфографии и для её использования дисграфия не помеха. Второе - у меня тоже дисграфия, шах и мат. Только когда у меня эта проблема появилась еще в школе (80-е годы), то никто не знал что это и просто всё сводилось к тому, что я двоечник по русскому. "Вылечилось" всё, если так можно сказать - начитанностью книг, то есть я перестал писать слова как совокупность слогов, а пишу слова целиком, помня как именно их нужно писать в такой ситуации. Если я повышаю темп набора, то у меня запросто получаются слова "элкеторфиакция", и размер этого повышения улыбнёт любого, кто набирает слепым набором, так как это всё еще очень медленно.

            И , как мне показалось, будто вы чем то жизнью обижены?

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

            Будьти позитивнее - улучшает настроение - продлевает жизнь

            А откуда взяться позитиву в нежелании человека окружающим делать хорошо?

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

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

            Ну и ещё поговорка "относись к людям так, как хочешь, чтобы они относились к тебе". И я всегда ПОЗИТИВНО встречаю все претензии к моей орфографии, так как у меня будет возможность научиться еще чему-то, но я всегда негативен к тем, кто ленится, исповедует принципы "и так сойдёт" (во всём), и кто неуважителен к тем, с кем он общается. Да-да, мил человек, когда ты заставляешь читать свою тарабарщину других, то ты просто плюёшь на них, прикрываясь своими проблемами.


  1. MANAB
    27.04.2024 04:46

    Как это дополнительно влияет на качество фото? Добавляет/убирает цифровой шум, зернистость, еще что-нибудь?


    1. maksim_sitnikov Автор
      27.04.2024 04:46

      Там есть управляющие параметры, если мы например исключим сглаживание карты трансмиссии то появиться зернистость обусловленная размером патча для тёмного канала. Так как мы искали локальные минимумы и выставляли их в окне патча, я думаю размер патча нужно брать в процентах от размера изображения, слишком мелкий может не убрать засветы от частиц, слишком крупный засветы уберёт но снизиться общая яркость. Шум может быть только от фильтра сглаживания для тёмного канала, но это максимально нивелируется тем что он влияет опосредовано только как коэффициенты для каждого пикселя. Субъективно скорее убирает шум. Зернистость можно получить пропустив этап сглаживания тёмного канала и увеличив размер патча, предметы будут чётче но общая яркость упадёт.


  1. Jury_78
    27.04.2024 04:46

    Глупый вопрос, а просто контраст подкрутить не тоже самое?


    1. maksim_sitnikov Автор
      27.04.2024 04:46

      Не совсем, так же и если яркость убирать добавлять, меняя контраст/яркость вы как бы нормализуете всё пиксели по всём каналам сразу, тут же более индивидуальный подход и к пикселям и каналам. Я уже выше писал, постараюсь сделать работу по DCP для дехейзинга с использованием формата HSV.