双线性内插法--图像缩放算法

8 篇文章 4 订阅

目录

一、问题描述

二、算法原理

双线性内插法

双线性内插法参数计算

三、算法效果

四、算法代码


一、问题描述

我们在处理图像的时候常常会遇到图像放大的问题,那么选择什么样的图像放大算法,能有什么样的效果,就是我们比较关心的问题了。最近(其实是很久以前),我根据网上大神们,关于双线性内插算法的资料,总结了一个用于图像缩放的算法的代码,我把它总结在博客里,希望能够方便自己和大家随时的使用。

二、算法原理

首先要介绍一下双线性内插算法的基本原理,这部分转载自 GoldBeetle 大佬的博客

https://www.cnblogs.com/GoldBeetle/archive/2018/09/17/9662871.html

 

双线性内插法

v(x,y) = ax + by + cxy + d

双线性内插法参数计算

已知Q11, Q12, Q21, Q22,要插值的点为P点,首先在x轴上,对R1,R2两个点进行插值

然后根据R1和R2对P点进行插值

化简得

             

对于边界值的处理,若x1 < 0 ,则直接令f(Q11), f(Q12) = 0

 

 

 

三、算法效果

这个算法期初被我用在了Qt的图像处理中,后来被我移植到了ESP8266的LCD屏幕驱动中,还是比较好用的,下面我先展示一下再Qt中放大的效果。

 

基于此算法,我为了方便只使用了灰度值进行数据处理,效果就是如图所示,当然也可以分为多个通道处理彩色图像。

后来我又修改此算法处理二值图像,用在ESP8266中作为文字的放大函数,使用小字库就可以在LCD屏幕上显示任意大的字体,也是非常方便的,节省了超大字体的字符所占用的空间。

四、算法代码

接下来我将代码展示一下,

输入参数分别是 输入图像的数组指针,输入图像的大小,输出图像指针,输出图像大小。

int offset_x=0,offset_y=0;

#define gray_to_RGB(gray) qRgb(gray,gray,gray)
void Bilinear(uint8_t* inpBmpBuf, int src_x,int src_y,uint8_t* outpBmpBuf,int dstWidth,int dstHeight)
{
    double lx=1,ly=1;//缩小倍数
    if(src_x/dstWidth>1) {lx=src_x/(double)dstWidth;} 
    else{lx=src_x/(double)dstWidth;}

    if(src_y/dstHeight>1){ly=src_y/(double)dstHeight;}
    else{ly=src_y/(double)dstHeight;}

    int x1, x2, y1, y2, Fq11, Fq12, Fq21, Fq22;
        double x, y, r1, Fr1, Fr2, Fp;
        for (int i = 0; i < dstHeight; ++i){
            for (int j = 0; j < dstWidth; ++j){
                x = lx*j; // 原图像坐标
                y = ly*i;
                // 四个坐标值
                x1 = floor(x); x2 = x1 + 1;// 取整ceil向上,floor向下
                y1 = floor(y); y2 = y1 + 1;
                // 四个坐标对应的灰度值
                Fq11 = inpBmpBuf[x1*src_y+y1] ;
                Fq12 = inpBmpBuf[x1*src_y+y2];
                Fq21 = inpBmpBuf[x2*src_y+y1];
                Fq22 = inpBmpBuf[x2*src_y+y2];
                // x方向插值和y方向插值
                Fr1 = 0; Fr2 = 0;

                Fr1 = (x2 - x) / (x2 - x1)*Fq11 + (x - x1) / (x2 - x1)*Fq21;
                Fr2 = (x2 - x) / (x2 - x1)*Fq12 + (x - x1) / (x2 - x1)*Fq22;
                Fp = (y2 - y) / (y2 - y1)*Fr1 + (y - y1) / (y2 - y1)*Fr2;
                // 新图像灰度值赋值
                if (Fp >= 0 && Fp <= 255){
                    outpBmpBuf[i+j*dstHeight]=round(Fp); // 新图像
                }
            }
        }

        //将计算得到的像素值放入图像画布
        for(int i=0;i<dstWidth && i<Show_image.size().width();i++)
        {
            for(int j=0;j<dstHeight && j<Show_image.size().height();j++)
            {
                Show_image.setPixel(i,j,gray_to_RGB(outpBmpBuf[(i+offset_x)*dstHeight+(j+offset_y)]));
            }
        }

}

今天的总结就到这里啦,欢迎大家给我点赞关注、与我交流讨论呀。O(∩_∩)O哈哈~

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值