gebbissimo
gebbissimo

Reputation: 2659

cv2.fillConvexPoly and cv2.polylines yield different edges?

After drawing adjacent filled polygons with cv2.fillConvexPoly, edges between the polygons are drawn using cv2.polylines

Expected behavior: The edges nicely fit in between two drawn polygons

Actual behavior: Some edges actually lie inside one polygon! (see picture below)

enter image description here

Code to reproduce

# params
h,w = 20,30
points_yx = [(5, 1), (7, 22), (16, 13)]
points_xy = [(x,y) for y,x in points_yx]

# create voronoi partitiion
rect = (0, 0, w,h)
subdiv = cv2.Subdiv2D(rect)
subdiv.insert(points_xy)
polygons, centers = subdiv.getVoronoiFacetList([])
polygons_int = [np.round(poly).astype(np.int) for poly in polygons]

# draw voronoi polygons on image
img = np.zeros((h, w))
for i, poly in enumerate(polygons_int):
    color = i + 1
    cv2.fillConvexPoly(img, poly, color=color, lineType=cv2.LINE_8)
    x,y = points_xy[i]
    img[y, x] = 0

# draw borders of polygons
cv2.polylines(img, polygons_int, isClosed=False, color=0, thickness=0,
              lineType=cv2.LINE_8)

# plot
fig, ax = plt.subplots(1, 1)
ax.imshow(img, interpolation=None)
plt.show()

Upvotes: 0

Views: 1166

Answers (1)

gebbissimo
gebbissimo

Reputation: 2659

Ok, at least one solution is to use cv2.drawContours for drawing the filled polygons as well as the polygon edges:

# params
h,w = 20,30
points_yx = [(5, 1), (7, 22), (16, 13)]
points_xy = [(x,y) for y,x in points_yx]

# create voronoi partitiion
rect = (0, 0, w,h)
subdiv = cv2.Subdiv2D(rect)
subdiv.insert(points_xy)
polygons, centers = subdiv.getVoronoiFacetList([])
polygons_int = [np.round(poly).astype(np.int) for poly in polygons]

# draw voronoi on image
img = np.zeros((h, w))
for i, poly in enumerate(polygons_int):
    cv2.drawContours(img, [poly], contourIdx=-1, color=i+1, thickness=cv2.FILLED)
    x,y = points_xy[i]
    img[y, x] = 0

# draw borders of polygons
cv2.drawContours(img, polygons_int, contourIdx=-1, color=0, thickness=0)

# plot
fig, ax = plt.subplots(1, 1)
ax.imshow(img, interpolation=None)
plt.show()

enter image description here

Upvotes: 1

Related Questions