服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - 基于Matlab实现水波倒影特效的制作

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

2022-10-31 12:14slandarer C/C++

这篇文章主要介绍了如何利用Matlab制作出水波倒影的特效,文中的示例代码讲解详细,对我们学习Matlab有一定帮助,需要的可以参考一下

1.使用效果

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

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

 

2.图像翻转及白化

导入图像:

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

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

翻转及白化图像:

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

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

% 图片翻转及白化 ==========================================================
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实现水波倒影特效的制作

当然如果我们将这一行:

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

更改为:

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

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

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

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

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实现水波倒影特效的制作

 

3.波纹图像构造

生成噪声并模糊: 

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

噪声图:

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

模糊后噪声图:

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

浮雕特效: 

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

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

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

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实现水波倒影特效的制作

透视变换:

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

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

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

% 图像透视变换 ============================================================
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实现水波倒影特效的制作

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

例如大波浪代码:

% 图像透视变换 ============================================================
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实现水波倒影特效的制作

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

 

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实现水波倒影特效的制作

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

 

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实现水波倒影特效的制作

 

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实现水波倒影特效的制作

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

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

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

奇怪画风哈哈哈: 

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

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

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

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

原文地址:https://mp.weixin.qq.com/s/7ppBHtMtzNl3N08fqDuLgg

延伸 · 阅读

精彩推荐
  • C/C++C++调用C#的DLL实现方法

    C++调用C#的DLL实现方法

    这篇文章主要介绍了C++调用C#的DLL实现方法,很有实用价值,需要的朋友可以参考下...

    C++教程网11432021-01-23
  • C/C++C++堆和栈的区别与联系讲解

    C++堆和栈的区别与联系讲解

    今天小编就为大家分享一篇关于C++堆和栈的区别与联系讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来...

    yangyongUestc11682021-07-27
  • C/C++了解C++编程中指定的异常和未经处理的异常

    了解C++编程中指定的异常和未经处理的异常

    这篇文章主要介绍了C++中指定的异常和未经处理的异常,介绍了有关noexcept和terminate的作用,并结合了C++11标准的新特性,需要的朋友可以参考下...

    C++教程网6992021-03-23
  • C/C++Qt中QPixmap、QImage、QPicture、QBitmap四者区别详解

    Qt中QPixmap、QImage、QPicture、QBitmap四者区别详解

    Qt 提供了四个类来处理图像数据:QImage、QPixmap、QBitmap 和 QPicture,本文就详细的介绍一下四者区别,文中通过示例代码介绍的非常详细,具有一定的参考价...

    luoyayun3617372022-10-18
  • C/C++C语言数据结构与算法之图的遍历(二)

    C语言数据结构与算法之图的遍历(二)

    这篇文章主要是介绍了利用广度优先算法实现图的遍历,文中利用图文详细的介绍了实现步骤,对我们学习数据结构与算法有一定的帮助,需要的朋友可以...

    玄澈_7712022-07-09
  • C/C++C++ 中Vector常用基本操作

    C++ 中Vector常用基本操作

    标准库vector类型是C++中使用较多的一种类模板,本文给大家分享C++ 中Vector常用基本操作,感兴趣的朋友一起看看吧...

    Ginger_27102021-06-07
  • C/C++C++实现职工工资管理系统

    C++实现职工工资管理系统

    这篇文章主要为大家详细介绍了C++实现简单的职工工资管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    玛珈山大萌新11522022-10-10
  • C/C++C++ 整数拆分方法详解

    C++ 整数拆分方法详解

    整数拆分,指把一个整数分解成若干个整数的和。本文重点给大家介绍C++ 整数拆分方法详解,非常不错,感兴趣的朋友一起学习吧...

    Code·Hadilo9332021-04-12