圖像色彩量化
請參考:圖像色彩量化講解及實現
k-means算法
請參考:k-means算法講解及實現
算法流程:
- 從圖像中隨機選取K個RGB分量(K是k-means的類別數)
- 將圖像中的像素分配到顏色距離最短的那個類別的索引中去,色彩距離按照下面的方法計算:
- 計算各個索引下像素的顏色的平均值,這個平均值成為新的類別
- 如果原來的類別和新的類別一致,算法結束;不一致,重復步驟2和步驟3
- 將原圖中各個像素分配到色彩距離最小的那個類別中去
算法實現(python):
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
from glob import glob
def k_means(img, Class=5):
# get shape
H, W, C = img.shape
# initiate random seed
np.random.seed(0)
# reshape image
img = np.reshape(img, (H * W, -1))
# get index randomly
i = np.random.choice(np.arange(H * W), Class, replace=False)
Cs = img[i].copy()
print(Cs)
while True:
# prepare pixel class label
clss = np.zeros((H * W), dtype=int)
# each pixel
for i in range(H * W):
# get distance from index pixel
dis = np.sqrt(np.sum((Cs - img[i])**2, axis=1))
# get argmin distance
clss[i] = np.argmin(dis)
# selected pixel values
Cs_tmp = np.zeros((Class, 3))
# each class label
for i in range(Class):
Cs_tmp[i] = np.mean(img[clss == i], axis=0)
# if not any change
if (Cs == Cs_tmp).all():
break
else:
Cs = Cs_tmp.copy()
# prepare out image
out = np.zeros((H * W, 3), dtype=np.float32)
# assign selected pixel values
for i in range(Class):
out[clss == i] = Cs[i]
print(Cs)
out = np.clip(out, 0, 255)
# reshape out image
out = np.reshape(out, (H, W, 3))
out = out.astype(np.uint8)
return out
# read image
img = cv.imread("../paojie.jpg").astype(np.float32)
# K-means
out = k_means(img,Class=3)
cv.imwrite("out.jpg", out)
cv.imshow("result", out)
cv.waitKey(0)
cv.destroyAllWindows()