Как я могу перевести изображение с точностью до субпикселя? - PullRequest
5 голосов
/ 14 сентября 2011

У меня есть система, которая требует перемещения изображения на экране. В настоящее время я использую png и просто помещаю его в нужные координаты экрана.

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

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

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

Ответы [ 2 ]

10 голосов
/ 14 сентября 2011

Субпиксельная интерполяция относительно проста.Как правило, вы применяете то, что составляет фильтр всех проходов с постоянным фазовым сдвигом, где фазовый сдвиг соответствует требуемому сдвигу субпиксельного изображения.В зависимости от требуемого качества изображения вы можете использовать, например, 5-точечную Lanczos или другую оконную функцию sinc, а затем применить ее по одной или обеим осям в зависимости от того, хотите ли вы сдвиг X или Y или оба.

Например, для сдвига в 0,5 пикселя коэффициенты могут быть [ 0.22954, 0.65507, 0.95725, 0.95725, 0.65507 ].Чтобы сгенерировать горизонтальный сдвиг, вы должны свести эти коэффициенты с пикселями от x - 2 до x + 2, например,

const float kCoeffs[5] = { 0.22954f, 0.65507f, 0.95725f, 0.95725f, 0.65507f };

for (y = 0; y < height; ++y)         // for each row
    for (x = 2; x < width - 2; ++x)  // for each col (apart from 2 pixel border)
    {
        float p = 0.0f;              // convolve pixel with Lanczos coeffs

        for (dx = -2; dx <= +2; ++dx)
            p += in[y][x + dx] * kCoeffs[dx + 2];

        out[y][x] = p;               // store interpolated pixel
    }
1 голос
/ 29 ноября 2018

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

Коэффициент масштабирования зависит от точности перевода субпикселя, который вы хотите сделать. Если вы хотите перевести на 0,5 градуса, вам нужно увеличить исходное изображение в 2 раза, а затем перевести полученное изображение на 1 пиксель; если вы хотите перевести на 0,25 градуса, вам нужно увеличить в 4 раза и т. д.

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

...