Как стать автором
Обновить

Максимально точное увеличение разрешения изображений: билинейная аппроксимация

Уровень сложностиСредний
Время на прочтение8 мин
Количество просмотров4.5K
Всего голосов 17: ↑17 и ↓0+20
Комментарии19

Комментарии 19

Аж ностальгия в глаз попала. А про глобальный кубический (с контролем производных) и сплайн Акимы будет?

Если сил хватит или найду готовую программу специально для изображений, постараюсь. Уточните, что значит с контролем производных? Я так понял глобальный кубический сохраняет производные до второй. В чём контроль?

Да иммено сохранение имел ввиду.

После выхода вашей первой статьи выложил в паблик и свою поделку на ту же тему. Бонусом идёт решение проблемы крайних значений (чтобы не было яркости меньше нуля и больше максимума), ресайз в линейном цветовом пространстве (проходит тест с картинкой scaling software rulez) и с предумноженной альфой.

https://crates.io/crates/sharpened_bilinear

Большое спасибо, изучу, а можно ещё релиз *.exe на гитхаб?

Windows Defender'ом - Защитником Windows

https://www.virustotal.com/gui/url/ffe23bceaf14e889c20a9d67d106c6d8ba6fb3dc58a78bde21a4abddd3027258
ВирусТотал не видит троянов. Windows Defender я не отключал. Но трояны, конечно, могут быть, просто я не в курсе.

Лучше изучите исходный код на отсутствие закладок (там всего 300 строк без каких-либо подозрительных частей, и две известные и проверенные временем зависимости), поставьте компилятор Rust (https://www.rust-lang.org/tools/install, нужно скачать и запустить инсталлятор. И если инсталлятор попросит, то поставить Microsoft C++ Build Tools), и скомпилируйте самостоятельно запустив команду `cargo build --release` в папке с кодом, после чего в подпапке target появится exe-шник.

в URL конечно не будет вирусов - там 200 Success "view-source:https://github.com/orekhoff/sharpened_bilinear/releases/download/v1.0.0/sharpened_bilinear.exegithub.com" - там *.exe нету, проверьте свой компьютер "Полная проверка" любым антивирусом с последними сигнатурами (обновлениями)

Попробовал Kaspersky VRT, ничего не нашёл. VirusTotal прошёл по ссылке и скачал весь 5.42 МБ блоб, но я так же загрузил и сам файл вручную - на этот раз один антивирус на что-то ругнулся, но остальные ничего не обнаружили, так что считаю это ложным срабатыванием.

Можно подробнее про алгоритм? На взгляд - происходит билинейная интерполяция с краевой сеткой, а потом корректировка ближайшим соседом с центрированной сеткой. У Вас интерполяция в итоге или есть и экстраполяция (значения 4 точек влияют и за пределами квадрата, который они образуют)? (В Rust и чужом коде плохо разбираюсь)

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

Значения в узлах сетки билинейного интерполянта нам неизвестны, их нужно найти. Для начала положим их равными яркостям пикселей. Для каждого пикселя изображения находим каким должно быть значение яркости в узле сетки в его центре, чтобы интеграл от +/-0.5 для x и y дал значение яркости как у пикселя исходного изображения, и присваиваем это значение узлу сетки. Так как значения соседних пикселей так же изменились, а наш интеграл зависит от соседей, то значение оказалось немного неверным, так что повторяем процедуру пока ошибка не станет пренебрежимо мала. Попутно следим, чтобы значения сетки не выходили за пределы 0 и 1, а если есть альфа, то и не превышали альфу.

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

Круто - реверс интерполяции!

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

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

Обычно, проблема, которой вы занялись, называется Super-Resolution (супер-резолюция). Погуглите, много информации найдете. То что вы называете "звоном", это Gibbs ringing artefacts. Извините, по-русски не знаю как называется. Эх, горячая была тема лет 10 тому назад. "Условие среднего" вы называете непосредственно постановку задачи, которую вы правда не довели до конца.

Представте, что у вас подряд идут значения пикселей в оригинальной картинке (рассматриваем как бы одномерный случай):

x_1, x_2, x_3, ... , x_n

А в текущей (известной) картинке у вас другие значения:
 y_1 = (x_1+x_2)/2, y_2 = (x_3+x_4)/2, ... , y_{n/2}=(x_{n-1}+x_n)/2. И их в 2 раза меньше чем иксов. У вас, как я понимаю, чуть более сложное представление, и не в 2 раза а больше, но его, все-равно, можно привести в подобный вид. Для простоты пусть будет в 2.

И теперь задача теперь сводится к тому чтобы найти иксы, при заданных игреках. Задача линейная, значит её можно решить матричными методами, а поскольку количество неизвестных больше чем известных, то 100% восстановить удаленную информацию невозможно. Отсюда и ringing artefacts появляются. Как вы возможно заметили, в моём уравнении игреки независимы друг от друга, и вроде как могут решаться независимо, но поскольку мы все-таки в 2Д и плюс мы ходим выудить что-то еще из данных (те-же производные), то они перестают быть независимы и становятся "сцеплены" друг с другом. Это все можно записать в виде большой прямоугольной матрицы n x (n/2), и добавлять кучу разных условий туда. И что-бы производные хорошо подходили, а можем и вторые производные запихнуть. Но вся мякотка в том что можно еще кучу интересных условий надобавлять. Например, мы знаем что градиенты в натуральных изображениях распределены по Гауссу, а может даже и Лапласу. Это значит что разница между соседними пикселями чаще всего мала, а если нужен резкий переход он должен проходить как можно чётче. С помощью хитрых способов это все можно завернуть в ту самую матрицу.

Есть еще другие трюки, типа BM3D. Утверждаем что в каждой картинке для кажного блока пикселей 8x8 пожно найти еще несколько очень похожих блоков. Почти в любых текстурах можно найти много повторений. Это значит что для восстановления иксов можно пользоваться информацией не только от соседних пикселей, но и пикселей что в похожих блоках. Тут уже не матричные методы правда.

Потом, Compressive Sensing, это уже десерт. Мы знаем что натуральные изображения очень хорошо сжимаются всякими преобразованиями типа Фурье или Косинусного. А почему бы тогда не искать неизвестные иксы не в пиксельном представлении, а прямо в спектральном? Оказывается что нам нужно найти не так уж и много неизвестных, а остальные компоненты спектра будут нули. Это ваще бомба.

Для больших картинок матричные методы со временем становятся слишком тяжелыми. Хотя, всегда можно сказать что информация о пикселе не может слишком уж далеко от него быть, поэтому все эти иксы можно икать по очереди в независимых окнах, и распараллелить даже. Но потом пришли нейросети и заменили всю эту математику практически везде. Теперь super-resolution делается на StableDiffusion и миллионе похожих архитектур. Ха-ха, без видео-карты от NVidia теперь уже и пернуть нельзя ))

Спасибо за информацию, уверен вместе мы, если не придём к решению, то хотя бы обнаружим лучшее из уже созданных! Чёткая постановка задачи будет в следующей статье. Матричное решение - супер, только пока в конкретном виде я его не видел. Есть пара идей по Compressive Sensing - они в будущих статьях. Если мы хотя бы сможем математически понять решение (пусть уже существующее в виде нейросети), то, уверен, это снизит времязатраты (сложность) алгоритма и галлюцинации, вызванные избыточностью и перетренированностью нейросети.

Бедный Ланцош, что только с его фамилией не делали

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории