コンピュータビジョンの色補正方法

調色と色補正の違い

調色とは、画像の色相、彩度、明るさなどのパラメータを調整することによって、画像の全体的な色効果を変更することを指します。この調整は、個人またはアーティストの美的意図に基づいて主観的なものになる場合があります。カラー グレーディングは、特定の視覚効果や感情表現を実現するために、画像処理、写真、映画製作などの分野で一般的に使用されます。

色補正(Color Correction)とは、画像の色を実際のシーンの色と一致するように補正することを指します。色補正は、画像内の色かぶり、色ずれ、またはカラーバランスの問題を除去し、真の色を復元することを目的としています。これは、画像のカラー分布を調整するか、カラー チャネルを調整することによって行われます。

要約すると、色補正は芸術性と主観性に重点を置き、パラメーターを調整することで画像の全体的なトーンと効果を変更します。一方、色補正は、実際のシーンの色をより正確に反映できるように、画像内の色の問題を修正することに重点を置いています。

以下では主に、ヒストグラム法、カラーマトリックス CCM 法、深層学習法などのいくつかの手法と対応する実装コード (既に実行済み) を紹介します。

ヒストグラムの等化

撮影環境が暗いと画像が暗く見える傾向があります。ヒストグラム処理方法により画像の色を補正し、画像の明るさとコントラストを向上させることができます。ヒストグラム処理手法は、画素の輝度値に基づく統計解析手法であり、画像の輝度値を再割り当てすることで補正を実現します。

このアプローチでは、最初に画像のヒストグラム、特にピクセル強度値の確率密度関数 (PDF) を観察します。夜間に撮影された画像は、より低いスペクトルに偏った分布を示す傾向があります。これは、画像内の強度値が暗い領域に集中する傾向があることを意味します。

この歪みを修正するために、私たちの目標は、画像の累積分布関数 (CDF) を新しいターゲット CDF まで拡張することです。このようにして、低いスペクトルに含まれる強度値がより高い強度値にマッピングされ、画像が明るくなります。これは、画像のピクセル値を変換することで行います。

具体的には、ヒストグラム処理方法としては、ヒストグラム等化やヒストグラム指定などの手法を用いることができる。ヒストグラム等化は、ピクセル強度値を再配分することによって画像のコントラストを強化します。一方、ヒストグラム仕様は、画像の CDF をターゲット CDF に一致させることで強度値の分布を調整します。これらの方法はすべて、画像内の強度値の統計情報を利用して、画像の視覚効果を向上させます。

撮影環境が明るい場合も同様です。

原理

ヒストグラム均等化のための画像処理を行う場合、元の画像を赤、緑、青の 3 つのチャネル (RGB) に分割します。次に、各チャネルに対して次の計算プロセスが実行されます。

  1. 各チャネルのヒストグラムを計算する: グレースケール画像のヒストグラム計算方法を使用して、各ピクセル値の頻度をカウントします。
  2. 累積分布関数 (CDF) を計算します。ヒストグラムが累積されて、各ピクセル値の累積頻度が取得されます。
  3. 正規化 CDF: CDF 値を画像の総ピクセル数で除算し、その範囲を 0 ~ 1 の間に固定します。
  4. ターゲット CDF のビルド: ピクセル値が 0 から 255 まで均一に分布する線形分布の CDF を作成します。
  5. ピクセル値のマッピング: 各ピクセル値について、現在のチャネルの正規化 CDF とターゲット CDF に従って、最も近いピクセル値を見つけてマッピングします。
  6. チャネルの再構築: マッピングされたチャネルを再構築します。
  7. 残りの 2 つのチャネルに対して手順 2 ~ 6 を繰り返します。

3 つの処理されたチャネルをスタックして、最終的な処理された画像を取得します。

実装コード

インポートライブラリ

import numpy as np
import matplotlib.pyplot as plt
from skimage.io import imread, imshow
from skimage import img_as_ubyte, img_as_float
from skimage.color import rgb2gray
from skimage.exposure import histogram, cumulative_distribution
from scipy.stats import norm, cauchy, logistic

meimei = imread('meimei.jpg')
meimei_gray = rgb2gray(meimei)

ここに画像の説明を挿入

  1. skimage.exposure.histogram(画像, nbins=256):

    • この関数は、画像のヒストグラムを計算するために使用されます。
    • パラメータ image は入力画像配列です。
    • パラメータ nbins はヒストグラム内のビンの数で、デフォルトでは 256 です。
    • 戻り値は 2 つの配列を含むタプル (hist、bin_centers) です。ここで、hist は長さ nbins の配列で、各ビン内のピクセル数を示し、bin_centers は対応するビンの中心値です。
  2. skimage.exposure.cumulative_distribution(画像, nbins=256):

    • この関数は、画像の累積分布関数 (CDF) を計算するために使用されます。
    • パラメータと戻り値はskimage.exposure.histogram関数と同じです。
    • 返された CDF 配列は、イメージ内の対応するピクセル値以下のピクセルの割合を表します。

まず、この姉妹の実際の CDF とターゲット CDF の比較を見てみましょう。

image_intensity = img_as_ubyte(meimei_gray)
freq, bins = cumulative_distribution(image_intensity)
target_bins = np.arange(256)
target_freq = np.linspace(0, 1, 256)
new_vals = np.interp(freq, target_freq, target_bins)


fig, ax = plt.subplots(1,2, figsize=(15,5))
ax[0].step(bins, freq, c='b', label='Actual CDF')
ax[0].plot(target_bins, target_freq, c='r', label='Target CDF')
ax[0].legend()
ax[0].set_title('Grayscale: Actual vs. Target Cumulative Distribution')

ax[1].imshow(new_vals[image_intensity.clip(0, len(new_vals)-1)].astype(np.uint8), 
             cmap='gray')
ax[1].set_title('Corrected Image in Grayscale');

ここに画像の説明を挿入
CDF変換を実現するための分割チャンネル

def linear_distribution(image, channel):
    image_intensity = img_as_ubyte(image[:,:,channel])
    print(len(image_intensity))
    freq, bins = cumulative_distribution(image_intensity)
    target_bins = np.arange(255)
    target_freq = np.linspace(0, 1, len(target_bins))
    new_vals = np.interp(freq, target_freq, target_bins)
    print(len(new_vals))
    return new_vals[image_intensity.clip(0,len(new_vals)-1)].astype(np.uint8)

red_channel = linear_distribution(meimei, 0)
green_channel = linear_distribution(meimei, 1)
blue_channel = linear_distribution(meimei, 2)

fig, ax = plt.subplots(1,2, figsize=(15,5))
ax[0].imshow(meimei);
ax[0].set_title('Original Image')
ax[1].imshow(np.dstack([red_channel, green_channel, blue_channel]));
ax[1].set_title('Transformed Image');

ここに画像の説明を挿入

CCM色補正マトリックス

CCM(Color Correction Matrix、色補正マトリックス)とは、画像の色を補正する手法です。入力画像の色空間とターゲット色空間の間のマッピング関係を確立することで、画像の色の補正と調整を実現します。CCM 方式は、画像内の色かぶり、色の歪み、色の不一致などの問題を修正し、より正確で自然な色のパフォーマンスを得ることができます。

CCM の基本原理は、入力画像の色空間とターゲットの色空間の間のマッピング関係を確立することです。通常、CCM は行列を使用してこのマッピング関係を表します。マトリックスの各要素は、入力カラー チャネルとターゲット カラー チャネルの間の重み関係を表します。補正されたカラー値は、入力画像の各ピクセル値に CCM マトリックスを乗算することで得られますこのようにして、入力画像の色は、事前に定義されたターゲット色に従って調整され、色の補正と調整が実現されます。

原理

CCM 法の計算プロセスは次のとおりです。

  1. 参照画像と参照データを収集します。

X-Rite Colorchecker などの、さまざまな色を表す複数のカラー ブロックを含むカラー テスト チャートを使用します。
参照データは、標準参照値、分光計を使用して測定された値、または「ゴールド スタンダード」画像から抽出された Lab* 値です。

  1. 画像の前処理:

線形化処理: CCM の計算には線形の R、G、B 値が必要なため、入力データが線形に表現されるように画像に対して適切な線形化処理を実行する必要があります。
彩度処理: ニーズに応じて、色の鮮やかさを制御したり、色の歪みを軽減したりするために、画像の彩度を調整する必要がある場合があります。

  1. CCMの計算方法:

多項式フィッティング法:原画像データと参照データを多項式フィッティングすることにより、CCMの係数を計算します。フィッティングの目的は、フィッティング結果と参照データ間の差異を最小限に抑えることです。
3 次元ルックアップ テーブル (3D-LUT) 方式: 色空間を離散的なグリッドに分割し、各グリッド点で CCM を定義します。元の画像のピクセルを補間することで、その画像が含まれるグリッドを特定し、対応する CCM を使用して修正します。

  1. 最適化と評価:

目的関数の選択:CCM の補正効果を評価するために適切な目的関数を選択します。一般的に使用される目的関数には、二乗平均平方根誤差 (RMSE) および色差メトリクス (ΔE 2000 など) が含まれます。目的関数の選択は、特定のアプリケーション要件によって異なります。
非線形最適化アルゴリズム: 適切な最適化アルゴリズム (勾配降下法、レーベンバーグ・マルカート アルゴリズムなど) を使用して、目的関数を最小化する解を見つけます。つまり、CCM が元の画像を参照データに合わせて最適に補正できるパラメーターを見つけます。

  1. 評価と調整

計算された CCM を評価するために、他のテスト画像または検証データセットを使用して補正効果を検証できます。
評価結果によっては、より良いキャリブレーション結果を得るために、さらなる調整と最適化が必要になる場合があります。

CCM を計算するときは、次の式の計算が必要になります。

  1. カラー画像表現

カラー イメージは m × n × 3 配列として表すことができます。ここで、m はイメージの高さを表し、n はイメージの幅を表し、3 はカラー チャネル (R、G、B) を表します。元画像のピクセルデータをinput_imgとする。

  1. 線形化

各ピクセル i について、非線形の元のピクセル値を線形表現に変換するために、まず線形化が必要です。線形化後の画素値をlinear_imgで表す。具体的な線形化処理の式は以下の通りです。

ここに画像の説明を挿入

ここで、元のピクセル値を 255 で割ることは、ピクセル値を範囲 [0, 1] に正規化することを意味します。

  1. CCMの計算

CCM は、元の画像の色をターゲットの色に補正するために使用される 3×3 または 4×3 のマトリックスです。CCM を計算する前に、標準参照値、分光計測定値、または「ゴールド スタンダード」画像から抽出された Lab* 値などの参照データを定義する必要があります。
多項式フィッティング法:
多項式フィッティング法を使用して CCM を計算し、線形化された入力イメージ Linear_img と参照データをフィッティングします。CCM が ccm で表される 3×3 行列であると仮定すると、フィッティング プロセスは次の式で表すことができます。

ここに画像の説明を挿入

詳細については、リンクを参照してください: https://www.imatest.com/support/docs/23-1/colormatrix/

ディープラーニング Deep_White_Balance

論文アドレス: https://openaccess.thecvf.com/content_CVPR_2020/papers/Afifi_Deep_White-Balance_Editing_CVPR_2020_paper.pdf
プロジェクトアドレス: https://github.com/mahmoudnafifi/Deep_White_Balance

sRGB画像とは何ですか

sRGB (標準 Red Green Blue) は、Microsoft イメージング大手によって共同開発された色言語プロトコルであり、色を定義する標準的な方法を提供するため、さまざまなコンピュータ周辺機器や、ディスプレイ、印刷、スキャンなどのアプリケーション ソフトウェアが色の共通言語を持つことができます。

ホワイト バランス (略して WB) は、さまざまな照明条件下で撮影された画像の一貫した色を保証するように設計された重要な画像処理タスクです。ただし、従来のホワイト バランス編集方法では、特にカメラの統合シグナル プロセッサ (ISP) の非線形レンダリング効果により、間違ったホワイト バランス設定を修正する際にいくつかの課題に直面しています。この問題を解決するために、「ディープ ホワイトバランス編集」と呼ばれるディープラーニング手法を導入します。

ディープ ホワイト バランス編集は、エンドツーエンドのディープ ニューラル ネットワーク (DNN) モデルをトレーニングすることで、sRGB 画像の真のホワイト バランス編集を実現します。従来の k 最近傍 (KNN) ベースの方法と比較して、当社の DNN モデルは、間違ったホワイト バランス設定をより正確に修正できるだけでなく、ユーザーが画像のホワイト バランスを自由に編集して他の照明条件に合わせて調整することもできます。

この方法は、単一のエンコーダ ネットワークと 3 つのデコーダ ネットワークに基づいています。このうち、エンコーダー ネットワークは画像の特徴を抽出するために使用され、デコーダー ネットワークは 3 つのホワイト バランス設定 (正しい自動ホワイト バランス (AWB) 設定、屋内照明設定、屋外照明設定) について学習されます。最初のデコーダは、間違ったホワイト バランスを持つ画像の編集を可能にし、ポストでのホワイト バランス補正の目標を達成します。屋内および屋外のデコーダは、さまざまな異なるホワイト バランス効果を融合した出力を提供し、画像の美的ホワイト バランス特性を柔軟に調整できます。

問題の説明:

ディープ ホワイトバランス編集は、画像の色を編集する方法です。未知のカメラ ISP と任意のホワイト バランス設定を使用したWB ( in ) WB^{(in)}が与えられたとします。WB _( in )生成された sRGB 画像WB ( in ) WB^{(in)}WB _( ) 私たちの目標は、ターゲットのホワイト バランス設定WB ( t ) WB^{(t)}WB _( t )外観。

IWB ( t ) = G ( F ( IWB ( in ) ) ) I_{WB^{(t)}}=G(F(I_{WB^{(in)}}))WB _( t )=G ( F (WB _()))

方法の概要:

ディープ ホワイト バランス編集方法は、入力画像をさまざまなホワイト バランス設定を持つ出力画像に変換するエンコーダー/デコーダー モデルを構築することを目的としています。この手法は、画像処理チェーンにおける関数 G と関数 F の連携を解析することにより、ターゲット画像の生成を実現します。関数 F は入力イメージを中間表現 (つまり、現在の WB(in) 設定を持つ元の RGB 画像) に変換し、関数 G はこの中間表現を取得し、ターゲット WB 設定を使用して sRGB 色空間でエンコードされた最終イメージにレンダリングします。

さまざまなホワイト バランス設定のターゲットを達成するために、ディープ ホワイト バランス編集ではマルチデコーダー アーキテクチャが採用されています。各デコーダは、異なるホワイト バランス設定で出力画像を生成する役割を果たします。この方法では、3 つの異なるホワイト バランス設定が選択されました。AWB (自動ホワイト バランス、画像がキャプチャされたシーンの正しい照明を示します)、タングステン/白熱灯 (白熱灯、屋内照明のホワイト バランスを示します)、および Shade (日陰、屋外照明のホワイト バランスを示します)。これらのデコーダはそれぞれ gA、gT、gS と名付けられており、これら 3 つのホワイトバランス設定に対応する出力画像の生成は、独立したデコーダによって実現されます。

ここに画像の説明を挿入

モデルアーキテクチャ:

ディープ ホワイトバランス編集は、U-Net アーキテクチャを採用し、エンコーダーとデコーダー間のマルチスケール スキップ接続を使用します。全体のアーキテクチャは、4 レベル エンコーダ ユニットと 3 つの 4 レベル デコーダ ユニットという 2 つのメイン ユニットで構成されます。エンコーダは入力画像のマルチスケール潜在表現を抽出する役割を果たし、デコーダは特定のホワイト バランス設定に従って出力画像を生成します。エンコーダとデコーダのさまざまなレベルで、転置畳み込み層とさまざまな数のチャネルを持つ畳み込み層が使用され、特徴の転送と情報の再構成が実現されます。

トレーニング損失関数

モデルアプローチでは、L1 ノルム損失関数を使用して、再構成された画像と実際の画像の差を測定します。損失計算の具体的な手順は次のとおりです。

各トレーニング画像と対応するターゲット ホワイト バランス設定 (正しい AWB、陰影 WB、および白熱 WB) について、サイズ 128 × 128 の 4 つの画像パッチがトレーニング画像からそれぞれ入力画像および対応するターゲット画像としてランダムに選択されます。

入力画像はエンコーダ ネットワークを通じてエンコードされ、特徴表現が取得されます。

特徴表現はデコーダ ネットワークを介して渡され、AWB、シェード WB、および白熱灯 WB の 3 つのターゲット画像の再構成結果がそれぞれ生成されます。

各デコーダによって生成された再構成画像と対応するターゲット画像について、それらの間のピクセルレベルの差、つまり L1 ノルム損失が計算されます。これは、各ピクセルの差の絶対値を累積加算することで実現できます。

合計損失は、ターゲット画像の L1 損失を含む 3 つのデコーダによって生成された再構成画像を累積することによって取得されます。

具体的には、損失の計算式は次のようになります。

L = ∑ i ∑ p = 1 3 hw ∣ PWB ( i ) ( p ) − CWB ( i ) ( p ) ∣ L = \sum_i\sum_{p=1}^{3hw}|P_{WB^{(i)}}(p)-C_{WB^{(i)}}(p)|L=p = 13時間_∣P _WB _()( p )CWB _()( p )

このうち、L は全体の損失を表します。i ∈ A , T , S i \in {A, T, S}Sはターゲット ホワイト バランス設定 (AWB、シェード WB、および白熱 WB) のインデックスであり、p はトレーニング画像とターゲット画像のピクセル インデックスを表します。

PWB ( i ) ( p ) P_{WB^{(i)}}(p)PWB _()( p )は、デコーダ ( i ) ( p ) C_{WB^{(i)}}(p) によって生成された再構成画像内の
CWBCWB _()( p ) は、対応するターゲット画像内のピクセル値を表します。

すべてのピクセルが累積および合計されて、各ターゲット画像と対応する再構成画像の L1 損失が得られ、次に 3 つのターゲット画像の損失が累積されて全体の損失が得られます。

この損失計算手法により、対象画像に限りなく近い再構成結果をモデルに学習させることができ、正確なホワイトバランス編集を実現します。この損失関数を最適化することにより、モデルはさまざまなホワイト バランス設定の下で画像処理の精度を徐々に向上させることができます。

達成

このプロジェクトは、画像のホワイトバランス編集のためのディープラーニング手法を提供することを目的としています。以下に、プロジェクトの簡単な紹介と使用方法のガイドを示します。

環境要件:

Python 3.6
PyTorch (バージョン 1.2.0 および 1.5.0 がテスト済み)
torchvision (バージョン 0.4.0 および 0.6.0 がテスト済み)
cudatoolkit
tensorboard (オプション)
numpy
Pillow
future
tqdm
matplotlib
scipy
scikit-learn

コードは他のバージョンのライブラリでも動作する可能性があることに注意してください。

クイックスタート

:

  • 単一の画像を処理するには、demo_single_image.py を実行します。たとえば、AWB およびさまざまな WB 設定を適用します: python Demon_single_image.py --input_image .../example_images/00.jpg --output_image .../result_images --show。この例では、出力イメージを .../result_images ディレクトリに保存し、次の結果イメージを出力します。
    ここに画像の説明を挿入
  • デモ_images.py を実行して、画像ディレクトリを処理します。例: python Demon_images.py --input_dir .../example_images/ --output_image .../result_images --task AWB。利用可能なタスクは、AWB、すべて、および編集です。また、demo_single_image.py の例でタスクを指定することもできます。

トレーニングコード:

  • training.py を実行してトレーニングを開始します。コードを実行する前に、トレーニング イメージ ディレクトリを調整します。

例: CUDA_VISIBLE_DEVICE=0 python train.py --training_dir …/dataset/ --fold 0 --epochs 500 --learning-rate-drop-period 50 --num_training_images 0この例では、fold = 0およびnum_training_images = 0 は、トレーニングで相互検証なしですべてのトレーニング データが使用されることを意味します。トレーニング画像の数を n 画像に制限したい場合は、num_training_imagesを n に設定します。3 分割相互検証を行う場合は、fold=testing_foldを使用します。コードは残りのフォールドでトレーニングし、テスト用に選択したフォールドを保持します。

その他の便利なオプションには、--patches-per-image (画像ごとのランダム パッチの数を選択)、--learning-rate-drop-periodおよび --learning -rate-drop-factor (学習率の減衰期間と係数を制御)、および--patch-size (トレーニング パッチ サイズを設定) があります。--loadオプションを使用して、トレーニング チェックポイント .pth ファイルからトレーニングを再開できます。

マシンに TensorBoard がインストールされている場合は、トレーニングの開始後にtensorboard --logdir ./runs を実行して、トレーニングの進行状況を確認し、入出力パッチのサンプルを視覚化できます。

このプロジェクトでは、すぐに起動してホワイト バランス編集タスクを開始できるようにするためのサンプル コードとトレーニング コードを提供します。ニーズとデータセットに応じて適応でき、トレーニング コードにはニーズに合わせて調整できる柔軟なオプションが用意されています。トレーニング画像のディレクトリを指定し、使用するトレーニング データの量、トレーニング期間、学習率の減衰期間と係数、トレーニング パッチのサイズを選択できます。以前のトレーニング チェックポイント ファイルがすでにある場合は、--load オプションを使用してチェックポイント ファイルからトレーニングを再開することもできます。

あるいは、マシンに TensorBoard がインストールされている場合は、トレーニング中に tensorboard --logdir ./runs を実行して、トレーニングの進行状況を視覚化し、入出力パッチのサンプルを確認することができます。これは、モデルのパフォーマンスとトレーニング効果をより深く理解するのに役立ちます。

おすすめ

転載: blog.csdn.net/weixin_42010722/article/details/131534614