Given a simple binary mask (e.g. the boundary of a rectangle).

How can I use a polygon to get the x-y coordinates?
This is what I have tried so far:
coords = np.transpose(np.nonzero(mask))
However, this approach generates a filled object and not the desired boundary.
plt.plot(coords[:, 1], coords[:,0])

Basically, I want a list of x-y coordinates of the white pixels to use this list to re-draw the rectangle (not filled).
Using cv2.findContours works both for complex shapes and multiple objects. Polygons list contains coords lists each looking like this [x1, y1, x2, y2, x3, y3, ...].
contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
polygons = []
for obj in contours:
coords = []
for point in obj:
coords.append(int(point[0][0]))
coords.append(int(point[0][1]))
polygons.append(coords)
You can use np.column_stack() + np.where(). The idea is to determine the white pixels in the binary image then order then in corresponding (x, y) order
coords = np.column_stack(np.where(image > 0))
Another way is to find the coordinates of the bounding rectangle using OpenCV's cv2.boundingRect(). This will give you the width, height, and top-left (x,y) coordinates. Here's an example finding the coordinates then drawing the polygon onto a blank mask

import cv2
import numpy as np
image = cv2.imread('1.png', 0)
x,y,w,h = cv2.boundingRect(image)
mask = np.ones(image.shape, dtype=np.uint8) * 255
mask = cv2.merge([mask,mask,mask])
cv2.rectangle(mask, (x, y), (x + w, y + h), (36,255,12), 2)
cv2.imshow('mask', mask)
cv2.waitKey()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With