基于Matlab實現(xiàn)水波倒影特效的制作
1.使用效果


2.圖像翻轉(zhuǎn)及白化
導入圖像:
% 圖片導入
oriPic=imread('test.jpg');
[Row,Col,~]=size(oriPic);
翻轉(zhuǎn)及白化圖像:
翻轉(zhuǎn)就是單純的將行索引倒過來;
白化就是將當前像素的顏色按比例和白色取個帶權(quán)均值,行索引越大白色權(quán)重也越大,圖像也就越白。
% 圖片翻轉(zhuǎn)及白化 ==========================================================
whiteMat=((1:Row)./Row./1.2)'*ones(1,Col); % 白化比例矩陣
flipPic=zeros(Row,Col,3); % 翻轉(zhuǎn)后矩陣初始化
for i=1:3
tempChannel=double(oriPic(:,:,i)); % 獲得通道圖
tempChannel=tempChannel(end:-1:1,:); % 翻轉(zhuǎn)
tempChannel=tempChannel.*(1-whiteMat)+255.*whiteMat; % 白化
flipPic(:,:,i)=tempChannel;
end
當然如果我們將這一行:
tempChannel=tempChannel.*(1-whiteMat)+255.*whiteMat;
更改為:
tempChannel=tempChannel.*(1-whiteMat)+0.*whiteMat;
就變成了一個黑化的過程:

當然你也可以嘗試其他顏色,例如將整段改寫為:
Color=[255,0,0];
colorMat=((1:Row)./Row./1.2)'*ones(1,Col); % 比例矩陣
flipPic=zeros(Row,Col,3); % 翻轉(zhuǎn)后矩陣初始化
for i=1:3
tempChannel=double(oriPic(:,:,i)); % 獲得通道圖
tempChannel=tempChannel(end:-1:1,:); % 翻轉(zhuǎn)
tempChannel=tempChannel.*(1-colorMat)+Color(i).*colorMat; % 漸變
flipPic(:,:,i)=tempChannel;
end
imshow(uint8(flipPic))
3.波紋圖像構(gòu)造
生成噪聲并模糊:
noiseMat=ones(Row,Col);
noiseMat=imnoise(noiseMat,'gaussian',0,5); % 噪聲添加
gaussOpt=fspecial('gaussian',[3 3],1);
noiseMat=imfilter(noiseMat,gaussOpt);噪聲圖:

模糊后噪聲圖:

浮雕特效:
實際上浮雕特效就是用以下類似形式的矩陣對圖像進行卷積,卷積結(jié)果再加上RGB范圍的均值,[0,1]區(qū)間就加0.5,[0,255]區(qū)間就加128:

數(shù)值和位置不重要,重要的是相對位置互為相反數(shù),浮雕過程描述如下:
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;

透視變換:
就是近大遠小,這里為了方便起見只在橫向方向上做了近大遠小的拉伸,豎直方向進行了等比例拉伸,因而不是嚴格意義上的透視變換:

如圖所示實際操作就是把左側(cè)藍色區(qū)域拉伸成右側(cè)藍色區(qū)域,并只選取紅框內(nèi)部分,代碼如下:
% 圖像透視變換 ============================================================
exNoiseMat=zeros(Row,Col);
% 橫向拉伸上下邊倍數(shù)
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);
注: 如果原圖像尺寸過大,水波就會過于密集,這時候可以適當調(diào)整放縮倍數(shù)或者將原圖像重調(diào)大小到小一點的尺寸。
例如大波浪代碼:
% 圖像透視變換 ============================================================
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);小波浪及大波浪:


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

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)
6.完整代碼
function mirrorDown
% @author slandarer
% 圖片導入
oriPic=imread('test.jpg');
[Row,Col,~]=size(oriPic);
% 圖片翻轉(zhuǎn)及白化 ==========================================================
whiteMat=((1:Row)./Row./1.2)'*ones(1,Col); % 白化比例矩陣
flipPic=zeros(Row,Col,3); % 翻轉(zhuǎn)后矩陣初始化
for i=1:3
tempChannel=double(oriPic(:,:,i)); % 獲得通道圖
tempChannel=tempChannel(end:-1:1,:); % 翻轉(zhuǎn)
tempChannel=tempChannel.*(1-whiteMat)+255.*whiteMat; % 白化
flipPic(:,:,i)=tempChannel;
end
% imshow(uint8(flipPic))
% 噪聲圖構(gòu)造(高斯噪聲及高斯模糊)===========================================
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);
% 橫向拉伸上下邊倍數(shù)
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實現(xiàn)水波倒影特效的制作的詳細內(nèi)容,更多關(guān)于Matlab水波倒影的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C語言結(jié)構(gòu)體,枚舉,聯(lián)合體詳解
下面小編就為大家?guī)硪黄媪私釩語言結(jié)構(gòu)體,枚舉,聯(lián)合體。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2021-09-09
基于Qt OpenCV實現(xiàn)圖像數(shù)據(jù)采集軟件
這篇文章主要為大家詳細介紹了如何利用Qt+OpenCV實現(xiàn)圖像數(shù)據(jù)采集軟件,文中的示例代碼講解詳細,對我學習或工作有一定參考價值,感興趣的可以了解一下2022-07-07
解析C++中的for循環(huán)以及基于范圍的for語句使用
這篇文章主要介紹了解析C++中的for循環(huán)以及基于范圍的for語句使用,是C++入門學習中的基礎(chǔ)知識,需要的朋友可以參考下2016-01-01
VSCode 搭建 Arm 遠程調(diào)試環(huán)境的步驟詳解
這篇文章主要介紹了VSCode 搭建 Arm 遠程調(diào)試環(huán)境的步驟詳解,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-04-04

