Где я могу найти хорошую информацию о бикубической интерполяции и повторной выборке Ланцоша? - PullRequest
17 голосов
/ 03 июня 2009

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

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

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

Ответы [ 3 ]

12 голосов
/ 04 июня 2009

Хотя то, что говорит Антс Аасма, примерно описывает разницу, я не думаю, что она особенно информативна в отношении того, почему вы могли бы сделать такую ​​вещь.

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

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

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

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

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

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

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

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

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

12 голосов
/ 04 июня 2009

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

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

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

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

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

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

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

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

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

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

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

Кроме того, image_operations.cc и convolver.cc в Skia имеют довольно хорошо прокомментированную реализацию интерполяции Ланцоша.

5 голосов
/ 17 января 2013

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

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

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

...