1

I try to use cv2.kmeans to segment the left auricle DICOM image as mask.

enter image description here

I use the following code to do the k-means binary clustering in OpenCV.

import numpy as np
import cv2
import os
from matplotlib import pyplot as plt

img = cv2.imread('1_LA.jpg')
img2 = img.reshape((-1, 3))
img2 = np.float32(img2)

criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
ret, label, center = cv2.kmeans(img2, 2, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
center = np.uint8(center)

res = center[label.flatten()]
res2 = res.reshape((img.shape))
cv2.imwrite('1_LA_kmeans.jpg', res2)

Then, I can get this segmentation result well.

enter image description here

But how can I extract one of the segmentations as mask?

I have referred other similar questions, and I try to use the code from here.

import numpy as np
import cv2

img = cv2.imread('1_LA.jpg')
Z = np.float32(img.reshape((-1,3)))

criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K = 2
_,labels,centers = cv2.kmeans(Z, K, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
labels = labels.reshape((img.shape[:-1]))
reduced = np.uint8(centers)[labels]
result = [np.hstack([img, reduced])]

for i, c in enumerate(centers):
    mask = cv2.inRange(labels, i, i)
    mask = np.dstack([mask]*3) # Make it 3 channel
    ex_img = cv2.bitwise_and(img, mask)
    ex_reduced = cv2.bitwise_and(reduced, mask)
    result.append(np.hstack([ex_img, ex_reduced]))
    cv2.imwrite('kmeans/' + str(i) + '_1.jpg', np.vstack(result))

cv2.imwrite('1_LA_kmeans.jpg', np.vstack(result))

Then, I can get this output.

enter image description here

Becase I want to calculate the area of the left auricle, I need to extract the mask like below.

enter image description here

So, how can I extract one of the binary segmentation results?

Amit Joshi
  • 15,448
  • 21
  • 77
  • 141
TseHsien
  • 73
  • 8
  • 2
    Perhaps see https://stackoverflow.com/questions/70603461/is-there-any-function-or-method-to-display-clusters-of-mage-after-k-means-image/70616126#70616126 – fmw42 Jul 03 '22 at 01:24

1 Answers1

1

Thanks for @fmw42's help.

After I refer this answer, and use the following code.

import cv2
import numpy as np

# read input and convert to range 0-1
image = cv2.imread('1.jpg')
h, w, c = image.shape

# reshape to 1D array
image_2d = image.reshape(h*w, c).astype(np.float32)

# set number of colors
numcolors = 2
numiters = 10
epsilon = 1
attempts = 10

# do kmeans processing
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, numiters, epsilon)
ret, labels, centers = cv2.kmeans(image_2d, numcolors, None, criteria, attempts, cv2.KMEANS_RANDOM_CENTERS)

# reconstitute 2D image of results
centers = np.uint8(centers)
newimage = centers[labels.flatten()]
newimage = newimage.reshape(image.shape)
#cv2.imwrite("1_test.jpg", newimage)
#cv2.imshow('new image', newimage)
#cv2.waitKey(0)

k = 0
for center in centers:
    # select color and create mask
    #print(center)
    layer = newimage.copy()
    mask = cv2.inRange(layer, center, center)

    # apply mask to layer 
    layer[mask == 0] = [0,0,0]
    #cv2.imshow('layer', layer)
    #cv2.waitKey(0)

    # save kmeans clustered image and layer 
    if(k == 0):
        cv2.imwrite("1_test{0}.jpg".format(k), layer)
    k = k + 1

I can extract the mask I want, appreciate.

enter image description here

TseHsien
  • 73
  • 8