问题 如何使用Matlab通过最近邻插值旋转图像


我的普通代码没有插值:

im1 = imread('lena.jpg');imshow(im1);    
[m,n,p]=size(im1);
thet = rand(1);
m1=m*cos(thet)+n*sin(thet);
n1=m*sin(thet)+n*cos(thet);    

for i=1:m
    for j=1:n
       t = uint16((i-m/2)*cos(thet)-(j-n/2)*sin(thet)+m1/2);
       s = uint16((i-m/2)*sin(thet)+(j-n/2)*cos(thet)+n1/2);
       if t~=0 && s~=0           
        im2(t,s,:)=im1(i,j,:);
       end
    end
end
figure;
imshow(im2);

这段代码会产生黑点,问题是如何进行插值?谢谢大家的任何照明。 附:不要求内置函数:imrotate(im1,1 / thet,'nearest');


12053
2017-11-28 02:43


起源

您是要尝试对整个图像进行特征旋转还是全局旋转? - monksy
它是整个img的全球轮换 - MeadowMuffins


答案:


要旋转没有黑点的图像,您需要反方向。

旋转矩阵的倒数是它的转置。此外,旋转的图像总是更大,最大是45度旋转。因此, sqrt(2) 因子

im1 = imread('lena.jpg');imshow(im1);  
[m,n,p]=size(im1);
thet = rand(1);
mm = m*sqrt(2);
nn = n*sqrt(2);
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
figure;
imshow(im2);

10
2017-12-03 23:50



那么最近邻插值的常见求解是隐含的吗?我认为它会检测到最左边的可见像素和最右边的像素,然后逐行插值。 - MeadowMuffins
你描述的将是双线性插值。近邻只是获取最接近的像素值 - sjchoi


我记得了 上一个问题 在SO上有类似的问题。

我的想法是以相反的方向映射像素;对于旋转图像中的每个像素,找到在原始图像中映射到它的像素,然后问题变得更加简单。

我目前无法访问MATLAB,但我认为这是可行的。这里的困难是循环旋转的图像像素。


6
2017-11-28 03:18



谢谢,Amro。在我问之前,我确实检查了你以前的帖子。映射确实是相反的方向,这使得它更简单。而你只是遇到了困难。 - MeadowMuffins
+1 - 是理想的解决方案 - Jacob
这是通常执行旋转的方式,因为它避免了处理在最终结果中不可见的像素。 - Hannes Ovrén
它已经有一段时间了,但有人提出了更快的旋转问题实现,类似于在这个链接中的一个? - gcolucci


一旦你拥有了所有变换后的像素,就可以填充黑点 griddata 它采用不均匀的像素空间分布(旋转的像素)并使用线性,立方或者插值所需的像素(黑点) 最近的邻居


0
2017-11-28 07:06



尽管如此,它仍然是内置的插值功能。无论如何,谢谢你,雅各布。 - MeadowMuffins


可以通过这些行删除黑点,而其余代码保持不变:

im2= zeros(500,500);
im2(:)=1;

0
2018-01-13 16:23