使用双线性插值法放大图像(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的值,是不是很神奇?

实际上可以这样认为:双线性插值就是把放大后的图像再压缩到原来图像的尺寸大小,计算原图像中虚拟的像素值,等同于计算放大后图像的像素值,

对于本例来说,B图像的步长相当于A图像步长的(3-1)/(4-1)=0.66667倍。下面我们就可以利用这个比率来对应B中像素位置与A中虚拟像素位置的关系。

B(1,1) = A(1,1)                    (1-1)*0.66667+1=1

B(1,2) = A(1,1.66667)         (2-1)*0.66667+1=1.66667

B(1,3) = A(1,2.33334)         (3-1)*0.66667+1=2.33334

B(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的矩阵。

为了解决这个问题,在A的最后一行,与最后一列分别加上0,这样A就变成了4x4的矩阵。

图示中黑色虚线是添加的0行0列,红色斜箭头把需要用到扩展A矩阵的虚拟像素点位置都标了出来。

代码实现:

主程序代码:

clear ; close all; clc
image = imread(‘bird.png‘);  %载入图像的值
r = image(:,:,1);     %由于真彩图是红蓝绿三个像素的叠加
g = image(:,:,2);     %这里把r,g,b分离出来单独调用函数计算
b = image(:,:,3);     %计算完成后再进行组装
%这里需要手动设置放大的倍数
w = 4;   %w放大的是竖直方向
l = 4;   %l放大的是水平方向

r = extenRGB(r,w,l);  %调用函数计算放大后的r值
g = extenRGB(g,w,l);  %调用函数计算放大后的g值
b = extenRGB(b,w,l);  %调用函数计算放大后的b值
%下面把计算完成后的rgb再组装起来
outRGB(:,:,1) = r;
outRGB(:,:,2) = g;
outRGB(:,:,3) = b;

outRGB = uint8(outRGB);%格式转换,否则无法显示

imshow(outRGB);        %显示放大后的图像

主程序调用的函数:

%像素放大计算函数 extenRGB()
function Output = extenRGB(A,w,l)

% A矩阵分别代表r,g,b矩阵
[m,n] = size(A);      %读取A的行和列
A = [A;zeros(1,n)];   %在A的最后一行加入两行0
A = [A zeros(m+1,1)]; %在A的最后一列加入两列0
%这样A就变成(m+1)x(n+1)的矩阵,这是为了解决索引A矩阵时的边界溢出问题

ini_u = (m-1)/(w*m-1); %步长比,如果把原来的一步A(1,1)到A(2,1)看做1,那么计算放大后的
ini_v = (n-1)/(l*n-1); %图像B(2,1)相当于计算A(1+ini_u,1),即每步相当于加1

Output = zeros(w*m,l*n);            %初始化输出矩阵
for j = 1:l*n;                      %左边两个语句的功能是:z_u,z_v向左取整,u,v取小数,原理如下
    z_v = floor((j-1)*ini_v+1);     %比如A为3x3的矩阵,要放大为Output是4x4大小,即放大了4/3倍,
      v = (j-1)*ini_v+1 - z_v;      %新的一步的距离相当于原来的(3-1)/(4-1)=0.66667
    for i = 1:w*m;                  %Output(1,1) = A(1,1)       %(1-1)*0.66667+1=1
        z_u = floor((i-1)*ini_u+1); %Output(1,2) = A(1,1.66667) %(2-1)*0.66667+1=1.66667
          u = (i-1)*ini_u+1 - z_u;  %Output(1,3) = A(1,2.33334) %(3-1)*0.66667+1=2.33334
                                    %Output(1,4) = A(1,3.00001) %(4-1)*0.66667+1=3.00001

%===================下面是双线性插值的代码实现================================
        Output(i,j) = (1 - u)*(1 - v)*A(z_u,     z_v    ) + ...
                      (1 - u)* v     *A(z_u,     z_v + 1) + ...
                       u     *(1 - v)*A(z_u + 1, z_v    ) + ...
                       u     * v     *A(z_u + 1, z_v + 1);
    end
end
       
时间: 2024-10-28 05:52:00

使用双线性插值法放大图像(matlab实现)的相关文章

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

双线性插值(说的很明白) 来自:http://www.cnblogs.com/linkr/p/3630902.html http://www.cnblogs.com/linkr/p/3630902.html 双线性插值,这个名字咋一听很高大上的样纸,再在维基百科上一查(见文末,我去,一堆的公式吓死人),像俺这种半文盲,看到公式脑子就懵的类型,真心给跪.虽然看着好复杂,但仔细一看道理再简单不过了,所以还是自己梳理一下好. 双线性插值,顾名思义就是两个方向的线性插值加起来(这解释过于简单粗暴,哈哈)

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

原文地址:双线性插值算法进行图像缩放及性能效果优化 一)转自http://handspeaker.iteye.com/blog/1545126 最近在编程时用到了双线性插值算法,对图像进行缩放.网上有很多这方面的资料,介绍的也算明白.但是,这些文章只介绍了算法,并没有具体说怎么实现以及怎么实现最好,举个例子,你可以按照网上文章的算法自己写一个双线性插值程序,用它对一张图片进行处理,然后再用matlab或者openCV的resize函数对同一张图片进行处理,得到的结果是不一样的,如果源图片较小,效

图像matlab 频域处理

这篇文章实际上是笔者在学习冈萨雷斯 数字图像处理 matlab 版本 的第四章时,自己动手在matlab里敲入书上的程序实验得到的. 这个DFT的滤波步骤很重要,应该弄清楚. 1,  使用函数paddedsize()获得填充参数 FQ=paddedsize(size(I));%I为原始图像灰度矩阵 2,  得到使用填充的傅里叶变换 F=fft2(I,PQ(1,),PQ(2)); 3,  使用任何一种方法,例如lpfilter()生成一个大小为PQ(1)*PQ(2)的滤波函数H.这个函数如果居中,

MATLAB 中文论坛相关帖子整理

说明: 本资料所有问题及代码均摘选自matlab中文论坛(www.ilovematlab.cn),主要供自己学习使用. 非常感谢论坛的所有提出以及解答问题的会员. 目   录 1.GUI新手之--教你读懂GUI的M文件... 10 2.GUI程序中改变current directory引起的问题... 15 3.GUI中h0bject和handles 的区别... 16 4.handles结构中句柄和对象的关联问题... 17 5.Matlab利用定时器连续显示图片的问题... 19 5-1.G

MATLAB 几何运算之图像的放大

一.最近邻插值算法 思想&步骤: 1.根据放大的倍数,新建一个大小为原图像大小*倍数的0矩阵 2.0矩阵的每一个像素点的值根据原图像求出,即分别把x,y除以倍数后得到的小数取整( matlab中的round函数取小数的最近整数 ) 3.对于边缘的情况要注意 最邻近插值简单且直观,速度也最快,但得到的图像质量不高. 代码demo: A=imread('E:\matlab\work\tiger.jpg');%读取图像信息 imshow(A);%显示原图 title('原图'); Row=size(A

图像放大算法

http://www.cnblogs.com/celerychen/archive/2010/11/25/3588222.html 一. 图像放大算法 图像放大有许多算法,其关键在于对未知像素使用何种插值方式.以下我们将具体分析几种常见的算法,然后从放大后的图像是否存在色彩失真,图像的细节是否得到较好的保存,放大过程所需时间是否分配合理等多方面来比较它们的优劣. 当把一个小图像放大的时候,比如放大400%,我们可以首先依据原来的相邻4个像素点的色彩值,按照放大倍数找到新的ABCD像素点的位置并进

matlab 图像的几何变换

图像如果向前映射有效率低,不完成等缺点,所以一般我们使用向后映射. (1)平移: I = imread('apostles.jpg'); I = double(I); B = zeros(size(I)); H = size(I); move_x = 100; move_y = 150; B(move_y + 1:H(1), move_x+1:H(2), 1:H(3))=... I(1:H(1)-move_y, 1:H(2) - move_x, 1:H(3)); subplot(1,2,1),s

图像缩放——双线性插值算法

在数学上,双线性插值是有两个变量的插值函数的线性插值扩展,其核心思想是在两个方向分别进行一次线性插值.如果选择一个坐标系统使得  的四个已知点坐标分别为 (0, 0).(0, 1).(1, 0) 和 (1, 1),那么插值公式就可以化简为: 用矩阵运算来表示的话就是: 图像的空间变换,也称几何变换或几何运算,包括图像的平移.旋转.镜像变换.转置.缩放等.空间变换可如下表示:设(u,v)为源图像上的点,(x,y)为目标图像上的点,则空间变换就是将源图像上(u,v)处的颜色值与目标图像上(x,y)处

图像放大子程序

本程序实现图像横纵坐标个放大二倍的经典代码: 实现1个原像素和4个放大图像像素直接对应的巧妙实现. function A=blow(B) %%像素放大的完整子程序,其实第三维是完全meiyou必要的 [n,m,c]=size(B); %%第三维为1 n=2*n;m=2*m; A=zeros(n,m,c); %%长宽各放大2倍 A(1:2:n,1:2:m,:)=B; %%原始像素的的一个点与放大像素的四个点相对应,相当于直接放大图像的实现 A(1:2:n,2:2:m,:)=B; A(2:2:n,1