ビジュアル c.. で 2 つの画像を比較する効率的な方法は何ですか? また、どの形式の画像を保存する必要がありますか(bmp、gif、jpeg .....)?いくつかの提案をお願いします
5 に答える
比較しようとしている画像に、区別しようとしている独特の特性がある場合は、PCAが最適な方法です。必要なファイルの形式の問題は、実際には関係ありません。あなたはそれを数の配列としてプログラムにロードし、分析を行う必要があります。
MJPEG ストリームから動きを検出し、動きが発生した場合にのみ画像を記録するために、同様のことを行いました。
デコードされた各画像について、次の方法を使用して以前と比較しました。
- 画像のサイズを効果的なサムネイル サイズに変更します (かなり高解像度の画像のサイズを 10 分の 1 に縮小しました)。
- 各ピクセルの明るさを前の画像と比較し、はるかに明るいか暗い場合にフラグを立てます (しきい値 1)。
- ピクセルごとにそれを行ったら、異なるピクセルの数を使用して、画像が同じか異なるかを判断できます (しきい値 2)。
次に、2 つのしきい値を調整するだけでした。
System.Drawing.Bitmap を使用して比較を行いましたが、ソース イメージが jpg であるため、いくつかのアーティファクトがありました。
自分でロールする場合は、画像の違いを比較するのに便利な簡単な方法です。
あなたの質問は、複雑さの点でワームの缶を開きます。
2 つの画像を比較して同じかどうかを確認する場合は、ファイルに対して md5 を実行する必要があります (結果を歪める可能性のあるメタ情報を削除します)。
見た目が同じかどうかを比較する場合は、まったく別の話です。「同じに見える」とは、非常に大まかな意味を意図しています (たとえば、まったく同じ画像ですが、2 つの異なるファイル形式で保存されているなど)。このためには、2 つの画像が同じである確率を与える高度なアルゴリズムが必要です。この分野の専門家ではないので、次の「頭から発明した」アルゴリズムを実行します。
- 画像から任意のピクセル ポイントのセットを取得します。
- 各ピクセルに対して、色が近い周囲のピクセルからポリゴンを「成長」させます(HSV色空間による)
- 他の画像についても同じことを行います
- 1 つの画像の各ポリゴンについて、他の画像の他のすべてのポリゴンとの幾何学的な類似性を確認し、最も高い値を選択します。この値をポリゴンの面積で割ります (正規化するため)。
- 得られた最大値からベクトルを作成する
- このベクトルのノルムが高いほど、2 つの画像が同じである可能性が高くなります。
このアルゴリズムは、色のずれや画像の回転の影響を受けないようにする必要があります。たぶんスケーリングもします(面積に対して正規化します)。繰り返しますが、専門家ではありません。おそらくもっと優れた方法があり、子猫を泣かせる可能性があります。
2 つの画像が知覚的に同じかどうかを判断したい場合は、画像ハッシュ アルゴリズムを使用するのが最善の方法だと思います。両方の画像のハッシュを計算すると、ハッシュを使用して、それらがどの程度一致するかの信頼度を得ることができます。
私がある程度成功したのはpHashですが、Visual C で使用するのがどれほど簡単かはわかりません。「Geometric Hashing」または「Image Hashing」を検索すると役立つ場合があります。
厳密な同一性のテストは簡単です。ソース イメージ A のすべてのピクセルをイメージ B の対応するピクセル値と比較するだけです。すべてのピクセルが同一であれば、イメージは同一です。
しかし、私はこの種の厳密なアイデンティティを望んでいないと思います. 画像 B に特定の変換が適用されている場合でも、画像を「同一」にしたい場合があります。これらの変換の例は次のとおりです。
- 画像の明るさをグローバルに変更 (ピクセルごと)
- 画像の明るさを局所的に変更する (特定の領域のすべてのピクセルに対して)
- 全体的または局所的に画像の彩度を変更する
- ガンマ補正
- ある種のフィルタを画像に適用する (例: ぼかし、シャープ化)
- 画像のサイズの変更
- 回転
たとえば、画像を印刷して再度スキャンすると、おそらく上記のすべてが含まれます。
簡単に言えば、どの変換を「同一」として扱いたいかを決定し、それらの変換に対して不変である画像測定値を見つける必要があります。(または、翻訳を元に戻そうとすることもできますが、画像のぼかしやクリッピングなど、変換によって画像から情報が削除される場合は不可能です)