22

私のユーザーは私のウェブサイトに画像をアップロードしています。最初に、既にアップロードされた画像を最初に提供したいと思います。私の考えは、1.既存のすべての画像のある種の画像「ハッシュ」を作成することです2.新しくアップロードされた画像のハッシュを作成し、データベース内の他の画像と比較します

http://www.pureftpd.org/project/libpuzzlehttp://phash.org/などの興味深い解決策をいくつか見つけましたが、1 つ以上の問題がありました。

  1. PHP の非標準の拡張機能が必要です (または PHP にまったくない) - 私にとっては問題ありませんが、私の制御なしに多くのホスティング環境で使用されている人気のある CMS のプラグインとして作成したいと考えています。
  2. 彼らは 2 つの画像を比較していますが、1 対多数 (たとえば数千) を比較する必要があり、1 つずつ比較するのは非常に効果がありません/時間がかかります ... ...

非常に類似した画像のみを見つけても問題ありません(たとえば、サイズが異なる、jpgが再保存されている、またはjpg圧縮率が異なるなど)。

私が得た唯一のアイデアは、画像のサイズをたとえば 5px*5px* 256 色に変更し、その文字列表現を作成してから同じものを見つけることです。しかし、サイズが異なる同じ画像が2つあるだけでも、色にわずかな違いが生じている可能性があるため、100%同じ画像を見つけるだけでは意味がありません。

そのため、画像の文字列表現の適切な形式が必要です。これは、SQL関数で使用して、同様の方法やその他の良い方法を見つけることができます。たとえば、phash は知覚ハッシュを作成するため、2 つの数値が近い場合は画像も近いはずなので、最も近い距離を見つけるだけで済みます。しかし、これも外部ライブラリです。

簡単な方法はありますか?

4

4 に答える 4

23

私は以前にこれとまったく同じ問題を抱えていました。

私がしたことを自由にコピーしてください。うまくいけば、それがあなたの問題を解決するのに役立ちます。


どうやって解決したか

あなたが考えているのと同じように、失敗した最初のアイデアは、すべての画像 (サイズに関係なく) に対して文字列を作成することになったということです。しかし、これはデータベースを超高速でいっぱいにし、効果的ではないことにすぐに気付きました。

次のオプション(それは機能します)は(あなたの5pxアイデアのような)より小さな画像でした。私はまさにそれをしましたが、10px*10px画像を使用しました。各画像の「ハッシュ」を作成する方法はimagecolorat()関数でした。

ここでphp.netを参照してください。

画像の色を受け取ったとき、色が特定されないようrgbに、最も近い に丸めました。50その数字 ( ) は、検索を50どの程度具体的にしたいかによって変更したいものです。

例えば:

// Pixel RGB
rgb(105, 126, 225) // Original
rgb(100, 150, 250) // After rounding numbers to nearest 50

これをすべてのピクセルに対して実行した後 ( 10px*10pxは 100 をrgb()返します)、それらを配列に変換し、データベースにbase64_encode()andとして格納しましたserialize()

類似した画像を検索するとき、アップロードしたい画像に対してまったく同じプロセスを実行し、データベースから画像の「ハッシュ」を抽出してそれらすべてを比較し、一致する丸められたものを確認しましたrgb


チップ

  • 四捨五入が大きいほど、検索の具体性が低くなります (逆も同様です)。50rgb

  • SQLをより具体的にしたい場合は、画像に関する特別な情報や特定の情報をデータベースに保存して、データベースで取得する検索を制限できるようにすることをお勧めします。例えば。縦横比が の場合、データベースから4:3画像のみを取得4:3します。(等)

  • これを完全に5px*取得するのは難しい場合5pxがあるため、提案はphpthumbです。私は構文でそれを使用しました:

phpthumb.php?src=IMAGE_NAME_HERE.png&w=10&h=10&zc=1
// &w=  width of your image
// &h=  height of your image
// &zc= zoom control. 0:Keep aspect ratio, 1:Change to suit your width+height

頑張ってください、私が助けてくれることを願っています。

于 2012-07-05T01:17:51.337 に答える
2

簡単な php 実装については、https ://github.com/kennethrapp/phasher をご覧ください。

ただし、「比較」用のネイティブの mySql 関数があるのだろうか (上記の php クラスを参照)

于 2013-05-06T19:57:30.330 に答える
0

画像を 8x8 に縮小してから、RGB を 1 バイトの HSV に変換するので、結果のハッシュは 172 バイトの文字列になります。

HSVHSVHSVHSVHSVHSVHSVHSV... (from 8x8 block, 172 bytes long)
0fff0f3ffff4373f346fff00...

100% 正確というわけではありません (一部の重複は見つかりません) が、問題なく動作し、偽陽性の結果はないようです。

于 2013-12-17T11:01:01.110 に答える
0

Putting it down in an academical way, what you are looking for is a similarity function which takes in two images and returns an indicator how far/similar the two images are. This indicator could easily be a decimal number ranging from -1 to 1 (far apart to very close). Once you have this function you can set an image as a reference and compare all the images against it. Then finding the similar images to one is as simple as finding the closest similarity factor to it which is done with a simple search over a double field within an RDBMS like MySQL.

Now all that remains is how to define the similarity function. To be honest this is problem specific. It depends on what you call similar. But covariance is usually a good starting point, it just needs your two images to be of the same size which I think is of no big deal. Yet you can find lots of other ideas searching for 'similarity measures between two images'.

于 2013-12-28T20:10:33.963 に答える