#はじめに
OpenCVではHuモーメントを用いて画像の類似度判定が出来ます。ところが肝心のHuモーメントが一体何なのか、出てくる値にどういう意味があるのか、ググってもいまいちわからない。じゃあ書いちゃえ、という趣旨の記事です。
本記事はWikipediaをDeepLに突っ込んだり筆者が適当に意訳したりしたものです。
よって数学的に正しくない表現も含まれるでしょう。
間違ってもレポートの引用元などにしないこと。
Huモーメントとは
画像を演算することで得られる、平行移動、スケール、回転に対して不変な量です。形状のみによる量であるため、形状の比較に用いることが出来ます。
モーメントとは
2変数関数$f(x,y)$に対して、$(p+q)$次のモーメント(素モーメント1)を次のように定義します。
M_{pq} = \int_{-\infty}^{\infty} \int_{-\infty}^{\infty} x^p y^q f(x,y) dx dy
これをグレースケールのディジタル画像$I(x,y)$に適用すると以下のようになります。
M_{ij} = \sum_{x} \sum_{y} x^i y^j I(x,y)
いくつかの単純な画像のプロパティは、モーメントで表現することが出来ます。
$M_{00}$: 面積
$ { \bar{x}, \bar{y} } = \frac{M_{10}}{M_{00}},\frac{M_{01}}{M_{00}}$ :重心
対称性
素モーメントそのものは不変量ではありませんが、素モーメントを用いて不変量をつくることが出来ます。
中心モーメント
中心モーメント2は次のように表されます。
\mu_{pq} = \int_{-\infty}^{\infty} \int_{-\infty}^{\infty} (x-\bar{x})^p (y-\bar{y})^q f(x,y) dx dy
ただし、$ { \bar{x}, \bar{y} }$は先に示した重心です。二値画像$I(x,y)$では以下のようになります。
\mu_{ij} = \sum_{x} \sum_{y} (x-\bar{x})^i (y-\bar{y})^j I(x,y)
$p+q$の小さいいくつかの$\mu_{ij}$を示します。
\begin{align}
\mu_{00} &= M_{{00}},\\
\mu_{01} &= 0,\\
\mu_{10} &= 0,\\
\mu_{11} &= M_{{11}}-{\bar {x}}M_{{01}}=M_{{11}}-{\bar {y}}M_{{10}},\\
\mu_{20} &= M_{20}-{\bar {x}}M_{10},\\
\mu_{02} &= M_{02}-{\bar {y}}M_{01},\\
\end{align}
中心モーメントは並進不変性3を持ちます。
スケール不変性
次のような値を考えることで、スケールに対する不変量を作ることが出来ます。このモーメントは$i+j \geq 2$のとき並進不変性を持ちます。
\eta _{{ij}}={\frac {\mu _{{ij}}}{\mu _{{00}}^{{\left(1+{\frac {i+j}{2}}\right)}}}}\,\!
上の定義を代入してみるとわかりますが、$i+j<2$のときは定数になってしまい意味を持ちません(筆者注)
回転不変性
更に$\eta_{ij}$を用いて、回転に対して不変な量を構築することが出来ます。これはHuによって発見されたため、Huモーメント不変量4と呼ばれています。
\begin{align}
I_{1}&=\eta _{{20}}+\eta _{{02}}\\
I_{2}&=(\eta _{{20}}-\eta _{{02}})^{2}+4\eta _{{11}}^{2}\\
I_{3}&=(\eta _{{30}}-3\eta _{{12}})^{2}+(3\eta _{{21}}-\eta _{{03}})^{2}\\
I_{4}&=(\eta _{{30}}+\eta _{{12}})^{2}+(\eta _{{21}}+\eta _{{03}})^{2}\\
I_{5}&=(\eta _{{30}}-3\eta _{{12}})(\eta _{{30}}+\eta _{{12}})[(\eta _{{30}}+\eta _{{12}})^{2}-3(\eta _{{21}}+\eta _{{03}})^{2}]+(3\eta _{{21}}-\eta _{{03}})(\eta _{{21}}+\eta _{{03}})[3(\eta _{{30}}+\eta _{{12}})^{2}-(\eta _{{21}}+\eta _{{03}})^{2}]\\
I_{6}&=(\eta _{{20}}-\eta _{{02}})[(\eta _{{30}}+\eta _{{12}})^{2}-(\eta _{{21}}+\eta _{{03}})^{2}]+4\eta _{{11}}(\eta _{{30}}+\eta _{{12}})(\eta _{{21}}+\eta _{{03}})\\
I_{7}&=(3\eta _{{21}}-\eta _{{03}})(\eta _{{30}}+\eta _{{12}})[(\eta _{{30}}+\eta _{{12}})^{2}-3(\eta _{{21}}+\eta _{{03}})^{2}]-(\eta _{{30}}-3\eta _{{12}})(\eta _{{21}}+\eta _{{03}})[3(\eta _{{30}}+\eta _{{12}})^{2}-(\eta _{{21}}+\eta _{{03}})^{2}].\\
\end{align}
このうち$I_7$のみ、画像を鏡像にすると符号が反転するという性質を持ちます。(skew invariant)
ただしHuモーメント不変量は完全でも独立でもなく、次の式が抜け落ちているようです。回転モーメント不変量の完全かつ独立なセットを導出する一般的な理論は、J. Flusserによって提示されました。(このあたりからよくわかっていません筆者)
I_{8}=\eta _{{11}}[(\eta _{{30}}+\eta _{{12}})^{2}-(\eta _{{03}}+\eta _{{21}})^{2}]-(\eta _{{20}}-\eta _{{02}})(\eta _{{30}}+\eta _{{12}})(\eta _{{03}}+\eta _{{21}})
それにしても、意味を見出すのが難しそうな量ですね……。そら「こういう便利な量があります」で済ます訳だわ。
応用例
分散共分散行列や固有値への応用例が記載されていますが、Huモーメントとは関連がなさそうので省略します。気になる方は出典元をあたって下さい。
cv::matchShapeの中身
さて、ここまでくれば後は簡単です。cv::matchShape
は2つの画像についてHuモーメント不変量を求めて比較してくれます。比較方法には以下の3通りがあります。
\begin{align}
I_1 &= \sum_i \left| \frac{1}{m_i^a} - \frac{1}{m_i^b} \right| \\
I_2 &= \sum_i \left| m_i^a - m_i^b \right| \\
I_3 &= \sum_i \left| \frac{m_i^a - m_i^b}{m_i^a} \right|
\end{align}\\
ここで
m_i^a = sign (h_i^a) \dot \log(h_i^a)
です。$h_i^a$は画像aのi番目のhuモーメントです。使い分け方は残念ながらわかりませんでした。
まとめ
Huモーメントはさまざまな変換に対して不変である、形状のみによる7つの量であり、形状の比較に使うことができる。ただ、Huモーメントは複雑な量であり、その値に意味を見出すことは難しい。
疲れたうえに大した成果もなかった……。こんなもんよ。
出典
Image Moment -Wikipedia(en)
OpenCV Documentation