插值用于在 OpenCV 中平滑缩小图像

interpolation for smooth downscale of image in OpenCV

本文关键字:平滑 缩小 图像 OpenCV 用于 插值      更新时间:2023-10-16

我注意到,在下面两种将图像缩放N一半的方法中,第一种方法产生了更平滑的图像,看起来更吸引眼睛。

    while (lod-- > Payload->MaxZoom)
    {
        cv::resize(img, img, cv::Size(), 0.5, 0.5, cv::INTER_LINEAR);
    }

    double scale = 1.0 / (1<< (lod - Payload->MaxZoom));
    cv::resize(img, img, cv::Size(), scale, scale, cv::INTER_LINEAR);

我很想知道是否有一个插值会产生与第一次调整大小类似的结果,但不必循环 N 次。

关于为什么以乘数步长调整大小可以产生更好结果的任何数学见解也很有趣。

上面的后一种方法给出了一个非常像素化的结果(对于 N=5),其中第一个非常平滑(这是有道理的,因为它是 N 步 4 个像素的平均值)

发生这种情况是因为OpenCV的线性插值实现相当简单。

线性插值的简单实现采用最接近插值点的四个像素的值,并在它们之间进行插值。这对于放大是可以的,但是对于缩小,这将忽略许多像素的值 - 如果输出图像中有 N 个像素,则它取决于输入的最多 4N 个像素。当比例因子的乘积低于 0.25 时,这不能给出良好的结果。

正确的做法是考虑转换后与输出像素对应的所有输入像素,并计算它们的平均值(或者更一般地说,使用合适的重采样滤波器计算卷积)。

OpenCV似乎有一个名为cv::INTER_AREA的插值模式,它应该做你想要的事情。