MATLAB:调整对数值图的动态范围
我一直无法通过谷歌找到任何与此接近的内容,所以我担心我的问题本身可能有缺陷......尽管如此,这里是:
我希望在各种固定动态下显示值(Z)的矩阵范围。在本例中,固定为 0dB、10dB、...、40dB。
我当前的方法是找到 Zmag = abs(Z).^2, Zn = normalized(Zmag), Zdb = 10*log10(1+Zn)
为了查看不同的动态范围(例如 10dB),我将包括 '找到Zdb之前,Zn(Zn<0.1)=0.1'。对于 20dB,我执行相同的操作,只是感兴趣的值更改为 0.01。
然后,我绘制 Zn 的颜色网格图,并查看 XY(顶部,从 3D 角度)图,以查看类似于 imagesc(Zn) 给出的内容。目的是,当我增加动态范围时,我应该看到更详细的绘图(在本例中,最大值和最小值之间有更多颜色)。
我当前的方法的执行效果(我认为)为 10dB:10dB 动态范围网格 与 40dB 相比: 40dB 动态范围网格图
但是,我看不出 0 之间的差异、20、30 和 40dB 图。我预计值会从 0dB 逐渐增加到 40dB。
-迪伦
编辑:这是一些示例代码。这是真实代码的片段,但仍应运行:
%% Constants
fnum = 1;
Fc = 1/16;
taup = 128;
taumin = 1;
taumax = 512;
taux = taumin:taumax;
%% Signal
l = 1:16; %Signal length
s = sin(2*pi*Fc*l); %Original Signal
sig = zeros([1 taup+512]);
sig(taup:taup+size(l,2)-1) = s;
[mfr,fdy] = MatchedFilterResponse(sig,taup,l);
Z = mfr;
slices = true;
%full dynamic range
name = 'Short Tone Ping results with 0dB range';
Zmag = abs(Z).^2;
Zn = normalizeMat(Zmag);
Zdb = 10*log10(1+Zn);
fnum = plotSurfaces(taux,fdy,Zdb,fnum,name,slices);
slices = false;
%40dB dynamic range
name = 'Short Tone Ping results with 40dB range';
Z40mag = Zmag;
Z40n = normalizeMat(Z40mag);
Z40n(Z40n<0.0001) = 0.0001;
Z40db = 10*log10(1+Z40n);
fnum = plotSurfaces(taux,fdy,Z40db,fnum,name,slices);
function [mfr,fdy] = MatchedFilterResponse(sig,taup,l)
Fdmin = -1/16;
Fdmax = 1/16;
Fdinc = (0.125)/(255);
fdy = linspace(Fdmin,Fdmax,256);
i = 0;
for tau = 1:512
i = i+1;
j = 0;
for Fd = Fdmin:Fdinc:Fdmax
j = j+1;
a = sig(l+taup-1);
b = sig(l+tau).*exp(1i*2*pi*Fd*l);
mfr(j,i) = sum(a.*b);
end
end
return
end
function [fnum] = plotSurfaces(taux,fdy,z,fnum,name,slices)
fid = figure(fnum);
axes1 = axes('Parent',fid);
grid(axes1,'on');
hold(axes1,'all');
msh = mesh(taux,fdy,z,'Parent',axes1);
xlabel ('Delay - seconds');
ylabel ('Frequency offset from center frequency - Cycles/sample');
zlabel ('Ambiguity function (Normalized Magnitude-Squared)','Visible','off');
fname = strcat(name,' (Ambiguity Function z(\tau;F_d))');
title(fname);
ax = axis;
axis([50 200 ax(3) ax(4)])
cb = colorbar('peer',axes1);
set(get(cb,'ylabel'),'String','Magnitude-Squared (dB)');
hold off;
fnum = fnum + 1;
return
end
I have been unable to find anything close to this with Google, so I'm afraid that my question itself may be flawed... None the less, here goes:
I wish to display a matrix of values (Z) at various fixed dynamic ranges. In this case, fixed at 0dB, 10dB, ..., 40dB.
My current approach is to find Zmag = abs(Z).^2, Zn = normalized(Zmag), Zdb = 10*log10(1+Zn)
In order to view a different dynamic range (say, 10dB) I would include 'Zn(Zn<0.1)=0.1' before finding Zdb. For 20dB I do the same, except the value of interest changes to 0.01.
Then I do a color mesh plot of Zn and view the XY (top, from 3D perspective) plot to see something similar to what imagesc(Zn) would give. The intent is that as I increase the dynamic range, I should see a more detailed plot (with more colors between the maximum and minimum, in this case).
My current method is performing as (I think) it should for 10dB: 10dB dynamic range mesh
Compared to 40dB: 40dB dynamic range mesh plot
However, I can't see a difference between my 0,20,30, and 40dB plots. I would expect there to be a gradual increase in values from 0dB to 40dB.
-Dylan
EDIT: Here is some sample code. It is a snippit of the real code, but should still run:
%% Constants
fnum = 1;
Fc = 1/16;
taup = 128;
taumin = 1;
taumax = 512;
taux = taumin:taumax;
%% Signal
l = 1:16; %Signal length
s = sin(2*pi*Fc*l); %Original Signal
sig = zeros([1 taup+512]);
sig(taup:taup+size(l,2)-1) = s;
[mfr,fdy] = MatchedFilterResponse(sig,taup,l);
Z = mfr;
slices = true;
%full dynamic range
name = 'Short Tone Ping results with 0dB range';
Zmag = abs(Z).^2;
Zn = normalizeMat(Zmag);
Zdb = 10*log10(1+Zn);
fnum = plotSurfaces(taux,fdy,Zdb,fnum,name,slices);
slices = false;
%40dB dynamic range
name = 'Short Tone Ping results with 40dB range';
Z40mag = Zmag;
Z40n = normalizeMat(Z40mag);
Z40n(Z40n<0.0001) = 0.0001;
Z40db = 10*log10(1+Z40n);
fnum = plotSurfaces(taux,fdy,Z40db,fnum,name,slices);
function [mfr,fdy] = MatchedFilterResponse(sig,taup,l)
Fdmin = -1/16;
Fdmax = 1/16;
Fdinc = (0.125)/(255);
fdy = linspace(Fdmin,Fdmax,256);
i = 0;
for tau = 1:512
i = i+1;
j = 0;
for Fd = Fdmin:Fdinc:Fdmax
j = j+1;
a = sig(l+taup-1);
b = sig(l+tau).*exp(1i*2*pi*Fd*l);
mfr(j,i) = sum(a.*b);
end
end
return
end
function [fnum] = plotSurfaces(taux,fdy,z,fnum,name,slices)
fid = figure(fnum);
axes1 = axes('Parent',fid);
grid(axes1,'on');
hold(axes1,'all');
msh = mesh(taux,fdy,z,'Parent',axes1);
xlabel ('Delay - seconds');
ylabel ('Frequency offset from center frequency - Cycles/sample');
zlabel ('Ambiguity function (Normalized Magnitude-Squared)','Visible','off');
fname = strcat(name,' (Ambiguity Function z(\tau;F_d))');
title(fname);
ax = axis;
axis([50 200 ax(3) ax(4)])
cb = colorbar('peer',axes1);
set(get(cb,'ylabel'),'String','Magnitude-Squared (dB)');
hold off;
fnum = fnum + 1;
return
end
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
有几种压缩/扩展动态范围的方法,下面的阈值只是其中一种。您可以从上面设置阈值,或者可以使用更平滑的函数对动态范围进行“更软”的压缩。
您期望看到的逐渐增加取决于 Zn 值的分布,如果没有数据示例和您使用的代码,则很难找到代码中的原因或问题(如果它是一个错误)。
无论如何,如果您的目标是显示数据(而不是您可能想做的任何进一步分析),我建议您压缩颜色图的动态范围,而不是数据本身的动态范围。最快的方法是右键单击颜色栏并选择“交互式颜色图转换”,这样您就可以直接在颜色栏上使用鼠标来更改动态范围。
如果您想以编程方式执行此操作,请根据值的分布创建一些自定义颜色图。例如(为了简单起见,我仅使用红色值)
There are a few methods of compressing/expanding the dynamic range, and thresholding from below is just one. You could threshold from above, or you could do a 'softer' compression of the dynamic range, by using a smoother function.
The gradual increase you expect to see depends on the distribution of values of Zn, and without an example of data and the code you use, it's hard to find the cause or problem in code (if it is a bug at all).
Anyway if your aim is to display the data (as opposed to any further analysis you might want to do), I suggest you compress the dynamic range of the colormap, and not of the data itself. The fastest way to do it is to right-click the colorbar and choosing 'Interactive Colormap Shift', which enables you to use the mouse directly on the colrbar in order to change the dynamic range.
If you want to do it programatically, create a few custom colormaps according to the distribution of your values. For example (I am using only red values, for the sake of simplicity)