使用插值算法实现图像缩放是数字图像处理算法中经常遇到的问题。我们经常会将某种尺寸的图像转换为其他尺寸的图像,如放大或者缩小图像。由于在缩放的过程中会遇到浮点数,如何在FPGA中正确的处理浮点数运算是在FPGA中实现图像缩放的关键。
一、插值算法原理
在图像的缩放处理过程中,经常会用到插值算法,常见的插值算法包括最邻近插值,双线性插值,双三次线性插值,兰索斯插值等方法。其中,双线性插值由于折中的插值效果和实现复杂度,运用较为广泛。本文中仅介绍最临近插值,重点讨论如何在FPGA平台上使用双线性插值实现图像的缩放。
1.1 最临近插值---------最临近插值介绍
讲理论不如举例子来的快,所以为了更好更快的理解最临近插值,我们通过举个简单的例子来解释最临近插值是个什么神奇的东西。假如有一个3*3矩阵(一幅图像其实就是矩阵),如下,我们把这个图像叫做原图(source image):
66 28 128
25 88 200
36 68 120
在矩阵中,坐标(x,y)是这样确定的,矩阵的左上角的顶点为原点,从左到右为x轴,从上到下为y轴,如下所示:
![](https://i-blog.csdnimg.cn/blog_migrate/aacb49568e75cc5389b06a67bbfc7685.png)
假设我们想把这个3*3的原图扩大成4*4(我们把这个4*4的图像叫做目的图像destination image)我们该如何做呢?首先当然是先把4*4的矩阵画出来,如下所示:
? ? ? ?
? ? ? ?
? ? ? ?
? ? ? ?
矩阵画出来后,接下来就要像未知数里填充像素点了。要填入的值如何计算呢,通过如下公式进行计算:
首先我们先来填充目的图像 (0,0),套用上述公式可得到对应原图像的坐标点,srcX =0,srcY= 0;找到原图像中对应的坐标点的像素值,将该像素填充到目的图像中,如下
66 ? ? ?
? ? ? ?
? ? ? ?
接下来填充目的图像(1,0),仍然套用公式,srcX = 3/4,srcY = 0,结果发现得到的结果居然有小数,由于计算机中的像素点已经是最小单位,像素的坐标都是整数,没有小数。这是只需要按照四舍五入的思想将小数坐标转换为整数坐标即可.所以(3/4,0) ≈ (1,0),把原图像中(1,0)点的像素值填入目的图像(1,0)坐标处,得到如下结果:
66 28 ? ?
? ? ? ?
? ? ? ?
接下来重复上述过程,就可得到放大后的目的图像,如下:
66 28 128 128
25 88 200 200
36 68 120 120
36 68 120 120
这种放大图像的方法叫做最临近插值算法,这是一种最基本最简单的图像缩放算法,该方法缩放后的图像会出现失真现象。
1.2 双线性插值算法
双线性插值算法是一种比较好的缩放算法,它充分利用源图中虚拟点四周的四个像素点来共同决定目标图形中的一个像素值,因此缩放效果要比最临近插值算法好的多。
双线性插值算法的描述如下:
对于目的图像中的某点坐标,通过乘以缩放倍数(srcwidth/dstwidth、srcheight/dstheight)得到一个浮点坐标(i+u,j+v)(其中i,j均为浮点坐标的整数部分;u,v为浮点坐标的小数部分),则这个浮点坐标(i+u,j+v)处的像素值f(i+u,j+v)可以由原图像中的坐标点(i,j)、(i+1,j)、(i,j+1)、(i+1,j+1)所对应的四个像素值来共同决定,即
如1.1计算的目的像素坐标(1,0)对应源图像的坐标为(3/4,0),即 i = 0,u = 0.75;j = 0,v = 0;即目的图像(1,0)处的像素值由源图像中(0,0)、(1,0)、(0,1)(1,1)四个坐标点对应的像素值来确定,代入上述公式即可计算出(3/4,0)处的像素值。
看了上述内容应该对最临近插值算法和双线性插值算法有一定的了解,其基本原理应该已经掌握。
在网上刷博客发现有好多大佬讲解了双线性插值算法的优化(双线性插值算法总结),发现优化以后缩放效果更好一些,优化的具体细节就不再讲解,具体优化过程就是使用
来代替如下公式:
写到这里双线性插值算法的基本原理及优化方式已经基本讲述完毕,那么,如何使用FPGA来实现双线性插值呢?接下来我们进行