検索分野では、Google画像検索、Baidu画像検索、Taobaoの商品写真検索など、「類似画像・類似商品を探す」などの関連機能が以前から登場しています。画像の類似性を計算する同様の機能を実現するには、高尚な「人工知能」を使用するほか、実際には、js といくつかの簡単なアルゴリズムを通じてほぼ同様の効果を実現できます。 この記事を読む前に、Ruan Yifeng が何年も前に書いた記事「類似画像検索の原理」を読むことを強くお勧めします。この記事で取り上げているアルゴリズムも、この論文から引用したものです。 体験アドレス: https://img-compare.netlify.com/ 特徴抽出アルゴリズム 理解を容易にするために、各アルゴリズムは「特徴抽出」と「特徴比較」という 2 つのステップを経ます。次に、各アルゴリズムの「特徴抽出」ステップの詳細な解釈に焦点を当て、「特徴比較」については個別に説明します。 平均ハッシュアルゴリズム Ruan Da の記事によると、「平均ハッシュ アルゴリズム」は主に次の手順で構成されています。 最初のステップは、サイズを 8×8 に縮小して画像の詳細を削除し、構造や明暗などの基本的な情報のみを保持し、サイズや比率の違いによって生じる画像の違いを破棄することです。 2 番目のステップは、色を単純化することです。縮小した画像をグレースケールに変換します。 3 番目のステップは平均値を計算することです。すべてのピクセルの平均グレースケール値を計算します。 4 番目のステップは、ピクセルのグレースケールを比較することです。 64 ピクセルのグレースケール値を平均値と比較します。平均値以上の場合は 1 として記録され、平均値未満の場合は 0 として記録されます。 ステップ 5: ハッシュ値を計算します。前のステップの比較結果を組み合わせると、このイメージのフィンガープリントである 64 ビットの整数が形成されます。 6番目のステップは、ハッシュ値の差を計算し、類似度(ハミング距離またはコサイン値)を取得することです。 「平均ハッシュアルゴリズム」の原理と手順を理解したら、コーディングを開始できます。コードを読みやすくするために、この記事のすべての例では TypeScript を使用します。 画像圧縮: キャンバスの drawImage() メソッドを使用して画像圧縮を実装し、getImageData() メソッドを使用して ImageData オブジェクトを取得します。
なぜキャンバスを使って画像を圧縮できるのかと疑問に思う読者もいるかもしれません。簡単に言えば、「大きな画像」を「小さなキャンバス」に描画するために、類似した色を持ついくつかの隣接するピクセルが削除されることが多く、これにより画像の情報量が効果的に削減され、圧縮効果が得られます。 上記の CompressImg() 関数では、new Image() を使用して画像を読み込み、プリセット画像の幅と高さの値を設定して画像を指定されたサイズに圧縮し、最後に圧縮された画像の ImageData データを取得します。これは、画像のすべてのピクセルに関する情報を取得できることも意味します。 ImageData の詳細については、MDN ドキュメントを参照してください。 グレースケール画像 カラー画像をグレースケール画像に変換するには、まず「グレースケール画像」の概念を理解する必要があります。 Wikipedia ではグレースケール画像を次のように説明しています: コンピュータ サイエンスでは、グレースケールのデジタル画像とは、ピクセルごとに 1 つの色のみがサンプリングされた画像です。 ほとんどの場合、任意の色は 3 つのカラー チャネル (R、G、B) の明るさと色空間 (A) で構成でき、ピクセルは 1 つの色のみを表示するため、「ピクセル => RGBA」の対応関係が得られます。 「各ピクセルには 1 つのサンプル色のみがある」とは、このピクセルを構成する 3 つの原色チャネルの明るさが等しいことを意味するため、RGB の平均値を計算するだけで済みます。
ImageData.data は Uint8ClampedArray 配列であり、「RGBA 配列」として理解できます。配列内の各数値の範囲は 0 から 255 で、4 つの数値の各グループはピクセルの RGBA 値を表します。 ImageData は読み取り専用オブジェクトなので、context.createImageData() を使用して新しい ImageData オブジェクトを作成するための createImageData() メソッドを記述する必要があります。 グレースケール画像を取得したら、指紋抽出を実行できます。 指紋抽出 「平均ハッシュアルゴリズム」では、グレースケール画像内のピクセルのグレースケール値が平均値より大きい場合は 1 とみなされ、そうでない場合は 0 とみなされます。これらの情報を組み合わせると、画像の指紋が作成されます。グレースケール画像の ImageData オブジェクトがあるので、指紋の抽出は簡単になります。
上記の一連の手順により、「平均ハッシュ アルゴリズム」を通じて画像の指紋情報を取得できます (例はサイズ 8×8 のグレースケール画像です)。 知覚ハッシュアルゴリズム 「知覚ハッシュ アルゴリズム」の詳細な紹介については、こちらの記事「知覚ハッシュ アルゴリズムに基づく視覚オブジェクト追跡」を参照してください。 簡単に言えば、離散コサイン変換の後、アルゴリズムは画像をピクセル領域から周波数領域に変換し、有効な情報を運ぶ低周波成分が DCT マトリックスの左上隅に集中するため、この機能を使用して画像の特徴を抽出できます。 アルゴリズムの手順は次のとおりです。
コードに戻って、まず DCT メソッドを追加します。
次に、DCT 方式で生成された 1 次元配列を 2 次元配列 (行列) にアップグレードし、行列から「左上隅」の内容を取得するという 2 つの行列処理方式を追加します。
以前「平均ハッシュアルゴリズム」で記述したグレースケール画像変換関数 createGrayscale() を再利用すると、「知覚ハッシュアルゴリズム」の固有値を取得できます。
色分布法 まず、Ruan Da の「色彩配分法」の説明から一節を引用します。 Ruan Da は 256 色の値を 4 つに簡略化しました。この原則に基づいて、色配分法のアルゴリズムを設計するときに、この間隔の分割を変更可能に設定できます。唯一の要件は、間隔の数が 256 で割り切れる必要があることです。アルゴリズムは次のとおりです。
色の値を簡略化した後、さまざまなグループに分類できます。
最後に、各同一グループの合計数を数えるだけです。
コンテンツ機能メソッド 「コンテンツ特徴方式」とは、画像をグレースケール画像に変換した後、「バイナリ画像」に変換し、ピクセル値(黒または白)に基づいて指紋を形成して比較する方法を指します。このアルゴリズムの中核は、バイナリ画像を生成するための「しきい値」を見つけることです。 グレースケール画像を生成するために、「平均ハッシュ アルゴリズム」で説明した RGB 平均を取る方法とは異なり、ここでは加重アプローチを使用します。なぜこれをするのですか?これには色彩科学のいくつかの概念が関係します。 詳細については、以下に簡単にまとめた「グレースケールから RGB への変換」という記事を参照してください。 最も簡単な方法は、平均 RGB 値を持つグレースケール画像を使用することですが、赤、緑、青の 3 色の波長と、それらが画像全体に与える影響は無視されます。次の図を例にとると、RGB の平均値をそのままグレースケールとして取得すると、処理されたグレースケール画像は全体的に暗くなり、その後のバイナリ画像の生成に大きな支障をきたすことになります。 では、どうすればこの状況を改善できるのでしょうか?答えは、RGB の 3 つの色に異なる重みを追加することです。赤色光は波長が長く、緑色光は波長が短く視覚への刺激が比較的少ないことを考えると、赤色光の比重を意図的に減らし、緑色光の比重を増やす必要があります。統計の結果、より良い重量比は R:G:B = 0.299:0.587:0.114 です。 こうすることで、グレースケール処理関数を取得できます。
上記の関数は grayData 配列を返します。この配列の各要素はピクセルのグレー値を表します (RBG は同じ値を持つため、必要な値は 1 つだけです)。次に、Otsu法を使用して2値画像の閾値を計算します。 「大金法」については、すでに阮大氏の記事で詳しく論じられているので、ここでは詳しく述べません。ここで「Otsu Method」の Java 実装を見つけ、後で少し修正して js バージョンに変更しました。
OTSUAlgorithm() 関数は ImageData オブジェクトを受け取ります。前のステップで toGray() メソッドを通じてグレースケール値リストを取得した後、「Otsu 法」に従って最適なしきい値を計算して返します。次に、このしきい値を使用して元の画像を処理してバイナリ画像を取得します。
画像サイズが N×N の場合、バイナリ画像の「白か黒か」の特性に基づいて、N×N の 0-1 行列が得られます。これが指紋です。 特徴マッチングアルゴリズム さまざまな方法でさまざまな種類の画像フィンガープリント(特徴)を取得した後、それらをどのように比較すればよいでしょうか?ここでは、3 つの比較アルゴリズムを紹介し、これらのアルゴリズムが適用可能な状況を分析します。 ハミング距離 以下はWikipediaの「ハミング距離」の説明です。 情報理論では、同じ長さの 2 つの文字列間のハミング距離は、2 つの文字列の対応する位置にある異なる文字の数です。つまり、ある文字列を別の文字列に変換するために置き換える必要がある文字の数です。 例えば:
意味を理解したら、ハミング距離を計算するメソッドを書くことができます。
hammingDistance() メソッドを使用して、Wikipedia の例を確認します。 検証結果は予想通りです。 ハミング距離がわかれば、同じ長さの 2 つの文字列間の類似性もわかります (ハミング距離が小さいほど、類似性は大きくなります)。 類似度 = (文字列の長さ - ハミング距離) / 文字列の長さ コサイン類似度 Wikipedia からコサイン類似度の定義を学ぶことができます。 コサイン類似度は、2 つのベクトル間の角度のコサインを測定することによって、2 つのベクトル間の類似度を測定します。 0 度の角度のコサインは 1 であり、その他の角度のコサインは 1 以下であり、最小値は -1 です。したがって、2 つのベクトル間の角度の余弦によって、2 つのベクトルがほぼ同じ方向を向いているかどうかが決まります。 2 つのベクトルが同じ方向を向いている場合、コサイン類似度値は 1 になります。2 つのベクトル間の角度が 90° の場合、コサイン類似度値は 0 になります。2 つのベクトルが完全に反対方向を向いている場合、コサイン類似度値は -1 になります。これはベクトルの長さとは無関係であり、ベクトルが指す方向のみに関係することがわかります。コサイン類似度は通常、正の空間で使用されるため、指定される値は 0 から 1 の間になります。 これらの境界は任意の次元のベクトル空間に当てはまり、コサイン類似度は高次元の正の空間で最も一般的に使用されることに注意してください。 コサイン類似度は、2 つのベクトル間の角度を計算し、2 つのベクトルの方向が類似しているかどうかを直感的に示します。これは、2 つの N×N 0-1 行列の類似度を計算するのに非常に便利です。コサイン類似度の式に従って、その js 実装を記述できます。
2つの比較アルゴリズムの適用可能なシナリオ 「ハミング距離」と「コサイン類似度」という 2 つの特徴比較アルゴリズムを理解した後、どの特徴抽出アルゴリズムのシナリオに適しているかを確認する必要があります。 まずは「色の配分方法」について見てみましょう。 「色分布法」では、画像の色を区間に分割し、異なる色区間の数を数えることで特徴を取得します。ここでの固有値は「量」、つまり0-1以外の行列に関連しています。 明らかに、2 つの「色分布方法」の特徴の類似性を比較するには、「ハミング距離」は適用できず、「コサイン類似度」を通じてのみ計算できます。 次に「平均ハッシュアルゴリズム」と「コンテンツ特徴量法」について見てみましょう。結果から、両方の特徴抽出アルゴリズムは N×N 0-1 行列を取得でき、行列内の要素の値は「量」とは関係なく、0-1 のみであることがわかります。そのため、「ハミング距離」や「コサイン類似度」による類似度の計算に適しています。 計算精度 画像の特徴を抽出し、比較する方法を理解した後、最も重要なことは類似性の計算精度を理解することです。 この記事で説明されている類似性は客観的なアルゴリズムによってのみ達成されますが、2 つの画像が「類似している」かどうかを判断することは非常に主観的な問題です。そこで私は、異なるアルゴリズムと精度を使用して 2 つの画像の類似性を計算できるシンプルなサービスを作成しました。 https://img-compare.netlify.com/ さまざまな方法でさまざまな資料を比較した結果、次のような非常に主観的な結論に達しました。
まとめると、3 つの特徴抽出アルゴリズムと 2 つの特徴比較アルゴリズムにはそれぞれ長所と短所があり、実際のアプリケーションではさまざまな状況に応じて柔軟に選択する必要があります。 要約する この記事は、Ruan Yifeng の「類似画像検索の原則」に関する 2 つの記事を読んで、自分の実践を要約した後に書かれました。色彩や数学などの分野に対する私の理解は浅いため、記事には間違いが含まれている可能性があります。間違った記述を見つけた場合は、メッセージを残していただければ、すぐに修正します。 |
<<: このアルゴリズムはアーキテクチャを自動的に最適化し、エンジニアがニューラルネットワークを設計するのに役立ちます。
>>: 人工知能は、電力網とユビキタス電力のIoTの構築と開発にとって重要な方向性となるだろう
開発手段。イノベーションの結果は、企業が市場のニーズを満たす新製品を継続的に設計・生産することを奨励...
C# DES アルゴリズムの暗号化と復号化は、開発のセキュリティ部分として、その使用方法を理解する必...
導入これら 12 の質問は、現在の面接で最も人気のある質問です。これらは非常に基本的な質問ですが、面...
[51CTO.comより引用] 2013年頃、携帯電話やパソコンに短編動画が大量に登場し、低コスト、...
[[401318]]人工知能はリアルタイムで意思決定を行う能力があり、事前にプログラムされたアルゴリ...
機械学習が「人間レベル」の能力に到達するには、多くのトレーニング反復とラベル付きデータが必要です。こ...
今日、現代科学技術の出現と発展、そしてさまざまなインテリジェント技術の登場により、人類の宇宙旅行はよ...
なぜ組織は機械学習のガバナンスに苦労するのでしょうか? 組織の機械学習ガバナンスに取り組もうとすると...
[[432947]] JAVA ベースで開発された Weka は、機械学習やデータマイニングに適した...
[[440100]]半導体チップの継続的な不足が世界の自動車生産の減少につながるとの予測が高まって...