基于Matlab实现水波倒影特效的制作

1.使用效果

基于Matlab实现水波倒影特效的制作_第1张图片

基于Matlab实现水波倒影特效的制作_第2张图片

2.图像翻转及白化

导入图像:

% 图片导入 
oriPic=imread('test.jpg');
[Row,Col,~]=size(oriPic);

基于Matlab实现水波倒影特效的制作_第3张图片

翻转及白化图像:

翻转就是单纯的将行索引倒过来;

白化就是将当前像素的颜色按比例和白色取个带权均值,行索引越大白色权重也越大,图像也就越白。

% 图片翻转及白化 ==========================================================
whiteMat=((1:Row)./Row./1.2)'*ones(1,Col); % 白化比例矩阵
flipPic=zeros(Row,Col,3);                  % 翻转后矩阵初始化
for i=1:3
    tempChannel=double(oriPic(:,:,i));     % 获得通道图
    tempChannel=tempChannel(end:-1:1,:);   % 翻转
    tempChannel=tempChannel.*(1-whiteMat)+255.*whiteMat; % 白化
    flipPic(:,:,i)=tempChannel;
    
end

基于Matlab实现水波倒影特效的制作_第4张图片

当然如果我们将这一行:

tempChannel=tempChannel.*(1-whiteMat)+255.*whiteMat;

更改为:

tempChannel=tempChannel.*(1-whiteMat)+0.*whiteMat;

就变成了一个黑化的过程:

基于Matlab实现水波倒影特效的制作_第5张图片

当然你也可以尝试其他颜色,例如将整段改写为:

Color=[255,0,0];
colorMat=((1:Row)./Row./1.2)'*ones(1,Col); % 比例矩阵
flipPic=zeros(Row,Col,3);                  % 翻转后矩阵初始化
for i=1:3
    tempChannel=double(oriPic(:,:,i));     % 获得通道图
    tempChannel=tempChannel(end:-1:1,:);   % 翻转
    tempChannel=tempChannel.*(1-colorMat)+Color(i).*colorMat; % 渐变
    flipPic(:,:,i)=tempChannel;
    
end
imshow(uint8(flipPic))

基于Matlab实现水波倒影特效的制作_第6张图片

3.波纹图像构造

生成噪声并模糊: 

noiseMat=ones(Row,Col);
noiseMat=imnoise(noiseMat,'gaussian',0,5); % 噪声添加
gaussOpt=fspecial('gaussian',[3 3],1);
noiseMat=imfilter(noiseMat,gaussOpt);

噪声图:

基于Matlab实现水波倒影特效的制作_第7张图片

模糊后噪声图:

基于Matlab实现水波倒影特效的制作_第8张图片

浮雕特效: 

实际上浮雕特效就是用以下类似形式的矩阵对图像进行卷积,卷积结果再加上RGB范围的均值,[0,1]区间就加0.5,[0,255]区间就加128:

基于Matlab实现水波倒影特效的制作_第9张图片

数值和位置不重要,重要的是相对位置互为相反数,浮雕过程描述如下:

H=[cos(pi+pi/4)  ,0,cos(pi-pi/4);
   cos(pi+2*pi/4),0,cos(pi-2*pi/4);
   cos(pi+3*pi/4),0,cos(pi-3*pi/4)];
noiseMat=imfilter(noiseMat,H,'conv')+0.5;  
noiseMat=noiseMat.*255;
noiseMat(noiseMat<0)=0;

基于Matlab实现水波倒影特效的制作_第10张图片

透视变换:

就是近大远小,这里为了方便起见只在横向方向上做了近大远小的拉伸,竖直方向进行了等比例拉伸,因而不是严格意义上的透视变换:

基于Matlab实现水波倒影特效的制作_第11张图片

如图所示实际操作就是把左侧蓝色区域拉伸成右侧蓝色区域,并只选取红框内部分,代码如下:

% 图像透视变换 ============================================================
exNoiseMat=zeros(Row,Col);
% 横向拉伸上下边倍数
K1=10;K2=4;
for i=1:Row
    for j=1:Col
        k=K2+i*(K1-K2)/Row;
        nJ=(j-(1+Col)/2)/k+(1+Col)/2;
        if floor(nJ)==ceil(nJ)
            nJ=round(nJ);
            exNoiseMat(i,j)=noiseMat(i,nJ);
        else
            nJ1=floor(nJ);nJ2=ceil(nJ);
            exNoiseMat(i,j)=noiseMat(i,nJ1)*(nJ2-nJ)+noiseMat(i,nJ2)*(nJ-nJ1);
        end
    end
end
% 竖向拉伸3倍并只取一部分
exNoiseMat=imresize(exNoiseMat,[3*Row,Col]);
exNoiseMat=exNoiseMat(end-Row+1:end,:);
exNoiseMat=uint8(exNoiseMat);

基于Matlab实现水波倒影特效的制作_第12张图片

注: 如果原图像尺寸过大,水波就会过于密集,这时候可以适当调整放缩倍数或者将原图像重调大小到小一点的尺寸。

例如大波浪代码:

% 图像透视变换 ============================================================
exNoiseMat=zeros(Row,Col);
K1=40;K2=10;
for i=1:Row
    for j=1:Col
        k=K2+i*(K1-K2)/Row;
        nJ=(j-(1+Col)/2)/k+(1+Col)/2;
        if floor(nJ)==ceil(nJ)
            nJ=round(nJ);
            exNoiseMat(i,j)=noiseMat(i,nJ);
        else
            nJ1=floor(nJ);nJ2=ceil(nJ);
            exNoiseMat(i,j)=noiseMat(i,nJ1)*(nJ2-nJ)+noiseMat(i,nJ2)*(nJ-nJ1);
        end
    end
end
exNoiseMat=imresize(exNoiseMat,[8*Row,Col]);
exNoiseMat=exNoiseMat(end-Row+1:end,:);
exNoiseMat=uint8(exNoiseMat);

小波浪及大波浪:

基于Matlab实现水波倒影特效的制作_第13张图片

基于Matlab实现水波倒影特效的制作_第14张图片

4.扭曲置换

这个。。。老朋友了,具体原理还是看这一篇叭:利用Matlab制作抖音同款含褶皱面料图

% 扭曲置换 ================================================================
forePic=flipPic;
bkgPic=exNoiseMat;

exforePic=uint8(zeros(size(forePic)+[26,26,0]));
exforePic(14:end-13,14:end-13,1)=forePic(:,:,1);
exforePic(14:end-13,14:end-13,2)=forePic(:,:,2);
exforePic(14:end-13,14:end-13,3)=forePic(:,:,3);

for i=1:13
    exforePic(i,14:end-13,:)=forePic(1,:,:);
    exforePic(end+1-i,14:end-13,:)=forePic(end,:,:);
    exforePic(14:end-13,i,:)=forePic(:,1,:);
    exforePic(14:end-13,end+1-i,:)=forePic(:,end,:);
end
for i=1:3
    exforePic(1:13,1:13,i)=forePic(1,1,i);
    exforePic(end-13:end,end-13:end,i)=forePic(end,end,i);
    exforePic(end-13:end,1:13,i)=forePic(end,1,i);
    exforePic(1:13,end-13:end,i)=forePic(1,end,i);
end

newforePic=uint8(zeros(size(forePic)));
for i=1:size(bkgPic,1)
    for j=1:size(bkgPic,2)
        goffset=(double(bkgPic(i,j))-128)/10;
        offsetLim1=floor(goffset)+13;
        offsetLim2=ceil(goffset)+13;
        sep1=goffset-floor(goffset);
        sep2=ceil(goffset)-goffset;
        c1=double(exforePic(i+offsetLim1,j+offsetLim1,:));
        c2=double(exforePic(i+offsetLim2,j+offsetLim2,:));
        if sep1==0
            c=double(exforePic(i+offsetLim1,j+offsetLim1,:));
        else
            c=c2.*sep1+c1.*sep2;
        end
        newforePic(i,j,:)=c;
    end
end

基于Matlab实现水波倒影特效的制作_第15张图片

基于Matlab实现水波倒影特效的制作_第16张图片

5.图像拼接

就是把俩图像拼在一起,并把边缘模糊一下:

% 图像拼接 ================================================================
resultPic(:,:,1)=[oriPic(:,:,1);newforePic(:,:,1)];
resultPic(:,:,2)=[oriPic(:,:,2);newforePic(:,:,2)];
resultPic(:,:,3)=[oriPic(:,:,3);newforePic(:,:,3)];
% imshow(resultPic)


% 边缘模糊 ================================================================
gaussOpt=fspecial('gaussian',[3 3],0.5);
gaussPic=imfilter(resultPic,gaussOpt);
resultPic(Row-1:Row+2,:,1)=gaussPic(Row-1:Row+2,:,1);
resultPic(Row-1:Row+2,:,2)=gaussPic(Row-1:Row+2,:,2);
resultPic(Row-1:Row+2,:,3)=gaussPic(Row-1:Row+2,:,3);
imshow(resultPic)

基于Matlab实现水波倒影特效的制作_第17张图片

6.完整代码

function mirrorDown
% @author slandarer

% 图片导入 
oriPic=imread('test.jpg');
[Row,Col,~]=size(oriPic);

% 图片翻转及白化 ==========================================================
whiteMat=((1:Row)./Row./1.2)'*ones(1,Col); % 白化比例矩阵
flipPic=zeros(Row,Col,3);                  % 翻转后矩阵初始化
for i=1:3
    tempChannel=double(oriPic(:,:,i));     % 获得通道图
    tempChannel=tempChannel(end:-1:1,:);   % 翻转
    tempChannel=tempChannel.*(1-whiteMat)+255.*whiteMat; % 白化
    flipPic(:,:,i)=tempChannel;
    
end
% imshow(uint8(flipPic))


% 噪声图构造(高斯噪声及高斯模糊)===========================================
noiseMat=ones(Row,Col);
noiseMat=imnoise(noiseMat,'gaussian',0,5); % 噪声添加
gaussOpt=fspecial('gaussian',[3 3],1);
noiseMat=imfilter(noiseMat,gaussOpt);
imshow(noiseMat)

H=[cos(pi+pi/4),0,cos(pi-pi/4);
   cos(pi+2*pi/4),0,cos(pi-2*pi/4);
   cos(pi+3*pi/4),0,cos(pi-3*pi/4)];
noiseMat=imfilter(noiseMat,H,'conv')+0.5;  
noiseMat=noiseMat.*255;
noiseMat(noiseMat<0)=0;
% imshow(uint8(noiseMat))


% 图像透视变换 ============================================================
exNoiseMat=zeros(Row,Col);
% 横向拉伸上下边倍数
K1=10;K2=4;
for i=1:Row
    for j=1:Col
        k=K2+i*(K1-K2)/Row;
        nJ=(j-(1+Col)/2)/k+(1+Col)/2;
        if floor(nJ)==ceil(nJ)
            nJ=round(nJ);
            exNoiseMat(i,j)=noiseMat(i,nJ);
        else
            nJ1=floor(nJ);nJ2=ceil(nJ);
            exNoiseMat(i,j)=noiseMat(i,nJ1)*(nJ2-nJ)+noiseMat(i,nJ2)*(nJ-nJ1);
        end
    end
end
% 竖向拉伸3倍并只取一部分
exNoiseMat=imresize(exNoiseMat,[3*Row,Col]);
exNoiseMat=exNoiseMat(end-Row+1:end,:);
exNoiseMat=uint8(exNoiseMat);
% imshow(exNoiseMat)


% 扭曲置换 ================================================================
forePic=flipPic;
bkgPic=exNoiseMat;

exforePic=uint8(zeros(size(forePic)+[26,26,0]));
exforePic(14:end-13,14:end-13,1)=forePic(:,:,1);
exforePic(14:end-13,14:end-13,2)=forePic(:,:,2);
exforePic(14:end-13,14:end-13,3)=forePic(:,:,3);

for i=1:13
    exforePic(i,14:end-13,:)=forePic(1,:,:);
    exforePic(end+1-i,14:end-13,:)=forePic(end,:,:);
    exforePic(14:end-13,i,:)=forePic(:,1,:);
    exforePic(14:end-13,end+1-i,:)=forePic(:,end,:);
end
for i=1:3
    exforePic(1:13,1:13,i)=forePic(1,1,i);
    exforePic(end-13:end,end-13:end,i)=forePic(end,end,i);
    exforePic(end-13:end,1:13,i)=forePic(end,1,i);
    exforePic(1:13,end-13:end,i)=forePic(1,end,i);
end

newforePic=uint8(zeros(size(forePic)));
for i=1:size(bkgPic,1)
    for j=1:size(bkgPic,2)
        goffset=(double(bkgPic(i,j))-128)/10;
        offsetLim1=floor(goffset)+13;
        offsetLim2=ceil(goffset)+13;
        sep1=goffset-floor(goffset);
        sep2=ceil(goffset)-goffset;
        c1=double(exforePic(i+offsetLim1,j+offsetLim1,:));
        c2=double(exforePic(i+offsetLim2,j+offsetLim2,:));
        if sep1==0
            c=double(exforePic(i+offsetLim1,j+offsetLim1,:));
        else
            c=c2.*sep1+c1.*sep2;
        end
        newforePic(i,j,:)=c;
    end
end
% imshow(newforePic)


% 图像拼接 ================================================================
resultPic(:,:,1)=[oriPic(:,:,1);newforePic(:,:,1)];
resultPic(:,:,2)=[oriPic(:,:,2);newforePic(:,:,2)];
resultPic(:,:,3)=[oriPic(:,:,3);newforePic(:,:,3)];
% imshow(resultPic)


% 边缘模糊 ================================================================
gaussOpt=fspecial('gaussian',[3 3],0.5);
gaussPic=imfilter(resultPic,gaussOpt);
resultPic(Row-1:Row+2,:,1)=gaussPic(Row-1:Row+2,:,1);
resultPic(Row-1:Row+2,:,2)=gaussPic(Row-1:Row+2,:,2);
resultPic(Row-1:Row+2,:,3)=gaussPic(Row-1:Row+2,:,3);
imshow(resultPic)

end

基于Matlab实现水波倒影特效的制作_第18张图片

基于Matlab实现水波倒影特效的制作_第19张图片

基于Matlab实现水波倒影特效的制作_第20张图片

基于Matlab实现水波倒影特效的制作_第21张图片

奇怪画风哈哈哈: 

基于Matlab实现水波倒影特效的制作_第22张图片

基于Matlab实现水波倒影特效的制作_第23张图片

基于Matlab实现水波倒影特效的制作_第24张图片

以上就是基于Matlab实现水波倒影特效的制作的详细内容,更多关于Matlab水波倒影的资料请关注脚本之家其它相关文章!

你可能感兴趣的:(基于Matlab实现水波倒影特效的制作)