Home > front end >  Is there any function or method to display clusters of mage after k means image segmentation?
Is there any function or method to display clusters of mage after k means image segmentation?

Time:01-07

import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('jelly.jpg') //reading the img
cv2.imshow(' img',img) //initial image
cv2.waitKey(0)

img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) // converting image to RGB

pixel_vals =img.reshape((-1,3)) //reshaping coloured 3d image to 2d image

pixel_vals = np.float32(pixel_vals)

criteria = (cv2.TERM_CRITERIA_EPS   cv2.TERM_CRITERIA_MAX_ITER,100,0.85) //setting criteria for kmeans

k= 5 //number of clusters

retval, labels, centers = cv2.kmeans(pixel_vals,k,None,criteria,10,cv2.KMEANS_RANDOM_CENTERS)


centers = np.uint8((centers))
segmented_data = centers[labels.flatten()]
segmented_img = segmented_data.reshape((img.shape)) //final image

cv2.imshow('K-means segmented img',segmented_img) // showing the final image after k means segmentation
cv2.waitKey(0)

cv2.destroyAllWindows() //destroying all window pop-up of images

I want to get only like violet part or brown part according to intensities. I have tried looking but i am not able to find any function. as there is a chance that the blue colour or any other colour is present in different shade. Is there a way to also get particular shade of different colours masking other areas ? enter image description here Original Image enter image description here K means segmented image

CodePudding user response:

I am not sure what you want to do because by your description you seem to want one thing and then by the title a completely different one. But I have segmented the parts you wanted.

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('jelly.png') 
plt.imshow(img)
plt.show()

img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) 

pixel_vals =img.reshape((-1,3))

pixel_vals = np.float32(pixel_vals)

criteria = (cv2.TERM_CRITERIA_EPS   cv2.TERM_CRITERIA_MAX_ITER,100,0.85)

k= 5

retval, labels, centers = cv2.kmeans(pixel_vals,k,None,criteria,10,cv2.KMEANS_RANDOM_CENTERS)


clustered_img = labels.reshape((img.shape[0], img.shape[1]))

clusters_to_0 = [1,2,4]

for c in clusters_to_0:
    clustered_img[clustered_img == c] = -1

clustered_img[clustered_img!=-1] = 1
clustered_img[clustered_img==-1] = 0

clustered_img
plt.imshow(clustered_img)
plt.show()

enter image description here

CodePudding user response:

I suggest another approach by transforming the image to the HSV channel and then thresholding the Hue channel since it contains the information about the tonality of the colours:

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('jelly.png') 

img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h,s,v = cv2.split(hsv)

(_, th) = cv2.threshold(h, 0, 1, cv2.THRESH_BINARY | cv2.THRESH_OTSU)

plt.subplot(131)
plt.imshow(img)
plt.title('Original image')
plt.subplot(132)
plt.imshow(h)
plt.title('Hue channels of the HSV color-space')
plt.subplot(133)
plt.imshow(th)
plt.title('Thresholded image')
plt.show()

enter image description here

  •  Tags:  
  • Related