6

我有一个需要在屏幕上移动图像的系统。我目前正在使用 png 并将其放置在所需的屏幕坐标处。

由于屏幕分辨率和所需帧速率的结合,一些帧是相同的,因为图像还没有移动一个完整的像素。不幸的是,屏幕的分辨率是不可协商的。

我对亚像素渲染如何平滑边缘有一个大致的了解,但我一直无法找到资源(如果存在)来了解如何使用着色将图像转换小于一个像素。

理想情况下,这可以用于任何图像,但如果只能用于简单的形状,如圆形或环形,那也是可以接受的。

4

2 回答 2

12

亚像素插值相对简单。通常,您应用相当于具有恒定相移的全通滤波器,其中相移对应于所需的子像素图像偏移。根据所需的图像质量,您可能会使用例如 5 点Lanczos或其他窗口 sinc 函数,然后根据您想要 X 位移或 Y 位移或两者都将其应用于一个或两个轴。

例如,对于 0.5 像素移位,系数可能为[ 0.06645, 0.18965, 0.27713, 0.27713, 0.18965 ]. (请注意,系数是标准化的,即它们的总和等于 1.0。)

要生成水平偏移,您可以将这些系数与从x - 2到的像素进行卷积x + 2,例如

const float kCoeffs[5] = { 0.06645f, 0.18965f, 0.27713f, 0.27713f, 0.18965f };

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
    }
于 2011-09-14T13:48:12.843 回答
1

从概念上讲,操作非常简单。首先你放大图像(使用任何你喜欢的插值方法),然后你翻译结果,最后你对原始图像大小进行二次采样。

比例因子取决于您想要进行的亚像素平移的精度。如果要平移 0.5 度,则需要将原始图像放大 2 倍,然后将结果图像平移 1 个像素;如果要平移 0.25 度,则需要放大 4 倍,以此类推。

请注意,此实现效率不高,因为当您按比例放大时,您最终会计算出您实际上不会使用的像素值,因为当您对原始图像大小进行二次采样时,它们只是被丢弃了。保罗的答案中的实施更有效。

于 2018-11-29T16:45:00.463 回答