如何使用 Matlab FastPeakFind 检测灰色背景上的峰?
How to detect peaks on gray background with Matlab FastPeakFind?
我正在测试具有不同线宽和背景的 FileExchange 项目 FindPeaksFast
的有效性。
测试 1 成功,该工具检测到从 1 像素到 10 像素的所有峰值。
然而,当测试在对象图的框架上找到峰值时,测试 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]); %
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 节输出错误,因为不知道如何在频谱图上应用该函数
2 使用 bla 的示例数据进行测试
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输出错误
3 使用频谱图进行测试
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
OS:Debian 8.5
您没有正确使用该功能。
您的代码是这样的(逐字):
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);
即使您只有单个像素,这也不是函数应该具有的,因为据说峰值点扩散函数需要大于一些像素,并且假设它们稀疏。该函数在示例图像上进行了演示,效果很好。
此外,完全不清楚您在这里所说的峰值是什么意思。
编辑:
下面是如何使用该函数的示例。首先让我们 select 随机位置 "create" 峰值:
I=rand(200)>0.9995;
这将生成一个二进制矩阵,其中只有大于 0.9995 selected(或值为 1)的点。在每个步骤中,您都可以 imagesc(I)
查看 I
的外观。
在现实生活中,相机在这些点上会有一些强度,所以我们写:
I=I*100;
这很重要,因为牙列的峰值需要是其附近的最大值。在现实生活中,峰值大多不是单个像素,它们有一些 "width" 或扩散(这也是函数所说的它处理的内容):
I=conv2(I,fspecial('gaussian',10,2),'same');
这里,这个传播是由一个 "point-spread function" 一些宽度的高斯完成的。
让我们添加一些 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
参数,因为这不适用于图像边缘的峰值。我认为可以通过用零填充图像来解决这辆出租车...
我正在测试具有不同线宽和背景的 FileExchange 项目 FindPeaksFast
的有效性。
测试 1 成功,该工具检测到从 1 像素到 10 像素的所有峰值。
然而,当测试在对象图的框架上找到峰值时,测试 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]); %
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 节输出错误,因为不知道如何在频谱图上应用该函数
2 使用 bla 的示例数据进行测试
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输出错误
3 使用频谱图进行测试
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
OS:Debian 8.5
您没有正确使用该功能。
您的代码是这样的(逐字):
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);
即使您只有单个像素,这也不是函数应该具有的,因为据说峰值点扩散函数需要大于一些像素,并且假设它们稀疏。该函数在示例图像上进行了演示,效果很好。
此外,完全不清楚您在这里所说的峰值是什么意思。
编辑:
下面是如何使用该函数的示例。首先让我们 select 随机位置 "create" 峰值:
I=rand(200)>0.9995;
这将生成一个二进制矩阵,其中只有大于 0.9995 selected(或值为 1)的点。在每个步骤中,您都可以 imagesc(I)
查看 I
的外观。
在现实生活中,相机在这些点上会有一些强度,所以我们写:
I=I*100;
这很重要,因为牙列的峰值需要是其附近的最大值。在现实生活中,峰值大多不是单个像素,它们有一些 "width" 或扩散(这也是函数所说的它处理的内容):
I=conv2(I,fspecial('gaussian',10,2),'same');
这里,这个传播是由一个 "point-spread function" 一些宽度的高斯完成的。
让我们添加一些 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
参数,因为这不适用于图像边缘的峰值。我认为可以通过用零填充图像来解决这辆出租车...