图像中存在漏洞的原因是您正在计算位置imagerot
中每个像素的imagepad
。您需要以相反的方式进行计算。也就是说,对于每个像素imagerot
插入imagepad
。为此,您只需要应用逆变换,在旋转矩阵的情况下,逆变换只是矩阵的转置(只需更改每个矩阵上的符号)sin
并以另一种方式翻译)。
循环像素imagerot
:
imagerot=zeros(size(imagepad)); % midx and midy same for both
for i=1:size(imagerot,1)
for j=1:size(imagerot,2)
x= (i-midx)*cos(rads)+(j-midy)*sin(rads);
y=-(i-midx)*sin(rads)+(j-midy)*cos(rads);
x=round(x)+midx;
y=round(y)+midy;
if (x>=1 && y>=1 && x<=size(imagepad,2) && y<=size(imagepad,1))
imagerot(i,j)=imagepad(x,y); % k degrees rotated image
end
end
end
另请注意,您的midx
and midy
需要计算size(imagepad,2)
and size(imagepad,1)
分别是,因为第一个维度指的是行数(高度),第二个维度指的是宽度。
注意:当您决定采用最近邻以外的插值方案时,同样的方法也适用,如 Rody 的线性插值示例。
EDIT:我假设您使用循环用于演示目的,但实际上不需要循环。这是最近邻插值的示例(您正在使用的),保持相同大小的图像,但您可以修改它以生成包含整个源图像的更大图像:
imagepad = imread('peppers.png');
[nrows ncols nslices] = size(imagepad);
midx=ceil((ncols+1)/2);
midy=ceil((nrows+1)/2);
Mr = [cos(pi/4) sin(pi/4); -sin(pi/4) cos(pi/4)]; % e.g. 45 degree rotation
% rotate about center
[X Y] = meshgrid(1:ncols,1:nrows);
XYt = [X(:)-midx Y(:)-midy]*Mr;
XYt = bsxfun(@plus,XYt,[midx midy]);
xout = round(XYt(:,1)); yout = round(XYt(:,2)); % nearest neighbor!
outbound = yout<1 | yout>nrows | xout<1 | xout>ncols;
zout=repmat(cat(3,1,2,3),nrows,ncols,1); zout=zout(:);
xout(xout<1) = 1; xout(xout>ncols) = ncols;
yout(yout<1) = 1; yout(yout>nrows) = nrows;
xout = repmat(xout,[3 1]); yout = repmat(yout,[3 1]);
imagerot = imagepad(sub2ind(size(imagepad),yout,xout,zout(:))); % lookup
imagerot = reshape(imagerot,size(imagepad));
imagerot(repmat(outbound,[1 1 3])) = 0; % set background value to [0 0 0] (black)
要将上述内容修改为线性插值,请计算每个坐标的 4 个相邻像素XYt
并使用分数分量乘积作为权重执行加权和。我将把它作为练习,因为它只会使我的答案进一步超出你的问题范围。 :)