在二维数据中查找峰值(区域)
Find peak (regions) in 2D data
我想在 2D 数据中找到 峰值区域 (如果你愿意,灰度图像或 2D 景观,通过 Hough 变换创建)。 峰值区域是指局部最大峰值,但不是单点 但周围的一部分 贡献区域 随之而来。我知道,这是一个模糊的定义,但也许 mountain 这个词或下面的图片会让您对我的意思有一个直觉。
红色标记的峰(1-4)是我想要的,粉红色的峰(5-6)是"grey zone"的示例,如果找不到那些较小的峰也没关系但也可以,如果他们是。
图像包含 1-20 个高度不同的尖峰区域。上面的 surf plot 的 2D 数据和一个可能的结果如下所示(橙色对应于 Peak 1,绿色对应于 Peak 2 a/b,...)。可以在描述链接中找到用于测试的单张图像:
左图:input image - - - - middle: (okaish) result - - - - 右:结果叠加在图像上。
上面的结果是使用简单的阈值处理(MATLAB 代码)产生的:
% thresh_scale = 15; % parameter: how many thresholding steps
% thresh_perc = 6; % parameter: threshold at which we clip
thresh = multithresh(H,thresh_scale);
q_image = imquantize(H, thresh);
q_image(q_image <= thresh_perc) = 0; % regions under threshold are thrown away
q_image(q_image > thresh_perc) = 1; % ... while all others are preserved
q_image = imbinarize(q_image); % binarize for further processing
B = bwareaopen(q_image, nhood_minsize); % Filter really small regions
[L, L_num] = bwlabel(B); % <- result % Label connected components
如果几乎没有类似的峰,像这些(15 和 6)这样的一些值通常工作正常,但如果存在更多的峰或它们变化很大,这就不一致了。我主要有两个问题,也不是简单调整参数就能解决的:
- 较高的峰可以掩盖较低(但可清楚区分)的峰。由于阈值是相对于最高峰的,其他峰可能低于。
- 在某些情况下,两个峰之间的谷值高于阈值,将多个峰合并为一个峰(如峰 2 a/b 所示)。
我也不想要一个巨大的山峰区域,所以 峰区 应该定义为山的一定百分比。我认为与其使用全局阈值,不如使用一种方法来找到与其直接环境相关的峰值区域。我研究了均值漂移和 MSER 分割,但它们似乎适合分割真实图像,而不适合分割合成数据。
不知何故,我想象用一定量的水填充景观的负片会给我正在寻找的区域:随着周围区域的形状填充和扩散的盆地。就像将水倒在下面的图像上,由此产生的水池就是我要寻找的区域。
我认为这就是 floodfill 或 watershed 算法所做的,但是 floodfill 看起来完全是另外一回事,分水岭结果根本不是我想要的,在应用一些我认为可能有帮助的预处理时也是如此(剪裁在 1/10):
或者当使用与上述示例相同的裁剪阈值时(裁剪为 6/15):
使用此代码 (MATLAB) 生成:
thresh = multithresh(H, 10); % set to either 10 || 15 for the examples
q_image = imquantize(H, thresh);
mask = false(size(q_image)); % create clipping mask...
mask(q_image > 1) = true; % ... to remove lowest 10% || lowest 6/15
% show with: figure, imshow(mask);
% OPTIONAL: Gaussian smoothing
H = imgaussfilt(H, 2); % apply before adding Inf values
% OPTIONAL: H-minima transform
H = imhmin(H, 10); % parameter is threshold for suppressing shallow minima
H = -H; % Complement the image
H(~mask) = Inf; % force "ground" pixels to Inf
L = watershed(D);
L(~mask) = 0; % clip "ground" from result
imshow(label2rgb(L,'lines',[.5 .5 .5])); % show result
我现在的问题: 有没有一种算法可以填充景观并给我生成的水池(对于倒了不同量的水)来完成我试图用上述方法实现的目标? 或欢迎任何其他建议。我正在实现 MATLAB(或者如果需要 Python),但我可以使用任何代码或伪代码。
为了与 this question 区分开来,我的最大值没有被零值分隔。我想要的是相似的,但是 none 的建议很有帮助(hill-climbing/simulated 退火只会给你一分...)。
This question 也很有趣,但它解决了约束问题(假设正好有 5 个特定大小的峰),这使得建议的方法对我的情况没有用。
在这种找峰问题中,我主要使用形态学操作。由于 Hough 变换结果大多有噪声,我更喜欢先模糊它,然后应用 tophat 和扩展的最大值变换。然后对于每个局部最大值,使用自适应阈值找到它周围的区域。这是一个示例代码:
im=imread('udIuy.png');
% blur
im=imgaussfilt(im,1);
% tophat transform
im2=imtophat(im,strel('disk',5));
% extended maximums
im3=imextendedmax(im2,10);
% Extract each blob
s=regionprops(im3,'Centroid','PixelIdxList');
figure,imagesc(im),axis image
for i=1:numel(s)
x=ceil(s(i).Centroid);
tmp=im*0;
tmp(s(i).PixelIdxList)=1;
tmp2=tmp.*im2;
% The maximum amplitude and location
[refV,b]=max(tmp2(:));
[x2,y2]=ind2sub(size(im),b);
% select the region around local max amplitude
tmp=bwselect(im2>refV*0.6,y2,x2,4);
[xi,yi]=find(tmp);
hold on, plot(yi,xi,'r.')
hold on, text(y2+10,x2,num2str(i),'Color','white','FontSize',16)
end
我想在 2D 数据中找到 峰值区域 (如果你愿意,灰度图像或 2D 景观,通过 Hough 变换创建)。 峰值区域是指局部最大峰值,但不是单点 但周围的一部分 贡献区域 随之而来。我知道,这是一个模糊的定义,但也许 mountain 这个词或下面的图片会让您对我的意思有一个直觉。
红色标记的峰(1-4)是我想要的,粉红色的峰(5-6)是"grey zone"的示例,如果找不到那些较小的峰也没关系但也可以,如果他们是。
图像包含 1-20 个高度不同的尖峰区域。上面的 surf plot 的 2D 数据和一个可能的结果如下所示(橙色对应于 Peak 1,绿色对应于 Peak 2 a/b,...)。可以在描述链接中找到用于测试的单张图像:
左图:input image - - - - middle: (okaish) result - - - - 右:结果叠加在图像上。
上面的结果是使用简单的阈值处理(MATLAB 代码)产生的:
% thresh_scale = 15; % parameter: how many thresholding steps
% thresh_perc = 6; % parameter: threshold at which we clip
thresh = multithresh(H,thresh_scale);
q_image = imquantize(H, thresh);
q_image(q_image <= thresh_perc) = 0; % regions under threshold are thrown away
q_image(q_image > thresh_perc) = 1; % ... while all others are preserved
q_image = imbinarize(q_image); % binarize for further processing
B = bwareaopen(q_image, nhood_minsize); % Filter really small regions
[L, L_num] = bwlabel(B); % <- result % Label connected components
如果几乎没有类似的峰,像这些(15 和 6)这样的一些值通常工作正常,但如果存在更多的峰或它们变化很大,这就不一致了。我主要有两个问题,也不是简单调整参数就能解决的:
- 较高的峰可以掩盖较低(但可清楚区分)的峰。由于阈值是相对于最高峰的,其他峰可能低于。
- 在某些情况下,两个峰之间的谷值高于阈值,将多个峰合并为一个峰(如峰 2 a/b 所示)。
我也不想要一个巨大的山峰区域,所以 峰区 应该定义为山的一定百分比。我认为与其使用全局阈值,不如使用一种方法来找到与其直接环境相关的峰值区域。我研究了均值漂移和 MSER 分割,但它们似乎适合分割真实图像,而不适合分割合成数据。
不知何故,我想象用一定量的水填充景观的负片会给我正在寻找的区域:随着周围区域的形状填充和扩散的盆地。就像将水倒在下面的图像上,由此产生的水池就是我要寻找的区域。
我认为这就是 floodfill 或 watershed 算法所做的,但是 floodfill 看起来完全是另外一回事,分水岭结果根本不是我想要的,在应用一些我认为可能有帮助的预处理时也是如此(剪裁在 1/10):
或者当使用与上述示例相同的裁剪阈值时(裁剪为 6/15):
使用此代码 (MATLAB) 生成:
thresh = multithresh(H, 10); % set to either 10 || 15 for the examples
q_image = imquantize(H, thresh);
mask = false(size(q_image)); % create clipping mask...
mask(q_image > 1) = true; % ... to remove lowest 10% || lowest 6/15
% show with: figure, imshow(mask);
% OPTIONAL: Gaussian smoothing
H = imgaussfilt(H, 2); % apply before adding Inf values
% OPTIONAL: H-minima transform
H = imhmin(H, 10); % parameter is threshold for suppressing shallow minima
H = -H; % Complement the image
H(~mask) = Inf; % force "ground" pixels to Inf
L = watershed(D);
L(~mask) = 0; % clip "ground" from result
imshow(label2rgb(L,'lines',[.5 .5 .5])); % show result
我现在的问题: 有没有一种算法可以填充景观并给我生成的水池(对于倒了不同量的水)来完成我试图用上述方法实现的目标? 或欢迎任何其他建议。我正在实现 MATLAB(或者如果需要 Python),但我可以使用任何代码或伪代码。
为了与 this question 区分开来,我的最大值没有被零值分隔。我想要的是相似的,但是 none 的建议很有帮助(hill-climbing/simulated 退火只会给你一分...)。
This question 也很有趣,但它解决了约束问题(假设正好有 5 个特定大小的峰),这使得建议的方法对我的情况没有用。
在这种找峰问题中,我主要使用形态学操作。由于 Hough 变换结果大多有噪声,我更喜欢先模糊它,然后应用 tophat 和扩展的最大值变换。然后对于每个局部最大值,使用自适应阈值找到它周围的区域。这是一个示例代码:
im=imread('udIuy.png');
% blur
im=imgaussfilt(im,1);
% tophat transform
im2=imtophat(im,strel('disk',5));
% extended maximums
im3=imextendedmax(im2,10);
% Extract each blob
s=regionprops(im3,'Centroid','PixelIdxList');
figure,imagesc(im),axis image
for i=1:numel(s)
x=ceil(s(i).Centroid);
tmp=im*0;
tmp(s(i).PixelIdxList)=1;
tmp2=tmp.*im2;
% The maximum amplitude and location
[refV,b]=max(tmp2(:));
[x2,y2]=ind2sub(size(im),b);
% select the region around local max amplitude
tmp=bwselect(im2>refV*0.6,y2,x2,4);
[xi,yi]=find(tmp);
hold on, plot(yi,xi,'r.')
hold on, text(y2+10,x2,num2str(i),'Color','white','FontSize',16)
end