我正在测试具有不同线宽和背景的FileExchange项目FindPeaksFast
的有效性。
测试1成功,该工具检测从1px到10px的所有峰值。
然而,当测试在对象图的帧(即灰色背景上的对象(图))上找到峰值时,测试2失败。
该工具在白色背景上运作良好。
代码
close all; clear all; clc;
f = figure;
hax = axes(f);
% Comment this out for Test 2
%zeroFigureDecorations(hax);
af = figure('Name', 'Do Not Touch');
x = rand(1,100);
y = rand(1,100);
linewidth=1;
plot(hax, x,y, 'LineWidth', linewidth);
I = getframe(hax);
I = I.cdata;
% https://se.mathworks.com/matlabcentral/fileexchange/37388-fast-2d-peak-finder
p=FastPeakFind(I);
% Input: 344x435x3 uint8
hold(hax, 'on');
plot(hax, p(1:2:end),p(2:2:end),'r+')
hold(hax, 'off');
function zeroFigureDecorations(ax)
axis(ax, 'tight');
set(ax, 'yTickLabel', []);
set(ax, 'xTickLabel', []);
set(ax, 'Ticklength', [0 0]); % http://stackoverflow.com/a/15529630/54964
colormap(ax, 1-gray(1024));
box(ax, 'off');
axis(ax, 'off');
end
以下输出,图1显示当背景为白色而不是正确位置时,该功能可以在线上检测到某些内容。
Linewidth Output 10 166x1 double 1 844x1 double Table: full axis decoration in Test 1 Linewidth Output 10 [] 1 [] Table: no axis decorations, after zeroFigureDecorations(hax) in Test 2
图。 1行作为输入(参见Bla的回答)及其输出, 图2第2节输出错误, 图3另一个例子,你不能将功能应用于简单的曲线, 图4第3节输出错误,因为不知道如何在频谱图上应用该功能
f0 = figure;
hax0 = axes(f0);
d=uint16(conv2(reshape(single( 2^14*(rand(1,128*128)>0.9995) ),[128 128]) ,fspecial('gaussian', 10,2),'same')+2^4*rand(128));
imagesc(d, 'Parent', hax0);
I = getframe(hax0);
I = I.cdata;
p=FastPeakFind(I);
hold(hax0, 'on');
plot(hax0, p(1:2:end),p(2:2:end),'r+')
hold(hax0, 'off');
图2中输出错误
f3 = figure;
hax3 = axes(f3);
N = 1024*10;
n = 0:N-1;
w0 = 2*pi/5;
x = sin(w0*n)+10*sin(2*w0*n);
s = spectrogram(x);
spectrogram(x,'yaxis')
p=FastPeakFind(s);
hold on;
plot(p(1:2:end),p(2:2:end),'r+')
Matlab:2016b
操作系统:Debian 8.5
答案 0 :(得分:1)
您没有正确使用此功能。
你的代码是这样的(逐字):
f = figure;
hax = axes(f);
af = figure('Name', 'Do Not Touch');
x = rand(1,100);
y = rand(1,100);
linewidth=1;
plot(hax, x,y, 'LineWidth', linewidth);
I = getframe(hax);
I = I.cdata;
矩阵I
不是包含函数意图具有的峰的矩阵。这就是它的样子:
imagesc(I);
即使您拥有的只是单个像素,也不是该功能应该具有的功能,因为据说峰值点扩散函数需要大于某些像素数,并且它们被认为是疏。该函数对样本图像进行了演示,工作正常。
此外,完全不清楚你在这里的峰值甚至意味着什么。
编辑:
以下是如何使用该功能的示例。首先让我们选择我们“创造”峰值的随机位置:
I=rand(200)>0.9995;
这使得二元矩阵仅选择大于0.9995的点(或具有值1)。在每一步,您都可以imagesc(I)
查看I
的外观。
在现实生活中,相机在这些点上会有一些强度,所以我们写道:
I=I*100;
这很重要,因为牙列的峰值需要是其附近的最大值。在现实生活中,峰值大多不是单个像素,它们有一些“宽度”或扩散(这也是它所处理的功能):
I=conv2(I,fspecial('gaussian',10,2),'same');
这里,这种传播是通过某个宽度的高斯的“点扩散函数”完成的。
让我们添加30%的噪音(请注意,在最后一步之后,峰值的最大值不再是100,因为它也会扩散到其他像素):
I=I+0.3*max(I(:))*rand(size(I));
让我们找到峰值
p=FastPeakFind(I);
看看它是怎么做的:
subplot(1,2,1);imagesc(I);
subplot(1,2,2);imagesc(I); hold on
plot(p(1:2:end),p(2:2:end),'r+')
在功能代码中,示例是在一行中执行我在此处写的内容。请注意,有一个edg
参数,因为这不适用于图像边缘的峰。这个驾驶室可以通过用零填充图像来解决...我认为...