博客 / 詳情

返回

使用SOM進行圖像顏色量化

使用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()

car.png

代碼説明

  1. 圖像預處理

    • 支持RGBA和RGB格式的PNG圖像
    • 自動適配8位和16位PNG圖像的位深度
    • 包含亮度增強功能,改善PNG圖像可能的偏暗問題
  2. SOM訓練

    • 使用3x3的SOM網格,將顏色量化為9種代表色
    • 訓練1000次以確保充分擬合圖像的顏色分佈
    • 保存初始權重和學習後的權重用於對比
  3. 結果可視化

    • 展示原始圖像和量化後的圖像
    • 對比SOM初始權重和學習後的權重變化
    • 清晰展示顏色量化的效果

使用方法

  1. 確保安裝了必要的庫:

    pip install minisom numpy matplotlib
  2. 將代碼中的image_path替換為您的圖像路徑
  3. 運行代碼,即可看到顏色量化的效果

這種基於SOM的顏色量化方法能夠有效地減少圖像中的顏色數量,同時保持圖像的主要視覺特徵,適用於圖像壓縮、色彩分析等應用場景。

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.