双线性插值
- 格式:doc
- 大小:270.00 KB
- 文档页数:3
图像缩放算法及速度优化——(⼆)双线性插值 双线性插值作为OpenCV中默认使⽤的图像缩放算法,其效果和速度都是不错的。
并且效果也⽐较稳定,计算复杂度并不算太⾼。
我看了很多⽹上的算法,⾃⼰也没看太懂,下⾯是从⽹上找的双线性插值算法的讲解。
“图像的双线性插值放⼤算法中,⽬标图像中新创造的象素值,是由源图像位置在它附近的2*2区域4个邻近象素的值通过加权平均计算得出的。
双线性内插值算法放⼤后的图像质量较⾼,不会出现像素值不连续的的情况。
然⽽次算法具有低通滤波器的性质,使⾼频分量受损,所以可能会使图像轮廓在⼀定程度上变得模糊。
” 下⾯还是根据我⾃⼰的理解来继续讲述吧,相信读者中有很多⾼⼿,希望读者能给予我指点⼀下,让我也能更明⽩⼀些。
双线性插值算法和最近邻插值算法⽐较类似。
在最近邻插值算法中,⽬标图像中的某个点(x,y)是去源图像中找最邻近的⼀个点(x0, y0)即可。
⽬标图像中的点(x, y)对应于源图像中的点(x0',y0'),x0'、y0'很可能不是整数,⽽是⼩数,⽽最近邻插值算法是找其邻近整型值(int(x0'+0.5f),int(y0'+0.5f))(上篇⽂章中没有进⾏四舍五⼊)。
我们现在找x0', y0'所在位置旁边的四个点,根据这四个点与(x0',y0')距离的关系计算⽬标图像中(x,y)⼀点的像素值。
算法描述如下:(1)计算源图像与⽬标图像宽与⾼的⽐例w0 : 表⽰源图像的宽度h0 : 表⽰源图像的⾼度w1 : 表⽰⽬标图像的宽度h1 : 表⽰⽬标图像的⾼度float fw = float(w0-1)/(w1-1);float fh = float(h0-1)/(h1-1);(2)针对⽬标图像的⼀个点(x, y),计算在源图像中的对应坐标,结果为浮点数。
float x0 = x * fw;float y0 = y * fh;int x1 = int(x0);int x2 = x1 + 1;int y1 = int(y0);int y2 = y1+1;所求的源图像中的四个点坐标为(x1, y1) (x1, y2) (x2, y1) (x2,y2)(3)求周围四个点所占的权重⽐值如上图,fx1 = x0 - x1;fx2 = 1.0f - fx1;fy1 = y0 - y1;fy2 = 1.0f - fy1;float s1 = fx1*fy1;float s2 = fx2*fy1;float s3 = fx2*fy2;float s4 = fx1*fy2;我们以value(坐标)来代表取得此点的坐标值,则:value(x0,y0) = value(x2,y2)*s1+value(x1,y2)*s2+value(x1,y1)*s3+value(x2,y1)*s4;如果对上述运算不够明⽩的话,可以这样来求。
双线性插值法(bilinearinterpolation)前⾯讲解了最近邻插值法缩放图像以及不⾜之处,本篇介绍另外⼀种插值法,介绍双线性插值法之前先介绍线性插值。
1. 线性插值 线性插值是指插值函数为⼀次多项式的插值⽅式,其在插值节点上的插值误差为零。
线性插值可以⽤来近似代替原函数,也可以⽤来计算得到查表过程中表中没有的数值。
如图所⽰现在已知y=f(x)的两个点坐标分别是(x0,y0),(x1,y1),现在在区间(x0,x1)内给定任意x,如何求y,线性插值法采⽤图中红点的y值代替f(x)的y值。
假设x处的直线上的红点坐标为(x,Y),那么Y约等于y。
根据图可以得到公式:⽤y0,y1表⽰得到公式很好记,将分式看做权重系数。
2. 双线性插值法 双线性插值法也叫双线性内插,其核⼼思想是在两个⽅向分别进⾏⼀次线性插值。
双线性插值作为数值分析中的⼀种插值算法,⼴泛应⽤在信号处理,数字图像和视频处理等⽅⾯。
如坐标图所⽰,⽤横纵坐标代表图像像素的位置,f(x,y)代表该像素点(x,y)的彩⾊值或灰度值。
将图像放⼤或缩⼩,⽬的像素dst对应的原像素src中的坐标转换公式如下,公式很好理解,可参考上⼀章最近邻插值法。
srcX=dstX*(srcWidth/dstWidth) srcY=dstY*(srcHeight/dstHeight) 上式中,dstX与dstY为⽬标图像的某个像素的横纵坐标,dstWidth与dstHeight为⽬标图像的长与宽;srcWidth与srcHeight为原图像的宽度与⾼度。
srcX,srcY为⽬标图像在该点(dstX,dstY)对应的原图像的坐标。
现在假设⽬标图像的像素点(x’,y’)映射到原图像中是(x,y),也就是图中的P点。
设Q11 = (x1, y1)、Q12 = (x1, y2)、Q21 = (x2, y1) 、Q22 = (x2, y2),图中Q11,Q12,Q21,Q22分别为距离P点的最近的四个点。
最邻近插值和双线性插值算法的比较摘要:图像缩放是数字图像处理的一个基本内容,为了更好地对数字图像细节进行描述,本文简单介绍了图像处理中的空间变换、最邻近插值算法,重点分析了双线性插值算法,并通过MATLAB仿真进行图像的缩放,比较实验结果,从而验证双线性插值算法效果较好。
关键词:图像缩放;空间变换;最邻近插值;双线性插值;0引言数字图像处理的对象因其涉及到社会的各个领域,倍受到越来越多的关注,而图像缩放作为数字图像处理中的基本操作尤为重要,在社会的很多领域都需要对图像进行放大和缩小。
本文主要比较了空间变换、最邻近插值算法和双线性插值算法。
1图像处理中的空间变换图像的空间变换[1],也称几何变换或几何运算,包括图像的平移、旋转、镜像变换、转置、缩放等。
几何运算可改变图像中各物体之间的空间关系,这种运算可以跛看成是将各物体在图像内移动。
空间变换可如下表示:设(u,v)为源图像上的点,(x,y)为目标图像上的点,则空间变换就是将源图像上(u,v)处的颜色值与目标图像上(X,y)处的颜色对应起来(u,v) (x,y)并具有以下关系:x=X(u,v),y=Y(u,v) (即由(u,v)计算对应(x,y))(1) 或u=U(x,y),v=V(x,y) (即由(x,y)计算对应(u,v))(2) 其中X(u,v)、Y(u,v)、U(x,y)、V(x,y)均为变换。
由(1.1)对应的变换称作向前映射法也叫像素移交法,而由(1.2)对应的变换称作向后映射法也叫像素填充法,向后映射法是向前映射法的逆[1,4]。
对于向前映射法来说,由于许多输入像素可能映射到输出图像的边界之外,故向前映射法有些浪费,而且每个输出像素的灰度值可能要由许多输入像素的灰度值来决定,因此要涉及多次运算。
如果空间变换中包括缩小处理,则会有四个以上的输入像素来决定输出像素的灰度值。
如果含有放大处理,则一些输出像素可能被漏掉。
而向后映射算法是逐像素、逐行地产生输出图像。
图像插值技术——双线性插值法在图像处理中,如果需要对图像进⾏缩放,⼀般可以采取插值法,最常⽤的就是双线性插值法。
本⽂⾸先从数学⾓度推导了⼀维线性插值和⼆维线性插值的计算过程,并总结了规律。
随后将其应⽤到图像的双线性插值上,利⽤Matlab编程进⾏图像的缩放验证,实验证明,⼆维线性插值能够对图像做出较好的缩放效果。
数学⾓度的线性插值⼀维线性插值假设有⼀个⼀元函数 y=f(x) , 已知曲线上的两点,A 和 B 的坐标分别为 (x0,y0) 、(x1,y1) 。
现在要在A 和 B 之间通过插值计算出⼀个点 P ,若已知 P点的横坐标 x,如何求出 P点的纵坐标 y ?这⾥我们的插值之所以叫做线性插值,就是因为我们假定了 P 点落在 A 点和 B 点的连线上,使得他们的坐标之间满⾜线性关系。
所以,根据初中的知识,可以得到下⾯的等式:y−y0 y1−y0=x−x0 x1−x0这⾥我们令:α=x−x0 x1−x0于是,我们可以得到P点的纵坐标 y 的表达式:y=(1−α)f(x0)+αf(x1)⼆维线性插值⼀维线性插值可以扩展到⼆维的情况。
假设有⼀个⼆元函数 z=f(x,y) , 已知曲⾯上的四点,A 、B 、C、D的坐标分别为 (x0,y0) 、(x1,y0) 、(x1,y1)、(x0,y1) 。
现在要在A 、B 、C、D之间通过插值计算出⼀个点 P ,若已知 P点的坐标 (x,y),如何求出 P点的函数值坐标 z ?这⾥我们依旧可以仿照⼀维线性插值,进⾏计算。
假设先计算 y 轴⽅向的插值点 P0 和 P1 ,则根据上⾯的推导过程,且令α=y−y0 y1−y0则, P0 的取值 z0为:z0=(1−α)f(x0,y0)+αf(x0,y1) P1 的取值 z1为:z1=(1−α)f(x1,y0)+αf(x1,y1)再计算 x 轴⽅向的插值点 P,令β=x−x0 x1−x0则 P 的取值 z为:z=(1−β)z0+βz1整理得到下⾯的式⼦:z =(1−β)(1−α)f x 0,y 0+αf x 0,y 1+β(1−α)f x 1,y 0+αf x 1,y 1=(1−β)(1−α)f x 0,y 0+(1−β)αf x 0,y 1+β(1−α)f x 1,y 0+βαf x 1,y 1⼩结由⼀维线性插值过渡到⼆维线性插值,我们发现,⼆者在表达式上有相似的规律:⼀维线性插值:y =f (x )α=x p −x 0x 1−x 0y p =(1−α)f x 0+αf x 1⼆维线性插值:z =f (x ,y )α=x p −x 0x 1−x 0,β=y p −y 0y 1−y 0z p =(1−β)(1−α)f x 0,y 0+(1−β)αf x 0,y 1+β(1−α)f x 1,y 0+βαf x 1,y 1图像中的双线性插值我们可以⽤函数来表⽰⼀幅图像(假设为单通道)。
图像缩放的双线性内插值算法的原理解析图像的缩放很好理解,就是图像的放大和缩小。
传统的绘画工具中,有一种叫做“放大尺”的绘画工具,画家常用它来放大图画。
当然,在计算机上,我们不再需要用放大尺去放大或缩小图像了,把这个工作交给程序来完成就可以了。
下面就来讲讲计算机怎么来放大缩小图象;在本文中,我们所说的图像都是指点阵图,也就是用一个像素矩阵来描述图像的方法,对于另一种图像:用函数来描述图像的矢量图,不在本文讨论之列。
越是简单的模型越适合用来举例子,我们就举个简单的图像:3X3 的256级灰度图,也就是高为3个象素,宽也是3个象素的图像,每个象素的取值可以是0-255,代表该像素的亮度,255代表最亮,也就是白色,0代表最暗,即黑色。
假如图像的象素矩阵如下图所示(这个原始图把它叫做源图,Source):234 38 2267 44 1289 65 63这个矩阵中,元素坐标(x,y)是这样确定的,x从左到右,从0开始,y从上到下,也是从零开始,这是图象处理中最常用的坐标系,就是这样一个坐标:---------------------->X|||||∨Y如果想把这副图放大为4X4大小的图像,那么该怎么做呢?那么第一步肯定想到的是先把4X4的矩阵先画出来再说,好了矩阵画出来了,如下所示,当然,矩阵的每个像素都是未知数,等待着我们去填充(这个将要被填充的图的叫做目标图,Destination):? ? ? ?? ? ? ?? ? ? ?? ? ? ?然后要往这个空的矩阵里面填值了,要填的值从哪里来来呢?是从源图中来,好,先填写目标图最左上角的象素,坐标为(0,0),那么该坐标对应源图中的坐标可以由如下公式得出:srcX=dstX* (srcWidth/dstWidth) , srcY = dstY * (srcHeight/dstHeight)好了,套用公式,就可以找到对应的原图的坐标了(0*(3/4),0*(3/4))=>(0*0.75,0*0.75)=>(0,0),找到了源图的对应坐标,就可以把源图中坐标为(0,0)处的234象素值填进去目标图的(0,0)这个位置了。
双线性插值公式
双线性插值公式,又称作双线性插值法,是数学中最常用的样条插值法之一。
它通过在一个二维空间中用一条线来进行插值计算,从而实现二维曲线上给定点间的准确插值。
这种插值法显然比一维插值法更加复杂,它更多是用来处理二维曲线上给定点之间的数据插值。
双线性插值法是一种可以自由拟合数据点,以解决在二维空间中分布的数据插值问题的一种插值方法。
它的基本原理是将原始数据平面化,并对平面中给定的点采用以一条线为中心的方式进行插值计算。
首先以一条平行于给定的点的连线为中心,延伸出一条线段,然后在这条线段上进行一定的插值计算,从而实现了给定点间的插值。
此外,这种插值法还可以采用多条线来拟合数据,以实现更准确的插值结果。
双线性插值法最常用的地方是在数值分析、地理空间信息技术、计算机视觉、图像处理等领域,它也可以应用到游戏开发中,为了更准确和真实地表达游戏环境中的地形等信息,从而使游戏拥有更强的视觉感受。
双线性插值法的实施需要仔细考虑需要估计的点,以及如何选择预测点来保证准确度。
首先,双线性插值法要求预测点必须在原始数据中,即在预测点A处有三个点,P1,P2,P3,其中P1和P2是原始数据,P3是估计的点。
此外,在采用双线性插值法时,最重要的是
要注意选择线段的方向,一般情况下要求选择和预测点A朝同一方向的线段来进行插值计算,从而保证插值的准确性。
总的来说,双线性插值法是一种有效的插值方法,它可以用来解
决给定点之间数据插值的问题,尤其适用于多维数据插值,具有良好的准确性。
而在实施插值时,还要考虑估计点的选择,以及线段的方向,从而保证插值的准确度。
三种插值算法最近邻插值法的双线性内插值:对于图像中一个目的像素,设置坐标通过反向变换得到的浮点坐标为(i+u,j+v,其中 i 、 j 均为非负整数, u 、 v 为 [0,1区间的浮点数,则这个像素得值f(i+u,j+v 可由原图像中坐标为 (i,j、 (i+1,j、 (i,j+1、 (i+1,j+1所对应的周围四个像素的值决定,即:f(i+u,j+v = (1-u(1-vf(i,j + (1-uvf(i,j+1 + u(1-vf(i+1,j + uvf(i+1,j+1其中 f(i,j表示源图像 (i,j处的的像素值,以此类推这就是双线性内插值法。
双线性内插值法计算量大,但缩放后图像质量高, 不会出现像素值不连续的的情况。
由于双线性插值具有低通滤波器的性质, 使高频分量受损,所以可能会使图像轮廓在一定程度上变得模糊插值的计算方法有很多, 比较常用的有最近像素插值算法、双线性插值算法、双三次插值算法和分形算法的四种。
其中, 最近像素插值算法是最简单的一种插值算法, 这种方法是当图片放大时, 缺少的像素通过直接使用与之最接近的原有像素的颜色生成, 也就是说照搬旁边的像素。
如图 1所示,当图片扩大时,要增加 X 点处的像素,由于 X 点与 A 、 B 这两个有效像素中的 B 点最接近,因此 X 点会直接照搬B 点的像素,从而使到 X 点生成的效果与 B 点一样。
虽然这种算法简单, 因此处理的速度很快, 但结果通常会产生明显可见的锯齿, 效果往往不佳。
双线性插值算法, 是指输出的图像的每个像素都是原图中四个像素运算的结果, 由于它是从原图四个像素中运算的, 因此这种算法很大程度上消除了锯齿现象, 而且效果也比较好。
双三次插值算法是双线性插值算法的改进算法,它输出图像的每个像素都是原图 16个像素运算的结果, 由于效果好, 运算速度也不慢, 因而这种插值方法是一种很常见的算法, 普遍用在图像编辑软件、打印机驱动和数码相机上。
数字影像重采样的方法
数字影像重采样是将数字图像从一个像素格点网格映射到另一个像素格点网格的过程。
这通常涉及到调整图像的尺寸、分辨率或方向。
以下是一些常见的数字影像重采样方法:
1.最近邻插值(Nearest-neighbor interpolation):
最近邻插值是一种简单的插值方法,它将目标像素的值设定为原始图像中最近的像素的值。
这种方法计算速度快,但可能导致图像出现锯齿状的块状效应。
2.双线性插值(Bilinear interpolation):
双线性插值使用了目标像素周围的四个最近邻像素的权重来计算目标像素的值。
这种方法相比最近邻插值产生了更平滑的图像,但在一些情况下可能引入一些模糊。
3.双三次插值(Bicubic interpolation):
双三次插值在计算目标像素值时使用了周围16个最近邻像素的权重。
相较于双线性插值,双三次插值可以提供更高的图像质量,但计算复杂度也更高。
4.立方卷积插值(Cubic convolution interpolation):
立方卷积插值是一种使用像素值的立方函数的插值方法,对图像进行平滑处理。
它相对于双三次插值在一些情况下可能产生更好的结果。
nczos 插值:
Lanczos 插值使用sinc 函数的权重来计算目标像素的值,是一种高质量的插值方法。
它通常用于需要较高图像质量的应用,如图像放大。
在选择重采样方法时,需考虑应用场景、计算资源和图像质量要求。
不同的插值方法在不同的情况下表现良好,因此最佳的选择可能取决于具体的应用需求。
双线性插值算法
双线性插值(Bilinear Interpolation)是一种非常常见的插值算法,它可以用来插值两个或多个维度的数据,广泛应用于图像处理、机器学习等领域。
双线性插值的基本原理是:从数据中取出四个点,比如a、b、c、d,然后在这四个点上构建一个双线性曲面,曲面的函数为:f(x,y)=ax+by+cxy+d,其中a,b,c,d是待求的系数。
双线性插值的具体过程是:首先确定子区域的四个顶点,比如:a(x1,y1),b(x1,y2),c(x2,y1),d(x2,y2),接着在这四个顶点上求出曲面的函数,即:f(x,y)=ax+by+cxy+d,其中a,b,c,d是待求的系数,我们可以用矩阵求解法来解出这四个系数。
最后,对于子区域内的任一点,都可以用双线性插值算法来求出它的函数值:
f(x,y)=ax+by+cxy+d。
双线性插值算法的优势在于它可以用来插值两个或多个维度的数据,而且插值的精度高,可以达到很好的效果。
此外,双线性插值算法的运算速度也比较快,不需要太多的计算量,因此在实际应用中得到了广泛的应用。
综上所述,双线性插值算法是一种高效、精确的插值算法,广泛应用于图像处理、机器学习等领域。
它可以用来插值两个或多个维度
的数据,插值精度高,且运算速度快。
双线性插值,又称为双线性内插。
在数学上,双线性插值是有两个变量的插值函数的线性插值扩展,其核心思想是在两个方向分别进行一次线性插值。
例如已知的红色数据点与待插值得到的绿色点如图1所示:
图1
假如我们想得到未知函数在点的值,假设我们已知函数在, , , 及四个点的值。
首先在 x 方向进行线性插值,得到
然后在 y 方向进行线性插值,得到
这样就得到所要的结果,
如果选择一个坐标系统使得的四个已知点坐标分别为(0, 0)、(0, 1)、(1, 0) 和(1, 1),那么插值公式就可以化简为
或者用矩阵运算表示为
这就是双线性内插值法。
双线性内插值法计算量大,但缩放后图像质量高,不会出现像素值
不连续的的情况。
由于双线性插值具有低通滤波器的性质,使高频分量受损,所以可能会使
图像轮廓在一定程度上变得模糊。
双线性插值法的MATLAB源代码为:
I=imread('lena.jpg'); %读入原图像
[nrows,ncols,z]=size(I); %读取图像矩阵大小,方便后面操作
K = str2double(inputdlg('please input scale factor (must
between 0.2 - 5.0)', 'INPUT scale factor', 1, {'0.5'}));
width = K * nrows;
height = K * ncols;
J = uint8(zeros(width,height,z));
widthScale = nrows/width;
heightScale = ncols/height;
for x = 5:width - 5 % 5是为了防止矩阵超出边界溢出
for y = 5:height - 5
for z=1:3
xx = x * widthScale; % xx, yy为原坐标,x,y为新坐标
yy = y * heightScale;
if((xx/double(uint16(xx))==1.0)&&(yy/double(uint16(yy))==1.0))
J(x,y,z) = I(int16(xx),int16(yy),z); %若xx,yy为整数,直接赋值
else
a = double(uint16(xx));
b = double(uint16(yy));
x11 = double(I(a,b,z)); % x11 <- I(a,b)
x12 = double(I(a,b+1,z)); % x12 <- I(a,b+1)
x21 = double(I(a+1,b,z)); % x21 <- I(a+1,b)
x22 = double(I(a+1,b+1,z));% x22 <- I(a+1,b+1) J(x,y,z) = uint8((b+1-yy)*((xx-a)*x21+(a+1-xx)*x11)+(yy-b)*
((xx-a)*x22+(a+1-xx)*x12)); %用双线性插值计算公式计算
end
end
end
end
imshow(I);
figure;
imshow(J);
程序运行后原图如图2所示:
图2
双线性插值法放大2倍后图像如图3所示:
图3。