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

Posted

技术标签:

【中文标题】如何使用 Matlab 通过最近邻插值旋转图像【英文标题】:How To Rotate Image By Nearest Neighbor Interpolation Using Matlab 【发布时间】:2010-12-21 03:33:25 【问题描述】:

没有插值的我的纯代码:

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');

【问题讨论】:

您是要对整个图像进行特征旋转还是全局旋转? 是整个img的全局旋转 【参考方案1】:

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

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

【讨论】:

【参考方案2】:

要旋转没有黑点的图像,你需要往相反的方向走。

旋转矩阵的逆是它的转置。此外,旋转后的图像总是更大,最大旋转 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);

【讨论】:

那么最近邻插值的常见求解是隐式的?我以为它会检测最左边和最右边的可见像素,然后逐行插值。 您所描述的将是双线性插值。近邻只取最近的像素值【参考方案3】:

获得所有转换后的像素后,您可以使用 griddata 填充黑点,它采用非均匀空间分布的像素(您的旋转像素)并使用线性插值所需的像素(您的黑点) 、立方或最近邻

【讨论】:

不过,它仍然是进行插值的内置功能。无论如何,谢谢你,雅各布。【参考方案4】:

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

我的想法是将像素映射到相反方向;对于旋转图像中的每个像素,在原始图像中找到映射到它的像素,那么问题就变得简单了。

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

【讨论】:

谢谢,阿姆罗。在我问之前,我确实检查了你以前的帖子。映射确实是相反的方向,这使得它更简单。而你只是得到了我的困难。 这就是通常执行旋转的方式,因为它避免了处理最终结果中不可见的像素。 已经有一段时间了,但是有人想出一个更快的实现来解决旋转问题,类似于这个链接中的那个吗?

以上是关于如何使用 Matlab 通过最近邻插值旋转图像的主要内容,如果未能解决你的问题,请参考以下文章

matlab图像旋转怎么操作?

对颤振图像使用最近邻插值

matlab中figure的图像旋转

使用 OpenCL 内核的最近邻插值代码

matlab中图像旋转

使用双线性插值调整图像大小而不使用 imresize