双线性插值原理与实现

在对图像进行空间变换的过程中,典型的情况是在对图像进行放大处理的时候,图像会出现失真的现象。这是由于在变换之后的图像中,存在着一些变换之前的图像中没有的像素位置。为了说明这个问题,不妨假设有一副大小为64x64的灰度图像A,现在将图像放大到256x256,不妨令其为图像B,如图1所示。显然,根据简单的几何换算关系,可以知道B图像中(x,y)处的像素值应该对应着A图像中的(x/4,y/4)处的象素值,即

B(x,y) = A(x/4,y/4) (式1)

对于B中的(4,4),(4,8),(4,16)…(256,256)这些位置,通过式1就可以计算出其在A中的位置,从而可以得到灰度值。但是,对于B中的(1,1),(1,2),(1,3)…等等这些坐标点而言,如果按照式1计算的话,那么它们在A中对应的坐标不再是整数。比如,对于B中的坐标点(1,1),其在A中的对应坐标就变成了(0.25,0.25)。对于数字图像而言,小数坐标是没有意义的。因此,必须考虑采用某种方法来得到B中像素点在A中对应位置上的灰度级。处理这一问题的方法被称为图像灰度级插值。常用的插值方式有三种:最近邻域插值、双线性插值、双三次插值。理论上来讲,最近邻域插值的效果最差,双三次插值的效果最好,双线性插值的效果介于两者之间。不过对于要求不是非常严格的图像插值而言,使用双线性插值通常就足够了。

本文中将采用matlab实现一个双线性插值的程序。双线性插值的原理如图2所示。图像之间坐标映射有两种方式:如果是从原图像的坐标映射到目标图像,称为前向映射,反之则称为后向映射。显然,双线性插值采用的是后向映射方式。下面对图2的具体含义进行说明。首先,根据几何关系,从B图像中的坐标(x,y)得到A图像中的坐标(x/4,y/4),但是,映射得到的这个坐标(x/4,y/4)并没有刚好位于A图像中的整数坐标上,而是映射到了四个像素坐标(a,b)、(a+1,b)、(a,b+1)、(a+1,b+1)所围成的矩形之间,其中,a、b是A图像的整数坐标。现在的问题就是如何根据A(a,b)、A(a+1,b)、A(a,b+1)、A(a+1,b+1)这四个点上的灰度级求出A(x/4,y/4)处的灰度级。双线性插值技术采用的方法是:假设A图像的灰度级变化在纵向方向上是线性变化的,这样根据直线方程或者几何比例关系就能够求得(a,y/4)和(a+1,y/4)坐标处的灰度级A(a,y/4)和A(a+1,y/4)。然后,再假设在((a,y/4),A(a,y/4))和(a+1,y/4),A(a+1,y/4))这两点所确定的直线上,灰度级仍然是线性变化的。求出直线方程,于是就可以求得(x/4,y/4)处的灰度级A(x/4,y/4)。这就是双线性插值的基本思路。其中用到的两个基本假设是:首先灰度级在纵向方向上是线性变化的,然后假定灰度级在横向方向上也是线性变化的。

图1 图像缩放示意图

图2 双线性插值示意图

附录:

I=imread(‘image1.bmp‘);

[m,n]=size(I);

K=3;

width = K * m;

height = K * n;

J = uint8(zeros(width,height));

% width scale and height scale

widthScale = m/width;

heightScale = n/height;

% bilinear interplot

for x = 5:width - 5

for y = 5:height - 5

xx = x * widthScale;

yy = y * heightScale;

if (xx/double(uint16(xx)) == 1.0) & (xx/double(uint16(xx)) == 1.0)

J(x,y) = I(int16(xx),int16(yy));

else % a or b is not integer

a = double(uint16(xx)); % (a,b) is the base-dot

b = double(uint16(yy));

x11 = double(I(a,b)); % x11 <- I(a,b)

x12 = double(I(a,b+1)); % x12 <- I(a,b+1)

x21 = double(I(a+1,b)); % x21 <- I(a+1,b)

x22 = double(I(a+1,b+1)); % x22 <- I(a+1,b+1)

J(x,y) = uint8( (b+1-yy) * ((xx-a)*x21 + (a+1-xx)*x11) + (yy-b) * ((xx-a)*x22 +(a+1-xx) * x12)); % calculate J(x,y)

end

end

end

% 显示图像

imwrite(J, ‘放大的图像.jpg‘, ‘jpg‘);

imshow(I),title(‘原图‘);

figure

imshow(J),title(‘放大图‘);

  

I=imread(‘image1.bmp‘);

[m,n]=size(I);

K=3;

width = K * m;

height = K * n;

J = uint8(zeros(width,height));

% width scale and height scale

widthScale = m/width;

heightScale = n/height;

% bilinear interplot

for x = 5:width - 5

for y = 5:height - 5

xx = x * widthScale;

yy = y * heightScale;

if (xx/double(uint16(xx)) == 1.0) & (xx/double(uint16(xx)) == 1.0)

J(x,y) = I(int16(xx),int16(yy));

else % a or b is not integer

a = double(uint16(xx)); % (a,b) is the base-dot

b = double(uint16(yy));

x11 = double(I(a,b)); % x11 <- I(a,b)

x12 = double(I(a,b+1)); % x12 <- I(a,b+1)

x21 = double(I(a+1,b)); % x21 <- I(a+1,b)

x22 = double(I(a+1,b+1)); % x22 <- I(a+1,b+1)

J(x,y) = uint8( (b+1-yy) * ((xx-a)*x21 + (a+1-xx)*x11) + (yy-b) * ((xx-a)*x22 +(a+1-xx) * x12)); % calculate J(x,y)

end

end

end

% 显示图像

imwrite(J, ‘放大的图像.jpg‘, ‘jpg‘);

imshow(I),title(‘原图‘);

figure

imshow(J),title(‘放大图‘);

  

时间: 2024-10-24 16:27:17

双线性插值原理与实现的相关文章

双线性插值原理和实现

来源:http://m.blog.csdn.net/HUSTLX/article/details/50810057 在对图像进行空间变换的过程中,典型的情况是在对图像进行放大处理的时候,图像会出现失真的现象.这是由于在变换之后的图像中,存在着一些变换之前的图像中没有的像素位置.为了说明这个问题,不妨假设有一副大小为64x64的灰度图像A,现在将图像放大到256x256,不妨令其为图像B,如图1所示.显然,根据简单的几何换算关系,可以知道B图像中(x,y)处的像素值应该对应着A图像中的(x/4,y

图像缩放算法

图像缩放算法较多,下面仅以最邻近插值算法和双线性插值算法作介绍. 如下图1所示,表示原始图像和缩放以后的图像. 图1 图像缩放(原始图像à缩放图像) 图像缩放就是将原始图像中的点经过某一算法映射到目标图像的点的行为,即要找到目标图像中的点p1对应在原始图像中点p0,简单而言就是找点p0. 假设: 原始图像src的分辨率为(srcW * srcH): 目标图像dst的分辨率为(dstW * dstH). 那么: 原始图像宽与目标图像宽的比例 原始图像高与目标图像高的比例 由 所以,原始图像中的点p

图像旋转后出现黑点 - (二) - 填坑

前接:图像旋转后出现黑点 - (一) - 入坑 这是填坑篇,之前写的图片旋转程序把图片变成了桌布,几个世纪后,在一个月黑风高的夜晚,我灵光乍现,何不试试双线性插值? 先上代码和效果图. 1 # !/usr/bin/env python3 2 # -*-coding:utf-8-*- 3 """ 4 双线性插值参考资料: 双线性插值原理及Python实现 - Jinglever https://www.jianshu.com/p/29e5c84ea539 5 6 如果出现错误:

基于OpenCV进行图像拼接原理解析和编码实现(提纲 代码和具体内容在课件中)

一.背景 1.1概念定义 我们这里想要实现的图像拼接,既不是如题图1和2这样的"图片艺术拼接",也不是如图3这样的"显示拼接",而是实现类似"BaiDU全景"这样的全部的或者部分的实际场景的重新回放. 对于图像拼接的流程有很多定义方式,本教程中主要介绍实现主流方法,总结梳理如下: 图像采集->投影变换->特征点匹配->拼接对准->融合->反投影 图像采集不仅仅指的是普通的图像数据的获取.为了能够拼接过程能够顺利进行.

OpenCV ——双线性插值(Bilinear interpolation)

1,原理 在图像的仿射变换中,很多地方需要用到插值运算,常见的插值运算包括最邻近插值,双线性插值,双三次插值,兰索思插值等方法,OpenCV提供了很多方法,其中,双线性插值由于折中的插值效果和运算速度,运用比较广泛. 越是简单的模型越适合用来举例子,我们就举个简单的图像:3*3 的256级灰度图.假如图像的象素矩阵如下图所示(这个原始图把它叫做源图,Source):       234 38 22       67 44 12       89 65 63 这 个矩阵中,元素坐标(x,y)是这样

图像水波纹特效原理分析和实现

前段时间注意到一些软件上有图像的水波纹特效,似乎很炫,想深入了解下该效果的具体原理与实现方式,上网搜了不少些资料,都讲得不清不楚,没办法只能靠自己了.花了一整个下午先去复习了高中物理的波的知识,试着自己来推导原理并实现了下.下面的推导是我根据一些资料以及自己分析出的,如有错误,望请指出.上张效果图先: 基本原理 水波效果反映到图像上,则是像素点的偏移.因此对图像的处理就如同图像缩放一样,对于输出图像的每个点,计算其对应于原始输入图像的像素点,通过插值的方法即可计算其颜色值. 先说下关于水波的基础

Cesium原理篇:3最长的一帧之地形(4:重采样)

       地形部分的原理介绍的差不多了,但之前还有一个刻意忽略的地方,就是地形的重采样.通俗的讲,如果当前Tile没有地形数据的话,则会从他父类的地形数据中取它所对应的四分之一的地形数据.打个比方,当我们快速缩放影像的时候,下一级的影像还没来得及更新,所以会暂时把当前Level的影像数据放大显示, 一旦对应的影像数据下载到当前客户端后再更新成精细的数据.Cesium中对地形也采用了这样的思路.下面我们具体介绍其中的详细内容.        上图是一个大概流程,在创建Tile的时候(prepa

SIFT特征原理简析(HELU版)

SIFT(Scale-Invariant Feature Transform)是一种具有尺度不变性和光照不变性的特征描述子,也同时是一套特征提取的理论,首次由D. G. Lowe于2004年以<Distinctive Image Features from Scale-Invariant Keypoints[J]>发表于IJCV中.开源算法库OpenCV中进行了实现.扩展和使用. 本文主要依据原始论文和网络上相关专业分析,对SIFT特征提取的算法流程进行简单分析.由于涉及到的知识概念较多,本人

【OpenCV】SIFT原理与源码分析:关键点描述

<SIFT原理与源码分析>系列文章索引:http://www.cnblogs.com/tianyalu/p/5467813.html 由前一篇<方向赋值>,为找到的关键点即SIFT特征点赋了值,包含位置.尺度和方向的信息.接下来的步骤是关键点描述,即用用一组向量将这个关键点描述出来,这个描述子不但包括关键点,也包括关键点周围对其有贡献的像素点.用来作为目标匹配的依据(所以描述子应该有较高的独特性,以保证匹配率),也可使关键点具有更多的不变特性,如光照变化.3D视点变化等. SIFT