![]() |
OpenCV 5.0.0
Open Source Computer Vision
|
色補正の最初のステップは、検出された色を線形化することである。入力色空間はキャリブレーションされていない可能性があるため、線形化には経験的手法が用いられる。代表的な手法は以下のとおりである:
線形化は通常、要素ごとに作用する関数である。以下の記号を用いる:
\(C\): 任意の色チャンネル ( \(R, G\), または \(B\)) \(R, G, B\): それぞれの色チャンネル \(G\): グレースケール \(s, sl\): 検出データとその線形化値を表す。前者が入力、後者が出力である \(d, dl\): 参照データとその線形化値
恒等変換による線形化では何の変更も行われない。これは通常、入力RGB画像の三刺激値がすでに輝度に比例しているためである。\ 例えば、入力された測定データがRAW形式である場合、その測定データはすでに線形であるため、線形化は不要である。
計算式:
\[ C_{sl}=C_s \]
ガンマ補正はRGB空間で非線形性を扱う手段であり、詳細はColor Spaceのドキュメントを参照。\ 線形化の段階では、\(gamma\) の値は通常2.2に設定される。値はカスタマイズすることもできる。
計算式:
\[ \begin{aligned} C_{sl}=C_s^{\gamma},\qquad C_s\ge0\\ C_{sl}=-(-C_s)^{\gamma},\qquad C_s<0\\\\ \end{aligned} \]
多項式フィッティングによる線形化。
多項式の形式:
\[ f(x)=a_nx^n+a_{n-1}x^{n-1}+... +a_0 \]
このとき:
\[ C_{sl}=f(C_s) \]
過学習を避けるため、通常 n ≤ 3 とする。\ 多項式パラメータの計算には、通常、線形化された参照色とそれに対応する検出色を用いる必要がある。\ ただし、すべての色を計算に用いることはできない。飽和した検出色は除去する必要がある。詳細はアルゴリズム解説ドキュメントを参照。
3つの多項式 \(r(x), g(x), b(x)\) を用いて、RGB色空間の各チャンネルを線形化する[1-3]:
\[ \begin{aligned} R_{sl}=r(R_s)\\ G_{sl}=g(G_s)\\ B_{sl}=b(B_s)\\ \end{aligned} \]
多項式は、検出データと線形化された参照データとの間の残差平方和を最小化することで生成される。\ 例としてRチャンネルを取り上げる:
\[ R=\arg min_{f}(\Sigma(R_{dl}-f(R_S)^2)) \]
これは以下の方程式に対する最小二乗回帰を求めることと等価である:
\[ \begin{aligned} f(R_{s1})=R_{dl1}\\ f(R_{s2})=R_{dl2}\\ ... \end{aligned} \]
多項式を用いると、方程式は次のようになる:
\[ \begin{bmatrix} R_{s1}^{n} & R_{s1}^{n-1} & ... & 1\\ R_{s2}^{n} & R_{s2}^{n-1} & ... & 1\\ ... & ... & ... & ... \end{bmatrix} \begin{bmatrix} a_{n}\\ a_{n-1}\\ ... \\ a_0 \end{bmatrix} = \begin{bmatrix} R_{dl1}\\ R_{dl2}\\ ... \end{bmatrix} \]
これは行列形式で次のように表せる:
\[ AX=B \]
係数の計算:
\[ X=(A^TA)^{-1}A^TB \]
多項式の係数が得られれば、多項式 r を求めることができる。\ この多項式係数の求め方は numpy の numpy.polyfit で実装でき、ここでは次のように表す:
\[ R=polyfit(R_S, R_{dl}) \]
なお、一般に求めたい多項式は区間 [0,1] において単調増加であることが保証される必要があるが、\ これを満たすには多項式を生成するために非線形な手法が必要となる(詳細は [4] を参照)。\ これによりプログラムの複雑さが大きく増大する。\ 単調性が色補正プログラムの正しい動作に影響しないことを考慮し、ここでは依然として polyfit を用いてプログラムを実装する。
他のチャンネルの引数も同様の方法で導出できる。
この手法[2]では、すべてのチャンネルに単一の多項式を用いる。多項式は依然として、検出色から線形参照色へのpolyfit結果である。ただし、計算に参加できるのは参照色のグレーのみである。
参照色のグレーに対応する検出色は必ずしもグレーではないため、グレー化する必要がある。グレースケールはXYZ色空間のYチャンネルを指す。検出データの色空間は確定しておらず、XYZ空間に変換できない。そのため、sRGBの式を用いて近似する[5]。
\[ G_{s}=0.2126R_{s}+0.7152G_{s}+0.0722B_{s} \]
そして、polyfit を用いることで多項式の引数を求めることができる:
\[ f=polyfit(G_{s}, G_{dl}) \]
\(f\) が得られた後、線形化を実行できる。
ガンマ補正の対数をとる:
\[ ln(C_{sl})={\gamma}ln(C_s),\qquad C_s\ge0\ \]
\(ln(C_s)\) と \(ln(C_{sl})\) の間には線形の関係があることがわかる。この式は多項式関係の近似と考えることができ、すなわち多項式 \(f\) が存在して次が成り立つ[2]:
\[ \begin{aligned} ln(C_{sl})=f(ln(C_s)), \qquad C_s>0\\ C_{sl}=0, \qquad C_s=0 \end{aligned} \]
\(exp(ln(0))\to\infty \) であるため、この式ではゼロであるチャンネル成分は直接ゼロにマッピングされる。
対数値に対して polyfit を用いてフィッティングする:
\[ \begin{aligned} r=polyfit(ln(R_s),ln(R_{dl}))\\ g=polyfit(ln(G_s),ln(G_{dl}))\\ b=polyfit(ln(B_s),ln(B_{dl}))\\ \end{aligned} \]
注意: \(ln(*) \) の引数はゼロにはなり得ない。したがって、\(R_s \) と \(R_{dl} \)、\(G_s\) と \(G_{dl}\)、\(B_s\) と \(B_{dl}\) からチャンネル値が0であるものをすべて削除する必要がある。
最終的なフィッティングの方程式は次のようになる:
\[ \begin{aligned} \ln(R_{sl}) &= r(\ln(R_s)), \qquad R_s > 0 \\ R_{sl} &= 0, \qquad R_s = 0 \\ \ln(G_{sl}) &= g(\ln(G_s)), \qquad G_s > 0 \\ G_{sl} &= 0, \qquad G_s = 0 \\ \ln(B_{sl}) &= b(\ln(B_s)), \qquad B_s > 0 \\ B_{sl} &= 0, \qquad B_s = 0 \end{aligned} \]
グレースケール多項式については、次も成り立つ:
\[ f=polyfit(ln(G_{sl}),ln(G_{dl})) \]
および:
\[ \begin{aligned} ln(C_{sl})=f(ln(C_s)), \qquad C_s>0\\ C_sl=0, \qquad C_s=0 \end{aligned} \]
これらの機能は次に含まれている:
このドキュメントは OpenCV の photo モジュールの一部である。