【问题标题】:Explanation of nearest neighbor interpolation algorithm for image rotation图像旋转的最近邻插值算法说明
【发布时间】:2019-11-07 17:10:09
【问题描述】:

我正在尝试了解用于图像旋转的最近邻算法的实现。我知道的常规最近邻算法,计算不同点之间的一些显式欧几里德距离,并将欧几里德距离最小的点作为最佳点。但是在图像插值中,我在实现中没有找到任何明确的欧几里得距离。我指的是this 对另一个类似问题的回答。给定的解决方案将输入图像完美地旋转给定角度。但是我对代码有很多疑问(我不明白他们在做什么)。

1.) 为什么作者将sqrt(2) 乘以新索引(第 4 行和第 5 行)?

2.) 作者在以下代码行中做了什么(准确地说,我知道他是在将索引乘以旋转矩阵。但是为什么他有额外的术语,如m/2n/2t-mm/2s-nn/2 ?他在用 if i>0 && j>0 && i<=m && j<=n 做什么?)? :

for t=1:mm
   for s=1:nn
      i = uint16((t-mm/2)*cos(thet)+(s-nn/2)*sin(thet)+m/2);
      j = uint16(-(t-mm/2)*sin(thet)+(s-nn/2)*cos(thet)+n/2);
      if i>0 && j>0 && i<=m && j<=n           
         im2(t,s,:)=im1(i,j,:);
      end
   end
end

任何帮助将不胜感激!

【问题讨论】:

  • 作者在答案中解释了sqrt(2) 因子,“旋转的图像总是更大,最大旋转45度。因此,sqrt(2) 因子”。至于if 条件,所做的只是确保这些点在原始图像im1 的范围内。
  • @beaker 是的,我意识到这一点。但为什么只有 sqrt(2) 用于乘法? sqrt(2) 的意义是什么?在if 条件下,我看到他实际上是从源图像中复制数据,而不是进行任何最近邻插值(当我们截断cos(theta)sin(theta) 的浮点值时,估计缺失索引的像素值) .没有使用 b 样条函数或任何其他最近邻插值......他在这里做什么?
  • “没有使用 b 样条函数或任何其他最近邻插值” 最近邻插值实际上是找到离您的子像素位置最近的像素并取其值。 B 样条插值是完全不同的东西。舍入浮点位置是最近邻插值。代码应该执行round(...),而不是截断。它不一样,只会导致两个方向上的半像素偏移,您可能不会注意到。

标签: matlab image-processing interpolation nearest-neighbor image-rotation


【解决方案1】:

代码实现了围绕图像中心的旋转。由于图像内的坐标(索引)在 MATLAB 中从 1 开始,因此旋转的自然原点围绕图像左上角外的一个像素。根据my answer to your previous question,这样的旋转涉及移动坐标,应用旋转矩阵,然后将它们向后移动。

代码使用图像中心x=n/2y=m/2 作为旋转原点,mn 是输入图像的大小。然后它将旋转的坐标向后移动一点,因此新图像的中心位于 (mm/2,nn/2),mm = m*sqrt(2)nn = n*sqrt(2) 是输出图像的大小。 (请注意,如果我们旋转 45 度,我们需要输出图像为 sqrt(2) 乘以输入大小以不丢失任何数据,对于较小的旋转,我们可以使用较小的输出大小来完成)。

如果您将所有这些值放入我在上一个答案中显示的矩阵中,您应该(希望)得到代码中显示的方程式。

最后,代码有一个条件语句来避免读取输入图像域之外的内容(索引越界会产生错误)。当旋转图像并产生更大的输出图像时,一些输出像素将映射到输入图像之外的区域。这些在代码中保留为 0。

请注意,链接到的代码根本没有效率。它不会预先分配输出矩阵,因此它会在写入时反复调整输出数组的大小,这非常昂贵。它还可以预先计算循环内完成的一些计算,例如cos(thet) 在循环迭代之间不会改变。

【讨论】:

    猜你喜欢
    • 2016-06-01
    • 1970-01-01
    • 2010-12-21
    • 2012-04-24
    • 2010-12-05
    • 2019-11-05
    • 2019-02-20
    • 2020-09-10
    • 2012-07-19
    相关资源
    最近更新 更多