Я делаю сегментацию опухоли головного мозга, используя кластеризацию k-средних, и вот код, который я использую, чтобы сделать это.
from PIL import Image, ImageStat
import numpy
def converged(centroids, old_centroids):
if len(old_centroids) == 0:
return False
if len(centroids) <= 5:
a = 1
elif len(centroids) <= 10:
a = 2
else:
a = 4
for i in range(0, len(centroids)):
cent = centroids[i]
old_cent = old_centroids[i]
if ((int(old_cent[0]) - a) <= cent[0] <= (int(old_cent[0]) + a)) and (
(int(old_cent[1]) - a) <= cent[1] <= (int(old_cent[1]) + a)) and (
(int(old_cent[2]) - a) <= cent[2] <= (int(old_cent[2]) + a)):
continue
else:
return False
return True
# Method used to find the closest centroid to the given pixel.
def getMin(pixel, centroids):
minDist = 9999
minIndex = 0
for i in range(0, len(centroids)):
d = numpy.sqrt(int((centroids[i][0] - pixel[0])) ** 2 + int((centroids[i][1] - pixel[1])) ** 2 + int(
(centroids[i][2] - pixel[2])) ** 2)
if d < minDist:
minDist = d
minIndex = i
return minIndex
# Assigns each pixel to the given centroids for the algorithm.
# Method finds the closest centroid to the given pixel, then
# assigns that centroids to the pixel.
def assignPixels(centroids):
clusters = {}
for x in range(0, img_width):
for y in range(0, img_height):
p = px[x, y]
minIndex = getMin(px[x, y], centroids)
try:
clusters[minIndex].append(p)
except KeyError:
clusters[minIndex] = [p]
return clusters
# Method is used to re-center the centroids according
# to the pixels assigned to each. A mean average is
# applied to each cluster's RGB values, which is then
# set as the new centroids.
def adjustCentroids(centroids, clusters):
new_centroids = []
keys = sorted(clusters.keys())
# print(keys)
for k in keys:
n = numpy.mean(clusters[k], axis=0)
new = (int(n[0]), int(n[1]), int(n[2]))
print(str(k) + ": " + str(new))
new_centroids.append(new)
return new_centroids
# Used to initialize the k-means clustering
def startKmeans(someK):
centroids = []
old_centroids = []
rgb_range = ImageStat.Stat(im).extrema
i = 1
# Initializes someK number of centroids for the clustering
for k in range(0, someK):
cent = px[numpy.random.randint(0, img_width), numpy.random.randint(0, img_height)]
centroids.append(cent)
print("Centroids Initialized. Starting Assignments")
print("===========================================")
while not converged(centroids, old_centroids) and i <= 20:
print("Iteration #" + str(i))
i += 1
old_centroids = centroids # Make the current centroids into the old centroids
clusters = assignPixels(centroids) # Assign each pixel in the image to their respective centroids
centroids = adjustCentroids(old_centroids,
clusters) # Adjust the centroids to the center of their assigned pixels
print("===========================================")
print("Convergence Reached!")
print(centroids)
return centroids
# Once the k-means clustering is finished, this method
# generates the segmented image and opens it.
def drawWindow(result):
img = Image.new('RGB', (img_width, img_height), "white")
p = img.load()
for x in range(img.size[0]):
for y in range(img.size[1]):
RGB_value = result[getMin(px[x, y], result)]
p[x, y] = RGB_value
img.show()
num_input = str(input("Enter image number: "))
k_input = int(input("Enter K value: "))
img = "img/test" + num_input.zfill(2) + ".jpg"
im = Image.open(img)
img_width, img_height = im.size
px = im.load()
result = startKmeans(k_input)
drawWindow(result)
Я хочу ввести и изображение, и число кластеры, чтобы я мог получить правильную сегментацию опухоли. Это было реализовано в коде, упомянутом выше. Но когда я даю номер изображения и количество кластеров, это выдает ошибку, подобную следующей.
Enter image number: >? 01
Enter K value: >? 02
Centroids Initialized. Starting Assignments
===========================================
Iteration #1
Traceback (most recent call last):
File "C:\Users\Lahiru Gayanga\AppData\Roaming\Python\Python37\site-packages\IPython\core\interactiveshell.py", line 3319, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-2-8dce0adb6c87>", line 1, in <module>
runfile('C:/Users/Lahiru Gayanga/Documents/FYP/thale/k-means/kmeans.py', wdir='C:/Users/Lahiru Gayanga/Documents/FYP/thale/k-means')
File "C:\Program Files\JetBrains\PyCharm 2019.1.3\plugins\python\helpers\pydev\_pydev_bundle\pydev_umd.py", line 197, in runfile
pydev_imports.execfile(filename, global_vars, local_vars) # execute the script
File "C:\Program Files\JetBrains\PyCharm 2019.1.3\plugins\python\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "C:/Users/Lahiru Gayanga/Documents/FYP/thale/k-means/kmeans.py", line 134, in <module>
result = startKmeans(k_input)
File "C:/Users/Lahiru Gayanga/Documents/FYP/thale/k-means/kmeans.py", line 103, in startKmeans
clusters = assignPixels(centroids) # Assign each pixel in the image to their respective centroids
File "C:/Users/Lahiru Gayanga/Documents/FYP/thale/k-means/kmeans.py", line 55, in assignPixels
minIndex = getMin(px[x, y], centroids)
File "C:/Users/Lahiru Gayanga/Documents/FYP/thale/k-means/kmeans.py", line 37, in getMin
d = numpy.sqrt(int((centroids[i][0] - pixel[0])) ** 2 + int((centroids[i][1] - pixel[1])) ** 2 + int(
TypeError: 'int' object is not subscriptable
Я хотел знать, как решить эту проблему, и есть ли лучший способ ввода изображения и числа кластеров в систему.