Java图像缩放

简介

         图像的缩放(scale)是图像处理里很常见的运算,太常见了以致于我们根本不会认为它有什么特别的地方。比如我们在HTML里用<img> 加载一幅图片,然后指定它的宽度和高度,浏览器就自动帮我们把图片缩放到了合适的尺寸。看起来这应该是已经很简单的事情,不过仔细想想就会发现没有想象的那么简单。事实上,不存在”最优“的缩放算法。对于所有的图片,很难说某种算法是最好的。

         首先我们来考虑放大一个图片,考虑最简单的情况,把2个像素的图片放到2倍成4个像素的图片,像素2和4的值对应原来图片像素1和2的值,那么新增的像素 1和3呢?直觉的,你会想到像素2的值是原来像素1,像素3是原来像素2。为什么可以这样做呢?我们刚才做的事情用术语来说就是“插值 (interpolation)",因为像素的值的物理意义比如亮度是连续的量,所以可以用最接近的点来预测当前点的情况。除了最简单的最近邻 (NEAREST NEIGHBOR),常用的还包括线性插值,三次插值等等。

         相反的,我们考虑缩小一幅图片,比如把4个像素点缩小到2个像素点,那么缩放后像素1的值到底是取原来像素1的值还是原来像素2的值呢?或者取它们的平均值?如果像素1和2相同,那么取1或2和取平均值没有任何区别,如果像素1和2差别很大呢?那么取平均值其实就是在做平滑(smoothing),从频率角度分析,就是低通滤波,也就是把高频的信息去掉了。什么是高频?通俗的说就是变化剧烈的。比如图片的边缘,一般都是颜色变化较大的地方(很多边缘抽取的算法都会用到差分/微分,其实就是变化大的点)。这样的话图片看起来比较平滑,但是同时也可能损失一些对比度。

         另外我们考虑的缩放都是整数倍的,如果不是整数倍呢?那么也需要插值。从上面的例子可以发现,缩放一幅图片并不如想象中的那么容易。下面形式化的介绍图片缩放的流程。

几何变换(Geometrical Transformation)

         常见的变换包括仿射变换(_AffineTransform),投影变换(_projection transformation),和非线性的变换(比如双线性变换)

  1.    仿射变换
    包括平移,旋转和缩放,它的特点是直线经过仿射变换还是直线,仿射变化不改变两点间的距离,平行的直线变换后还是平行的直线。3个点可以确定变换的所有参数。所有正方形仿射变换后变成了平行四边形。
  2.    投影变换
    会改变两点的距离,正方形变换成普通四边形,它可以由4个点确定变换参数。
  3.    非线性变换

          我们缩放就属于第一种仿射变换。

源->目标 or 目标->源

        上面讨论的都加上图像是个连续的二元函数,但实际上在计算机里都是数字化的图像,也就是连续图像采样后的结果。

         源->目标

                把源图像的点通过变换函数映射到目标图像上,由于是连续的函数,所以新的坐标可能不是整数,所以常见的做法是把这个点挪到最接近的整坐标点上。它的缺点是有些点不会出现在目标图片上(浪费计算);

         目标->源

                对目标图片的每个点,通过逆变换找到源图片的点,如果这个点不是整数,那么需要通过周围的整数插值。

         一般都使用第二种方式。

插值(interpolation)

         插值可以说是缩放的核心。常见的插值方法包括最近邻插值,线性插值和3次样条插值。由于图像是2维的,所以对应的就是最近邻插值(这个与维度无关了),BILINEAR(翻译成双线性?),BICUBIC。

         最近邻和Bi-Linear没什么好说的,主要说说BI-Cubic。

        在说它之前先得说说离散信号的采样和重建。

        根据奈奎斯特(Harry Nyquist)采样定理,一个带限的连续信号,如果带宽小于采样频率/2的话,那么原始信号可以由采样后的离散信号完全重建出来。重建时会用到sinc函数 ,它的频率响应是个矩形窗。理想情况下应该用它来插值。sinc函数是延展到无穷的,所以一幅图片当前点的值依赖于所有点的值,不过sinc函数随着x的增大衰减的非常快,一般到了第3个旁瓣后就基本等于0了。sinc函数是一个理想的低通滤波器,它可以很好的保证图片缩放是的平滑,但是它的缺点是图片的剧烈变化也会被它平滑掉。与此对应,最近邻插值的时域是一个分段的线段(矩形窗),它能够较好的反应图片的变化,但它的去点是连续的区域变得不平滑了。所以从理论上来说&#x

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值