[英]How to convert NumPy arrays obtained from cv2.findContours to Shapely polygons?
I am using CV2 to find contours from an image and then converting them into polygons using Shapely. 我正在使用CV2从图像中查找轮廓,然后使用Shapely将其转换为多边形。 I am currently stuck because when I try putting one of the contour arrays into
Polygon()
from Shapely it throws an unspecified error. 我目前陷入困境,因为当我尝试将一个轮廓数组从Shapely放入
Polygon()
,会引发未指定的错误。
I have double-checked that I imported everything I needed, and that creating a Shapely polygon works when I manually enter the array coordinate points. 我已经仔细检查了是否导入了我需要的所有内容,以及当我手动输入数组坐标点时创建Shapely多边形的工作原理。
Here is the problematic section of the code: 这是代码中有问题的部分:
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
testcontour = contours[1]
ply = Polygon(testcontour)
Where the list of contours looks like this: 轮廓列表如下所示:
contours = [np.array([[[700, 700]],
[[700, 899]],
[[899, 899]],
[[899, 700]]]),
np.array([[[774, 775]],
[[775, 774]],
[[824, 774]],
[[825, 775]],
[[825, 824]],
[[824, 825]],
[[775, 825]],
[[774, 824]]]),
np.array([[[200, 200]],
[[200, 399]],
[[399, 399]],
[[399, 200]]]),
np.array([[[274, 275]],
[[275, 274]],
[[324, 274]],
[[325, 275]],
[[325, 324]],
[[324, 325]],
[[275, 325]],
[[274, 324]]])]
The error I get is: 我得到的错误是:
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-65-4124f49b42e1> in <module>
----> 1 ply = Polygon(testcontour)
~\AppData\Local\Continuum\anaconda3\envs\geocomp\lib\site-packages\shapely\geometry\polygon.py in __init__(self, shell, holes)
238
239 if shell is not None:
--> 240 ret = geos_polygon_from_py(shell, holes)
241 if ret is not None:
242 self._geom, self._ndim = ret
~\AppData\Local\Continuum\anaconda3\envs\geocomp\lib\site-packages\shapely\geometry\polygon.py in geos_polygon_from_py(shell, holes)
492
493 if shell is not None:
--> 494 ret = geos_linearring_from_py(shell)
495 if ret is None:
496 return None
~\AppData\Local\Continuum\anaconda3\envs\geocomp\lib\site-packages\shapely\speedups\_speedups.pyx in shapely.speedups._speedups.geos_linearring_from_py()
AssertionError:
The problem is that for some reason cv2.findContours
returns each contour as a 3D NumPy array with one redundant dimension: 问题是由于某种原因
cv2.findContours
将每个轮廓作为具有一个冗余尺寸的3D NumPy数组返回:
>>> contours[1]
array([[[774, 775]],
[[775, 774]],
[[824, 774]],
[[825, 775]],
[[825, 824]],
[[824, 825]],
[[775, 825]],
[[774, 824]]])
but Shapely expects a 2D array in this form ( see the docs ): 但Shapely希望采用这种形式的2D数组( 请参阅docs ):
array([[774, 775],
[775, 774],
[824, 774],
[825, 775],
[825, 824],
[824, 825],
[775, 825],
[774, 824]])
So, what we can do is to use np.squeeze
to remove that redundant dimension, and use the result to obtain our polygon: 因此,我们可以做的是使用
np.squeeze
删除该多余的尺寸,并使用结果获得多边形:
import numpy as np
from shapely.geometry import Polygon
contour = np.squeeze(contours[1])
polygon = Polygon(contour)
print(polygon.wkt)
# POLYGON ((774 775, 775 774, 824 774, 825 775, 825 824, 824 825, 775 825, 774 824, 774 775))
In case if you want to convert all of the contours at once, I would do it like this: 如果您想一次转换所有轮廓,我会这样做:
contours = map(np.squeeze, contours) # removing redundant dimensions
polygons = map(Polygon, contours) # converting to Polygons
multipolygon = MultiPolygon(polygons) # putting it all together in a MultiPolygon
The resulting multipolygon
will look like this: 产生的
multipolygon
将如下所示:
And to get the second polygon from here you would just write: 要从此处获取第二个多边形,您只需编写:
my_polygon = multipolygon[1]
print(my_polygon.wkt)
# POLYGON ((774 775, 775 774, 824 774, 825 775, 825 824, 824 825, 775 825, 774 824, 774 775))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.