如何在Python中检测外部模块中的崩溃?

时间:2015-08-17 20:57:34

标签: python crash triangulation delaunay

我正在使用Triangle模块生成受约束的Delaunay三角剖分(可在http://www.lfd.uci.edu/~gohlke/pythonlibs/处获得)。在某些情况下,函数triangle.triangulate崩溃,窗口说'Python.exe已停止响应'。我尝试过使用try / except结构,如下例所示,它不一致地崩溃。我假设三角测量过程的一部分是随机的(参见下面的“第二个问题”),但我并不完全确定。

不一致是相当令人担忧的。我在Windows上。

from shapely.geometry import Polygon, MultiPolygon, LineString

import numpy as np
import triangle
import matplotlib.pyplot as plt
import matplotlib.tri as tri
import random

def meshXOR(polyRef, shape, otherVerts, otherSegs, otherHole):

    verts = []
    verts3 = []
    segs = []
    outerLength = len(polyRef[shape[0]])

    for i in range(outerLength-1):#-1 because xorpoly duplicates first point into last spot
        verts.append((polyRef[shape[0]][i][0],polyRef[shape[0]][i][1])) #append the point to the verts array which will be fed into the delaunay triangulator
        if i == outerLength - 2:
            segs.append([i,0])
        else:
            segs.append([i,i+1])

    h = []
    for cInd in shape[1]:
        shift = len(verts)
        innerLength = len(polyRef[cInd])
        for i in range(innerLength-1):
            verts.append((polyRef[cInd][i][0],polyRef[cInd][i][1]))
            if i == innerLength - 2:
                segs.append([i+shift,shift])
            else:
                segs.append([i+shift,i+1+shift])
        h += list(Polygon(polyRef[cInd]).representative_point().coords)
    print 'verts are: ', verts
    #output: verts are:  [(0.0, 5.0), (0.0, 10.0), (10.0, 10.0), (10.0, 0.0), (0.0, 0.0), (0.0, 5.0), (7.0, 3.0), (7.0, 7.0)]
    print 'segs are: ', segs
    #output: segs are:  [[0, 1], [1, 2], [2, 3], [3, 4], [4, 0], [5, 6], [6, 7], [7, 5]]
    print 'holes are: ', h
    #output: holes are:  [(5.25, 6.0)]

    print 'verts: ', verts == otherVerts
    print 'segs: ', segs == otherSegs
    print 'hole: ', h == otherHole

    return verts, segs, h



pA = Polygon([[0.0,0.0],[10.0,0.0],[10.0,10.0],[0.0,10.0]])
pB = Polygon([[0.0,5.0],[7.0,3.0],[7.0,7.0]])

xorPoly = pA.symmetric_difference(pB)

if xorPoly.geom_type == 'Polygon': xorPoly = MultiPolygon([xorPoly])

otherVerts = [(0.0, 5.0), (0.0, 10.0), (10.0, 10.0), (10.0, 0.0), (0.0, 0.0), (0.0, 5.0), (7.0, 3.0), (7.0, 7.0)]
otherSegs = [[0, 1], [1, 2], [2, 3], [3, 4], [4, 0], [5, 6], [6, 7], [7, 5]]
otherHole = [(5.25,6.0)]
xorPolys = []                                               
shapes = []                                                 
for poly in xorPoly:                                                    
    shapes.append([len(xorPolys), [], len(shapes)])
    xorPolys.append(list(poly.exterior.coords))
    for ip in poly.interiors:
        shapes[-1][1].append(len(xorPolys))
        xorPolys.append(list(ip.coords))

try:
    verts, segs, holes = meshXOR(xorPolys, shapes[0], otherVerts, otherSegs, otherHole) # i even tried placing it here
except:
    print 'failed'

if len(holes)>0:
    A  = dict(vertices = np.asarray(verts), segments = np.asarray(segs), holes = holes)
else:
    A  = dict(vertices = np.asarray(verts), segments = np.asarray(segs))

print 'about to tri'
B = triangle.triangulate(A, opts = 'pi') #this is the step that try/except doesn't work on
print 'completed tri'
try:
    B_t = B["triangles"].tolist()
except:
    print 'no trianlges'

if B_t != []:
    cols = []
    import random
    for tri in B_t:
        cols.append(random.random())
    plt.figure()
    plt.gca().set_aspect('equal')
    xy = np.asarray(verts)
    plt.tripcolor(xy[:,0], xy[:,1], B_t, facecolors=np.array(cols))
    #for tri in B_t:
        #print 'tri is: ', [verts[t] for t in tri]
    plt.show()
else:
    print 'no triangles'

我的问题:有没有办法做一些像'Try / Except'结构来捕捉这个错误?或者,我是否对三角模块做错了什么?

编辑:

解决方案:来自 Gamrix的响应的引用会导致解决方案。如果点之间的差异太小(欧氏距离),则三角函数会崩溃。删除小于1e-12的点数可以解决问题。

3 个答案:

答案 0 :(得分:1)

根据您描述的行为,似乎外部代码陷入死锁或无限循环。没有办法在用户端捕获这个,没有产生额外的线程,如果进程花费太长时间就会杀死当前线程。

然而,即使这样也无法真正解决您所面临的问题。我查看了三角形库(python版本只是我链接的版本的包装),我在网站上发现了以下内容。仔细阅读它,看看它是否解释了您的问题发生的原因:

  

三角形不会终止,或者只是崩溃:

     

当三角形变得如此之小以至于距离时,会发生不好的事情   它们的顶点之间的精度并不比你的精度大很多   机器的算术。如果您已经为单精度编译了Triangle   算术,你可以通过重新编译来做得更好   双精度。然后,你可能只需要满足更多   对你的最小角度和最大面积的宽松约束   已经计划好了。

     

您可以通过确保原点所在来最小化精度问题   在您的顶点集内,或甚至在网格的最密集部分内。   如果你正在对一个x坐标都介于其间的对象进行三角测量   6247133和6247134,你没有留下太多的浮点精度   让Triangle合作。

     

如果输入PSLG包含两个,则可能会隐蔽地发生精度问题   以极端角度相交(或交叉)的部分,或者如果这样的话   角度由-c开关引入。如果你没有意识到这一点   角度正在形成,你可能永远不会发现为什么三角形   崩溃。要检查这种可能性,请使用-S开关(带有   找到的Steiner点数量的适当限制   试错了)提前停止Triangle,并查看输出.poly   文件显示我。仔细查看密集簇的区域   顶点正在形成,并且对于段之间的小角度。放大   密切关注,因为这些细分可能看起来像一个细分市场   距离。

     

如果某些输入值太大,Triangle可能会受到影响   尝试执行时由于溢出而导致的浮动异常   定向或外围测试。 (阅读有关精确算术的部分。)   再次,我建议将Triangle编译为double(而不是单个)   精确算术。

     

如果使用质量网格划分(-q,-a或。),则会出现意外问题   -u)输入不是段限制的 - 也就是说,如果您的输入是顶点集,或者您正在使用-c开关。如果凸壳   输入顶点在其边界上有一个共线顶点,一个输入   你认为位于凸壳上的顶点实际上可能只是谎言   在凸壳内。如果是这样,则形成一个极薄的三角形   它旁边的顶点和凸包边缘。当三角试图   细化网格以强制角度和区域约束,非常小   可以形成三角形,或者三角形可能由于不足而失败   浮点精度

http://www.cs.cmu.edu/~quake/triangle.trouble.html

答案 1 :(得分:0)

您所做的似乎已将错误本地化。如果它确实打印了即将到来的三个'然后在打印完成之前崩溃,看起来它会在三角形中崩溃。三角形。该函数因引发异常而崩溃。在那种情况下,我唯一能想到的就是用调试器逐步完成代码,并试着看看发生了什么。它可能与您的代码无关。看看这篇文章:Random "pythonw.exe has stopped working" crashing有没有办法在非Windows系统上运行此代码来测试它是否实际上是一个Windows问题?

答案 2 :(得分:0)

我对该库也遇到了一些问题,我试图对具有完美对齐点的多边形进行三角剖分。 我通过向输入顶点添加轻微的随机偏差来解决此问题,例如np.random.random([nvert,2])* 0.00001