双线性插值可放大位图图像

时间:2012-01-10 19:06:17

标签: c++ image-processing cuda interpolation image-resizing

我是学生,我的任务是通过调用CUDA的并行性来优化图像的双线性插值。

图像以24位.bmp格式提供。我已经有一个.bmp的阅读器,并已将像素存储在一个数组中。

现在我需要在阵列上执行双线性插值。我不理解它背后的数学(即使经过wiki article和其他谷歌搜索结果)。因此,我无法提出算法。

是否有人可以帮助我在1-D阵列上链接到现有的双线性插值算法?或者也许链接到一个开源图像处理库,利用双线性和双三次插值来缩放图像?

3 个答案:

答案 0 :(得分:37)

理解双线性插值的最简单方法是理解1D中的线性插值。

这第一个数字应该会给你回忆中学数学。给定一些位置 a 我们想要知道 f(a),我们采用相邻的“已知”值并在它们之间插入一条线。

Linear interpolation in 1D.

所以我们只使用旧的中学方程式y = mx + b和y-y1 = m(x-x1)。没什么好看的。

我们基本上将这个概念延伸到2-D以获得双线性插值。我们可以通过三次插值来解决为任何 a,b 找到 f(a,b)的问题。仔细研究下一个数字。不要被所有标签吓倒。它实际上非常简单。

Bilinear interpolation as three 1D interpolations.

对于双线性插值,我们再次使用相邻点。现在有四个,因为我们是二维的。诀窍是一次一维地攻击问题。

我们将(a,b)投射到两侧并首先计算两个(一维!)插值线。

  • f(a,y j 其中 y j 保持不变
  • f(a,y j + 1 其中 y j + 1 保持不变。

现在只有最后一步。你取两个你计算的点, f(a,y j f(a,y j + 1 )< / i>,并在它们之间插入一条线。那是蓝色的,在图中从左到右,经过 f(a,b)。沿着最后一行插值会给出最终答案。

我会为你留下2-D案例的数学。如果你从图表中工作并不难。自己完成它将帮助你真正了解正在发生的事情。

最后一点注意事项,前两个插值选择哪一边并不重要。您可以选择顶部和底部,然后在这两者之间完成第三条插补线。答案是一样的。

答案 1 :(得分:9)

通过用积分因子缩放边来放大图像时,可以将结果视为原始图像,并在原始像素之间插入额外的像素。

查看IMAGE RESIZE EXAMPLE中的图片。

this article in Wikipedia中的f(x,y)=...公式为您提供了一种计算插入像素的颜色f的方法:

enter image description here

对于每个插入的像素,您可以组合它周围的4个原始像素(Q11,Q12,Q21,Q22)的颜色。组合取决于插入的像素与周围原始像素之间的距离,它与其中一个像素越接近,它们的颜色越接近:

enter image description here

原始像素显示为红色。插入的像素显示为绿色。

这就是主意。

如果你用非积分因子缩放边,公式仍然成立,但现在你需要重新计算所有像素颜色,因为你不能只采用原始像素,只需在它们之间插入额外的像素。

答案 2 :(得分:3)

不要挂断C中的2D数组实际上是1D数组的事实。这是一个实现细节。从数学上讲,你仍然需要考虑2D数组。

考虑一维阵列上的线性插值。你知道0, 1, 2, 3, ...的价值现在假设我问你1.4的价值。您可以在12 (1 - 0.4)*A[1] + 0.4*A[2]给我一个加权的值组合。简单,对吧?

现在你需要扩展到2D。没问题。 2D插值可以分解为两个1D插值,在x轴上,然后在y轴上。假设你想要(1.4, 2.8)。在(1, 2)<->(2,2)(1,3)<->(2,3)之间获取1D插值。这是你的x轴步骤。现在,1D在它们之间插入y = 2.8的适当权重。

这应该很简单,使大规模并行。只需分别计算每个插值像素。通过对原始映像的共享内存访问,您将只进行读取,因此不会出现同步问题。