使用SOM進行圖像顏色量化
前言
自組織映射(Self-Organizing Map, SOM)是一種人工神經網絡,能夠將高維數據映射到低維空間,同時保持數據的拓撲結構。在圖像處理領域,SOM常被用於顏色量化,即減少圖像中的顏色數量,同時儘量保持圖像的視覺效果。
本文將介紹如何使用MiniSom庫實現基於SOM的圖像顏色量化,將一幅圖像的顏色從數百萬種減少到9種代表色,同時保持圖像的主要視覺特徵。
編碼實現
from minisom import MiniSom
import numpy as np
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings("ignore", category=RuntimeWarning)
# ---------------------- 1. PNG圖像加載與預處理 ----------------------
def load_and_preprocess_image(image_path):
"""
加載PNG圖像並進行預處理
"""
# 加載PNG圖像
img = plt.imread(image_path).astype(np.float32)
# 處理RGBA通道(若存在):保留RGB三通道
if img.ndim == 3 and img.shape[-1] == 4:
img = img[..., :3]
# 自動判斷位深度並標準化(適配8位/16位PNG)
max_val = img.max()
if max_val > 1.0: # 非浮點型PNG(8位/16位)
img = img / (65535 if max_val > 255 else 255)
# 亮度增強(針對PNG可能的偏暗問題)
img = np.clip(img * 1.5, 0, 1)
return img
# ---------------------- 2. SOM顏色量化 ----------------------
def som_color_quantization(img, grid_size=(3, 3), num_iterations=1000):
"""
使用SOM對圖像進行顏色量化
"""
# 數據展平:將圖像轉為像素列表(每行一個RGB像素)
pixels = img.reshape(-1, 3)
# 初始化SOM
som = MiniSom(
x=grid_size[0],
y=grid_size[1],
input_len=3, # RGB三通道
sigma=1.0,
learning_rate=0.3,
random_seed=42
)
# 隨機初始化權重並保存初始狀態
som.random_weights_init(pixels)
initial_weights = som.get_weights().copy()
# 訓練SOM
som.train_random(pixels, num_iterations)
# 顏色量化
quantized_pixels = som.quantization(pixels)
quantized_img = quantized_pixels.reshape(img.shape)
return quantized_img, initial_weights, som.get_weights()
# ---------------------- 3. 結果可視化 ----------------------
def plot_results(original_img, quantized_img, initial_weights, learned_weights):
"""
可視化處理結果
"""
plt.figure(figsize=(12, 10))
# 原始圖像
plt.subplot(221)
plt.imshow(original_img)
plt.title('Original Image')
plt.axis('off')
# 量化後圖像
plt.subplot(222)
plt.imshow(quantized_img)
plt.title('Quantized Image (9 colors)')
plt.axis('off')
# 初始權重顏色
plt.subplot(223)
plt.imshow(initial_weights)
plt.title('Initial SOM Weights')
plt.axis('off')
# 學習後權重顏色
plt.subplot(224)
plt.imshow(learned_weights)
plt.title('Learned SOM Weights')
plt.axis('off')
plt.tight_layout()
plt.show()
# ---------------------- 4. 主函數 ----------------------
def main():
# 加載並預處理圖像
image_path = 'car.png' # 請替換為您的圖像路徑
img = load_and_preprocess_image(image_path)
# 使用SOM進行顏色量化
quantized_img, initial_weights, learned_weights = som_color_quantization(img)
# 顯示結果
plot_results(img, quantized_img, initial_weights, learned_weights)
if __name__ == "__main__":
main()
代碼説明
-
圖像預處理:
- 支持RGBA和RGB格式的PNG圖像
- 自動適配8位和16位PNG圖像的位深度
- 包含亮度增強功能,改善PNG圖像可能的偏暗問題
-
SOM訓練:
- 使用3x3的SOM網格,將顏色量化為9種代表色
- 訓練1000次以確保充分擬合圖像的顏色分佈
- 保存初始權重和學習後的權重用於對比
-
結果可視化:
- 展示原始圖像和量化後的圖像
- 對比SOM初始權重和學習後的權重變化
- 清晰展示顏色量化的效果
使用方法
-
確保安裝了必要的庫:
pip install minisom numpy matplotlib - 將代碼中的
image_path替換為您的圖像路徑 - 運行代碼,即可看到顏色量化的效果
這種基於SOM的顏色量化方法能夠有效地減少圖像中的顏色數量,同時保持圖像的主要視覺特徵,適用於圖像壓縮、色彩分析等應用場景。