MATLAB循環嵌套的優化,可否改成矩陣運算?
當數據量很龐大時,用matlab計算循環耗時很久,不知道能否進行優化,讓循環成其他運算方法,比如矩陣運算?
下面是題主遇到的實際問題,最後要生成兩個矩陣(均值和方差):
[m n]=size(im); %%im是個1024*2048的double型矩陣
p=(row-1)/2; %% row=col=5
q=(col-1)/2;
temp=padarray(im,[p q],『symmetric』); %%拓展矩陣,維數是(m+2p,n+2q)
temp2=zeros(row,col); %%滑動窗口,一個小的方陣,維數是(row,col)
temp_mean=zeros(m,n); %%均值矩陣
temp_var=zeros(m,n); %%方差矩陣
for ii=p+1:p+m
for jj=q+1:1:q+n
temp2=temp(ii-p:1:ii+p,jj-q:1:jj+q);
temp3=temp2(:); %%矩陣變向量
temp_mean(ii-p,jj-q)=mean(temp3); %%取平均數
temp_var(ii-p,jj-q)=var(temp3); %%取方差
end
end
im = rand(1024,2048);
row = 5; col = 5;
% 原始程序
tic
[m,n]=size(im); %%im是個1024*2048的double型矩陣
p=(row-1)/2; %% row=col=5
q=(col-1)/2;
temp=padarray(im,[p q],"symmetric"); %%拓展矩陣,維數是(m+2p,n+2q)
temp2=zeros(row,col); %%滑動窗口,一個小的方陣,維數是(row,col)
temp_mean=zeros(m,n); %%均值矩陣
temp_var=zeros(m,n); %%方差矩陣
for ii=p+1:p+m
for jj=q+1:1:q+n
temp2=temp(ii-p:1:ii+p,jj-q:1:jj+q);
temp3=temp2(:); %%矩陣變向量
temp_mean(ii-p,jj-q)=mean(temp3); %%取平均數
temp_var(ii-p,jj-q)=var(temp3); %%取方差
end
end
toc
% 修改
tic
n = row*col;
tm = imfilter(im,ones(row,col)/n,"symmetric");
tv = imfilter(im.^2,ones(row,col)/(n-1),"symmetric")-n/(n-1)*tm.^2;
toc
% 驗證
norm(temp_mean(:)-tm(:))
norm(temp_var(:)-tv(:))
結果:
時間已過 27.949467 秒。
時間已過 0.037127 秒。
ans =
1.28280355334838e-13
ans =
1.20941060414099e-13
如果你的 GPU 支持 CUDA,可以用 gpuArray, 應該會更快些
找到了一個matlab內建的函數用於求均值矩陣,然而方差矩陣還是沒有辦法。
改進之後的代碼如下:
[m n]=size(im); %%im是個1024*2048的double型矩陣
p=(row-1)/2; %% row=col=5
q=(col-1)/2;
temp=padarray(im,[p q],『symmetric』); %%拓展矩陣,維數是(m+2p,n+2q)
temp_var=zeros(m,n); %%方差矩陣
for ii=p+1:p+m
for jj=q+1:1:q+n
temp2=temp(ii-p:1:ii+p,jj-q:1:jj+q);
temp3=temp2(:); %%矩陣變向量
temp_var(ii-p,jj-q)=var(temp3); %%取方差
end
end
temp_mean=filter2(fspecial("average",5),temp);%%均值濾波,模板是5*5
temp_mean=(temp_mean(2:(m+1),2:(n+1)));%%截取中間m*n的矩陣塊,得到所需均值矩陣
推薦閱讀:
※一個N*N的矩陣,取值為0或1,有什麼好的演算法判斷一行或一列全為1啊?
※卡爾曼濾波器是如何運用於多感測器融合的?
※MD5加密相比於其他加密有什麼好處?
※怎麼看演算法書?
※演算法競賽和數學競賽對選手的考察點有什麼不同?