Подтвердить что ты не робот

Где я могу найти хорошее чтение о бикубической интерполяции и повторной выборке Lanczos?

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

Я пробовал читать Википедию, но материал для меня слишком сух. Может быть, есть более приятные объяснения этих алгоритмов? Я ничего не мог найти ни на SO, ни в Google.

Добавлено: Похоже, никто не может дать мне хорошую ссылку на эти темы. Может кто-нибудь хотя бы попытаться объяснить их здесь?

4b9b3361

Ответ 1

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

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

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

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

Для интерполяции lanczos функция свертки основана на функции sinc (x) = sin (x * pi)/x, но берутся только первые несколько лепестков. Обычно 3:

lanczos(x) = {
    0 if abs(x) > 3,
    1 if x == 0,
    else sin(x*pi)/x
}

Эта функция называется ядром фильтра.

Чтобы выполнить повторный выбор с помощью lanczos, предположите, что вы накладываете вывод и ввод через eachother, с точками, указывающими, где расположены пиксели. Для каждого местоположения выходного пикселя вы берете прямоугольник + - 3 выходных пикселя из этой точки. Для каждого входного пикселя, который находится в этом поле, вычислите значение функции lanczos в этом месте с расстоянием от местоположения вывода в координатах выходного пикселя в качестве параметра. Затем вам необходимо нормализовать вычисленные значения, масштабируя их так, чтобы они добавили до 1. После этого умножьте каждое значение входного пикселя на соответствующее значение масштабирования и добавьте результаты вместе, чтобы получить значение выходного пикселя.

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

Бикубическая свертка в основном такая же, с другой функцией ядра фильтра.

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

Кроме того, image_operations.cc и convolver.cc в skia есть довольно хорошо прокомментированная реализация интерполяции lanczos.

Ответ 2

В то время как то, что говорит Ants Aasma, грубо описывает разницу, я не думаю, что это особенно информативно, почему вы можете так поступать.

Что касается ссылок, вы задаете очень простой вопрос в обработке изображений, и любой достойный вступительный учебник по этому вопросу описывает это. Если я правильно помню, Gonzales and Woods по-настоящему приличный, но я не могу прочитать свои книги и не могу проверить.

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

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

Теперь изображение двухмерное, поэтому вы действительно хотите сделать это как в левом, так и в верхнем направлениях. Используйте результат для вашей оценки и вуаля, у вас есть "билинейная" интерполяция.

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

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

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

Оказывается, вы можете спроектировать ядро ​​свертки, которое имеет свойства, подобные кубическому сплайну, и использовать его для получения быстрого "бикубического"

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

Ответ 3

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

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

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