经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » MATLAB » 查看文章
基于Matlab实现水波倒影特效的制作
来源:jb51  时间:2022/3/29 11:47:58  对本文有异议

1.使用效果

2.图像翻转及白化

导入图像:

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

翻转及白化图像:

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

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

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

当然如果我们将这一行:

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

更改为:

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

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

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

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

3.波纹图像构造

生成噪声并模糊: 

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

噪声图:

模糊后噪声图:

浮雕特效: 

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

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

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

透视变换:

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

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

  1. % 图像透视变换 ============================================================
  2. exNoiseMat=zeros(Row,Col);
  3. % 横向拉伸上下边倍数
  4. K1=10;K2=4;
  5. for i=1:Row
  6. for j=1:Col
  7. k=K2+i*(K1-K2)/Row;
  8. nJ=(j-(1+Col)/2)/k+(1+Col)/2;
  9. if floor(nJ)==ceil(nJ)
  10. nJ=round(nJ);
  11. exNoiseMat(i,j)=noiseMat(i,nJ);
  12. else
  13. nJ1=floor(nJ);nJ2=ceil(nJ);
  14. exNoiseMat(i,j)=noiseMat(i,nJ1)*(nJ2-nJ)+noiseMat(i,nJ2)*(nJ-nJ1);
  15. end
  16. end
  17. end
  18. % 竖向拉伸3倍并只取一部分
  19. exNoiseMat=imresize(exNoiseMat,[3*Row,Col]);
  20. exNoiseMat=exNoiseMat(end-Row+1:end,:);
  21. exNoiseMat=uint8(exNoiseMat);

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

例如大波浪代码:

  1. % 图像透视变换 ============================================================
  2. exNoiseMat=zeros(Row,Col);
  3. K1=40;K2=10;
  4. for i=1:Row
  5. for j=1:Col
  6. k=K2+i*(K1-K2)/Row;
  7. nJ=(j-(1+Col)/2)/k+(1+Col)/2;
  8. if floor(nJ)==ceil(nJ)
  9. nJ=round(nJ);
  10. exNoiseMat(i,j)=noiseMat(i,nJ);
  11. else
  12. nJ1=floor(nJ);nJ2=ceil(nJ);
  13. exNoiseMat(i,j)=noiseMat(i,nJ1)*(nJ2-nJ)+noiseMat(i,nJ2)*(nJ-nJ1);
  14. end
  15. end
  16. end
  17. exNoiseMat=imresize(exNoiseMat,[8*Row,Col]);
  18. exNoiseMat=exNoiseMat(end-Row+1:end,:);
  19. exNoiseMat=uint8(exNoiseMat);

小波浪及大波浪:

4.扭曲置换

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

  1. % 扭曲置换 ================================================================
  2. forePic=flipPic;
  3. bkgPic=exNoiseMat;
  4.  
  5. exforePic=uint8(zeros(size(forePic)+[26,26,0]));
  6. exforePic(14:end-13,14:end-13,1)=forePic(:,:,1);
  7. exforePic(14:end-13,14:end-13,2)=forePic(:,:,2);
  8. exforePic(14:end-13,14:end-13,3)=forePic(:,:,3);
  9.  
  10. for i=1:13
  11. exforePic(i,14:end-13,:)=forePic(1,:,:);
  12. exforePic(end+1-i,14:end-13,:)=forePic(end,:,:);
  13. exforePic(14:end-13,i,:)=forePic(:,1,:);
  14. exforePic(14:end-13,end+1-i,:)=forePic(:,end,:);
  15. end
  16. for i=1:3
  17. exforePic(1:13,1:13,i)=forePic(1,1,i);
  18. exforePic(end-13:end,end-13:end,i)=forePic(end,end,i);
  19. exforePic(end-13:end,1:13,i)=forePic(end,1,i);
  20. exforePic(1:13,end-13:end,i)=forePic(1,end,i);
  21. end
  22.  
  23. newforePic=uint8(zeros(size(forePic)));
  24. for i=1:size(bkgPic,1)
  25. for j=1:size(bkgPic,2)
  26. goffset=(double(bkgPic(i,j))-128)/10;
  27. offsetLim1=floor(goffset)+13;
  28. offsetLim2=ceil(goffset)+13;
  29. sep1=goffset-floor(goffset);
  30. sep2=ceil(goffset)-goffset;
  31. c1=double(exforePic(i+offsetLim1,j+offsetLim1,:));
  32. c2=double(exforePic(i+offsetLim2,j+offsetLim2,:));
  33. if sep1==0
  34. c=double(exforePic(i+offsetLim1,j+offsetLim1,:));
  35. else
  36. c=c2.*sep1+c1.*sep2;
  37. end
  38. newforePic(i,j,:)=c;
  39. end
  40. end

5.图像拼接

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

  1. % 图像拼接 ================================================================
  2. resultPic(:,:,1)=[oriPic(:,:,1);newforePic(:,:,1)];
  3. resultPic(:,:,2)=[oriPic(:,:,2);newforePic(:,:,2)];
  4. resultPic(:,:,3)=[oriPic(:,:,3);newforePic(:,:,3)];
  5. % imshow(resultPic)
  6.  
  7.  
  8. % 边缘模糊 ================================================================
  9. gaussOpt=fspecial('gaussian',[3 3],0.5);
  10. gaussPic=imfilter(resultPic,gaussOpt);
  11. resultPic(Row-1:Row+2,:,1)=gaussPic(Row-1:Row+2,:,1);
  12. resultPic(Row-1:Row+2,:,2)=gaussPic(Row-1:Row+2,:,2);
  13. resultPic(Row-1:Row+2,:,3)=gaussPic(Row-1:Row+2,:,3);
  14. imshow(resultPic)

6.完整代码

  1. function mirrorDown
  2. % @author slandarer
  3.  
  4. % 图片导入
  5. oriPic=imread('test.jpg');
  6. [Row,Col,~]=size(oriPic);
  7.  
  8. % 图片翻转及白化 ==========================================================
  9. whiteMat=((1:Row)./Row./1.2)'*ones(1,Col); % 白化比例矩阵
  10. flipPic=zeros(Row,Col,3); % 翻转后矩阵初始化
  11. for i=1:3
  12. tempChannel=double(oriPic(:,:,i)); % 获得通道图
  13. tempChannel=tempChannel(end:-1:1,:); % 翻转
  14. tempChannel=tempChannel.*(1-whiteMat)+255.*whiteMat; % 白化
  15. flipPic(:,:,i)=tempChannel;
  16. end
  17. % imshow(uint8(flipPic))
  18.  
  19.  
  20. % 噪声图构造(高斯噪声及高斯模糊)===========================================
  21. noiseMat=ones(Row,Col);
  22. noiseMat=imnoise(noiseMat,'gaussian',0,5); % 噪声添加
  23. gaussOpt=fspecial('gaussian',[3 3],1);
  24. noiseMat=imfilter(noiseMat,gaussOpt);
  25. imshow(noiseMat)
  26.  
  27. H=[cos(pi+pi/4),0,cos(pi-pi/4);
  28. cos(pi+2*pi/4),0,cos(pi-2*pi/4);
  29. cos(pi+3*pi/4),0,cos(pi-3*pi/4)];
  30. noiseMat=imfilter(noiseMat,H,'conv')+0.5;
  31. noiseMat=noiseMat.*255;
  32. noiseMat(noiseMat<0)=0;
  33. % imshow(uint8(noiseMat))
  34.  
  35.  
  36. % 图像透视变换 ============================================================
  37. exNoiseMat=zeros(Row,Col);
  38. % 横向拉伸上下边倍数
  39. K1=10;K2=4;
  40. for i=1:Row
  41. for j=1:Col
  42. k=K2+i*(K1-K2)/Row;
  43. nJ=(j-(1+Col)/2)/k+(1+Col)/2;
  44. if floor(nJ)==ceil(nJ)
  45. nJ=round(nJ);
  46. exNoiseMat(i,j)=noiseMat(i,nJ);
  47. else
  48. nJ1=floor(nJ);nJ2=ceil(nJ);
  49. exNoiseMat(i,j)=noiseMat(i,nJ1)*(nJ2-nJ)+noiseMat(i,nJ2)*(nJ-nJ1);
  50. end
  51. end
  52. end
  53. % 竖向拉伸3倍并只取一部分
  54. exNoiseMat=imresize(exNoiseMat,[3*Row,Col]);
  55. exNoiseMat=exNoiseMat(end-Row+1:end,:);
  56. exNoiseMat=uint8(exNoiseMat);
  57. % imshow(exNoiseMat)
  58.  
  59.  
  60. % 扭曲置换 ================================================================
  61. forePic=flipPic;
  62. bkgPic=exNoiseMat;
  63.  
  64. exforePic=uint8(zeros(size(forePic)+[26,26,0]));
  65. exforePic(14:end-13,14:end-13,1)=forePic(:,:,1);
  66. exforePic(14:end-13,14:end-13,2)=forePic(:,:,2);
  67. exforePic(14:end-13,14:end-13,3)=forePic(:,:,3);
  68.  
  69. for i=1:13
  70. exforePic(i,14:end-13,:)=forePic(1,:,:);
  71. exforePic(end+1-i,14:end-13,:)=forePic(end,:,:);
  72. exforePic(14:end-13,i,:)=forePic(:,1,:);
  73. exforePic(14:end-13,end+1-i,:)=forePic(:,end,:);
  74. end
  75. for i=1:3
  76. exforePic(1:13,1:13,i)=forePic(1,1,i);
  77. exforePic(end-13:end,end-13:end,i)=forePic(end,end,i);
  78. exforePic(end-13:end,1:13,i)=forePic(end,1,i);
  79. exforePic(1:13,end-13:end,i)=forePic(1,end,i);
  80. end
  81.  
  82. newforePic=uint8(zeros(size(forePic)));
  83. for i=1:size(bkgPic,1)
  84. for j=1:size(bkgPic,2)
  85. goffset=(double(bkgPic(i,j))-128)/10;
  86. offsetLim1=floor(goffset)+13;
  87. offsetLim2=ceil(goffset)+13;
  88. sep1=goffset-floor(goffset);
  89. sep2=ceil(goffset)-goffset;
  90. c1=double(exforePic(i+offsetLim1,j+offsetLim1,:));
  91. c2=double(exforePic(i+offsetLim2,j+offsetLim2,:));
  92. if sep1==0
  93. c=double(exforePic(i+offsetLim1,j+offsetLim1,:));
  94. else
  95. c=c2.*sep1+c1.*sep2;
  96. end
  97. newforePic(i,j,:)=c;
  98. end
  99. end
  100. % imshow(newforePic)
  101.  
  102.  
  103. % 图像拼接 ================================================================
  104. resultPic(:,:,1)=[oriPic(:,:,1);newforePic(:,:,1)];
  105. resultPic(:,:,2)=[oriPic(:,:,2);newforePic(:,:,2)];
  106. resultPic(:,:,3)=[oriPic(:,:,3);newforePic(:,:,3)];
  107. % imshow(resultPic)
  108.  
  109.  
  110. % 边缘模糊 ================================================================
  111. gaussOpt=fspecial('gaussian',[3 3],0.5);
  112. gaussPic=imfilter(resultPic,gaussOpt);
  113. resultPic(Row-1:Row+2,:,1)=gaussPic(Row-1:Row+2,:,1);
  114. resultPic(Row-1:Row+2,:,2)=gaussPic(Row-1:Row+2,:,2);
  115. resultPic(Row-1:Row+2,:,3)=gaussPic(Row-1:Row+2,:,3);
  116. imshow(resultPic)
  117.  
  118. end

奇怪画风哈哈哈: 

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

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号