1.光学成像系统 Part I - 物理基础 (一)2.光学成像系统 Part II - 光源模型分析 (一)3.光学成像系统 Part II - 光源模型分析 (二)4.光学成像系统 Part II - 光源IES文件测试 (三)5.光学成像系统 Part III - 物体反射光场BRDF模型 (一)
6.光学成像系统 Part III - BRDF测试数据使用 (二)
7.光学成像系统 Part IV - 成像镜头@景深 (三)8.光学成像系统 Part IV - 成像镜头@变焦镜头 (二)9.光学成像系统 Part VI - 成像质量评估 : MTF10.光学成像系统 Part V - CMOS传感器基础 (一)11.光学成像系统 Part V - CMOS光电结构再探 (二)12.光学成像系统 Part V - CMOS光电转换特性 (三)13.光学成像系统 Part VI - 杂谈14.光学成像系统 Part VII - 仿真实例15.光学成像系统 Part II - 热红外辐射源一、BRDF实验数据使用方法
1. 数据集-下载
I. 数据集格式(Anisotropic BRDF Data File Format)
解压后的数据集以 .dat
尾缀结束,文件包括了 64Bytes
的文件头,用来表示文件中数据的维度,存储格式等信息,在表头之后的便是对应的数据值,具体如下所示:

图1 文件 Header 头部分解释
对于 ParamType=1 的标准数据集,数据集的四个维度 ,依次对应了入射光束 , 出射光束 : ,参考理论分析章节,而这些空间角度对应的范围为:
- 如果 Half_data=1: 否则
🌻 数据集中测量不可靠的数据,在数据集中用 标识。
II. 数据集Matlab读取文件
function [B,format]= read_brdf(filename, channel)
% [B, format] = read_brdf(filename, channel)
%
% Output: B - BRDF ( num_channel x dim0 x dim1 x dim2 x dim3 ) , format - struct with tabular format parameters
% Input: filename, channel ( 0 - 'red' , 1 - 'green', 2 - 'blue', -1 - 'All')
%
% Written by Addy Ngan - MIT
%
% Ver 1.01 7/20/2005
% Ver 1.0 6/19/2005
fid = fopen(filename, 'rb');
format.dims = fread(fid,4,'uint32');
% Read in dimensions of the tabulated BRDF
% Standard Parameterization: Theta_In x Theta_Out x Phi_Diff x Phi_In
% Theta_In and Theta_Out range from 0 to pi/2, Phi_Diff range from 0 to pi
% (if half_data == 0) or 2pi (if half_data == 1), Phi_In from 0 to 2pi
% for anisotropic materials.
[modes, count1] = fread(fid,10,'int32');
[expon, count2] = fread(fid,1,'double');
if (count1~=10 || count2~=1)
error('File error');
else
format.paramType = modes(3); % 0 - Rusinkiewicz Parameterization, 1 - Standard Parameterization
format.binType = modes(4); % 0 - linear binning interval, 1 - reserved
format.half_data = modes(6)>0; % 0 - Phi_Diff range [0 2pi] , 1 - Phi_Diff range [0 pi]
format.num_channels = modes(7); % Always 3 for our data (R,G,B)
format.expon = expon; % reserved
end
num_channels = format.num_channels;
if channel~=-1
fseek(fid, channel*prod(format.dims)*4, 0);
num_channels=1;
end
B = fread(fid,num_channels*prod(format.dims),'float=>single');
fclose(fid);
if prod(size(B))<num_channels*prod(format.dims)
B=0;
error('Loading failed');
end
% Reshaping the data into desired dimensions
B=reshape(B,[fliplr(format.dims') num_channels]);
p = length(size(B)):-1:1;
B = permute(B,p);
if num_channels ==1
B = reshape(B, [1 size(B)]);
end
2. 数据集-使用
I. 固定视角下的BRDF数据绘制实验
在确定的观察角度下,不同光束入射角度在材料上形成的反射系数展示如下,横坐标代表入射光 ,纵坐标代表入射光 角:
[B,format]= read_brdf("./yellow_satin.dat", 0); % brushed_alum.dat red_velvet.dat yellow_satin.dat purple_satin.dat
ndims(B)
BRDF_Size = size(B); % 获取BRDF数据集的数据格式维度
B(1,26,27,13,172) % 5D-Single Data 中任取一个BRDF数据
FixViewDirVec = [27,13]; % 确定的一个视角观察点位置 theta_out & phi_diff
BRDFValArray = zeros(BRDF_Size(2),BRDF_Size(5)); % 创建一个BRDF缓冲空间用来存储遍历的BRDF数据
for theta_in = 1:1:BRDF_Size(2) % 在输入光线的 theta 方向上进行遍历操作
for phi_in = 1:1:BRDF_Size(5) % 在输入光线的 phi 方向上进行遍历操作
if B(1,theta_in,FixViewDirVec(1),FixViewDirVec(2),phi_in) < 0 % 判断当前遍历位置处的BRDF数据是否为 -1 , 如果为 -1 则数据无效不能使用
BRDFValArray(theta_in,phi_in) = 0; % 使用 0 代替无效数据
else
BRDFValArray(theta_in,phi_in) = B(1,theta_in,FixViewDirVec(1),FixViewDirVec(2),phi_in); % 将BRDF数据存储到 BRDFValArray 变量当中
end
end
end
mesh(BRDFValArray) % 绘制 BRDFValArray 3D 数据
% 任何平面的情况下,可以绘制在同一观察角度下,同一点光源条件下,不同入射角度
🐶 Result:
II. 点光源+观察点 物体BRDF数据绘制
图中 * 表示点光源,o 表示观察点。
Matlab Source Code:
[ObjMeshGridX,ObjMeshGridY] = meshgrid(-5:0.1:5, -4:0.1:4); % 绘制一个二维数据网格用来代表有限元划分的BRDF反射平面
ViewPos = [-1,-10,10]; % 设置三维空间中的观察点位置坐标
DotLSrc = [0,10,10]; % 设置三维空间中的点光源位置坐标
GridSize = size(ObjMeshGridX); % 获得网格维度数据
Lintensity = zeros(GridSize); % 通过网格维度数据创建数组用于存储计算得到的反射光强度
Z = 0; % 设置Z轴分量为0
NormalZ = [0,0,1]; % 配置Z坐标轴的单位向量
NormalY = [0,1,0]; % 配置Y坐标轴的单位向量
NormalX = [1,0,0]; % 配置X坐标轴的单位向量
theta_in_Array = zeros(GridSize); % 创建空间保存对应点光源对应到反射平面上的 theta 矩阵
theta_out_Array = zeros(GridSize); % 创建空间保存对应观察点对应到反射平面上的 theta 矩阵
phi_in_Array = zeros(GridSize); % 创建空间保存对应点光源对应到反射平面上的 varphi 矩阵
phi_diff_Array = zeros(GridSize); % 创建空间保存对应观察点对应到反射平面上的 varphi 矩阵
B_Array = zeros(GridSize); % 通过网格维度数据创建数组用于存储计算得到的BRDF反射系数
OriIntensity = 800; % 点光源光强度值 800
for x = 1:1:GridSize(1) % 遍历反射平面网格 X 轴
for y = 1:1:GridSize(2) % 遍历反射平面网格 Y 轴
X = ObjMeshGridX(x,y); % 反射平面 X 轴坐标值
Y = ObjMeshGridY(x,y); % 反射平面 Y 轴坐标值
ObjPos = [X,Y,Z]; % 反射平面上对象点三维坐标值 Z = 0
LsrcVect = DotLSrc-ObjPos; % 计算点光源与对象点之间的向量 LsrcVect
ViewVect = ViewPos-ObjPos; % 观察点光源与对象点之间的向量 ViewVect
LenLsrcVect = norm(LsrcVect); % 计算向量的模长
LenViewVect = norm(ViewVect); % 计算向量的模长
theta_in = acos(dot(LsrcVect,NormalZ)/(LenLsrcVect*norm(NormalZ))); % 通过两空间向量的点积得到空间夹角
theta_in_Array(x,y) = theta_in; % 存储入射光空间夹角 theta
theta_out = acos(dot(ViewVect,NormalZ)/(LenViewVect*norm(NormalZ))); % 通过两空间向量的点积得到空间夹角
theta_out_Array(x,y) = theta_out; % 存储出射光空间夹角 theta
ShadingLsrcVec = [LsrcVect(1), LsrcVect(2),0]; % 通过空间向量 LsrcVect 在XY平面上投影得到平面向量
ShadingViewVec = [ViewVect(1), ViewVect(2),0]; % 通过空间向量 ViewVect 在XY平面上投影得到平面向量
phi_in = acos(dot(ShadingLsrcVec,NormalX)/(norm(ShadingLsrcVec)*norm(NormalX))); % 通过两空间向量的点积得到空间夹角
phi_in_Array(x,y) = phi_in; % 存储入射光空间夹角 phi
phi_diff = 2*pi - acos(dot(ShadingViewVec,NormalX)/(norm(ShadingViewVec)*norm(NormalX))); % 通过两空间向量的点积得到空间夹角
phi_diff_Array(x,y) = phi_diff; % 存储出射光空间夹角 phi
BRDFCofficient = B(1,ceil(theta_in*2/pi*45),ceil(theta_out*2/pi*45),ceil(phi_in/2/pi*180),ceil(phi_diff/2/pi*180)); % 在BRDF数据中查找对应的反射系数 BRDFCofficient
if BRDFCofficient < 0 % 对反射系数为 -1 的数据做处理
BRDFCofficient = 0;
end
B_Array(x,y) = BRDFCofficient; % 存储系数到 B_Array 矩阵中
Lintensity(x,y) = OriIntensity*BRDFCofficient; % 求取反射光强度
end
end
figure, % 绘制 Lintensity 反射光强度分布情况
mesh(ObjMeshGridX, ObjMeshGridY, Lintensity)
hold on
plot3(ViewPos(1),ViewPos(2),ViewPos(3),'ro') % ViewPos
hold on
plot3(DotLSrc(1),DotLSrc(2),DotLSrc(3),'r*') % DotLSrc
title("Intensity Distribution")
figure, % 绘制 theta_in_Array 入射光 theta 角度分布
mesh(ObjMeshGridX, ObjMeshGridY, theta_in_Array*180/pi)
hold on
plot3(ViewPos(1),ViewPos(2),0,'ro')
hold on
plot3(DotLSrc(1),DotLSrc(2),0,'r*')
title("ThetaInVal Distribution")
figure, % 绘制 phi_in_Array 入射光 phi 角度分布
mesh(ObjMeshGridX, ObjMeshGridY, phi_in_Array*180/pi)
hold on
plot3(ViewPos(1),ViewPos(2),0,'ro')
hold on
plot3(DotLSrc(1),DotLSrc(2),0,'r*')
title("PhiInVal Distribution")
figure, % 绘制 theta_out_Array 出射光 theta 角度分布
mesh(ObjMeshGridX, ObjMeshGridY, theta_out_Array*180/pi)
hold on
plot3(ViewPos(1),ViewPos(2),0,'ro')
hold on
plot3(DotLSrc(1),DotLSrc(2),0,'r*')
title("ThetaOutVal Distribution")
figure, % 绘制 phi_diff_Array 出射光 phi 角度分布
mesh(ObjMeshGridX, ObjMeshGridY, phi_diff_Array*180/pi)
hold on
plot3(ViewPos(1),ViewPos(2),0,'ro')
hold on
plot3(DotLSrc(1),DotLSrc(2),0,'r*')
title("PhiOutVal Distribution")
max(max(theta_in_Array))
max(max(theta_out_Array))
max(max(phi_in_Array))
max(max(phi_diff_Array))
空间角度分布的情况:
🌻 Concluosion:
从上述数据结果可以发现,存在大量的数据点为 0 的情况,这是由于在 BRDF 数据采集的过程中存在的数据错误问题导致的,考虑到更为精细的仿真设计需求,需要采集更加精细化的数据采集平台,后续考虑使用 MERL BRDF Database 数据。
二、BRDF分布函数使用方法
Reference
转载请注明出处!感谢GISPALAB实验室的老师和同学们的帮助和支持~
合集:
成像系统
分类:
光路光学设计 / 光学成像系统
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具