以下是对图像应用仿射变换的简单实现。一些矩阵可能会颠倒,因为我是从记忆中做的。我不确切知道你是如何格式化你的 pts 数组的,所以我认为一个工作示例是我能做的最好的。该interp2
函数应用双线性插值,该bilinear
函数执行将模拟滤波器描述为数字滤波器的双线性变换。这不是你想要的。
PS 在应用图像变形时必须确保使用逆变换(即为输出图像中的每个点定义要在输入图像中采样的点)。如果您执行正向变换(即定义输入图像中每个点映射到的输出图像中的点),那么您最终会遇到一些严重的混叠效应和输出图像中的潜在漏洞。
希望这可以帮助。如果您有任何问题,请告诉我。
img = double(imread('rice.png'))/255;
theta = 30; % rotate 30 degrees
R = [cosd(theta) -sind(theta) 0; ...
sind(theta) cosd(theta) 0; ...
0 0 1];
sx = 15; % skew by 15 degrees in x
Skx = [1 tand(sx) 0; ...
0 1 0; ...
0 0 1];
% Translate by 1/2 size of image
tx = -size(img, 2)/2;
ty = -size(img, 1)/2;
T = [1 0 tx; ...
0 1 ty; ...
0 0 1];
% Scale image down by 1/2
sx = 0.5;
sy = 0.5;
S = [sx 0 0; ...
0 sy 0; ...
0 0 1];
% translate, scale, rotate, skew, then translate back
A = inv(T)*Skx*R*S*T;
% create meshgrid points
[x, y] = meshgrid(1:size(img,2), 1:size(img,1));
% reshape so we can apply matrix op
V = [reshape(x, 1, []); reshape(y, 1, []); ones(1, numel(x))];
Vq = inv(A)*V;
% probably not necessary for these transformations but project back to the z=1 plane
Vq(1,:) = Vq(1,:) ./ V(3,:);
Vq(2,:) = Vq(2,:) ./ V(3,:);
% reshape back into a meshgrid
xq = reshape(Vq(1,:), size(img));
yq = reshape(Vq(2,:), size(img));
% use interp2 to perform bilinear interpolation
imgnew = interp2(x, y, img, xq, yq);
% show the resulting image
imshow(imgnew);