I used K-Means Clustering to perform segmentation on this traffic sign as shown below.

These are my code
Read image and blur
img = cv.imread('000_0001.png')
img_rgb = cv.cvtColor(img, cv.COLOR_BGR2RGB)
kernel_size = 5
img_rgb = cv.blur(img_rgb, (kernel_size, kernel_size))
# reshape
img_reshape = img_rgb.reshape((-1, 3))
img_reshape = np.float32(img_reshape)
Perform k-means clustering
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K = 4
attempts = 10
ret, label, center = cv.kmeans(img_reshape, K, None, criteria, attempts, cv.KMEANS_PP_CENTERS)
# reshape into original dimensions
center = np.uint8(center)
res = center[label.flatten()]
result = res.reshape(img_rgb.shape)
plt.figure(figsize = (15, 15))
plt.subplot(1, 2, 1)
plt.imshow(img_rgb)
plt.subplot(1, 2, 2)
plt.imshow(result)
plt.show()
create masks
from numpy import linalg as LN
red = (255, 0, 0)
Idx_min_red = np.argmin(LN.norm(center-red, axis = 1))
white = (255, 255, 255)
Idx_min_white = np.argmin(LN.norm(center-white, axis = 1))
black = (0, 0, 0)
Idx_min_black = np.argmin(LN.norm(center-black, axis = 1))
mask_red = result == center[Idx_min_red]
mask_white = result == center[Idx_min_white]
mask_black = result == center[Idx_min_black]
pre_mask = cv.bitwise_or(np.float32(mask_red), np.float32(mask_white))
mask = cv.bitwise_or(np.float32(pre_mask), np.float32(mask_black))
Segment the image
seg_img = img*(mask.astype("uint8"))
Morphological Transformation
kernel = np.ones((5, 5), dtype = np.uint8)
img_dilate = cv.morphologyEx(seg_img, cv.MORPH_OPEN, kernel)
res = np.hstack((img, img_dilate))
cv.imshow("res", res)
cv.waitKey(0)
cv.destroyAllWindows()
Question here These codes can only segment red traffic signs, is it possible to tweak a little bit on different colours so that it can segment red, blue and yellow traffic signs? (like the one below for example)
Update, this is what I have tried:
I used a pipeline to do OR operation on all the masks
mask = mask_red | mask_white | mask_black | mask_blue



