【照片动态特效系列】旋转吧,照片!

21 篇文章 3 订阅

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:T
    for 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);
    end
    imshow(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 direction
    block = rows/group;
    center = [cols,block]/2;
    [X,Y] = meshgrid(1:cols,1:block);
    for t = 1:T
        for 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));
        end
        imSequence(:,:,:,t) = imnew;
    end
else
    block = cols/group;
    center = [block,rows]/2;
    [X,Y] = meshgrid(1:block,1:rows);    
    for t = 1:T
        for 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));
        end
        imSequence(:,:,:,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

到这里就能做出一开始的效果咯

其他

  1. 想一想,如果要斜着旋转改如何修改呢
  2. 如果每一个块旋转速度不同又会是什么效果呢
  3. 生成动图代码可参考MATLAB制作动图或视频
  4. 演示视频可上B站旋转吧,照片
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值