回答編集履歴
1
refine
answer
CHANGED
@@ -2,10 +2,9 @@
|
|
2
2
|
|
3
3
|
[`average_hash`](https://github.com/JohannesBuchner/imagehash/blob/master/imagehash/__init__.py#L132)では文字通りピクセル平均値(`mean()`)を基準値に用いるため、ガンマ補正やヒストグラム補正などの画面全体のピクセル値分布を歪める操作に対してロバストでない、つまりそのような操作によってハッシュ値が大きく変化してしまいます。
|
4
4
|
|
5
|
-
|
6
5
|
一方の[`phash`](https://github.com/JohannesBuchner/imagehash/blob/master/imagehash/__init__.py#L157)では、離散コサイン変換(DCT)によって得られる係数値の中央値(`median`)を基準値として用います。
|
7
6
|
|
8
|
-
DCTを理解している前提での説明:ガンマ補正やヒストグラム補正といった全体的なピクセル値操作
|
7
|
+
DCTを理解している前提での説明:ガンマ補正やヒストグラム補正といった全体的なピクセル値操作をおこなっても、画像データが持つ空間的な構造/情報は維持されるため、DCT係数の大部分を占めるAC係数の分布はあまり変化しません。(※:詳細後述しますが、このPython実装には問題があるように思えます)
|
9
8
|
|
10
9
|
DCTをかなり乱暴に説明すると、1次元8点DCTは「1個の平均値(直流成分;DC)」+「7個のデータ"詳細度"=周波数別に分解された値(交流成分;AC)」への変換です。画像は2次元データですからそれぞれ縦/方向に適用すると2次元8x8点DCTとなり、「1個の平均値(DC)」+「63個のAC値」となります。ガンマ補正やヒストグラム補正はピクセル値を一律で変化させるためDC値に強く影響しますが、AC値はデータがもっている空間的な構造情報(=周波数)に対応するため、そのような変換では値が変化しずらいという性質があります。
|
11
10
|
|
@@ -13,7 +12,7 @@
|
|
13
12
|
|
14
13
|
> ・Average hashでは8x8に縮小していたのにphashでは32×32に縮小していました。DCTを行うには良い大きさらしいですがそれは何故ですか?
|
15
14
|
|
16
|
-
ドキュメントの誤読です。DCT処理にとって好都合というわけではなく、32x32DCT係数のうち8x8
|
15
|
+
ドキュメントの誤読です。DCT処理にとって好都合というわけではなく、32x32DCT係数のうち低周波数側8x8個の係数だけを拾ってくると、画像の低周波情報=おおまかな空間構造をバランスよく捉えられると言っています。なおDCTの計算都合だけでいえば、2のベキ乗ならばOKです。
|
17
16
|
|
18
17
|
---
|
19
18
|
> ・imagehashのphashのアルゴリズム5.の平均値を計算するという所で、『最初の項は除去する』と書いてあるのですがそれはどういうことなのでしょうか?
|
@@ -22,4 +21,4 @@
|
|
22
21
|
|
23
22
|
> 最初の行だけという意味で合ってますかね?
|
24
23
|
|
25
|
-
オリジナルのpHash実装では、2次元DCT係数の **第1行目および第1列目をすべて除去** しているようです。一方、Python imagehashの`phash`ではこの処理を **全く適用して
|
24
|
+
オリジナルのpHash実装では、2次元DCT係数の **第1行目および第1列目をすべて除去** しているようです。一方、Python imagehashの`phash`ではこの処理を **全く適用しておらず**、DC係数も含めてハッシュ計算を行なっています。本来のアルゴリズム意図からすれば、imagehash実装が誤っているようにも思えます。
|