c++ - 双线性插值,我的实现有问题

标签 c++

我正在尝试实现双线性插值函数,但由于某种原因,我的输出很糟糕。我似乎无法弄清楚出了什么问题,任何帮助走上正轨的人都将不胜感激。

double lerp(double c1, double c2, double v1, double v2, double x)
{
if( (v1==v2) ) return c1;
double inc = ((c2-c1)/(v2 - v1)) * (x - v1);
double val = c1 + inc;
return val;
};

void bilinearInterpolate(int width, int height)
{
// if the current size is the same, do nothing
if(width == GetWidth() && height == GetHeight())
    return;

//Create a new image
std::unique_ptr<Image2D> image(new Image2D(width, height));

// x and y ratios
double rx = (double)(GetWidth()) / (double)(image->GetWidth()); // oldWidth / newWidth
double ry = (double)(GetHeight()) / (double)(image->GetHeight());   // oldWidth / newWidth


// loop through destination image
for(int y=0; y<height; ++y)
{
    for(int x=0; x<width; ++x)
    {
        double sx = x * rx;
        double sy = y * ry;

        uint xl = std::floor(sx);
        uint xr = std::floor(sx + 1);
        uint yt = std::floor(sy);
        uint yb = std::floor(sy + 1);

        for (uint d = 0; d < image->GetDepth(); ++d)
        {
            uchar tl    = GetData(xl, yt, d);
            uchar tr    = GetData(xr, yt, d);
            uchar bl    = GetData(xl, yb, d);
            uchar br    = GetData(xr, yb, d);
            double t    = lerp(tl, tr, xl, xr, sx);
            double b    = lerp(bl, br, xl, xr, sx);
            double m    = lerp(t, b, yt, yb, sy);
            uchar val   = std::floor(m + 0.5);
            image->SetData(x,y,d,val);
        }
    }
}

//Cleanup
mWidth = width; mHeight = height;
std::swap(image->mData, mData);
}

Input Image (4 pixels wide and high)

输入图像(4 像素宽和高)

My Output

我的输出

Expected Output (Photoshop's Bilinear Interpolation)

预期输出(Photoshop 的双线性插值)

最佳答案

Photoshop 的算法假设每个源像素的颜色位于像素的中心,而您的算法假设颜色位于像素的左上角。与 Photoshop 相比,这会导致您的结果向上和向左移动半个像素。

另一种看待它的方法是,您的算法将 x 坐标范围 (0, srcWidth) 映射到 (0, dstWidth),而 Photoshop 映射 (-0.5, srcWidth-0.5)(-0.5, dstWidth-0.5),y坐标相同。

代替:

double sx = x * rx;
double sy = y * ry;

您可以使用:

double sx = (x + 0.5) * rx - 0.5;
double sy = (y + 0.5) * ry - 0.5;

得到相似的结果。请注意,这可能会给您 sxsy 一个负值。

关于c++ - 双线性插值,我的实现有问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10720586/

相关文章:

c++ - std::vector 在 iOffset 位置更新 N 个值

c++ - C++中的url响应时间跟踪器

c++ - libc++ 与 VC++ : Can non-UTF conversions be done with wstring_convert?

c++ - cairo 上下文中的鼠标事件

c++ - c++中唯一标识任意对象

c++ - 函数中参数包后的参数

c++ - 这个加法类会不会导致内存泄露?

c++ - 存放高分表,用什么容器?

c++ - 为什么 static_cast 可以编译将原始指针转换为智能指针

c++ - Visual Studio 2005/08/10 是否会取代嵌入式 Visual C++ 4.0?