在過往的技術發展歷程中,由於硬體限制與標準差異,並非所有電腦設備都能呈現完整的色彩範圍。與此同時,每個人的色彩敏感度也存在明顯個體差異,有些人能夠輕易辨別細微的色調變化,而多數人則可能難以察覺這些差異。
在這種背景下,如何在刻意減少色彩變化的情況下,依然能夠最大程度地保留並重新呈現原始圖片的視覺特徵,同時適應不同使用者的視覺感知能力,成為一個既具技術挑戰性又富有藝術考量的問題,而這正是我們在本文中所要深入探討的核心議題。
素材取用
概念釐清
啥是色彩量化
色彩量化 (Colour Quantization) 是一種數位圖像處理技術,目的是減少圖像中使用的顏色數量,同時盡可能保持原始圖像的視覺外觀。其原理是將接近的顏色分類為有限數量的集群,然後選擇每個集群中的代表色來重新製作對應的圖像區塊。這種技術巧妙地利用了人類色彩敏感度的有限性,使得多數觀察者難以察覺到明顯的品質下降。
- 壓縮圖片:通過減少圖片的色彩深度,顯著壓縮從而減小圖像檔案大小。
- 潤飾風格:創造簡潔明快的視覺效果,廣泛應用於平面設計和數位藝術創作。
- 影像分析:通過簡化過後的區塊分布,容易進行圖像分割與特徵提取之工作。
如果我們採用 RGB 或 BGR 之形式來表現色彩,這通常被稱為「24 位元色彩」、「全彩」或「真彩色」。總共有 256^3 種即 16,777,216 個色彩,已然遠超人類所能分辨的百萬種顏色,這也是為什麼色彩量化在許多應用中能夠有效減少顏色數量而不會明顯影響視覺感知。
啥是色彩敏銳度
色彩敏銳度屬於色覺的一部分,指的是個人對於顏色差異的感知能力。當兩個極為接近的顏色擺在一起,是否能夠區分不同,甚至按照色調重新排列。
這邊筆者炫耀一下,關於 x-rite 的色調測驗首次便獲得滿分。這個測驗只需將色彩依照頭尾,按照色調排列即可,不會占用過多時間,有興趣的人能挑戰看看。這個測驗是基於其收購的色票公司 Pantone 所做的,針對色彩相關職缺所製作的測驗。

實作過程
方法展示
*此處 NumPy 版本為 1.26.4
import numpy as np
import cv2
# 色彩量化
#
# 使用少量色彩貼近原始圖樣
#
# [ARR] i:img 輸入圖片
# [INT] i:K 顏色數量
#
# [ARR] o:res2 輸出圖片
def colourQuantization(img, K=8):
# 3D (高,寬,通道) --> 2D (像素,通道)
Z = img.reshape((-1, 3))
# 轉換成 np.float 32 以符合下方 K-Means 處理需求
Z = np.float32(Z)
# 定義終止條件
#
# 精度達到 1.0 時即可終止
# 迭代超過 10 次必須終止
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
# 進行 K-Means Clustering
ret, label, center = cv2.kmeans(
Z, K, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
# 將代表顏色 (Cluster 的中心) 轉回 0~255 之數據
center = np.uint8(center)
# 依照 label 讓像素對照代表顏色
res = center[label.flatten()]
# 還原為 3D
res2 = res.reshape((img.shape))
return res2
回到先前我們解釋到,需要抓取相近的色彩用單個代表色來呈現。而這邊將使用 K-Means Clustering 之結果,我們選定要找 K 個族群,等同於只用 K 個顏色。這個時候透過回傳的 標籤 與 中心代表色,我們修改周遭的像素色彩,最終形成量化後的圖片。而關於終止規則的宣告,則有一個特定的格式,詳情請閱參考 [3]。
結果對照
但建議實際應用時設置 K>=2,否則輸出圖像將只呈現一張單色色卡,失去了原始圖像的視覺資訊。而就個人而言,筆者特別喜歡 K=2 的效果,這種二值化處理後的圖像具有高度的對比性和簡潔性,看起來非常適合作為橡皮印章或剪紙插圖的設計,而不是單純的黑白兩色。
然而,當你調整 K 值向上增加時,需要特別注意一些權衡因素。當要尋找的色彩族群越多,意味著需要更多的處理時間,尤其是對於高解析度的圖像。但若設定的顏色數量太少,則存在圖像細節被過度簡化或關鍵特徵被「篡改」的風險。比如在下方 K=32 的示範中,我們可以觀察到手遊明日方舟中那個小可愛迷迭香的瞳孔顏色就變色了。

或許擁有繪畫經驗的人,對於透過色彩量化而導致的細節減少會感到相當不滿意。然而如果我們將此結果進一步應用到畫風簡化後,反而能夠達到一種有效的降噪效果,使圖像看起來更加協調。
後話
色彩量化作為一種經典的圖像處理技術,在當今高色彩深度的數位時代依然具有其獨特價值。透過本文的介紹與實作示範,我們看到了如何利用 K-Means Clustering 實現這項技術,以及不同 K 值設定對結果的影響。
值得一提的是,色彩量化不僅是一種技術處理手段,同是一種藝術表現形式。當我們刻意減少色彩數量時,往往能突顯出原始圖像中被過度刻劃的細節與紋理,創造出更為簡潔的視覺效果。
參考
[1] K-Means Clustering in OpenCV — OpenCV
https://docs.opencv.org/4.x/d1/d5c/tutorial_py_kmeans_opencv.html
[2] Clustering — OpenCV
https://docs.opencv.org/4.x/d5/d38/group__core__cluster.html#ga9a34dc06c6ec9460e90860f15bcd2f88
[3] Term Criteria — OpenCV
https://docs.opencv.org/3.4/d9/d5d/classcv_1_1TermCriteria.html
[4] OpenCV K 均值分類 — CSDN 博客 by 暴风雨中的白杨
https://blog.csdn.net/first_bug/article/details/123514692