我正在寻找2D 数据中的峰值区域(如果您愿意,可以通过 Hough 变换创建灰度图像或 2D 风景)。峰值区域是指局部最大峰值,但不是单个点,而是与之相关的周围贡献区域的一部分。我知道,这是一个模糊的定义,但也许山这个词或下面的图片会让你直观地理解我的意思。
标记为红色 (1-4) 的峰是我想要的,粉红色 (5-6) 中的峰是“灰色区域”的示例,如果没有找到那些较小的峰也可以,但如果它们是也可以.
图像包含 1-20 个峰值区域,高度不同。上面冲浪图的 2D 数据如下所示,并带有一个可能的结果(橙色对应于峰 1,绿色对应于峰 2 a/b,...)。可以在描述链接中找到用于测试的单个图像:
图像左:输入图像- - - -中:(okaish)结果- - - -右:结果叠加在图像上。
上面的结果是使用简单的阈值(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 分割,但这些似乎适合分割真实图像,而不是合成数据。
不知何故,我想象用一定量的水填充景观的负片会给我正在寻找的区域:填充和扩散周围区域形状的盆地。就像在下图中倒水一样,由此产生的水池是我正在寻找的区域。
我认为这是洪水填充或分水岭算法所做的,但洪水填充似乎完全是另外一回事,分水岭结果根本不是我想到的,在应用一些我认为可以帮助的预处理时(剪裁为 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),但我可以使用任何代码或伪代码。
为了将此与这个问题区分开来,我的最大值没有被零值分隔。我想要的是相似的,但没有任何建议有帮助(爬山/模拟退火只会给你一分......)。
这个问题也很有趣,但它解决了约束问题(假设恰好有 5 个特定大小的峰值),这使得建议的方法对我的情况没有用处。