###前提・実現したいこと
Pythonでクラスタリングを勉強しています。
コードはhttps://github.com/joelgrus/data-science-from-scratch/blob/master/code/clustering.pyのを使用しています。
実現したいことは、画像の色にクラスタリングをかけて少ない色で画像を表示させたいです。
コード中ではK=5となっているので画像の色を5色で表現したいです。
現在は処理を行うと真っ黒の画像が表示させてしまいます。
mpimg.imreadが画像を配列にしているのはわかったのですがその後、どのような処理が行われているのかも教えていただきたいです。
###発生している問題・エラーメッセージ
画像を指定して実行したみたのですがoverflowとなってしまい結果が出力されません。
またどのように改良すれば良いのかわからず困っています。
/Users/Desktop/Python19-5.py:35: RuntimeWarning: overflow encountered in ubyte_scalars return sum(v_i * w_i for v_i, w_i in zip(v, w)) /Users/Desktop/Python19-5.py:18: RuntimeWarning: overflow encountered in ubyte_scalars return [v_i - w_i for v_i, w_i in zip(v,w)] /Users/Desktop/Python19-5.py:14: RuntimeWarning: overflow encountered in ubyte_scalars return [v_i + w_i for v_i, w_i in zip(v,w)]
###該当のソースコード
Python
1from __future__ import division 2import math, random 3from functools import reduce 4import re, math, random 5from collections import defaultdict, Counter 6import matplotlib.pyplot as plt 7import matplotlib.image as mpimg 8# 9# functions for working with vectors 10# 11 12def vector_add(v, w): 13 """adds two vectors componentwise""" 14 return [v_i + w_i for v_i, w_i in zip(v,w)] 15 16def vector_subtract(v, w): 17 """subtracts two vectors componentwise""" 18 return [v_i - w_i for v_i, w_i in zip(v,w)] 19 20def vector_sum(vectors): 21 return reduce(vector_add, vectors) 22 23def scalar_multiply(c, v): 24 return [c * v_i for v_i in v] 25 26# this isn't right if you don't from __future__ import division 27def vector_mean(vectors): 28 """compute the vector whose i-th element is the mean of the 29 i-th elements of the input vectors""" 30 n = len(vectors) 31 return scalar_multiply(1/n, vector_sum(vectors)) 32 33def dot(v, w): 34 """v_1 * w_1 + ... + v_n * w_n""" 35 return sum(v_i * w_i for v_i, w_i in zip(v, w)) 36 37def sum_of_squares(v): 38 """v_1 * v_1 + ... + v_n * v_n""" 39 return dot(v, v) 40 41def magnitude(v): 42 return math.sqrt(sum_of_squares(v)) 43 44def squared_distance(v, w): 45 return sum_of_squares(vector_subtract(v, w)) 46 47def distance(v, w): 48 return math.sqrt(squared_distance(v, w)) 49 50class KMeans: 51 def __init__(self, k): 52 self.k = k # CLUSTERの数 53 self.means = None # 各CLUSTERの重心 54 55 def classify(self, input): 56 # 入力されたノードのに一番近いCLUSTERの番号(0~k)を返す 57 return min(range(self.k), 58 key=lambda i: squared_distance(input, self.means[i])) 59 60 def train(self, inputs): 61 # 各CLUSTERの重心をランダムに選出 62 self.means = random.sample(inputs, self.k) 63 # 各ノードがどのCLUSTERに属しているかのリストを初期化 64 assignments = None 65 66 while True: 67 # 各ノードがどのCLUSTERに属しているかのリストを作成 68 new_assignments = list(map(self.classify, inputs)) 69 70 # 上記の所属CLUSTERリストが変更していなかったら終了 71 if assignments == new_assignments: 72 return 73 74 # 上記の所属CLUSTERリストを保持 75 assignments = new_assignments 76 77 # CLUSTER番号毎に重心を算出する処理を行う 78 for i in range(self.k): 79 # CLUSTER(i)に属しているノードリストを抽出 80 i_points = [p for p, a in zip(inputs, assignments) if a == i] 81 # 上のCLUSTER(i)のノードリストからCLUSTERの重心を算出 82 if i_points: 83 self.means[i] = vector_mean(i_points) 84 85 86# using clustering to recolor an image 87# 88 89def recolor_image(input_file, k=5): 90 91 path_to_png_file = r"画像のある場所" 92 img = mpimg.imread(path_to_png_file) 93 top_row = img[0] 94 top_left_pixel = top_row[0] 95 red, green, blue = top_left_pixel 96 pixels = [pixel for row in img for pixel in row] 97 clusterer = KMeans(k) 98 clusterer.train(pixels) # this might take a while 99 100 def recolor(pixel): 101 cluster = clusterer.classify(pixel) # index of the closest cluster 102 return clusterer.means[cluster] # mean of the closest cluster 103 104 new_img = [[recolor(pixel) for pixel in row] 105 for row in img] 106 107 plt.imshow(new_img) 108 plt.axis('off') 109 plt.show() 110 111recolor_image("IMG_2155.jpg")
###補足情報(言語/FW/ツール等のバージョンなど)
Python3.5
「真っ黒の画像が表示」との事ですが、その画像で使われている色は何種類ありますか?
回答1件
あなたの回答
tips
プレビュー