照片动态特效系列】旋转吧,照片!"/>
【照片动态特效系列】旋转吧,照片!
【照片动态特效系列】旋转吧,照片!
- 实现“旋转”
- 核心-二维仿射变换
- 基础旋转
- 分块旋转
- 多方向+彩图
- 核彩图处理心部分
- 主函数
- 其他
by 今天不飞了
突然就想做,然后就做了……先看效果
大概就是这么个效果,接下来一步步实现哦
实现“旋转”
首先观察下图体会一下“三维空间的图片旋转就是二维空间的缩放”
蓝色-旋转的图片,红色-蓝色的投影(缩放的图片)
有了这个原理,实现起来就很简单了
核心-二维仿射变换
function [Xq,Yq] = resample(X,Y,center,option)
% 变为向量
[rows,cols] = size(X);
coor = [X(:),Y(:),ones(rows*cols,1)]';
% 将旋转中心移至原点
opt0 = [1,0,-center(1); 0,1,-center(2); 0,0,1];
% 缩放/旋转
opt1 = [1/option(1),0,0; 0,1/option(2),0; 0,0,1];
% 将图像中心还原
opt2 = [1,0,center(1); 0,1,center(2); 0,0,1];
% 仿射变换矩阵
opt = opt2*opt1*opt0;
coorq = opt*coor;
% 还原为矩阵
coorq = coorq';
Xq = reshape(coorq(:,1),[rows,cols]);
Yq = reshape(coorq(:,2),[rows,cols]);
end
基础旋转
% 读图像
im = imread('test-gray.jpg');
im = im2double(im);
% 计算旋转中心
[rows,cols] = size(im);
center = [cols,rows]/2;
% 生成网格点
[X,Y] = meshgrid(1:cols,1:rows);
for n = 1:200
% 旋转角
theta = 0.01*n*pi;
option = [1*cos(theta), 1];
% 重采样
[Xq,Yq] = resample(X,Y,center,option);
imnew = interp2(X,Y,im,Xq,Yq);
% 显示
imshow(imnew)
drawnow
end
效果如下
分块旋转
把原图拆成很多小块,对每个小块进行相同的操作,并且设置每个小块初始状态不同就能~
im = imread('test-gray.jpg');
im = im2double(im);%% 参数
group = 32; % 分块数
speed = 0.01*pi; %旋转速度
period = 2*pi; % 持续% 中心
[rows,cols] = size(im);
center = [cols,rows]/2;
T = floor(period/speed);% 开始
block = rows/group;
[X,Y] = meshgrid(1:cols,1:block);
for t = 1:Tfor g = 1:group% 提取块imtmp = im(1+block*(g-1):block*g,:);% 设置参数theta = t*speed+g*pi/group;option = [1*cos(theta), 1];% 重采样[Xq,Yq] = resample(X,Y,center,option);imnew(1+block*(g-1):block*g,:) = interp2(imtmp,Xq,Yq);endimshow(imnew)
end
效果如下,哟吼吼,开始有意思了
多方向+彩图
修改旋转方向,并使用三通道哦
核彩图处理心部分
function imSequence = GeneratingSequenceRGB(im,group,speed,period,direction)
[rows,cols,~] = size(im);
T = floor(period/speed);
imSequence = zeros(rows,cols,3,T);
if directionblock = rows/group;center = [cols,block]/2;[X,Y] = meshgrid(1:cols,1:block);for t = 1:Tfor g = 1:group% 提取块imtmp = im(1+block*(g-1):block*g,:,:);% 设置参数theta = t*speed+g*pi/group;option = [1*cos(theta), 1];% 重采样[Xq,Yq] = resample(X,Y,center,option);imnew(1+block*(g-1):block*g,:) = cat(3,interp2(imtmp(:,:,1),Xq,Yq),...interp2(imtmp(:,:,2),Xq,Yq),interp2(imtmp(:,:,3),Xq,Yq));endimSequence(:,:,:,t) = imnew;end
elseblock = cols/group;center = [block,rows]/2;[X,Y] = meshgrid(1:block,1:rows); for t = 1:Tfor g = 1:group% 提取块imtmp = im(:,1+block*(g-1):block*g,:);% 设置参数theta = t*speed+g*pi/group;option = [1, 1*cos(theta)];% 重采样[Xq,Yq] = resample(X,Y,center,option);imnew(:, 1+block*(g-1):block*g,:) = cat(3,interp2(imtmp(:,:,1),Xq,Yq),...interp2(imtmp(:,:,2),Xq,Yq),interp2(imtmp(:,:,3),Xq,Yq));endimSequence(:,:,:,t) = imnew;end
end
end
主函数
im = imread('test-rgb.jpg');
im = im2double(im);%% 参数
direction = 0; % 变换方向 1-横,0-竖
group = 256; % 分块数
speed = 0.01*pi; %旋转速度
period = 4*pi; % 持续%% 生成序列
tic
imSequence = GeneratingSequenceRGB(im,group,speed,period,direction);
oc%% 显示序列
figure('Position',[10,10,1550,900])%
for n = 1:size(imSequence,4)imshow(imSequence(:,:,:,n))
end
到这里就能做出一开始的效果咯
其他
- 想一想,如果要斜着旋转改如何修改呢
- 如果每一个块旋转速度不同又会是什么效果呢
- 生成动图代码可参考MATLAB制作动图或视频
- 演示视频可上B站旋转吧,照片
更多推荐
【照片动态特效系列】旋转吧,照片!
发布评论