回答:
これは非常に大きなトピックであり、3行のコードから研究雑誌全体に回答しています。
そのような最も一般的な手法とその結果について概説します。
最も単純で最速の方法の1つ。画像の類似性を見つける手段として数十年前に提案されました。アイデアは、森にはたくさんの緑があり、人間の顔にはたくさんのピンクなどがあるということです。したがって、2つの画像を森林と比較すると、ヒストグラムに類似性が得られます。両方に緑がたくさんあるからです。
欠点:単純すぎる。どちらも黄色なので、バナナとビーチは同じに見えます。
OpenCVメソッド:compareHist()
ここでの良い例は、matchTemplateが適切な一致を見つけることです。検索対象の画像と検索画像をたたみ込みます。これは通常、大きい画像部分から小さい画像部分を見つけるために使用されます。
欠点:同じ画像、同じサイズと向きでのみ良い結果が返されます。
OpenCVメソッド:matchTemplate()
画像検索を行う最も効率的な方法の1つと考えられています。画像から多数の特徴が抽出され、回転、拡大縮小、または傾斜した場合でも同じ特徴が再び認識されることが保証されます。この方法で抽出された特徴は、他の画像特徴セットと照合できます。最初の画像と一致する特徴の割合が高い別の画像は、同じシーンを描いていると見なされます。
2組の点の間のホモグラフィを見つけると、元の画像間の撮影角度の相対的な違いや重なりの量も見つけることができます。
これには多くのOpenCVチュートリアル/サンプルがあり、ここに素晴らしいビデオがあります。OpenCVモジュール全体(features2d)が専用です。
欠点:遅いかもしれません。完璧ではありません。
上の上OpenCVのQ&AサイトIは、画像における人間の顔や車などのオブジェクトを識別するために使用され、全体像と質感記述子を比較する際に最適です特徴記述子、との違いについて話しています。
absdiff
codota.com / code / java / methods / org.opencv.core.Core / absdiffを使用し て結果をしきい値処理することもできますシーンごとに変化した領域を強調表示できるマスクを作成します。
同じ画像を一致させる場合(同じサイズ/向き)
// 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
}
サムのソリューションで十分です。ヒストグラムの違いとテンプレートマッチングの両方を組み合わせて使用しました。これは、100%の時間で1つの方法が機能しなかったためです。ただし、ヒストグラム法はそれほど重要ではありません。これが私が単純なpythonスクリプトで実装した方法です。
import cv2
class CompareImage(object):
def __init__(self, image_1_path, image_2_path):
self.minimum_commutative_image_diff = 1
self.image_1_path = image_1_path
self.image_2_path = image_2_path
def compare_image(self):
image_1 = cv2.imread(self.image_1_path, 0)
image_2 = cv2.imread(self.image_2_path, 0)
commutative_image_diff = self.get_image_difference(image_1, image_2)
if commutative_image_diff < self.minimum_commutative_image_diff:
print "Matched"
return commutative_image_diff
return 10000 //random failure value
@staticmethod
def get_image_difference(image_1, image_2):
first_image_hist = cv2.calcHist([image_1], [0], None, [256], [0, 256])
second_image_hist = cv2.calcHist([image_2], [0], None, [256], [0, 256])
img_hist_diff = cv2.compareHist(first_image_hist, second_image_hist, cv2.HISTCMP_BHATTACHARYYA)
img_template_probability_match = cv2.matchTemplate(first_image_hist, second_image_hist, cv2.TM_CCOEFF_NORMED)[0][0]
img_template_diff = 1 - img_template_probability_match
# taking only 10% of histogram diff, since it's less accurate than template method
commutative_image_diff = (img_hist_diff / 10) + img_template_diff
return commutative_image_diff
if __name__ == '__main__':
compare_image = CompareImage('image1/path', 'image2/path')
image_difference = compare_image.compare_image()
print image_difference
少し外れたトピックですが、Pythonic numpy
アプローチが役立ちます。その堅牢で高速ですが、ピクセルを比較するだけで、画像に含まれるオブジェクトやデータは比較しません(同じサイズと形状の画像が必要です)。
openCVやコンピュータービジョン用のライブラリなしでこれを行うための非常にシンプルで高速なアプローチは、
import numpy as np
picture1 = np.random.rand(100,100)
picture2 = np.random.rand(100,100)
picture1_norm = picture1/np.sqrt(np.sum(picture1**2))
picture2_norm = picture2/np.sqrt(np.sum(picture2**2))
両方の標準化された画像(または行列)を定義した後、比較する画像の乗算を合計できます。
1)同様の画像を比較すると、合計は1を返します。
In[1]: np.sum(picture1_norm**2)
Out[1]: 1.0
2)それらが類似していない場合、0と1の間の値(100を掛けるとパーセンテージ)が得られます。
In[2]: np.sum(picture2_norm*picture1_norm)
Out[2]: 0.75389941124629822
あなたがカラー写真を持っているなら、あなたは3次元すべてでこれをしなければならないか、単にグレースケール版を比較しなければならないことに注意してください。膨大な量の写真と任意のコンテンツを比較しなければならないことがよくありますが、これは非常に高速な方法です。