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



推荐阅读
  • Explore how Matterverse is redefining the metaverse experience, creating immersive and meaningful virtual environments that foster genuine connections and economic opportunities. ... [详细]
  • 本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ... [详细]
  • 本文探讨了如何在给定整数N的情况下,找到两个不同的整数a和b,使得它们的和最大,并且满足特定的数学条件。 ... [详细]
  • PyCharm下载与安装指南
    本文详细介绍如何从官方渠道下载并安装PyCharm集成开发环境(IDE),涵盖Windows、macOS和Linux系统,同时提供详细的安装步骤及配置建议。 ... [详细]
  • 技术分享:从动态网站提取站点密钥的解决方案
    本文探讨了如何从动态网站中提取站点密钥,特别是针对验证码(reCAPTCHA)的处理方法。通过结合Selenium和requests库,提供了详细的代码示例和优化建议。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 1.如何在运行状态查看源代码?查看函数的源代码,我们通常会使用IDE来完成。比如在PyCharm中,你可以Ctrl+鼠标点击进入函数的源代码。那如果没有IDE呢?当我们想使用一个函 ... [详细]
  • 前言--页数多了以后需要指定到某一页(只做了功能,样式没有细调)html ... [详细]
  • 本文深入探讨了 Java 中的 Serializable 接口,解释了其实现机制、用途及注意事项,帮助开发者更好地理解和使用序列化功能。 ... [详细]
  • Python自动化处理:从Word文档提取内容并生成带水印的PDF
    本文介绍如何利用Python实现从特定网站下载Word文档,去除水印并添加自定义水印,最终将文档转换为PDF格式。该方法适用于批量处理和自动化需求。 ... [详细]
  • 本文介绍了如何在C#中启动一个应用程序,并通过枚举窗口来获取其主窗口句柄。当使用Process类启动程序时,我们通常只能获得进程的句柄,而主窗口句柄可能为0。因此,我们需要使用API函数和回调机制来准确获取主窗口句柄。 ... [详细]
  • 本文详细解析了Python中的os和sys模块,介绍了它们的功能、常用方法及其在实际编程中的应用。 ... [详细]
  • 离线环境下的Python及其第三方库安装指南
    在项目开发中,有时会遇到电脑只能连接内网或完全无法联网的情况。本文将详细介绍如何在这种环境下安装Python及其所需的第三方库,确保开发工作的顺利进行。 ... [详细]
  • 本文介绍如何使用 Python 提取和替换 .docx 文件中的图片。.docx 文件本质上是压缩文件,通过解压可以访问其中的图片资源。此外,我们还将探讨使用第三方库 docx 的方法来简化这一过程。 ... [详细]
  • 本文详细介绍了Java中org.w3c.dom.Text类的splitText()方法,通过多个代码示例展示了其实际应用。该方法用于将文本节点在指定位置拆分为两个节点,并保持在文档树中。 ... [详细]
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社区 版权所有