類似性のために2つの画像を比較する簡単で高速な方法が必要です。つまりまったく同じものが含まれているが、背景が若干異なる場合があり、数ピクセル単位で移動/サイズ変更される場合は、高い値を取得します。
(より具体的には、それが重要な場合:1つの画像はアイコンであり、もう1つの画像はスクリーンショットのサブエリアです。そのサブエリアがまさにアイコンであるかどうかを知りたいです。)
私は手元にOpenCVを持っていますが、まだ慣れていません。
これまで考えていた可能性の1つは、両方の写真を10x10のセルに分割し、それらの100個のセルのそれぞれについて、色のヒストグラムを比較することです。次に、作成されたしきい値を設定し、取得した値がそのしきい値を超えている場合、それらは類似していると想定します。
私はまだそれをどれほどうまくやっているか試していませんが、それで十分だと思います。画像はすでにかなり似ているので(私の使用例では)、かなり高いしきい値を使用できます。
多かれ少なかれ機能する他の解決策は他にもたくさんあると思います(タスク自体は非常に単純なので、本当に類似している場合にのみ類似性を検出したいので)。何を提案しますか?
画像から署名/指紋/ハッシュを取得することに関して、いくつかの非常に関連する/同様の質問があります。
また、指紋を取得する機能を備えたこれらの実装に出くわしました。
知覚的画像ハッシュに関するいくつかの議論: here
少しオフトピック:音声指紋を作成する多くの方法があります。 MusicBrainz は、曲の指紋ベースの検索を提供するWebサービスで、 Wikiの概要 があります。現在、 AcoustID を使用しています。これは、正確な(またはほとんど正確な)一致を見つけるためのものです。同様の一致を見つけるには(またはスニペットやノイズが多い場合)、 Echoprint を見てください。関連するSO質問は here です。したがって、これはオーディオ用に解決されているようです。これらのソリューションはすべて非常に良好に機能します。
一般的なファジー検索に関するやや一般的な質問は here です。例えば。 局所性に敏感なハッシュ と 最近傍検索 があります。
スクリーンショットまたはアイコンを変換できますか(スケーリング、回転、傾斜...)?私の頭の上には、おそらくあなたを助けることができるかなりの方法があります:
これらのほとんどはすでにOpenCVに実装されています-たとえば、cvMatchTemplateメソッドを参照してください(ヒストグラムマッチングを使用): http://dasl.mem.drexel.edu/~noahKuntz/openCVTut6.html 。顕著なポイント/エリア検出器も利用可能です- OpenCV Feature Detection を参照してください。
私は最近同じ問題に直面し、この問題を解決するために(2つの画像を比較するためのシンプルで高速なアルゴリズム)、すべてのために、opencv_contribに img_hash module を提供します。詳細は このリンク 。
img_hashモジュールは、非常に使いやすい6つの画像ハッシュアルゴリズムを提供します。
コード例
#include <opencv2/core.hpp>
#include <opencv2/core/ocl.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/img_hash.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
void compute(cv::Ptr<cv::img_hash::ImgHashBase> algo)
{
auto input = cv::imread("lena.png");
cv::Mat similar_img;
//detect similiar image after blur attack
cv::GaussianBlur(input, similar_img, {7,7}, 2, 2);
cv::imwrite("lena_blur.png", similar_img);
cv::Mat hash_input, hash_similar;
algo->compute(input, hash_input);
algo->compute(similar_img, hash_similar);
std::cout<<"gaussian blur attack : "<<
algo->compare(hash_input, hash_similar)<<std::endl;
//detect similar image after shift attack
similar_img.setTo(0);
input(cv::Rect(0,10, input.cols,input.rows-10)).
copyTo(similar_img(cv::Rect(0,0,input.cols,input.rows-10)));
cv::imwrite("lena_shift.png", similar_img);
algo->compute(similar_img, hash_similar);
std::cout<<"shift attack : "<<
algo->compare(hash_input, hash_similar)<<std::endl;
//detect similar image after resize
cv::resize(input, similar_img, {120, 40});
cv::imwrite("lena_resize.png", similar_img);
algo->compute(similar_img, hash_similar);
std::cout<<"resize attack : "<<
algo->compare(hash_input, hash_similar)<<std::endl;
}
int main()
{
using namespace cv::img_hash;
//disable opencl acceleration may(or may not) boost up speed of img_hash
cv::ocl::setUseOpenCL(false);
//if the value after compare <= 8, that means the images
//very similar to each other
compute(ColorMomentHash::create());
//there are other algorithms you can try out
//every algorithms have their pros and cons
compute(AverageHash::create());
compute(PHash::create());
compute(MarrHildrethHash::create());
compute(RadialVarianceHash::create());
//BlockMeanHash support mode 0 and mode 1, they associate to
//mode 1 and mode 2 of PHash library
compute(BlockMeanHash::create(0));
compute(BlockMeanHash::create(1));
}
この場合、ColorMomentHashは最高の結果をもたらします
各アルゴリズムの長所と短所
Img_hashのパフォーマンスも良好です
PHashライブラリとの速度比較(ukbenchからの100枚の画像)
これらのアルゴリズムの推奨しきい値を知りたい場合は、この投稿を確認してください( http://qtandopencv.blogspot.my/2016/06/introduction-to-image-hash-module-of.html =)。 img_hashモジュールのパフォーマンスを測定する方法に興味がある場合(速度とさまざまな攻撃を含む)、このリンクを確認してください( http://qtandopencv.blogspot.my/2016/06/speed-up-image -hashing-of-opencvimghash.html )。
スクリーンショットにはアイコンのみが含まれていますか?その場合、2つの画像のL2距離で十分です。 L2距離が機能しない場合、次のステップは、 Lucas-Kanade のような単純で十分に確立されたものを試すことです。 OpenCVで利用できると確信しています。
2つの写真の類似性に関するインデックスを取得する場合は、メトリックからSSIMインデックスをお勧めします。人間の目とより一致しています。それについての記事は次のとおりです: Structural Similarity Index
OpenCVにも実装されており、GPUで高速化できます: OpenCV SSIM with GPU
テンプレート(アイコン)をテスト領域に正確に配置できることが確実な場合は、ピクセル差の古い合計が機能します。
アライメントがほんの少しだけずれている場合は、ピクセルの差の合計を見つける前に cv :: GaussianBlur で両方の画像をローパスできます。
アライメントの品質が潜在的に低い場合、 Histogram of Oriented Gradients またはOpenCVの便利なキーポイント検出/記述子アルゴリズムのいずれか( SIFT または SURF )。
同一の画像をマッチングする場合-L2距離のコード
// Compare two images by getting the L2 error (square-root of sum of squared error).
double getSimilarity( const Mat A, const Mat B ) {
if ( A.rows > 0 && A.rows == B.rows && A.cols > 0 && A.cols == B.cols ) {
// Calculate the L2 relative error between images.
double errorL2 = norm( A, B, CV_L2 );
// Convert to a reasonable scale, since L2 error is summed across all pixels of the image.
double similarity = errorL2 / (double)( A.rows * A.cols );
return similarity;
}
else {
//Images have a different size
return 100000000.0; // Return a bad value
}
速い。しかし、照明/視点などの変化に対して堅牢ではありません。 ソース
画像の類似性を比較する場合は、OpenCVを使用することをお勧めします。 OpenCVでは、機能のマッチングとテンプレートのマッチングはほとんどありません。特徴マッチングには、SURF、SIFT、FASTなどのディテクターがあります。これを使用して、画像を検出、説明、および照合できます。その後、特定のインデックスを使用して、2つの画像間の一致数を見つけることができます。