热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PythonAlphaShape:基于点集估算图像区域的Alpha形状算法解析

本文探讨了基于点集估算图像区域的Alpha形状算法在Python中的应用。通过改进传统的Delaunay三角剖分方法,该算法能够生成更加灵活和精确的形状轮廓,避免了单纯使用Delaunay三角剖分时可能出现的过大三角形问题。这种“模糊Delaunay三角剖分”技术不仅提高了形状的准确性,还增强了对复杂图像区域的适应能力。

好的,这是个主意. Delaunay三角剖分将产生不加区别的大三角形.它也会有问题,因为只会生成三角形.

因此,我们将生成您可能称之为“模糊Delaunay三角剖分”的东西.我们将所有点都放入kd树中,对于每个点p,查看它的k个最近邻点. kd树让这个快.

对于这些k个邻居中的每一个,找到到焦点p的距离.使用此距离生成加权.我们希望附近的点比更远的点更受青睐,所以这里指数函数exp(-alpha * dist)是合适的.使用加权距离建立概率密度函数,描述绘制每个点的概率.

现在,从该分布中抽出很多次.将经常选择附近的积分,而不太经常选择更远的积分.对于绘制的点,记下为焦点绘制的次数.结果是加权图,其中图中的每条边连接附近的点,并根据选择对的频率进行加权.

现在,从权重太小的图表中剔除所有边缘.这些是可能没有连接的点.结果如下:

现在,让我们将所有剩余的边缘扔到shapely.然后我们可以通过缓冲它们将边缘转换为非常小的多边形.像这样:

使用覆盖整个区域的大多边形来区分多边形将产生用于三角测量的多边形.可能还要等一下.结果如下:

最后,剔除所有太大的多边形:

#!/usr/bin/env python

import numpy as np

import matplotlib.pyplot as plt

import random

import scipy

import scipy.spatial

import networkx as nx

import shapely

import shapely.geometry

import matplotlib

dat = np.loadtxt('test.asc')

xycoors = dat[:,0:2]

xcoors = xycoors[:,0] #Convenience alias

ycoors = xycoors[:,1] #Convenience alias

npts = len(dat[:,0]) #Number of points

dist = scipy.spatial.distance.euclidean

def GetGraph(xycoors, alpha=0.0035):

kdt = scipy.spatial.KDTree(xycoors) #Build kd-tree for quick neighbor lookups

G = nx.Graph()

npts = np.max(xycoors.shape)

for x in range(npts):

G.add_node(x)

dist, idx = kdt.query(xycoors[x,:], k=10) #Get distances to neighbours, excluding the cenral point

dist = dist[1:] #Drop central point

idx = idx[1:] #Drop central point

pq = np.exp(-alpha*dist) #Exponential weighting of nearby points

pq = pq/np.sum(pq) #Convert to a PDF

choices = np.random.choice(idx, p=pq, size=50) #Choose neighbors based on PDF

for c in choices: #Insert neighbors into graph

if G.has_edge(x, c): #Already seen neighbor

G[x][c]['weight'] += 1 #Strengthen connection

else:

G.add_edge(x, c, weight=1) #New neighbor; build connection

return G

def PruneGraph(G,cutoff):

newg = G.copy()

bad_edges = set()

for x in newg:

for k,v in newg[x].items():

if v['weight']

bad_edges.add((x,k))

for b in bad_edges:

try:

newg.remove_edge(*b)

except nx.exception.NetworkXError:

pass

return newg

def PlotGraph(xycoors,G,cutoff=6):

xcoors = xycoors[:,0]

ycoors = xycoors[:,1]

G = PruneGraph(G,cutoff)

plt.plot(xcoors, ycoors, "o")

for x in range(npts):

for k,v in G[x].items():

plt.plot((xcoors[x],xcoors[k]),(ycoors[x],ycoors[k]), 'k-', lw=1)

plt.show()

def GetPolys(xycoors,G):

#Get lines connecting all points in the graph

xcoors = xycoors[:,0]

ycoors = xycoors[:,1]

lines = []

for x in range(npts):

for k,v in G[x].items():

lines.append(((xcoors[x],ycoors[x]),(xcoors[k],ycoors[k])))

#Get bounds of region

xmin = np.min(xycoors[:,0])

xmax = np.max(xycoors[:,0])

ymin = np.min(xycoors[:,1])

ymax = np.max(xycoors[:,1])

mls = shapely.geometry.MultiLineString(lines) #Bundle the lines

mlsb = mls.buffer(2) #Turn lines into narrow polygons

bbox = shapely.geometry.box(xmin,ymin,xmax,ymax) #Generate background polygon

polys = bbox.difference(mlsb) #Subtract to generate polygons

return polys

def PlotPolys(polys,area_cutoff):

fig, ax = plt.subplots(figsize=(8, 8))

for polygon in polys:

if polygon.area

mpl_poly = matplotlib.patches.Polygon(np.array(polygon.exterior), alpha=0.4, facecolor=np.random.rand(3,1))

ax.add_patch(mpl_poly)

ax.autoscale()

fig.show()

#Functional stuff starts here

G = GetGraph(xycoors, alpha=0.0035)

#Choose a value that rips off an appropriate amount of the left side of this histogram

weights = sorted([v['weight'] for x in G for k,v in G[x].items()])

plt.hist(weights, bins=20);plt.show()

PlotGraph(xycoors,G,cutoff=6) #Plot the graph to ensure our cut-offs were okay. May take a while

prunedg = PruneGraph(G,cutoff=6) #Prune the graph

polys = GetPolys(xycoors,prunedg) #Get polygons from graph

areas = sorted(p.area for p in polys)

plt.plot(areas)

plt.hist(areas,bins=20);plt.show()

area_cutoff = 150000

PlotPolys(polys,area_cutoff=area_cutoff)

good_polys = ([p for p in polys if p.area

total_area = sum([p.area for p in good_polys])



推荐阅读
author-avatar
骏天天在线
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有