双线性插值-matlab实现
- 格式:doc
- 大小:828.50 KB
- 文档页数:3
一、插值的定义在数学和计算机科学中,插值是指在已知数据点的基础上,利用插值算法来估算出在这些数据点之间未知位置上的数值。
插值可以用于生成平滑的曲线、曲面或者函数,以便于数据的分析和预测。
二、matlab中的插值方法在matlab中,有多种插值方法可以用来在两个数据点之间插值一条曲线。
这些方法包括线性插值、多项式插值、样条插值等。
下面我们将逐一介绍这些方法及其使用场景。
1. 线性插值线性插值是最简单的插值方法之一。
它的原理是通过已知的两个数据点之间的直线来估算未知位置上的数值。
在matlab中,可以使用interp1函数来进行线性插值。
该函数的调用格式为:Y = interp1(X, Y, Xq, 'linear')其中X和Y分别是已知的数据点的横纵坐标,Xq是待估算数值的位置,'linear'表示使用线性插值方法。
使用线性插值可以快速地生成一条近似直线,但是对于非线性的数据分布效果可能不佳。
2. 多项式插值多项式插值是利用多项式函数来逼近已知数据点之间的曲线。
在matlab中,可以使用polyfit和polyval函数来进行多项式插值。
polyfit函数用于拟合多项式曲线的系数,polyval函数用于计算多项式函数在给定点的数值。
多项式插值的优点是可以精确地通过已知数据点,并且可以适用于非线性的数据分布。
3. 样条插值样条插值是一种比较常用的插值方法,它通过在每两个相邻的数据点之间拟合一个低阶多项式,从而保证整条曲线平滑且具有良好的拟合效果。
在matlab中,可以使用splinetool函数来进行样条插值。
样条插值的优点是对于非线性的数据分布可以有较好的拟合效果,且能够避免多项式插值过拟合的问题。
4. 三角函数插值三角函数插值是一种常用的周期性数据插值方法,它利用三角函数(如sin和cos)来逼近已知数据点之间的曲线。
在matlab中,可以使用interpft函数来进行三角函数插值。
利用双线性插值算法实现图像放大
一、双线性插值算法的原理
双线性插值是指利用映射点在输入图像的4 个邻点的灰度值对映射点进行插值,即待插点处的数值用离待插点最近的四个点的值加权求得。
在同一行内根据待插值像素点与其前后的原图像像素点的位置距离进行加权线性插值,即离原图像像素点越近的待插值像素点,原图像像素的加权系数就越大;行间根据待插值行与其上下的原图像行间的距离进行加权线性插值,即离原图像行越近的待插值行,原图像行的加权系数就越大。
其原理图如下图所示。
双线性插值算法原理示意图
二、算法(MATLAB)
A=imread('1234.jpg');%读取图片
imshow(A);%显示图片
title('放大前原图像');%图片名字
C=imresize(A,5,'bilinear'); %双线性插值法
figure;%打开图片显示窗口
imshow(C);%重新显示放大后的图片
title('双线性插值法放大5倍');
三、程序运行结果截图。
图像插值技术——双线性插值法在图像处理中,如果需要对图像进⾏缩放,⼀般可以采取插值法,最常⽤的就是双线性插值法。
本⽂⾸先从数学⾓度推导了⼀维线性插值和⼆维线性插值的计算过程,并总结了规律。
随后将其应⽤到图像的双线性插值上,利⽤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图像中的双线性插值我们可以⽤函数来表⽰⼀幅图像(假设为单通道)。
13. 数据插值与拟合实际中,通常需要处理实验或测量得到的离散数据(点)。
插值与拟合方法就是要通过离散数据去确定一个近似函数(曲线或曲面),使其与已知数据有较高的拟合精度。
1.如果要求近似函数经过所已知的所有数据点,此时称为插值问题(不需要函数表达式)。
2.如果不要求近似函数经过所有数据点,而是要求它能较好地反映数据变化规律,称为数据拟合(必须有函数表达式)。
插值与拟合都是根据实际中一组已知数据来构造一个能够反映数据变化规律的近似函数。
区别是:【插值】不一定得到近似函数的表达形式,仅通过插值方法找到未知点对应的值。
【拟合】要求得到一个具体的近似函数的表达式。
因此,当数据量不够,但已知已有数据可信,需要补充数据,此时用【插值】。
当数据基本够用,需要寻找因果变量之间的数量关系(推断出表达式),进而对未知的情形作预测,此时用【拟合】。
一、数据插值根据选用不同类型的插值函数,逼近的效果就不同,一般有:(1)拉格朗日插值(lagrange插值)(2)分段线性插值(3)Hermite(4)三次样条插值Matlab 插值函数实现:(1)interp1( ) 一维插值(2)intep2( ) 二维插值(3)interp3( ) 三维插值(4)intern( ) n维插值1.一维插值(自变量是1维数据)语法:yi = interp1(x0, y0, xi, ‘method’)其中,x0, y0为原离散数据(x0为自变量,y0为因变量);xi为需要插值的节点,method为插值方法。
注:(1)要求x0是单调的,xi不超过x0的范围;(2)插值方法有‘nearest’——最邻近插值;‘linear’——线性插值;‘spline’——三次样条插值;‘cubic’——三次插值;默认为分段线性插值。
例1 从1点12点的11小时内,每隔1小时测量一次温度,测得的温度的数值依次为:5,8,9,15,25,29,31,30,22,25,27,24.试估计每隔1/10小时的温度值。
Matlab中插值函数汇总和使用说明MATLAB中的插值函数为interp1,其调用格式为: yi= interp1(x,y,xi,'method')其中x,y为插值点,yi为在被插值点xi处的插值结果;x,y为向量, 'method'表示采用的插值方法,MATLAB提供的插值方法有几种: 'method'是最邻近插值, 'linear'线性插值; 'spline'三次样条插值; 'cubic'立方插值.缺省时表示线性插值注意:所有的插值方法都要求x是单调的,并且xi不能够超过x的范围。
例如:在一天24小时内,从零点开始每间隔2小时测得的环境温度数据分别为12,9,9,10,18 ,24,28,27,25,20,18,15,13,推测中午12点(即13点)时的温度.x=0:2:24;y=[12 9 9 10 18 24 28 27 25 20 18 15 13];a=13;y1=interp1(x,y,a,'spline')结果为: 27.8725若要得到一天24小时的温度曲线,则:xi=0:1/3600:24;yi=interp1(x,y,xi, 'spline');plot(x,y,'o' ,xi,yi)命令1 interp1功能一维数据插值(表格查找)。
该命令对数据点之间计算内插值。
它找出一元函数f(x)在中间点的数值。
其中函数f(x)由所给数据决定。
x:原始数据点Y:原始数据点xi:插值点Yi:插值点格式(1)yi = interp1(x,Y,xi)返回插值向量yi,每一元素对应于参量xi,同时由向量x 与Y 的内插值决定。
参量x 指定数据Y 的点。
若Y 为一矩阵,则按Y 的每列计算。
yi是阶数为length(xi)*size(Y,2)的输出矩阵。
使⽤双线性插值法放⼤图像(matlab实现)双线性插值的概念及公式可以参考百度,这⾥仅对算法原理进⾏简单的说明:双线性插值计算公式:f(i+u,j+v) = (1-u)(1-v)f(i,j)+u(1-v)f(i+1,j)+(1-u)vf(i,j+1)+ uvf(i+1,j+1)这个公式表明了如何利⽤矩阵中的四个像素值计算新的像素值,这些新的像素值就组成了放⼤后的图像。
下图是如何将3x3的图像放⼤为4x4的图像:原图像表⽰为3x3的矩阵(像素值处在⿊线的交叉点上),如何计算4x4矩阵的值呢?(像素值处在红⾊虚线交叉点及红线与⿊线的交点上)⽐如新图像B的第⼀列与原图像A的第⼀列的对应关系是:B(1,1) = A(1,1)B(1,2) = A(1,1.66667)B(1,3) = A(1,2.33334)B(1,4) = A(1,3.00001)应⽤上⾯的公式,实际上就是⽤A的含有⼩数点的位置的像素值来计算B的像素值,但含有⼩数点位的像素是不存在的,这⾥称为虚拟位置。
⽤原图像A的值就能计算出放⼤后B的值,是不是很神奇?实际上可以这样认为:双线性插值就是把放⼤后的图像再压缩到原来图像的尺⼨⼤⼩,计算原图像中虚拟的像素值,等同于计算放⼤后图像的像素值,对于本例来说,B图像的步长相当于A图像步长的(3-1)/(4-1)=0.66667倍。
下⾯我们就可以利⽤这个⽐率来对应B中像素位置与A中虚拟像素位置的关系。
B(1,1) = A(1,1) (1-1)*0.66667+1=1B(1,2) = A(1,1.66667) (2-1)*0.66667+1=1.66667B(1,3) = A(1,2.33334) (3-1)*0.66667+1=2.33334B(1,4) = A(1,3.00001) (4-1)*0.66667+1=3.00001根据上⾯的对应关系,我们就可以⽤代码实现了。
现在还有⼀个问题:我们计算虚拟像素值是需要周围四个原像素值,⽐如上列中的(下图中红圈圈住的部分)A(1,3) = (1-0)(1-0)A(1,3) + (1-0)0A(1,4) + 0(1-0)A(2,3) + 00A(2,4)显然这⾥的A(1,4)和A(2,4)是⽆法索引到得,因为原图像是3x3的矩阵。
% 本程序实现双线性插值% 对于取整% there is a decimal a, the value of round and ceil is the nearest integer >a;% on the contrast, floor and fix is the nearest integer <a;% round = ceil ;floor = fix% 双线性插值:% 输出像素值是它在输入图像中2*2邻域采样点的平均值,% 它根据某像素周围4个像素的灰度值在水平和垂直两个方法上对其插值。
为了方便理解,先考虑一维情况下的线性插值:% 对于一个数列c,% 假设c[a]到c[a+1]之间是线性变化的,那么对于浮点数% %-------------------第一种表达% x( a <= x < a+1)% c(x) = c[a+1]*( x - a) + c[a]*( 1 + a - x);% c(x) = c[a] + [ (c[a+1]-c[a])/(b-a)]*( x - a);% b = a+1;% c(x) = c[a] + [ c[a+1] - c[a]]*( x - a);% 把这种插值方式扩展到二维情况:对于一个二维数组c,% 我们假设对于任意一个浮点数i,c(a,i)到c(a+1,i)之间是线性变化的,c(i,b)到c(i,b+1)之间也是线性变化的(a,b都是整数) ,% 那么对于浮点数的坐标(x,y)满足(a <= x < a+1, b <= y < b+1),可以先分别求出c(x,b)和c(x,b+1):% c(x,b) = c[a+1][b]*( x - a) + c[a][b]*( 1 + a - x);% c(x,b+1) = c[a+1][b+1]*( x - a) + c[a][b+1]*( 1 + a - x);% 好,现在已经知道c(x,b)和c(x,b+1)了,而根据假设c(x,b)到c(x,b+1)也是线性变化的,所以:% c(x,y) = c(x,b+1)*( y - b) + c(x,b)*( 1 + b - y)% %------------第二种表达% c(x) = c[a+1]*( x - a) + c[a]*( 1 + a - x);% = c[a] + c[a+1]*( x - a) - c[a]( x - a);% c(x) = c[a] + ( c[a+1] - c[a])*( x - a);% 对于二维情况:% c(x,b) = c[a,b] + ( c[a+1,b] - c[a,b])*( x - a);% c(x,b+1) = c[a,b+1] + ( c[a+1,b+1] - c[a,b+1])*( x - a);% c(x,y) = c(x,b) + ( c(x,b+1) - c(x,b))*( y - b);%---------------------------------------------------------------------clc;clear all;Image = imread('1218.bmp');grayImage = rgb2gray(Image);figure,imshow(Image);figure,imshow(grayImage);% grayImage = [1 2 3 4 5;1 2 3 4 5;1 2 3 4 5;1 2 3 4 5;1 2 3 4 5];% grayImage = [1 2 3;1 2 3;1 2 3];rotation = [0.5 0.5;-0.5 0.5];[rows cols] = size(grayImage);grayImage = double(grayImage);for r = 1:rowsfor c = 1:colstemp = rotation*[r-rows/2;c-cols/2]+[rows/2;cols/2]; % 旋转% temp = [rows/2;cols/2];if( temp(1)>1 && temp(2)>1 && temp(1)<rows && temp(2)<cols) % 双线性插值x = floor(temp(1));y = floor(temp(2));% 插值公式1% v1 = grayImage( x+1,y)*( temp(1)-x) + grayImage( x,y)*( 1+x-temp(1));% v2 = grayImage( x+1,y+1)*( temp(1)-x) + grayImage( x,y+1)*( 1+x-temp(1)); % v = v2*( temp(2)-y) + v1*( 1+y-temp(2));% 插值公式2v1 = grayImage(x,y) + ( grayImage(x+1,y) - grayImage(x,y))*( temp(1) - x);v2 = grayImage(x,y+1) + ( grayImage(x+1,y+1) - grayImage(x,y+1))*( temp(1) - x);v = v1 + ( v2 - v1)*( temp(2) - y);grayImageN(r,c) = round(v);endendendgrayImage = uint8(grayImageN);figure,imshow(grayImage);本文来自: 高校自动化网() 详细出处参考(转载请保留本链接):/html/matlab/15410_2.html。
%双三次插值具体实现;('E:\\\\图片\');= 2()转化为灰度图像[](); %将图像隔行隔列抽取元素,得到缩小的图像f22;f = ();11f()(2*i,2*j);5; %设置放大倍数1 = (,'')双线性插值结果比较= 8(1);(1,:)(m,:); %将待插值图像矩阵前后各扩展两行两列,共扩展四行四列[f(1,1)(1,1)(:,1)'(m,1)(m,1)][f(1)(1)()'()()];a1=[];b1=[1'];1'1();g1 = (k**n);1*m %利用双三次插值公式对新图象所有像素赋值(); i1()+2;[(1) (u) (1) (2)];1*n()1()+2;[(1)(v)(1)(2)];[f1(i1-11-1) f1(i1-11) f1(i1-11+1) f1(i1-11+2)f1(i11-1) f1(i11) f1(i11+1) f1(i11+2)f1(i1+11-1) f1(i1+11) f1(i1+11+1) f1(i1+11+2)f1(i1+21-1) f1(i1+21) f1(i1+21+1) f1(i1+21+2)];g1()=(A*B*C);8(g1);(8(f)); ('缩小的图像'); %显示缩小的图像()('原图'); %显示原图像(g)('双三次插值放大的图像'); %显示插值后的图像()('双线性插值放大结果'); %显示插值后的图像0()(g);2(2()); %计算原图像和插值图像的傅立叶幅度谱g2(2(g));(1,2,1)(((2)),[8,10])('原图像的傅立叶幅度谱');(1,2,2)(((g2)),[8,10])('双三次插值图像的傅立叶幅度谱');基函数代码:(w1)(w1);w<1>=01-2*w^2^3;w>=1<24-8*5*w^2^3;0;算法原理双三次插值又称立方卷积插值。
matlab插值函数用法在MATLAB 中,插值函数用于根据已知数据点的值,估计在这些数据点之间的位置的值。
MATLAB 提供了多种插值函数,常用的包括`interp1`、`interp2`、`interp3` 等。
下面是一些常见的MATLAB 插值函数的用法:1. interp1:一维插值函数,用于对一维数据进行插值。
```matlab% 创建一些示例数据x = 1:5;y = [3 7 2 5 8];% 定义插值点xi = 1:0.1:5;% 进行线性插值yi = interp1(x, y, xi, 'linear');```2. interp2:二维插值函数,用于对二维数据进行插值。
```matlab% 创建一些示例数据[X, Y] = meshgrid(1:5, 1:5);Z = peaks(5);% 定义插值点[XI, YI] = meshgrid(1:0.1:5, 1:0.1:5);% 进行二维插值ZI = interp2(X, Y, Z, XI, YI, 'linear');```3. interp3:三维插值函数,用于对三维数据进行插值。
```matlab% 创建一些示例数据[X, Y, Z] = meshgrid(1:5, 1:5, 1:5);V = rand(5, 5, 5);% 定义插值点[XI, YI, ZI] = meshgrid(1:0.1:5, 1:0.1:5, 1:0.1:5);% 进行三维插值VI = interp3(X, Y, Z, V, XI, YI, ZI, 'linear');```这些函数中的`'linear'` 参数表示使用线性插值方法,你也可以选择其他插值方法,比如`'nearest'`、`'spline'` 等。
此外,还可以根据需要进行更高级的插值操作,比如多项式插值、样条插值等。
1,插值算法(3种):(1)最邻近插值(近邻取样法):最邻近插值的的思想很简单,就是把这个非整数坐标作一个四舍五入,取最近的整数点坐标处的点的颜色。
可见,最邻近插值简单且直观,速度也最快,但得到的图像质量不高。
最邻近插值法的MA TLAB源代码为:A = imread('F:\lena.jpg');%读取图像信息imshow(A); %显示原图title('原图128*128');Row = size(A,1); Col = size(A,2);%图像行数和列数nn=8;%放大倍数m = round(nn*Row);%求出变换后的坐标的最大值n = round(nn*Col);B = zeros(m,n,3);%定义变换后的图像for i = 1 : mfor j = 1 : nx = round(i/nn); y = round(j/nn);%最小临近法对图像进行插值if x==0 x = 1; endif y==0 y = 1; endif x>Row x = Row; endif y>Col y = Col;endB(i,j,:) = A(x,y,:);endendB = uint8(B);%将矩阵转换成8位无符号整数figure;imshow(B);title('最邻近插值法放大8倍1024*1024');运行程序后,原图如图1所示:图1用最邻近插值法放大4倍后的图如图2所示:图2(2)双线性内插值法:在双线性内插值法中,对于一个目的像素,设置坐标通过反向变换得到的浮点坐标为(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-v)f(i,j) + (1-u)vf(i,j+1) + u(1-v)f(i+1,j) + uvf(i+1,j+1)其中f(i,j)表示源图像(i,j)处的的像素值,以此类推。
双线性插值算法张俊飞一、算法简介假设c[a]到c[a+1]之间是线性变化的,那么对于浮点数x( a <= x < a+1)c(x) = c[a+1]*( x - a) + c[a]*( 1 + a - x);c(x) = c[a] + [ (c[a+1]-c[a])/(b-a)]*( x - a);b = a+1;c(x) = c[a] + [ c[a+1] - c[a]]*( x - a);把这种插值方式扩展到二维情况:对于一个二维数组c,我们假设对于任意一个浮点数i,c(a,i)到c(a+1,i)之间是线性变化的,c(i,b)到c(i,b+1)之间也是线性变化的(a,b都是整数) ,那么对于浮点数的坐标(x,y)满足(a <= x < a+1, b <= y < b+1),可以先分别求出c(x,b)和c(x,b+1):c(x,b) = c[a+1][b]*( x - a) + c[a][b]*( 1 + a - x);c(x,b+1) = c[a+1][b+1]*( x - a) + c[a][b+1]*( 1 + a - x);现在已经知道c(x,b)和c(x,b+1)了,而根据假设c(x,b)到c(x,b+1)也是线性变化的,所以: c(x,y) = c(x,b+1)*( y - b) + c(x,b)*( 1 + b - y)二、matlab实现在command窗口输入chahzi('cameraman.tif',2),这里cameraman.tif为灰度图片,得到结果如下:origin imageresult image在command窗口输入chahzi('a.jpg',0.5),这里a.jpg为彩色图片,得到结果为:origin imageresult image由以上结果可知,该算法的鲁棒性较强,图片伸缩插值保真度高。
实验二图像几何变换与插值一、实验目的巩固图像处理编程的步骤格式,理解数据插值及图像几何变换的原理,掌握图像几何变换的实现方法。
二、实验内容1、理解反向变换的实现思路2、图像缩放及插值Matlab取整命令:floor, ceil, round分别实验最近邻插值和双线性插值f=imread('lena.bmp');beishu=0.5;[row,col]=size(f);r1=round(row*beishu);c1=round(col*beishu);b=zeros(r1,c1);for i=1:r1for j=1:c1i1=round(i/beishu);j1=round(j/beishu);if i1<1i1=1;endif j1<1j1=1;endb(i,j)=f(i1,j1);endendb=uint8(b);figure;imshow(f);figureimshow(b);3、图像旋转及插值以图像中心为轴实现任意角度(逆时针为正)的图像旋转,分别实验两种插值算法f=imread('lena.bmp');B=imrotate(f,45,'nearest','crop');C=imrotate(f,45,'bilinear','crop');figure;subplot(121);imshow(f);title('原图像');subplot(122);imshow(B);title('最近邻插值');figure;subplot(121);imshow(f);title('原图像');subplot(122);imshow(C);title('双线性插值');原图像最近邻插值处理原图像双线性插值处理%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% matlab练习程序(图像放大/缩小,最邻近插值)ccccl;w=0.6; %放大或缩小的宽度h=1.4; %放大或缩小的高度img=imread('Corner.png');imshow(img);[m n]=size(img);imgn=zeros(h*m,w*n);rot=[h 0 0;0 w 0;0 0 1]; %变换矩阵x=h*u,y=w*vinv_rot=inv(rot);for x=1:h*mfor y=1:w*npix=[x y 1]*inv_rot;imgn(x,y)=img(round(pix(1)),round(pix(2)));endendfigure,imshow(uint8(imgn)) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% matlab练习程序(图像放大/缩小,双线性插值)cccm=1.8; %放大或缩小的高度n=2.3; %放大或缩小的宽度img=imread('lena.jpg');imshow(img);[h w]=size(img);imgn=zeros(h*m,w*n);rot=[m 0 0;0 n 0;0 0 1]; %变换矩阵for i=1:h*mfor j=1:w*npix=[i j 1]/rot;float_Y=pix(1)-floor(pix(1));float_X=pix(2)-floor(pix(2));if pix(1) < 1%边界处理pix(1) = 1;endif pix(1) > hpix(1) = h;endif pix(2) < 1pix(2) =1;endif pix(2) > wpix(2) =w;endpix_up_left=[floor(pix(1)) floor(pix(2))];%四个相邻的点pix_up_right=[floor(pix(1)) ceil(pix(2))];pix_down_left=[ceil(pix(1)) floor(pix(2))];pix_down_right=[ceil(pix(1)) ceil(pix(2))];value_up_left=(1-float_X)*(1-float_Y);%计算临近四个点的权重value_up_right=float_X*(1-float_Y);value_down_left=(1-float_X)*float_Y;value_down_right=float_X*float_Y;%按权重进行双线性插值imgn(i,j)=value_up_left*img(pix_up_left(1),pix_up_left(2))+ ...value_up_right*img(pix_up_right(1),pix_up_right(2))+ ...value_down_left*img(pix_down_left(1),pix_down_left(2))+ ...value_down_right*img(pix_down_right(1),pix_down_right(2));endendfigure,imshow(uint8(imgn)) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% matlab练习程序(图像旋转,最邻近插值)ccccl;H=1; %索引pix中第一个元素,即高度W=2; %索引pix中第二个元素,即宽度jiaodu=45; %要旋转的角度,旋转方向为顺时针img=imread('Corner.png'); %这里v为原图像的高度,u为原图像的宽度imshow(img); %这里y为变换后图像的高度,x为变换后图像的宽度[v u]=size(img);theta=jiaodu/180*pi;rot=[cos(theta) -sin(theta) 0;sin(theta) cos(theta) 0;0 0 1];inv_rot=inv(rot);pix1=[1 1 1]*rot; %变换后图像左上点的坐标pix2=[1 u 1]*rot; %变换后图像右上点的坐标pix3=[v 1 1]*rot; %变换后图像左下点的坐标pix4=[v u 1]*rot; %变换后图像右下点的坐标height=round(max([abs(pix1(H)-pix4(H))+0.5 abs(pix2(H)-pix3(H))+0.5])); %变换后图像的高度width=round(max([abs(pix1(W)-pix4(W))+0.5 abs(pix2(W)-pix3(W))+0.5])); %变换后图像的宽度imgn=zeros(height,width);delta_y=abs(min([pix1(H) pix2(H) pix3(H) pix4(H)])); %取得y方向的负轴超出的偏移量delta_x=abs(min([pix1(W) pix2(W) pix3(W) pix4(W)])); %取得x方向的负轴超出的偏移量for y=1-delta_y:height-delta_yfor x=1-delta_x:width-delta_xpix=[y x 1]*inv_rot; %用变换后图像的点的坐标去寻找原图像点的坐标,%否则有些变换后的图像的像素点无法完全填充if pix(H)>=0.5 && pix(W)>=0.5 && pix(H)<=v && pix(W)<=uimgn(y+delta_y,x+delta_x)=img(round(pix(H)),round(pix(W)));endendendfigure,imshow(uint8(imgn))%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% matlab练习程序(图像旋转,双线性插值)cccjiaodu=45; %要旋转的角度,旋转方向为顺时针img=imread('lena.jpg'); %这里v为原图像的高度,u为原图像的宽度imshow(img); %这里y为变换后图像的高度,x为变换后图像的宽度[h w]=size(img);theta=jiaodu/180*pi;rot=[cos(theta) -sin(theta) 0;sin(theta) cos(theta) 0;0 0 1];pix1=[1 1 1]*rot; %变换后图像左上点的坐标pix2=[1 w 1]*rot; %变换后图像右上点的坐标pix3=[h 1 1]*rot; %变换后图像左下点的坐标pix4=[h w 1]*rot; %变换后图像右下点的坐标height=round(max([abs(pix1(1)-pix4(1))+0.5 abs(pix2(1)-pix3(1))+0.5])); %变换后图像的高度width=round(max([abs(pix1(2)-pix4(2))+0.5 abs(pix2(2)-pix3(2))+0.5])); %变换后图像的宽度imgn=zeros(height,width);delta_y=abs(min([pix1(1) pix2(1) pix3(1) pix4(1)])); %取得y方向的负轴超出的偏移量delta_x=abs(min([pix1(2) pix2(2) pix3(2) pix4(2)])); %取得x方向的负轴超出的偏移量for i=1-delta_y:height-delta_yfor j=1-delta_x:width-delta_xpix=[i j 1]/rot; %用变换后图像的点的坐标去寻找原图像点的坐标,%否则有些变换后的图像的像素点无法完全填充float_Y=pix(1)-floor(pix(1));float_X=pix(2)-floor(pix(2));if pix(1)>=1 && pix(2)>=1 && pix(1) <= h && pix(2) <= wpix_up_left=[floor(pix(1)) floor(pix(2))]; %四个相邻的点pix_up_right=[floor(pix(1)) ceil(pix(2))];pix_down_left=[ceil(pix(1)) floor(pix(2))];pix_down_right=[ceil(pix(1)) ceil(pix(2))];value_up_left=(1-float_X)*(1-float_Y); %计算临近四个点的权重value_up_right=float_X*(1-float_Y);value_down_left=(1-float_X)*float_Y;value_down_right=float_X*float_Y;imgn(i+delta_y,j+delta_x)=value_up_left*img(pix_up_left(1),pix_up_left(2))+ ...value_up_right*img(pix_up_right(1),pix_up_right(2))+ ...value_down_left*img(pix_down_left(1),pix_down_left(2))+ ...value_down_right*img(pix_down_right(1),pix_down_right(2));endendendfigure,imshow(uint8(imgn)) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%实验一 Matlab图像基本操作一、实验目的熟悉利用Matlab进行图像处理的基本操作,了解图像数据的存储形式及进行图像处理编程的步骤方法。
双线性插值算法
张俊飞一、算法简介
假设c[a]到c[a+1]之间是线性变化的,那么对于浮点数
x( a <= x < a+1)
c(x) = c[a+1]*( x - a) + c[a]*( 1 + a - x);
c(x) = c[a] + [ (c[a+1]-c[a])/(b-a)]*( x - a);
b = a+1;
c(x) = c[a] + [ c[a+1] - c[a]]*( x - a);
把这种插值方式扩展到二维情况:对于一个二维数组c,
我们假设对于任意一个浮点数i,c(a,i)到c(a+1,i)之间是线性变化的,c(i,b)到c(i,b+1)之间也是线性变化的(a,b都是整数) ,
那么对于浮点数的坐标(x,y)满足(a <= x < a+1, b <= y < b+1),可以先分别求出c(x,b)和c(x,b+1):
c(x,b) = c[a+1][b]*( x - a) + c[a][b]*( 1 + a - x);
c(x,b+1) = c[a+1][b+1]*( x - a) + c[a][b+1]*( 1 + a - x);
现在已经知道c(x,b)和c(x,b+1)了,而根据假设c(x,b)到c(x,b+1)也是线性变化的,所以: c(x,y) = c(x,b+1)*( y - b) + c(x,b)*( 1 + b - y)
二、matlab实现
在command窗口输入chahzi('cameraman.tif',2),这里cameraman.tif为灰度图片,得到结果如下:
origin image
result image
在command窗口输入chahzi('a.jpg',0.5),这里a.jpg为彩色图片,得到结果为:
origin image
result image
由以上结果可知,该算法的鲁棒性较强,图片伸缩插值保真度高。
三、代码
function []=chahzi(str,k)
% str input image
% k zoo in or out k times
% clear all
% clc
% k=2;
I=imread(str);
% if size(I,3)~=1
% I=rgb2gray(I);
% end
figure,imshow(I);
title('origin image');
I=double(I);
[rows cols tongdao]=size(I);
x_new=rows*k;
y_new=cols*k; %缩放至k倍。
I_new=zeros(x_new,y_new,tongdao );
for rgb=1:tongdao
for i=1:x_new
for j=1:y_new
x=i/k;a=floor(x); y=j/k;b=floor(y);
%% 双线性插值算法
if
a>0&&b>0&&a<rows&&b<cols
cxb=I(a+1,b,rgb)*(x-a)+I(a,b,rg b)*(1+a-x);
cxb1=I(a+1,b+1,rgb)*(x-a)+I(a,b +1,rgb)*(1+a-x);
I_new(i,j,rgb)=round(cxb1*(y-b) +cxb*(1+b-y));
end
end
end
end
% iftongdao==1%如果输入是灰度图,则% I_new=I_new(:,:,1);
% end
figure,imshow(uint8(I_new))
title('result image');。