视频图像处理基础知识0(双线性插值算法进行图像缩放)【转】

简介: 转自:http://blog.csdn.net/times_poem/article/details/51395781 版权声明:本文为博主原创文章,未经博主允许不得转载。 目录(?)[-] 双线性插值说的很明白 双线性插值算法进行图像缩放及性能效果优化   双线性插值(说的很明白) 来自:http://www.

转自:http://blog.csdn.net/times_poem/article/details/51395781

 

双线性插值(说的很明白)

来自:http://www.cnblogs.com/linkr/p/3630902.html

        http://www.cnblogs.com/linkr/p/3630902.html

双线性插值,这个名字咋一听很高大上的样纸,再在维基百科上一查(见文末,我去,一堆的公式吓死人),像俺这种半文盲,看到公式脑子就懵的类型,真心给跪。虽然看着好复杂,但仔细一看道理再简单不过了,所以还是自己梳理一下好。

双线性插值,顾名思义就是两个方向的线性插值加起来(这解释过于简单粗暴,哈哈)。所以只要了解什么是线性插值,分别在x轴和y轴都做一遍,就是双线性插值了。

线性插值的概念也非常简单粗暴,就是两个点A,B,要在AB中间插入一个点C(点C坐标在AB连线上),就直接让C的值落在AB的值的连线上就可以了。

如A点坐标(0,0),值为3,B点坐标(0,2),值为5,那要对坐标为(0,1)的点C进行插值,就让C落在AB线上,值为4就可以了。

但是如果C不在AB的线上肿么办捏,所以就有了双线性插值。如图,已知Q12,Q22,Q11,Q21,但是要插值的点为P点,这就要用双线性插值了,首先在x轴方向上,对R1和R2两个点进行插值,这个很简单,然后根据R1和R2对P点进行插值,这就是所谓的双线性插值。

clip_image001

 

附:维基百科--双线性插值:

双线性插值,又称为双线性内插。在数学上,双线性插值是有两个变量的插值函数的线性插值扩展,其核心思想是在两个方向分别进行一次线性插值。

假如我们想得到未知函数 f 在点 P=\left( x, y\right) 的值,假设我们已知函数 f 在 Q_{11} = \left( x_1, y_1 \right)Q_{12} = \left( x_1, y_2 \right)Q_{21} = \left( x_2, y_1 \right), 及 Q_{22} = \left( x_2, y_2 \right) 四个点的值。

首先在 x 方向进行线性插值,得到

f(R_1) \approx \frac{x_2-x}{x_2-x_1} f(Q_{11}) + \frac{x-x_1}{x_2-x_1} f(Q_{21}) \quad\mbox{Where}\quad R_1 = (x,y_1),
f(R_2) \approx \frac{x_2-x}{x_2-x_1} f(Q_{12}) + \frac{x-x_1}{x_2-x_1} f(Q_{22}) \quad\mbox{Where}\quad R_2 = (x,y_2).

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

f(P) \approx \frac{y_2-y}{y_2-y_1} f(R_1) + \frac{y-y_1}{y_2-y_1} f(R_2).

这样就得到所要的结果 f \left( x, y \right),

f(x,y) \approx \frac{f(Q_{11})}{(x_2-x_1)(y_2-y_1)} (x_2-x)(y_2-y) + \frac{f(Q_{21})}{(x_2-x_1)(y_2-y_1)} (x-x_1)(y_2-y)
+ \frac{f(Q_{12})}{(x_2-x_1)(y_2-y_1)} (x_2-x)(y-y_1) + \frac{f(Q_{22})}{(x_2-x_1)(y_2-y_1)} (x-x_1)(y-y_1).

如果选择一个坐标系统使得 f 的四个已知点坐标分别为 (0, 0)、(0, 1)、(1, 0) 和 (1, 1),那么插值公式就可以化简为

f(x,y) \approx f(0,0) \, (1-x)(1-y) + f(1,0) \, x(1-y) + f(0,1) \, (1-x)y + f(1,1) xy.

或者用矩阵运算表示为

f(x,y) \approx \begin{bmatrix}1-x & x \end{bmatrix} \begin{bmatrix}f(0,0) & f(0,1) \\f(1,0) & f(1,1) \end{bmatrix} \begin{bmatrix}1-y \\y \end{bmatrix}

与这种插值方法名称不同的是,这种插值方法的结果通常不是线性的,它的形式是

b_1 + b_2 x + b_3 y + b_4 x y. \,

常数的数目都对应于给定的 f 的数据点数目

b_1 = f(0,0)
b_2 = f(1,0) - f(0,0)
b_3 = f(0,1) - f(0,0)
b_4 = f(1,1) - f(1,0) - f(0,1) + f(0,0)

线性插值的结果与插值的顺序无关。首先进行 y 方向的插值,然后进行 x 方向的插值,所得到的结果是一样的。



 

双线性插值算法进行图像缩放及性能效果优化

一)转自http://handspeaker.iteye.com/blog/1545126

最近在编程时用到了双线性插值算法,对图像进行缩放。网上有很多这方面的资料,介绍的也算明白。但是,这些文章只介绍了算法,并没有具体说怎么实现以及怎么实现最好,举个例子,你可以按照网上文章的算法自己写一个双线性插值程序,用它对一张图片进行处理,然后再用matlab或者OpenCV的resize函数对同一张图片进行处理,得到的结果是不一样的,如果源图片较小,效果差距就更大。以下是对于双线性插值的讲解以及上述现象的解释:

 

1.双线性插值

假设源图像大小为mxn,目标图像为axb。那么两幅图像的边长比分别为:m/a和n/b。注意,通常这个比例不是整数,编程存储的时候要用浮点型。目标图像的第(i,j)个像素点(i行j列)可以通过边长比对应回源图像。其对应坐标为(i*m/a,j*n/b)。

显然,这个对应坐标一般来说不是整数,而非整数的坐标是无法在图像这种离散数据上使用的。双线性插值通过寻找距离这个对应坐标最近的四个像素点,来计算该点的值(灰度值或者RGB值)。如果你的对应坐标是(2.5,4.5),那么最近的四个像素是(2,4)、(2,5)、(3,4),(3,5)。

若图像为灰度图像,那么(i,j)点的灰度值可以通过一下公式计算:

f(i,j)=w1*p1+w2*p2+w3*p3+w4*p4;

其中,pi(i=1,2,3,4)为最近的四个像素点,wi(i=1,2,3,4)为各点相应权值。关于权值的计算,在维基百科和百度百科上写的很明白。

 

2.存在的问题

这部分的前提是,你已经明白什么是双线性插值并且在给定源图像和目标图像尺寸的情况下,可以用笔计算出目标图像某个像素点的值。当然,最好的情况是你已经用某种语言实现了网上一大堆博客上原创或转载的双线性插值算法,然后发现计算出来的结果和matlab、opencv对应的resize()函数得到的结果完全不一样。

那这个究竟是怎么回事呢?

其实答案很简单,就是坐标系的选择问题,或者说源图像和目标图像之间的对应问题。

按照网上一些博客上写的,源图像和目标图像的原点(0,0)均选择左上角,然后根据插值公式计算目标图像每点像素,假设你需要将一幅5x5的图像缩小成3x3,那么源图像和目标图像各个像素之间的对应关系如下:

只画了一行,用做示意,从图中可以很明显的看到,如果选择右上角为原点(0,0),那么最右边和最下边的像素实际上并没有参与计算,而且目标图像的每个像素点计算出的灰度值也相对于源图像偏左偏上。

那么,让坐标加1或者选择右下角为原点怎么样呢?很不幸,还是一样的效果,不过这次得到的图像将偏右偏下。

最好的方法就是,两个图像的几何中心重合,并且目标图像的每个像素之间都是等间隔的,并且都和两边有一定的边距,这也是matlab和openCV的做法。如下图:

如果你不懂我上面说的什么,没关系,只要在计算对应坐标的时候改为以下公式即可,

 

int x=(i+0.5)*m/a-0.5

int y=(j+0.5)*n/b-0.5

 

instead of 

 

 

int x=i*m/a

int y=j*n/b

 

利用上述公式,将得到正确的双线性插值结果


总结:

总结一下,我得到的教训有这么几条。

1.网上的一些资料有的时候并不靠谱,自己还是要多做实验。

2.不要小瞧一些简单的、基本的算法,让你写你未必会写,而且其中可能还藏着一些玄妙。

3.要多动手编程,多体会算法,多看大牛写的源码(虽然有的时候很吃力,但是要坚持看)。

二)转自http://www.cnblogs.com/Imageshop/archive/2011/11/12/2246808.html

 在图像处理中,双线性插值算法的使用频率相当高,比如在图像的缩放中,在所有的扭曲算法中,都可以利用该算法改进处理的视觉效果。首先,我们看看该算法的简介。

     在数学上,双线性插值算法可以看成是两个变量间的线性插值的延伸。执行该过程的关键思路是先在一个方向上执行线性插值,然后再在另外一个方向上插值。下图示意出这个过程的大概意思。

     用一个简单的数学表达式可以表示如下:

     f(x,y)=f(0,0)(1-x)(1-y)+f(1,0)x(1-y)+f(0,1)(1-x)y+f(1,1)xy

     合并有关项,可写为: f(x,y)=(f(0,0)(1-x)+f(1,0)x) (1-y)+(f(0,1)(1-x)+f(1,1)x)y

     由上式可以看出,这个过程存在着大量的浮点数运算,对于图像这样大的计算用户来说,是一个较为耗时的过程。

     考虑到图像的特殊性,他的像素值的计算结果需要落在0到255之间,最多只有256种结果,由上式可以看出,一般情况下,计算出的f(x,y)是个浮点数,我们还需要对该浮点数进行取整。因此,我们可以考虑将该过程中的所有类似于1-x、1-y的变量放大合适的倍数,得到对应的整数,最后再除以一个合适的整数作为插值的结果。

      如何取这个合适的放大倍数呢,要从三个方面考虑,第一:精度问题,如果这个数取得过小,那么经过计算后可能会导致结果出现较大的误差。第二,这个数不能太大,太大会导致计算过程超过长整形所能表达的范围。第三:速度考虑。假如放大倍数取为12,那么算式在最后的结果中应该需要除以12*12=144,但是如果取为16,则最后的除数为16*16=256,这个数字好,我们可以用右移来实现,而右移要比普通的整除快多了。 

      综合考虑上述三条,我们选择2048这个数比较合适。

      下面我们假定某个算法得到了我们要取样的坐标分别PosX以及PosY,其中PosX=25.489,PosY=58.698。则这个过程的类似代码片段如下:

复制代码
复制代码
 1 NewX = Int(PosX)                        '向下取整,NewX=25
 2 NewY = Int(PosY)                        '向下取整,NewY=58
 3 PartX = (PosX - NewX) * 2048            '对应表达式中的X
 4 PartY = (PosY - NewY) * 2048            '对应表达式中的Y
 5 InvX = 2048 - PartX                     '对应表达式中的1-X
 6 InvY = 2048 - PartY                     '对应表达式中的1-Y
 7 
 8 Index1 = SamStride * NewY + NewX * 3    '计算取样点左上角邻近的那个像素点的内存地址
 9 Index2 = Index1 + SamStride          '左下角像素点地址
10 ImageData(Speed + 2) = ((Sample(Index1 + 2) * InvX + Sample(Index1 + 5) * PartX) * InvY + (Sample(Index2 + 2) * InvX + 
                          Sample(Index2 +  5) * PartX) * PartY) \ 4194304       '处理红色分量
11 ImageData(Speed + 1) = ((Sample(Index1 + 1) * InvX + Sample(Index1 + 4) * PartX) * InvY + (Sample(Index2 + 1) * InvX +
                          Sample(Index2 +  4) * PartX) * PartY) \ 4194304       '处理绿色分量
12 ImageData(Speed) = ((Sample(Index1) * InvX + Sample(Index1 + 3) * PartX) * InvY + (Sample(Index2) * InvX +
                      Sample(Index2 +  3) * PartX) * PartY) \ 4194304           '处理蓝色分量
复制代码
复制代码

      以上代码中涉及到的变量都为整型(PosX及PosY当然为浮点型)。

      代码中Sample数组保存了从中取样的图像数据,SamStride为该图像的扫描行大小。

      观察上述代码,除了有2句涉及到了浮点计算,其他都是整数之间的运算。

      在BasiC语言中,编译时如果勾选所有的高级优化,则\ 4194304会被编译为>>22,即右移22位,如果使用的是c语言,则直接写为>>22。

      需要注意的是,在进行这代代码前,需要保证PosX以及PosY在合理的范围内,即不能超出取样图像的宽度和高度范围。

      通过这样的改进,速度较直接用浮点类型快至少100%以上,而处理后的效果基本没有什么区别。

【作者】 张昺华
【新浪微博】 张昺华--sky
【twitter】 @sky2030_
【facebook】 张昺华 zhangbinghua
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
目录
相关文章
|
1月前
|
机器学习/深度学习 人工智能 自然语言处理
【MM2024】阿里云 PAI 团队图像编辑算法论文入选 MM2024
阿里云人工智能平台 PAI 团队发表的图像编辑算法论文在 MM2024 上正式亮相发表。ACM MM(ACM国际多媒体会议)是国际多媒体领域的顶级会议,旨在为研究人员、工程师和行业专家提供一个交流平台,以展示在多媒体领域的最新研究成果、技术进展和应用案例。其主题涵盖了图像处理、视频分析、音频处理、社交媒体和多媒体系统等广泛领域。此次入选标志着阿里云人工智能平台 PAI 在图像编辑算法方面的研究获得了学术界的充分认可。
【MM2024】阿里云 PAI 团队图像编辑算法论文入选 MM2024
|
1月前
|
机器学习/深度学习 人工智能 算法
【MM2024】面向 StableDiffusion 的多目标图像编辑算法 VICTORIA
阿里云人工智能平台 PAI 团队与华南理工大学合作在国际多媒体顶级会议 ACM MM2024 上发表 VICTORIA 算法,这是一种面向 StableDiffusion 的多目标图像编辑算法。VICTORIA 通过文本依存关系来修正图像编辑过程中的交叉注意力图,从而确保关系对象的一致性,支持用户通过修改描述性提示一次性编辑多个目标。
|
5月前
|
算法 计算机视觉
图像处理之积分图应用四(基于局部均值的图像二值化算法)
图像处理之积分图应用四(基于局部均值的图像二值化算法)
535 0
|
1月前
|
算法 数据安全/隐私保护
织物图像的配准和拼接算法的MATLAB仿真,对比SIFT,SURF以及KAZE
本项目展示了织物瑕疵检测中的图像拼接技术,使用SIFT、SURF和KAZE三种算法。通过MATLAB2022a实现图像匹配、配准和拼接,最终检测并分类织物瑕疵。SIFT算法在不同尺度和旋转下保持不变性;SURF算法提高速度并保持鲁棒性;KAZE算法使用非线性扩散滤波器构建尺度空间,提供更先进的特征描述。展示视频无水印,代码含注释及操作步骤。
|
2月前
|
算法 数据可视化 数据安全/隐私保护
基于LK光流提取算法的图像序列晃动程度计算matlab仿真
该算法基于Lucas-Kanade光流方法,用于计算图像序列的晃动程度。通过计算相邻帧间的光流场并定义晃动程度指标(如RMS),可量化图像晃动。此版本适用于Matlab 2022a,提供详细中文注释与操作视频。完整代码无水印。
|
4月前
|
机器学习/深度学习 编解码 监控
算法金 | 深度学习图像增强方法总结
**图像增强技术概括** 图像增强聚焦于提升视觉效果和细节,广泛应用于医学、遥感等领域。空间域增强包括直方图均衡化(增强对比度)、对比度拉伸、灰度变换、平滑滤波(均值、中值)和锐化滤波(拉普拉斯、高通)。频率域增强利用傅里叶变换、小波变换,通过高频和低频滤波增强图像特征。现代方法涉及超分辨率重建、深度学习去噪(如CNN、Autoencoder)、图像修复(如GAN)和GANs驱动的多种图像处理任务。
140 14
算法金 | 深度学习图像增强方法总结
|
3月前
|
算法 前端开发 计算机视觉
基于均值坐标(Mean-Value Coordinates)的图像融合算法的优化实现
基于均值坐标(Mean-Value Coordinates)的图像融合算法的优化实现
40 0
|
3月前
|
自然语言处理 并行计算 算法
基于均值坐标(Mean-Value Coordinates)的图像融合算法的具体实现
基于均值坐标(Mean-Value Coordinates)的图像融合算法的具体实现
44 0
|
4月前
|
机器学习/深度学习 人工智能 自然语言处理
|
4月前
|
算法
基于粒子群优化的图像融合算法matlab仿真
这是一个基于粒子群优化(PSO)的图像融合算法,旨在将彩色模糊图像与清晰灰度图像融合成彩色清晰图像。在MATLAB2022a中测试,算法通过PSO求解最优融合权值参数,经过多次迭代更新粒子速度和位置,以优化融合效果。核心代码展示了PSO的迭代过程及融合策略。最终,使用加权平均法融合图像,其中权重由PSO计算得出。该算法体现了PSO在图像融合领域的高效性和融合质量。