光場相機模擬程序解讀

網上有寫的很好的光場相機模擬程序,由於沒有任何基礎,所以以小白的思維理解。
首先附上GitHub網址:https://github.com/muzichao/Light-field-camera
此程序使用近軸光學成像原理,實現相機的程序模擬。
傳統相機可簡化爲下圖(a);
光場相機簡化可以分爲透鏡+微透鏡陣列。如下圖(b)所示:

距透鏡d的物體,在透鏡後v處成像,若物體離透鏡的距離遠大於焦距,則適用於近軸光學。
第一部分代碼

addpath(genpath('/image'));
addpath(genpath('/image2'));
addpath(genpath('/data'));
addpath(genpath('/dataRGB'));
addpath(genpath('/len_sub'));

clearall

上述函數括號中內容 表示路徑
genpath(file)表示目標文件夾下的所有文件夾
addpath(genpath(file))將目標文件夾下所有文件夾都包括進調用函數的目錄

這樣表述,每個功能都能單獨存放在一個子文件夾裏,便於維護。matlab無分層概念,所以將其他子文件夾的數據添加到主程序目錄須在程序前添加上述代碼。

(參考https://blog.csdn.net/zhangyake1989/article/details/78580414)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%物體信息%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[obj,obj1,d,d2,object_num,error]=len_object();
if error == 1
	clearall
	break;
elseif object_num==1
	clear obj1
end

我們定位select_object()函數,在./len_sub文件夾中:

function [obj,obj2,d,d2,object_num,error]=select_object()
%2012 12 20 by lichao
%用於選擇場景
%用法:[obj,obj1,d,d2,object_num,error]=select_object()
%obj        場景1
%obj2       場景2
%d          場景1距離
%d2         場景2距離
%object_num 場景數量
%error      結束選擇
error=0;
obj=[];
obj2=[];
d=0;
d2=0;
object_num=menu('請選擇物體個數:','一個物體','兩個物體','結束');
if object_num ==1
	object=menu('請選擇成像面:','lena256','lena512','Baboon512','Peppers512','circle_card','lena101','一點','結束');
	if object<=7
		obj=select_obj(object);
        	d=250;%物距
    	else
        	error=1;
        	return;  
     	end
   
elseif object_num==2
     	object2=menu('請選擇成像面:','A和B','C和D','結束');
     	 if object2<=2
     	 	[obj,obj2]=select_2obj(object2);
     	 	d=250;
     	 	d2=400;
     	 else
     	 	error=1;
     	 	return;
     	 end
elseif object_num==3
	error=1;
	return;
end

menu函數的作用是生成UI界面目錄
m = menu(‘title’,‘n1’,‘n2’,…,‘nn’) 函數顯示以字符串變量‘title’爲標題的菜單,選項爲字符串變量:‘n1’,…,返回所輸入的值到m

上述函數是兩個選擇:首先選擇物體個數,其次選擇個數後選擇成像面。

所以第一段函數的意思就是如果按了結束,就清除所有;如果物體數目一個,則清除obj1
第二部分代碼

%%%%%%%%%%%%%%%%%相機參數信息%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%可調參數%%%%%%%%%%%%%%%%%%%%%%%%%%%
v=16;%像距,默認16
N_line=81;%對主透鏡的離散化,每個點在主透鏡有多少光線,默認81條
d_m=18;%物體是透鏡的多少倍
error =ensure_par(v,N_line,d_m,object_num,d,d2);
if error ==1
	clearall
	dis('請重新調整參數!');
	break;
end
fuction error =ensure_par(v,N_line,d_m,object_num,d,d2)
%用於確認參數信息是否準確
%error=ensure_par[v,N_line,d_m,object_num,d,d2]
%v         	 微透鏡位置
%N_line    	 主透鏡採樣率
%d_m       	 場景放大倍數
%object_num 	 場景數
%d          	 場景1的距離
%d2         	 場景2的距離

error =0;
if nargin<=5
	error=1;
	disp('請輸入足夠的參數:')
	return;
end

par_menu=menu('確認下列數據是否正確:',['微透鏡距離:v=',num2str(v)],['場景個數:object_num=',num2str(object_num)],...
    ['場景1的距離:d=',num2str(d)],['場景2的距離:d2=',num2str(d2)],['主透鏡採樣率:N_line=',num2str(N_line)],['場景放大倍數:d_m=',num2str(d_m)],'否','是');
if par_menu<=7
	error=1;
	return;
else
	disp(['可調參數(微透鏡位置):v=',num2str(v)]);	
 	disp(['可調參數(主透鏡採樣率):N_line=',num2str(N_line)]);		
	disp(['可調參數(場景放大倍數):d_m=',num2str(d_m)]);
	disp(['可調參數(場景1距離):d=',num2str(d)]);
	disp(['可調參數(場景2距離):d2=',num2str(d2)]); 
end	

ensure_par函數用來確認輸入的參數信息是否準確仍然是程序用戶UI界面,讓用戶判斷是否是自己選擇的參數。若不準確,退出,若準確,則進行下一步。

這樣,第二段代碼解說完畢了。

第三段代碼

D=4;				%直徑
F=16;				%焦距  f-num=4
lens_d=0.02;			%微透鏡直徑
sen_N=20;			%每個微透鏡後傳感器個數
lens_f=lens_d*F/D;		%微透鏡焦距
lens_v=lens_f+v; 		%傳感器位置
sen_N_total=micr_N*sen_N;	%傳感器總個數
sen_d=lens_d/sen_N;		%傳感器直徑
if mod(sen_N_total,2)==0
    sen_N_total=sen_N_total+1;
end
im_max=zeros(3,1);		%分別保存R,G,B的最大值,以便轉換爲uint8型,以節省內存

第三段代碼是設置固定參數

D=4;  %直徑
F=16;%焦距 f-num=4
lens_d=0.02;%微透鏡直徑
sen_N=20;%每個微透鏡後傳感器個數

lens_f=lens_d*F/D;%微透鏡焦距
lens_v=lens_f+v; %傳感器位置
micr_N=ceil(D/lens_d);%微透鏡個數
sen_N_total=micr_N*sen_N;%傳感器總個數
sen_d=lens_d/sen_N;%傳感器直徑
if mod(sen_N_total,2)==0
    sen_N_total=sen_N_total+1;
end
im_max=zeros(3,1);%分別保存R,G,B的最大值,以便轉換爲uint8型,以節省內存

第四段代碼

tic
for k=1:3
    if object_num==1
        fprintf_RGB(k);%字符串打印
        obje=obj(:,:,k);
        im=LF_sim(obje,d,d_m,D,N_line,F,v,lens_d,lens_f,sen_N);
        im_max(k)=max(max(max(max(im))));
    elseif object_num==2
        fprintf_RGB(k); %字符串打印
        obje=obj(:,:,k);
        im=LF_sim(obje,d,d_m,D,N_line,F,v,lens_d,lens_f,sen_N);
        obje=obj1(:,:,k);
        im=im+LF_sim(obje,d2,d_m,D,N_line,F,v,lens_d,lens_f,sen_N);
        im_max(k)=max(max(max(max(im))));
    end
    save (sprintf('./dataRGB/im_d_%d_v_%d_Nline_%d_%d.mat',d,v,N_line,k),'im');

end
t=toc;
fprintf(['\n模擬光場傳輸時間爲:t=',num2str(t),'s\n']);

第五段代碼

%%  畫出原始圖像
figure
if object_num==1
    imshow(uint8(obj),[]);title('obj——場景')
elseif object_num==2
    subplot(1,2,1),imshow(uint8(obj),[]);title('obj——第一個場景');
    subplot(1,2,2),imshow(uint8(obj1),[]);title('obj1——第二個場景');
end
fprintf('\n已畫出場景圖像!\n');

第六段代碼

%%  畫出傳感器成像
clear im
im_RGB=reshape4to2_im(d,v,N_line,micr_N,sen_N,im_max);
figure
warning off all
imshow(im_RGB,[]);title('傳感器圖像im');
warning on all
imwrite(im_RGB,sprintf('./dataRGB/im_d_%d_v_%d_Nline_%d_RGB.jpg',d,v,N_line));%將微透鏡圖像保存爲im_RGB.jpg
fprintf('\n已畫出傳感器圖像!\n');

第七段代碼

%% 原始數據求和重構後的圖像
im_micr=sum_4D_im(d,v,N_line,micr_N);
max_im_micr=max(max(max(im_micr)));
im_micr=uint8(im_micr/max_im_micr*255);
figure
imshow(im_micr,[]);title('原始數據求和重構:');
fprintf('\n已畫出原始數據重構圖像!\n');
disp('The end!');
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章