【问题标题】:rotation image - different degrees旋转图像 - 不同程度
【发布时间】:2013-10-27 21:05:58
【问题描述】:

我正在尝试在不使用 imrotate 的情况下执行自己的旋转图像算法。

clear all
img1 = imread('image1.jpg');imshow(img1);
[m,n,p]=size(img1);
thet = pi/6;

m1=round(m*1.5);
n1=round(n*1.5);
rotatedImg = zeros(m1,n1);

for i=1:m
    for j=1:n

        t = uint16((i)*cos(thet)-(j)*sin(thet)+m+100);
        s = uint16((i)*sin(thet)+(j)*cos(thet));
        if i>0 && j>0 && i<=m && j<=n

            try rotatedImg(t,s,1)=img1(i,j,1);
            catch
               a=1; 
            end

        end
    end
end


figure;
imshow(rotatedImg);

但是由于某些原因,在某个角度,图像的某些部分被剪裁了,所以不是整个图像都在窗口上。我似乎无法弄清楚如何正确地做到这一点。似乎我每次都需要以不同的角度使窗口变大,这样图像就不会被剪裁。

我的图像也充满了黑点,我认为我需要进行某种插值。我该怎么办?

*我使用的图像是 (http://i.stack.imgur.com/kDdx5.jpg) 并以这些角度旋转 - pi/6, pi/2, ((pi/6)*4) *

【问题讨论】:

    标签: matlab image-processing computer-vision


    【解决方案1】:

    嗯,有两个问题:

    1. 始终围绕原点旋转。这就是您需要为每个角度调整偏移量 (100) 的原因。更好的解决方案是围绕图像中心旋转。

    2. 您没有进行任何类型的插值。虽然这本身不是原因,但由于舍入误差,您可能没有击中目标图像中的每个像素。最好遍历目标图像并从源中获取正确的像素。

    这是我的解决方案:

    clear all
    img1 = imread('ngc6543a.jpg');
    imshow(img1);
    [m,n,p]=size(img1);
    thet = pi/6;
    
    m1=round(m*1.5);
    n1=round(n*1.5);
    rotatedImg = zeros(m1,n1, 3, 'uint8');
    tic
    for i=1:m1
        for j=1:n1
    
            p = [i; j] - [m1/2; n1/2];
    
            source = [cos(thet), sin(thet); -sin(thet), cos(thet)] * p;
    
            source = source + [m/2; n/2];       
    
            t = int16(source(1));
            s = int16(source(2));
    
            if t>0 && s>0 && t<=m && s<=n
                rotatedImg(i,j,:) = img1(t,s,:);
            end
        end
    end
    toc
    
    figure;
    imshow(rotatedImg);
    

    虽然看起来不错,但我绝对推荐双线性插值。


    我明白了,所以你的图像不是二次的。在这种情况下,将新尺寸计算为 old*1.5 是不够的,而是更精确(或更慷慨)。

    这是适用于所有角度和任意图像的最终解决方案。 Matlab 有点繁琐,因为索引是 (y,x),否则代码应该没问题。

    clear all
    img1 = imread('kDdx5.jpg');
    imshow(img1);
    [orgHeight,orgWidth,p]=size(img1);
    thet = pi/7;
    
    matrix = [cos(thet), -sin(thet); sin(thet), cos(thet)];
    p1 = abs(matrix * [orgWidth/2; orgHeight/2]);
    p2 = abs(matrix * [orgWidth/2; -orgHeight/2]);
    
    corner = [max(p1(1), p2(1)); max(p1(2), p2(2))];
    
    newWidth = ceil(2*corner(1));
    newHeight = ceil(2*corner(2));
    rotatedImg = zeros(newHeight, newWidth, 3, 'uint8');
    
    tic
    for i=1:newWidth
        for j=1:newHeight
    
            p = [i; j] - [newWidth/2; newHeight/2];
            source = matrix * p;
            source = source + [orgWidth/2; orgHeight/2;];       
            t = int16(source(1));
            s = int16(source(2));
    
            if t>0 && s>0 && s<=orgHeight && t<=orgWidth
                rotatedImg(j,i,:) = img1(s,t,:);
            end
        end
    end
    toc
    
    figure;
    imshow(rotatedImg);
    

    【讨论】:

    • 我用这张图片 (i.stack.imgur.com/kDdx5.jpg) 尝试了你的解决方案,但由于某种原因,图像的顶部和底部被剪裁了。我尝试使用这些角度 - pi/2 ,((pi/6 )*4) - 输出图像被剪裁
    • 我添加了正确的边界计算。注意循环内更改的索引。
    • 非常感谢您的帮助。我想知道如果上述不是双线性插值,您能否解释一下您使用了什么方法?
    • 这可能被称为“最近的邻居”。使用双线性时,您不应将坐标转换为 int16,而应从所有四个相邻像素中获取一些颜色。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-02
    • 2013-01-15
    • 1970-01-01
    • 1970-01-01
    • 2021-04-12
    • 1970-01-01
    相关资源
    最近更新 更多