热门标签 | 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])



推荐阅读
  • 本文详细介绍了Java中org.w3c.dom.Text类的splitText()方法,通过多个代码示例展示了其实际应用。该方法用于将文本节点在指定位置拆分为两个节点,并保持在文档树中。 ... [详细]
  • 本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ... [详细]
  • Docker的安全基准
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • Explore how Matterverse is redefining the metaverse experience, creating immersive and meaningful virtual environments that foster genuine connections and economic opportunities. ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 本文详细探讨了Java中的24种设计模式及其应用,并介绍了七大面向对象设计原则。通过创建型、结构型和行为型模式的分类,帮助开发者更好地理解和应用这些模式,提升代码质量和可维护性。 ... [详细]
  • 本文深入探讨了 Java 中的 Serializable 接口,解释了其实现机制、用途及注意事项,帮助开发者更好地理解和使用序列化功能。 ... [详细]
  • Android 渐变圆环加载控件实现
    本文介绍了如何在 Android 中创建一个自定义的渐变圆环加载控件,该控件已在多个知名应用中使用。我们将详细探讨其工作原理和实现方法。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • ImmutableX Poised to Pioneer Web3 Gaming Revolution
    ImmutableX is set to spearhead the evolution of Web3 gaming, with its innovative technologies and strategic partnerships driving significant advancements in the industry. ... [详细]
  • 本文探讨了如何优化和正确配置Kafka Streams应用程序以确保准确的状态存储查询。通过调整配置参数和代码逻辑,可以有效解决数据不一致的问题。 ... [详细]
  • 本文介绍如何使用阿里云的fastjson库解析包含时间戳、IP地址和参数等信息的JSON格式文本,并进行数据处理和保存。 ... [详细]
  • 本题通过将每个矩形视为一个节点,根据其相对位置构建拓扑图,并利用深度优先搜索(DFS)或状态压缩动态规划(DP)求解最小涂色次数。本文详细解析了该问题的建模思路与算法实现。 ... [详细]
  • 本文介绍了如何通过配置 Android Studio 和 Gradle 来显著提高构建性能,涵盖内存分配优化、并行构建和性能分析等实用技巧。 ... [详细]
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社区 版权所有