Huモーメントって何？


#はじめに

OpenCVではHuモーメントを用いて画像の類似度判定が出来ます。ところが肝心のHuモーメントが一体何なのか、出てくる値にどういう意味があるのか、ググってもいまいちわからない。じゃあ書いちゃえ、という趣旨の記事です。

本記事は**Wikipedia**を**DeepL**に突っ込んだり**筆者が適当に意訳**したりしたものです。
よって数学的に正しくない表現も含まれるでしょう。
間違ってもレポートの引用元などにしないこと。

# Huモーメントとは
画像を演算することで得られる、**平行移動、スケール、回転に対して不変な量**です。形状のみによる量であるため、形状の比較に用いることが出来ます。


# モーメントとは

2変数関数$f(x,y)$に対して、$(p+q)$次のモーメント(素モーメント[^1])を次のように定義します。

```math
M_{pq} = \int_{-\infty}^{\infty} \int_{-\infty}^{\infty} x^p y^q f(x,y) dx dy
```

これをグレースケールのディジタル画像$I(x,y)$に適用すると以下のようになります。

```math
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}}$ :重心


# 対称性

素モーメントそのものは不変量ではありませんが、素モーメントを用いて不変量をつくることが出来ます。

# 中心モーメント

中心モーメント[^3]は次のように表されます。

```math
\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)$では以下のようになります。

```math
\mu_{ij} = \sum_{x} \sum_{y} (x-\bar{x})^i (y-\bar{y})^j I(x,y)
```

$p+q$の小さいいくつかの$\mu_{ij}$を示します。

```math

\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}
```

中心モーメントは並進不変性[^4]を持ちます。

## スケール不変性

次のような値を考えることで、スケールに対する不変量を作ることが出来ます。このモーメントは$i+j \geq 2$のとき並進不変性を持ちます。

```math
\eta _{{ij}}={\frac  {\mu _{{ij}}}{\mu _{{00}}^{{\left(1+{\frac  {i+j}{2}}\right)}}}}\,\!
```

上の定義を代入してみるとわかりますが、$i+j<2$のときは定数になってしまい意味を持ちません(筆者注)


## 回転不変性
更に$\eta_{ij}$を用いて、回転に対して不変な量を構築することが出来ます。これはHuによって発見されたため、Huモーメント不変量[^5]と呼ばれています。

```math
\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によって提示されました。(このあたりからよくわかっていません筆者)

```math
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通りがあります。

```math
\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}\\
```
ここで

```math
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)](https://en.wikipedia.org/wiki/Image_moment)
[OpenCV Documentation](http://opencv.jp/opencv-2.1/cpp/structural_analysis_and_shape_descriptors.html?highlight=moment)


[^1]: raw moment
[^2]: summarized with.
[^3]: central moment
[^4]: translational invariant
[^5]: Hu Moment Invariant