线性插值,双线性插值Bilinear Interpolation算法

线性插值

先讲一下线性插值:已知数据 (x0, y0) 与 (x1, y1),要计算 [x0, x1] 区间内某一位置 x 在直线上的y值(反过来也是一样,略):

y−y0x−x0=y1−y0x1−x0

y=x1−xx1−x0y0+x−x0x1−x0y1

上面比较好理解吧,仔细看就是用x和x0,x1的距离作为一个权重,用于y0和y1的加权。双线性插值本质上就是在两个方向上做线性插值。

双线性插值

在数学上,双线性插值是有两个变量的插值函数的线性插值扩展,其核心思想是在两个方向分别进行一次线性插值[1]。见下图:

假如我们想得到未知函数 f 在点 P = (x, y) 的值,假设我们已知函数 f 在 Q11 = (x1, y1)、Q12 = (x1, y2), Q21 = (x2, y1) 以及 Q22 = (x2, y2) 四个点的值。最常见的情况,f就是一个像素点的像素值。首先在 x 方向进行线性插值,得到


然后在 y 方向进行线性插值,得到

综合起来就是双线性插值最后的结果:


由于图像双线性插值只会用相邻的4个点,因此上述公式的分母都是1。opencv中的源码如下,用了一些优化手段,比如用整数计算代替float(下面代码中的*2048就是变11位小数为整数,最后有两个连乘,因此>>22位),以及源图像和目标图像几何中心的对齐 

SrcX=(dstX+0.5)* (srcWidth/dstWidth) -0.5 

SrcY=(dstY+0.5) * (srcHeight/dstHeight)-0.5

这个要重点说一下,源图像和目标图像的原点(0,0)均选择左上角,然后根据插值公式计算目标图像每点像素,假设你需要将一幅5x5的图像缩小成3x3,那么源图像和目标图像各个像素之间的对应关系如下。如果没有这个中心对齐,根据基本公式去算,就会得到左边这样的结果;而用了对齐,就会得到右边的结果:


cv::Mat matSrc, matDst1, matDst2;

matSrc = cv::imread("lena.jpg", 2 | 4); 

matDst1 = cv::Mat(cv::Size(800, 1000), matSrc.type(), cv::Scalar::all(0)); 

matDst2 = cv::Mat(matDst1.size(), matSrc.type(), cv::Scalar::all(0));  double scale_x = (double)matSrc.cols / matDst1.cols;  double scale_y = (double)matSrc.rows / matDst1.rows; 

uchar* dataDst = matDst1.data;  int stepDst = matDst1.step; 

uchar* dataSrc = matSrc.data;  int stepSrc = matSrc.step;  int iWidthSrc = matSrc.cols;  int iHiehgtSrc = matSrc.rows;  for (int j = 0; j < matDst1.rows; ++j) 

    float fy = (float)((j + 0.5) * scale_y - 0.5); 

    int sy = cvFloor(fy); 

    fy -= sy; 

    sy = std::min(sy, iHiehgtSrc - 2); 

    sy = std::max(0, sy); 

    short cbufy[2]; 

    cbufy[0] = cv::saturate_cast((1.f - fy) * 2048); 

    cbufy[1] = 2048 - cbufy[0]; 

    for (int i = 0; i < matDst1.cols; ++i) 

    { 

        float fx = (float)((i + 0.5) * scale_x - 0.5); 

        int sx = cvFloor(fx); 

        fx -= sx; 

        if (sx < 0) { 

            fx = 0, sx = 0; 

        } 

        if (sx >= iWidthSrc - 1) { 

            fx = 0, sx = iWidthSrc - 2; 

        } 

        short cbufx[2]; 

        cbufx[0] = cv::saturate_cast((1.f - fx) * 2048); 

        cbufx[1] = 2048 - cbufx[0]; 

        for (int k = 0; k < matSrc.channels(); ++k) 

        { 

            *(dataDst+ j*stepDst + 3*i + k) = (*(dataSrc + sy*stepSrc + 3*sx + k) * cbufx[0] * cbufy[0] + 

                *(dataSrc + (sy+1)*stepSrc + 3*sx + k) * cbufx[0] * cbufy[1] + 

                *(dataSrc + sy*stepSrc + 3*(sx+1) + k) * cbufx[1] * cbufy[0] + 

                *(dataSrc + (sy+1)*stepSrc + 3*(sx+1) + k) * cbufx[1] * cbufy[1]) >> 22; 

        } 

    } 

cv::imwrite("linear_1.jpg", matDst1); 

cv::resize(matSrc, matDst2, matDst1.size(), 0, 0, 1); 

cv::imwrite("linear_2.jpg", matDst2); 

好了,本篇到这里,欢迎大家分享转载,注明出处即可。

参考资料

[1] 双线性插值(Bilinear Interpolation) 

[2] OpenCV ——双线性插值(Bilinear interpolation) 

[3] 双线性插值算法及需要注意事项 

[4] OpenCV中resize函数五种插值算法的实现过程

原文参考:http://blog.csdn.net/xbinworld/article/details/65660665

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容