PHPを使用して重複する写真を識別する方法

プロジェクトのヒューマンファクターをキャンセルした人はいません。ユーザーが自分でサイトに写真をアップロードした場合、重複を避けることはできません。 何千ものファイルに関しては、目ですべてをレビューすることはできません。また、写真を繰り返すと、誰も必要としないだけでなく、スペースを取り、リソースを消費し、最終的に作業が遅くなります。







したがって、遅かれ早かれ、繰り返しを検索するプロセスを自動化するという疑問が生じます。ここでは、主なものを検討し、ビジネスで試してみましょう。



ハッシュ関数によるファイルの比較



重複を識別する1つの方法は、指定されたファイルの内容からハッシュ値を生成することによりファイルを比較することです。



画像ハッシュを計算する簡単な例:



<?php imagecreatefrompng('image.png'); echo hash_file('md5', 'image.png'); ?>
      
      





結果は次のようになります。bff8b4bc8b5c1c1d5b3211dfb21d1e76



2つのイメージのハッシュが一致する場合、イメージは同じです。

この方法は、まったく同じ画像に対してのみ機能し、わずかな違いがあり、感覚がゼロであるため、最も正確な方法とはほど遠いものです。







Imagemagick



Imagick :: compareImages画像処理関数は、再構成された画像と画像間の差を含む配列を返します。



2つの画像を比較するときの使用例:



 <?php header("Content-Type: image/png"); $image1 = new imagick("image1.png"); $image2 = new imagick("image2.png"); $result = $image1->compareImages($image2, Imagick::METRIC_MEANSQUAREERROR); $result[0]->setImageFormat("png"); echo $result[0]; ?>
      
      





その結果、比較された2つの写真が1つに成形され、その上に違いが見えます。

各パラメーターの違いの数値表現を取得することもできます( Webサイトからの例)。



 -> compare -verbose -metric mae rose.jpg reconstruct.jpg difference.png Image: rose.jpg Channel distortion: MAE red: 2282.91 (0.034835) green: 1853.99 (0.0282901) blue: 2008.67 (0.0306503) all: 1536.39 (0.0234439)
      
      







gd2およびlibpuzzle



重複をすばやく見つけるには、 gd2およびlibpuzzleライブラリをインストールする必要があります



インストール:



 apt-get install libpuzzle-php php5-gd
      
      





Libpuzzleは、画像( GIFPNGJPEG )の視覚的な類似性をすばやく検索するように設計されています。 まず、ビットマップはブロックに分割されます。特に重要な情報を含まないフレームは自動的に破棄されます。 隣接するブロックの違いがベクトルを形成します-これはいわゆる画像キャプションです。 写真の類似性は、2つのそのようなベクトル間の距離によって決まります。 したがって、通常、色の変更、サイズ変更、または圧縮はlibpuzzleの出力に影響しません。







Libpuzzleは非常に使いやすいです。 2つの画像の署名計算:



 $cvec1 = puzzle_fill_cvec_from_file('img1.jpg'); $cvec2 = puzzle_fill_cvec_from_file('img2.jpg');
      
      





署名間の距離の計算:



 $d = puzzle_vector_normalized_distance($cvec1, $cvec2);
      
      





画像の類似性の確認:



 if ($d < PUZZLE_CVEC_SIMILARITY_LOWER_THRESHOLD) { echo "Pictures are looking similar\n"; } else { echo "Pictures are different, distance=$d\n"; }
      
      





データベースに保存するための署名の圧縮:



 $compress_cvec1 = puzzle_compress_cvec($cvec1); $compress_cvec2 = puzzle_compress_cvec($cvec2);
      
      







知覚ハッシュ



ほとんどの場合、重複を見つける最も正確な方法は、 知覚ハッシュを使用してファイルを比較することです。 類似性チェックは、2つのハッシュ間の異なる位置の数をカウントすることで行われます。これがハミング距離です。 距離が小さいほど、一致が大きくなります。







最初の方法と異なるのは、同じ/等しくないだけでなく、相違の程度も示す点です。 この原則の詳細については、 優れた翻訳をご覧ください。



UNIXプラットフォームへのインストールは次のようになります。



 $ ./phpize $ ./configure [--with-pHash=...] $ make $ make test $ [sudo] make install
      
      







i.onthe.io/phashで実際に試すことができます。 インターフェイスと「均一性」の出力インジケータを介して画像をダウンロードします。



仕組み



最初の画像のハッシュを取得します:



 $phash1 = ph_dct_imagehash($file1);
      
      





2番目の画像のハッシュを取得します。



 $phash2 = ph_dct_imagehash($file2);
      
      





2つの画像間のハミング距離を取得します。



 $dist = ph_image_dist($phash1,$phash2);
      
      







同じ写真でほとんどすべての可能な操作を行い、どの変更がpHashを介した重複の検出を妨げ、どの変更がそうでないかを確認しました。



たとえば、鏡像の場合、画像は認識されないままです。

しかし、好きなだけ色を再生できます-これは比較の結果に影響しません。

RGBチャネルの操作について言えないことは、ジョンは再び認識しませんでしたが、この場合のハミング距離ははるかに短くなります。



他の結果は次のようになります。

干渉しない(ハミング距離= 0) 干渉(カッコ内のハミング距離)
変更されたファイル名 クロップ(34)*
フォーマット(JPEG、PNG、GIF) 90°回転(32)**
Google PageSpeed Optimization 鏡像(36)
縦横比の変更 RGBチャネルでの曲線の再配置(18)
色域とシャープネスを変更する


*トリミングされた領域のサイズに依存します。 画像から数ピクセルの厚さの小さなフレームを切り取ると、ハミング距離はゼロになるため、類似性は100%です。 しかし、作物がより具体的になればなるほど-距離が長くなればなるほど-重複を見つける可能性は低くなります。 知覚的ハッシュを介したトリミングされた複製の検索については、 こちらをご覧ください



**作物と同じです。 数度回転する場合、距離は重要ではありませんが、傾斜角が大きいほど、差は大きくなります。



アブストラクト



  1. ImageMagickを使用して画像を比較し、ハッシュ比較を使用して完全に同一の画像を検索します。
  2. わずかに変更された画像を見つけるには、 libpuzzleライブラリを使用します。
  3. 知覚的ハッシュによる比較は最も信頼性の高いものの1つであり、 ここで試すことができます



All Articles