I want to get the contours of every unique (none-zero) value, so basically this output:
[array([[1, 1],
[3, 2],
[3, 1]], dtype=int32),
array([[4, 2],
[4, 3],
[5, 3],
[5, 2]], dtype=int32),
array([[2, 4],
[3, 4]], dtype=int32)]
I can achieve this by converting the image into binary mask and then using cv2's findContours function, which get the output which I want.
import numpy as np
import cv2
img = np.array([
[0,0,0,0,0,0,0],
[0,1,1,1,0,0,0],
[0,0,1,1,2,2,0],
[0,0,0,0,2,2,0],
[0,0,3,3,0,0,0]
])
contour_list = []
for level in [l for l in np.unique(img) if l != 0]:
mask = (img == level).astype(np.uint8)
contours = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[-2]
contours[0] = cv2.approxPolyDP(contours[0], 0.5, True)
contours_xy = contours[0][:, 0]
contour_list.append(contours_xy)
contour_list
However, this approach is slow for large images with many unique levels. Is there a way to improve the speed of this function (without multiprocessing)? I feel like I'm overlooking some functionality.


