双线性插值纯C实现

最近在学双线性插值,由于需要纯C的代码,就根据网上的博文自己改了一下,仅供参考,有问题可以一起讨论。

原理及推理过程参考博文https://blog.youkuaiyun.com/xbinworld/article/details/65660665

我写一下最终计算的公式,也就是代码中用到的公式。注意,图中的x2-x1=1,y2-y1=1

C代码如下。注:该代码仅支持8位深图像,如果考虑其他位深,需要传入位深信息,并在像素计算处考虑位深信息。

int bilinearInterpolation(unsigned char * srcIm, int srcW, int srcH, int channel, unsigned char * dstIm, int dstW, int dstH)
{
    float scale_x = float(srcW) / dstW;//缩放比例
    float scale_y = float(srcH) / dstH;
    int scale_int = 2048;//浮点数转成整数的比例
    int scale_bit = 22;//计算像素点时比例乘了两次,所以移位11*2
    //int scale_int = 32;
    //int scale_bit = 10;

    for (int j = 0; j < dstH; j++)
    {
        float fy = scale_y * (j + 0.5f) - 0.5f;//对齐
        int sy = floor(fy);
        fy -= sy;
        int fy_int = fy * scale_int;
        int fy_int_invert = scale_int - fy_int;
        sy = max(0, sy);
        sy = min(sy, srcH - 2);

        for (int i = 0; i < dstW; i++)
        {
            float fx = scale_x * (i + 0.5f) - 0.5f;
            int sx = floor(fx);
            fx -= sx;
            int fx_int = fx * scale_int;
            int fx_int_invert = scale_int - fx_int;
            sx = max(0, sx);
            sx = min(sx, srcW - 2);
                      
            for (int z = 0; z < channel; z++)
            {
                dstIm[j * dstW * channel + i * channel + z] = max(0, int((
                    srcIm[sy * srcW * channel + sx * channel + z] * fx_int_invert * fy_int_invert +
                    srcIm[sy * srcW * channel + (sx + 1) * channel + z] * fx_int * fy_int_invert +
                    srcIm[(sy + 1) * srcW * channel + sx * channel + z] * fx_int_invert * fy_int +
                    srcIm[(sy + 1) * srcW * channel + (sx + 1) * channel + z] * fx_int * fy_int) >> scale_bit));
           }
        }
    }

    return 0;
}

测试代码。注意:如果想比较像素值的差异,需要保存成bmp格式,不要保存成jpg!!!

#include <opencv2\opencv.hpp>
using namespace cv;

cv::Mat matSrc, matDst1, matDst2;
matSrc = cv::imread("D:\\3color.jpg", 2 | 4);
matDst1 = cv::Mat(cv::Size(500, 200), matSrc.type(), cv::Scalar::all(0));
matDst2 = cv::Mat(cv::Size(500, 200), matSrc.type(), cv::Scalar::all(0));

bilinearInterpolation(matSrc.data, matSrc.cols, matSrc.rows, matSrc.channels(), matDst1.data, matDst1.cols, matDst1.rows);
cv::imwrite("linear_self.bmp", matDst1);

cv::resize(matSrc, matDst2, matDst1.size(), 0, 0, 1);
cv::imwrite("linear_opencv.bmp", matDst2);

遗留问题:浮点数转成整数计算后,像素差异最大值是多少?

1/2048*256*4=0.5

所以差异为正负1?求解答。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值