【问题标题】:How to crop polygon to be within a rectangular region如何将多边形裁剪为矩形区域内
【发布时间】:2020-04-27 20:22:17
【问题描述】:

所以我有一个形状为(N, 2)numpy 多边形数组,我想对其进行裁剪,使其位于1 中看到的256x256 图像的范围内。也就是说,我想裁剪这个多边形,使其与256x256 区域内的黄色蒙版的边界相匹配;输出多边形的面积应与此遮罩等效,形状为(Mx2)

如图所示,我已经对多边形进行了光栅化以创建二进制掩码,使其位于256x256 的范围内。但是,我还想裁剪多边形,使其与二进制掩码的边界匹配。我怎样才能做到这一点?我正在考虑通过创建一个矩形多边形[(0,0), (0,256), (256,256), (256,0)] 来使用shapely,但是,我意识到我可能需要处理很多边缘情况:

  • 盒子与多边形相交,因此,我们想要得到相交的多边形
  • 盒子完全在多边形内,因此,输出盒子
  • 多边形完全在框内,因此,输出原始多边形
  • 交叉导致多个多边形,需要处理这个

也许编写一些代码来处理这一切并不是那么糟糕,但有没有某种库可以快速轻松地完成这件事?

【问题讨论】:

  • 您应该在问题中添加对边缘情况的描述,因为最明显的解决方案是按照您的建议使用 shapely。为了推荐替代品,我们都必须了解为什么您认为 shapely 不适合您的情况。
  • 更新了!但是,是的,也许匀称是我想的最简单的方法......只是想在我尝试这个之前检查是否有现成的东西。

标签: python computer-vision geometry polygon shapely


【解决方案1】:

Shapely 可以很好地解决您的问题。您的边缘案例是两个通用多边形相交的标准案例,您可以使用Polygon.intersection (link)。如果交叉点产生多个多边形,那么Polygon.intersection 只会给你一个MultiPolygon。下面举个例子来说明:

from shapely.geometry import Polygon
from shapely.affinity import scale,translate
import matplotlib.pyplot as plt
import numpy as np

# build squiggly polygon
theta=np.linspace(0,2*np.pi,100)
x=np.cos(theta)+0.1*np.sin(theta*10)
y=np.sin(theta)
A=Polygon(np.column_stack((x,y)))

# build a box
B=Polygon([[-.25,-1.5],[.25,-1.5],[.25,1.25],[-.25,1.25],[-.25,-1.5]])
# Intersection
C=A.intersection(B)
plt.subplot(2,2,1)
plt.plot(A.boundary.xy[0],A.boundary.xy[1],'k',label='A')
plt.plot(B.boundary.xy[0],B.boundary.xy[1],'b',label='B')
plt.plot(C.boundary.xy[0],C.boundary.xy[1],'--r',label='C')
plt.title('standard intersection')

# box in squiggly
B1=scale(B,0.5,0.5)
C=A.intersection(B1)
plt.subplot(2,2,2)
plt.plot(A.boundary.xy[0],A.boundary.xy[1],'k',label='A')
plt.plot(B1.boundary.xy[0],B1.boundary.xy[1],'b',label='B')
plt.plot(C.boundary.xy[0],C.boundary.xy[1],'--r',label='C')
plt.title('box in squiggly')

# squiggly in box
B1=scale(B,5,5)
C=A.intersection(B1)
plt.subplot(2,2,3)
plt.plot(A.boundary.xy[0],A.boundary.xy[1],'k',label='A')
plt.plot(B1.boundary.xy[0],B1.boundary.xy[1],'b',label='B')
plt.plot(C.boundary.xy[0],C.boundary.xy[1],'--r',label='C')
plt.title('squiggly in box')

# multipolygons
B1=translate(B,1.2,0)
C=A.intersection(B1)
plt.subplot(2,2,4)
plt.plot(A.boundary.xy[0],A.boundary.xy[1],'k',label='A')
plt.plot(B1.boundary.xy[0],B1.boundary.xy[1],'b',label='B')

for poly in C:
    plt.plot(poly.boundary.xy[0],poly.boundary.xy[1],'--r',label='C')

plt.title('multipolygons')
plt.show()

生成下图

【讨论】:

  • 谢谢!只是想知道,.boundary.exterior 有何不同?
猜你喜欢
  • 2023-03-20
  • 2011-09-08
  • 2015-10-18
  • 2011-11-10
  • 2013-04-04
  • 2020-08-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多