[編集] 画像比較のためのコードを考案しました。マッチング部分はまだ少し欠陥があり、私はいくつかの支援が大好きです。プロジェクトは- GitHub にあります。
私はこれらの2つの画像を持っています Img1 そして Img2:
OpenCVで次のコマンドを使用すると
Mat img1 = Highgui.imread("mnt/sdcard/IMG-20121228.jpg");
Mat img2 = Highgui.imread("mnt/sdcard/IMG-20121228-1.jpg");
try{
double l2_norm = Core.norm( img1, img2 );
tv.setText(l2_norm+"");
} catch(Exception e) {
//image is not a duplicate
}
L2_normの値が2倍になります。この二重の値は、重複する画像ペアによって異なります。ただし、イメージが異なる場合は、例外がスローされます。これは重複する画像をどのように識別するか?またはより良い方法はありますか?私は広範囲にグーグルで検索しましたが、本当に説得力のある答えを見つけることができませんでした。 2つの画像を比較し、画像に応じてtrue
またはfalse
のブール値を取得する方法について、コードと説明を教えてください。
編集
Scalar blah= Core.sumElems(img2);
Scalar blah1=Core.sumElems(img1);
if(blah.equals(blah1))
{
tv.setText("same image");
}
}
私はこれを試しましたが、if
条件が満たされることはありません。いくつかの違いがあると思いますが、compare
のScalar
関数はありません。私は何をしますか?
編集する
try{
Scalar blah= Core.sumElems(img2);
Scalar blah1=Core.sumElems(img1);
String b=blah.toString();
String b1=blah1.toString();
System.out.println(b+" "+b1);
double comp=b.compareTo(b1);
tv.setText(""+comp);
}
この方法にも欠陥があります。ある程度の精度で画像を比較するために使用できますが、画像のサイズが異なる場合は失敗します。
画像のサイズが異なり、スカラー値を印刷すると、次のようになります。
[9768383.0, 1.0052889E7, 1.0381814E7, 0.0] [1.5897384E7, 1.6322252E7, 1.690251E7, 0.0]
同じサイズの画像を比較した場合と比べて、それほど大きくはありませんが、2番目と3番目の数値間の変動は大きくありません。ただし、最初の数はほとんどの変化を被ります。
2つの画像の内容を比較する最も速い方法は何でしょうか?
[編集]
私が見つけたコードを使用しています here 。
私が理解できないのは、MatOfKeyPoint
変数keypoints
とlogoKeypoints
を初期化する方法です。これが私のコードスニペットです:
FeatureDetector detector = FeatureDetector.create(FeatureDetector.SURF);
//FeatureDetector detector = FeatureDetector.create(FeatureDetector.FAST);
//Imgproc.cvtColor(img1, img1, Imgproc.COLOR_RGBA2RGB);
//Imgproc.cvtColor(img2, img2, Imgproc.COLOR_RGBA2RGB);
DescriptorExtractor SurfExtractor = DescriptorExtractor
.create(DescriptorExtractor.SURF);
//extract keypoints
MatOfKeyPoint keypoints, logoKeypoints;
long time= System.currentTimeMillis();
detector.detect(img1, keypoints);
Log.d("LOG!", "number of query Keypoints= " + keypoints.size());
detector.detect(img2, logoKeypoints);
Log.d("LOG!", "number of logo Keypoints= " + logoKeypoints.size());
Log.d("LOG!", "keypoint calculation time elapsed" + (System.currentTimeMillis() -time));
//Descript keypoints
long time2 = System.currentTimeMillis();
Mat descriptors = new Mat();
Mat logoDescriptors = new Mat();
Log.d("LOG!", "logo type" + img2.type() + " intype" + img1.type());
SurfExtractor.compute(img1, keypoints, descriptors);
SurfExtractor.compute(img2, logoKeypoints, logoDescriptors);
Log.d("LOG!", "Description time elapsed" + (System.currentTimeMillis()- time2));
変数keypoints
とlogoKeypoints
をnullに初期化できないのは明らかです。その場合、nullポインタ例外が発生します。どうすれば初期化できますか?
これは単純な質問ではなく、従うことができるさまざまな概念があることを理解する必要があります。私はソースコードなしの2つのソリューションのみを指摘します。
これがお役に立てば幸いです。ご不明な点がございましたらお問い合わせください。
[UPDATE-1]C++チュートリアル: http://morf.lv/modules.php?name=tutorials&lasit=2# .UR-ewKU3vCk
一部のJavaCVチュートリアル: http://code.google.com/p/javacv/w/list
[UPDATE-2]以下は、デフォルトパラメータを使用したSIFT-DetectorおよびSIFT-Descriptorの例です。ホモグラフィのRANSACしきい値は65、再投影エラー(イプシロン)は10、交差検証が有効です。あなたは一致したものを数えることを試みることができます。 Inliner-Outlier-Ratioが高すぎる場合、このペアが重複していると見なされる可能性があります。 例:これらの画像は、IMG1で180キーポイント、IMG2で198キーポイントを生成します。一致する記述子は163であり、そのうち3つだけが外れ値です。したがって、これは本当に良い比率を提供します。これは、これらの画像が重複している可能性があることを意味するだけです。
[UPDATE-3]MatOfKeypointsを初期化できる理由がわかりません。 APIを読みました で、パブリックコンストラクタがあります。 AND:分析する画像のマットを使用できます。これはすごく素敵。 =)
MatOfKeyPoint reference = new MatOfKeyPoint(matOfReferenceImage);
マッチングには BRUTEFORCE_SL2 Descriptor-Matcher を使用します。これは、SURFまたはSIFTのユークリッド距離が必要になるためです。
cv2.absDiff
を使用して画像間の差を計算し、cv2.sumElems
を使用してすべてのピクセルの差の合計を取得します。
次に、2つの画像が類似しているかどうかを判断するためのしきい値を作成します。
次のコードを試すことができます:
Mat img1 = Highgui.imread("mnt/sdcard/IMG-20121228.jpg");
Mat img2 = Highgui.imread("mnt/sdcard/IMG-20121228-1.jpg");
Mat result = new Mat();
Core.compare(img1,img2,result,Core.CMP_NE);
int val = Core.countNonZero(result);
if(val == 0) {
//Duplicate Image
} else {
//Different Image
}
ここのコード比較関数は2つの画像を比較し、画像間に類似性がない場合、特定のマトリックス値は255になり、他のすべての値はゼロになります。次に、ゼロ以外の値の数をカウントして、イメージが等しいかどうかを判断できます。これは、まったく同じ画像に対してのみ機能します。
光の効果を無視して画像を比較したい場合は、最初にEdge画像を生成し(OpenCVのcanny関数を使用)、次に画像を比較することをお勧めします。
この答えがあなたを助けることを願っています!!