11-4ColorSeparation.py

000: import cv2
001: import numpy as np
002: import copy
003:
004: def __main():
005: global K_NUMBERS;
006: img = cv2.imread(“IMG_1200.JPG”)
007: img = getResize(img)
008:
009: colors = img.reshape(-1, 3) # 画像内の色一覧を配列に格納
010: colors = colors.astype(np.float32) # cv2.kmeans に渡すデータは float 型のため、キャスト
011: # K_NUMBERS = クラスタ数
012: # 最大反復回数: 10、要求される精度: 1.0
013: criteria = cv2.TERM_CRITERIA_MAX_ITER + cv2.TERM_CRITERIA_EPS, 10, 1.0
014: # 減色 (この処理は数秒かかる)
015: _, labels, center = cv2.kmeans(data=colors, K=K_NUMBERS, bestLabels=None, criteria=criteria, attempts=10, flags=cv2.KMEANS_RANDOM_CENTERS, centers=None)
016: _, colorWait = np.unique(labels, axis=0, return_counts=True) # 各クラスタに属するサンプル数を計算
017:
018: # 各画素を k平均法の結果に置き換える。
019: dst = center[labels.ravel()].reshape(img.shape)
020: dst = dst.astype(np.uint8)
021: BubbleSort(colorWait, center)
022:
023: cv2.imshow(“SEP”, dst)
024: cv2.imshow(“ORG”, img)
025: cv2.waitKey(0)
026: cv2.destroyAllWindows()
027:
028: # 減色した色の比率バーを作成する
029: def setColorBar(colorWait, center):
030: size = (100, 400, 3)
031: img = np.zeros(size, dtype=np.uint8)
032: cv2.rectangle(img, (0, 0), (size[1], size[0]), (255, 255, 255), -1)
033: totalPixels = 0
034: next_x = 0
035:
036: for pixels in colorWait:
037: totalPixels += pixels
038:
039: for num in range(K_NUMBERS):
040: height = totalPixels / colorWait[num]
041: x = next_x
042: y = 0
043: w = int(size[1] / height + 1)
044: h = 100
045:
046: next_x = x + w
047: angle = (x, y, w, h)
048: color = (int(np.ceil(center[num][0])), int(np.ceil(center[num][1])), int(np.ceil(center[num][2])))
049: cv2.rectangle(img, angle, color, -1)
050:
051: cv2.imshow(“Dominant Color”, img)
052:
053: def getResize(src):
054: basePixSize = 1280 # 縦横で大きい辺の変更したいサイズ
055: height = src.shape[0]
056: width = src.shape[1]
057:
058: largeSize = max(height, width) # 大きい方の辺のサイズ
059: resizeRate = basePixSize / largeSize # 変更比率を計算
060: dst = cv2.resize(src, (int(width * resizeRate), int(height * resizeRate)))
061:
062: return dst
063:
064: # 色の範囲が大きい順に並び替える
065: def BubbleSort(colorWait, center):
066: for i in range(len(colorWait)):
067: for j in range(len(colorWait) – 1, i, -1):
068: if colorWait[j] > colorWait[j – 1]:
069: colorWait[j], colorWait[j – 1] = colorWait[j – 1], colorWait[j]
070: center[j], center[j – 1] = copy.copy(center[j – 1]), copy.copy(center[j])
071:
072: setColorBar(colorWait, center)
073:
074: if __name__ == ‘__main__’:
075: print(cv2.__version__)
076:
077: K_NUMBERS = 6 # クラスタ数
078: __main()