我試圖對一張圖片進行量化,保持所有的原色,并去除所有的次要顏色,如 "抗鋸齒 "邊界。 例如,下面的圖片最終應該被量化為3種顏色,而原始圖片中的實際顏色數量超過了30種。所有的 "抗鋸齒 "邊框顏色都應該被認為是次要的,并在量化時被消除,還有 "jpeg偽影",它們由于過度優化而給影像增加了更多的顏色。 注意:一個源影像可以是png或jpeg。
對于量化本身,我使用PIL.quantize(...),K為要留下的顏色數量。它的效果相當好,并保持調色板與原版完全匹配。
def color_quantize(path, K)。
image = cv2.imread(path, cv2.IMREAD_UNCHANGED)
img = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
im_pil = Image.fromarray(np.uint8(img))
im_pil = im_pil.quantize(K, None, 0, None)
return cv2.cvtColor(np.array(im_pil.convert("RGB"), cv2.COLOR_RGB2BGR)
因此,如果我事先知道 "K"(三原色的數量),那么我就會把它用于im_pil.quantize(..)。基本上,我需要一種方法來獲得這個 "K "數。
有什么方法可以確定三原色的數量嗎?
BTW,關于 "jpeg偽影 "的去除,我目前正在使用img = cv2.bilateralFilter(img, 9, 75, 75),效果相當好。
uj5u.com熱心網友回復:
你可能想嘗試分析RGB通道的直方圖,找出它們有多少個峰值,希望你會有幾個大的峰值,和一些非常小的峰值,那么大峰值的數量應該是你的K。
uj5u.com熱心網友回復:
。結果
使用n_clusters=4,這里是最主要的顏色和百分比分布
[ 28.59165576 114.71245821 197.21921791] 4.30%。
[25.54783639 197.94045711 147.22737091 ] 17.94%。
[197.75739373 25.78053504 143.31173478] 19.04%。
[254.75762607 254.77925368 254.85116121] 58.72%。
每個顏色簇的可視化(白色是不可見的)
import cv2, numpy as np
from sklearn.cluster import KMeans
def visualize_colors(cluster, centroids) 。
# 獲取不同聚類的數量,創建直方圖,并歸一化。
labels = np.range(0, len(np.unique(cluster.labsels_)) 1)
(hist, _) = np.histogram(cluster.labs_, bins = labels)
hist = hist.astype("float"/span>)
hist /= hist.sum()
# 創建頻率矩形并迭代每個群組的顏色和百分比。
rect = np.zeros((50, 300, 3, dtype=np.uint8)
colors = sorted([(%, color) for (%, color) in zip(hist, centroids)] )
start=0
for (percent, color) in colors:
print(color, "{:0.2f}%".format( percent * 100)
end = start (% * 300)
cv2.rectangle(rect, (int(開始), 0), (int(結束), 50),
color.astype("uint8").tolist(), -1)
start = end
return rect
# 加載影像并轉換為像素串列'1.png')
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
reshape = image.reshape((image.shape[0] * image.shape[1] , 3)
# 找到并顯示最主要的顏色。
cluster = KMeans(n_clusters=4).fit(reshape)
visualize = visualize_colors(cluster, cluster.cluster_centers_)
visualize = cv2.cvtColor(visualize, cv2.COLOR_RGB2BGR)
cv2.imshow('visualize', visualize)
cv2.waitKey()
uj5u.com熱心網友回復:
我最終使用了以下函式來確定主導顏色的數量:
def get_dominant_color_number(img, threshold)。
# 去除顯著的偽影。
img = cv2.bilateralFilter(img, 9, 75, 75)
# 調整影像大小,使其在250x250上的處理更有效(沒有抗鋸齒以減少顏色空間)。
thumbnail = cv2.resize(img, (250, 250), None)
#轉換為HSV顏色空間。
imghsv = cv2.cvtColor(thumbnail, cv2.COLOR_BGR2HSV).astype("float32"/span>)
(h, s, v) = cv2.split(imghsv)
# 量化飽和度和值,以合并接近的顏色。
v = (v // 30) * 30
s = (s // 30) * 30
imghsv = cv2.merge([h,s,v])
thumbnail = cv2.cvtColor(imghsv.astype("uint8"), cv2.COLOR_HSV2BGR)
(unique, counts) = np.unique(thumbnail.reshape(-1, thumbnail.shape[2]), return_counts=True, axis =0)
# 計算每種顏色的頻率并對其進行排序。
freq = counts.astype("float")
freq /= freq.sum()
count_sort_ind = np.argsort(-counts)
# 獲取高于指定閾值的頻繁顏色。
n = 0
dominant_colors = []
for (c) in count_sort_ind:
n = 1;
dominant_colors.append(unique[c])
if (freq[c] <= threshold)。
break[/span
return (dominant_colors, n)
# -----------------------------------------------------------
img = cv2.imread("File.png", cv2.IMREAD_UNCHANGED)
channels = img.shape[2]
if channels == 4:
trans_mask = img[:,:,3] == 0.
img[trans_mask] = [254, 253, 254, 255]
img = cv2.cvtColor(img, cv2.COLOR_BGRA2BGR)
(dom_colors, dom_color_num) = get_dominant_color_number(img, .0045)
對于閾值".0045",它給出了一個可以接受的結果。然而,它仍然看起來有點 "人工"。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/320315.html
標籤:
上一篇:用c 移動輸入檔案


