答案 0 :(得分:2)
边界将由高度的局部最小值确定。找到它们并不像第一眼看上去那么容易。我会试试这个:
创建清晰的投资回报率屏蔽图像
让我们定义具有含义的 ROI 图像颜色:
0 - empty space
1 - slope from left
2 - slope from right
3 - hill border
10 - mountain 1
11 - mountain 2
12 - mountain 3 ...
并使用0
以x
方向扫描源图像
并从x+
方向设置所有下坡:
for (y=0;y<ys;y++)
for (x=1;x<=xs;x++)
if ((ROI[y][x]==0)&&(height[y][x-1]>height[y][x]+treshold))
ROI[y][x]=1;
同样扫描x-
方向
for (y=0;y<ys;y++)
for (x=xs-2;x>=0;x--)
if ((ROI[y][x]==0)&&(height[y][x+1]>height[y][x]+treshold))
ROI[y][x]=2;
现在您需要在1,2
之间的投资回报率中找到区域,并将它们设置为3
,这可能是边界。在此之后,使用1,2
清除所有0
ROI 像素。 treshold
只是对山坡敏感。此算法在平滑图像上效果最佳,因此如果存在太多伪像,您可以在应用此图像之前尝试平滑源图像几次。
过滤掉太小的边框
你应该过滤掉设置为3
的太小的 ROI 区域,以避免太小的山峰弄乱整个事情。treshold
可以避免达到一定程度价值或通过合并大区域内的小区域。
对y
方向做#2,#3(也可能是对角线)
通过病理操作扩大投资回报率边界
使用floodfill填充ROI中的空白区域
将第一个 ROI 像素设置为零并填充100
,然后填充101
等。在填充过程中,您可以计算填充的min,max,avg
高度区域以后丢弃过于平坦的区域(因为它们不被视为丘陵/山脉)。
答案 1 :(得分:2)
我会用图像处理工具箱来做。从您的图片开始,img
:
figure; imshow(img);
首先,最棘手的一步是定义山脉。人们可能会对引入高限制感到满意。但根据您的数据和您的期望,您还可以对该区域应用限制。在这里,我首先考虑的是高度:
bw = im2bw(img, .85);
figure; imshow(bw)
现在我过滤掉了很小的区域。你也可以玩这个门槛。
bw_cleaned = bwareaopen(bw, 100, 4);
figure; imshow(bw_cleaned)
接下来的步骤是以图示峰值的区域合并在一起的方式扩展白色区域,然后在每个峰值周围制作凸包,最后找到它的位置:
final_bw = bwconvhull(imdilate(bw_cleaned, strel('disk', 50)), 'objects');
figure; imshow(final_bw)
s = regionprops(final_bw, 'Centroid');
centroids = cat(1, s.Centroid);
hold on
plot(centroids(:,1), centroids(:,2), 'b*')
使用regionprops
,您可以做的不仅仅是找到质心。 Take a look.