图像旋转最近邻插值算法讲解
Explanation of nearest neighbor interpolation algorithm for image rotation
我想了解图像旋转的最近邻算法的实现。我所知道的常规最近邻算法,计算不同点之间的一些显式欧几里得距离,并将欧几里得距离最小的点作为最佳点。但是在图像插值中,我在实现中没有发现任何明确的欧氏距离。我指的是 this 对另一个类似问题的回答。给定的解决方案将输入图像完美地旋转了给定的角度。但是我对代码有很多疑问(我不明白他们在做什么)。
1.) 为什么作者对新索引(第 4 和 5 行)乘以 sqrt(2)
?
2.) 作者在下面的代码行中做了什么(准确地说,我理解他正在将索引乘以旋转矩阵。但是为什么他有额外的条款,如m/2
, n/2
、t-mm/2
和 s-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
任何帮助将不胜感激!
代码实现了围绕图像中心的旋转。由于图像内的坐标(索引)在 MATLAB 中从 1 开始,因此旋转的自然原点位于图像 top-left 角外的像素周围。根据 ,这样的旋转涉及移动坐标,应用旋转矩阵,然后将它们移回。
该代码使用图像中心作为旋转原点,x=n/2
、y=m/2
,以及输入图像的大小 m
和 n
。然后它将旋转后的坐标向后移动一点,因此新图像的中心位于 (mm/2
,nn/2
),mm = m*sqrt(2)
和 nn = n*sqrt(2)
的大小为输出图像。 (请注意,如果我们旋转 45 度,我们需要输出图像是输入大小的 sqrt(2)
倍才能不丢失任何数据,对于较小的旋转,我们可以使用较小的输出大小)。
如果您将所有这些值放入我在上一个答案中显示的矩阵中,您应该(希望)得到代码中显示的等式。
最后,代码有一个条件语句来避免在输入图像域之外读取(索引越界会产生错误)。当旋转图像并产生更大的输出图像时,一些输出像素将映射到输入图像之外的区域。这些在代码中保留为 0。
请注意,链接到的代码根本没有效率。它不预先分配输出矩阵,因此它在写入输出数组时反复调整输出数组的大小,这是非常昂贵的。它还可以预先计算循环内完成的一些计算,例如 cos(thet)
在循环迭代之间不会改变。
我想了解图像旋转的最近邻算法的实现。我所知道的常规最近邻算法,计算不同点之间的一些显式欧几里得距离,并将欧几里得距离最小的点作为最佳点。但是在图像插值中,我在实现中没有发现任何明确的欧氏距离。我指的是 this 对另一个类似问题的回答。给定的解决方案将输入图像完美地旋转了给定的角度。但是我对代码有很多疑问(我不明白他们在做什么)。
1.) 为什么作者对新索引(第 4 和 5 行)乘以 sqrt(2)
?
2.) 作者在下面的代码行中做了什么(准确地说,我理解他正在将索引乘以旋转矩阵。但是为什么他有额外的条款,如m/2
, n/2
、t-mm/2
和 s-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
任何帮助将不胜感激!
代码实现了围绕图像中心的旋转。由于图像内的坐标(索引)在 MATLAB 中从 1 开始,因此旋转的自然原点位于图像 top-left 角外的像素周围。根据
该代码使用图像中心作为旋转原点,x=n/2
、y=m/2
,以及输入图像的大小 m
和 n
。然后它将旋转后的坐标向后移动一点,因此新图像的中心位于 (mm/2
,nn/2
),mm = m*sqrt(2)
和 nn = n*sqrt(2)
的大小为输出图像。 (请注意,如果我们旋转 45 度,我们需要输出图像是输入大小的 sqrt(2)
倍才能不丢失任何数据,对于较小的旋转,我们可以使用较小的输出大小)。
如果您将所有这些值放入我在上一个答案中显示的矩阵中,您应该(希望)得到代码中显示的等式。
最后,代码有一个条件语句来避免在输入图像域之外读取(索引越界会产生错误)。当旋转图像并产生更大的输出图像时,一些输出像素将映射到输入图像之外的区域。这些在代码中保留为 0。
请注意,链接到的代码根本没有效率。它不预先分配输出矩阵,因此它在写入输出数组时反复调整输出数组的大小,这是非常昂贵的。它还可以预先计算循环内完成的一些计算,例如 cos(thet)
在循环迭代之间不会改变。