OpenCVにヒストグラム逆投影アルゴリズムを実装する



Implement Histogram Back Projection Algorithm Opencv



目標:2次元ヒストグラム投影アルゴリズムを理解する

理論



この論文のアルゴリズムは、Michael J.SwainとDanaH.Ballardによって書かれた論文「カラーヒストグラムによる索引付け」から派生しています。紙は2つの部分に分かれています。最初の部分では、オブジェクトの識別を実現するためのカラーヒストグラムとカラーヒストグラムのクロスについて詳しく説明します。オブジェクトの背景の区別、複雑なシーンでのオブジェクトの検索、さまざまな照明条件の影響などを実現できます。この方法では、背景のピクセル変換の安定性を維持でき、スケール変換に一定の干渉防止効果もありますが、スケール不変性の特徴。上記の理論に基づいて、2人の著者は、この方法で画像内の既知のオブジェクトの位置を特定できることを発見しました。彼らはこのメソッドをヒストグラム逆投影(逆投影)と呼びます。 (( https://wenku.baidu.com/view/c5613bfa770bf78a65295443.html 論文はこちらからご覧いただけます)

論文は非常に長いですが、簡単な文章にまとめることができますか?このアルゴリズムは、主に画像のセグメンテーションまたはターゲットオブジェクトの検索に使用されます。簡単に言えば、作成される画像は入力画像と同じサイズ(ただし、チャネルは1つのみ)であり、各ピクセルは、検索する必要のあるオブジェクトに属する確率に対応します。簡単に言うと、出力画像の対象部分のオブジェクトは、残りの部分よりも白くなります。さて、これは直感的な説明です。ヒストグラムの逆投影は、camshiftアルゴリズムと組み合わせて使用​​されます(Camshiftは、連続適応MeanShiftアルゴリズムと呼ばれるMeanShiftアルゴリズムの改良版です)。



このアルゴリズムを実装する方法は?最初に検索ターゲットを含む画像ヒストグラムを作成し、次に検索ターゲットの画像ヒストグラムを作成します。もちろん、ここでは2次元のカラーヒストグラムが使用されます。これは、グレースケールヒストグラムよりもターゲットオブジェクトを定義する方が簡単だからです。最後に、投影法を使用して2つのヒストグラムを計算します。つまり、ターゲット画像の各ピクセルの確率を計算し、最後にしきい値を設定して分離します。

以下では、numpy関連の関数を使用してこのアルゴリズムを実装しています。

最初のステップは、Mと呼ばれるターゲットオブジェクトの2次元ヒストグラムを見つけることです。



Iと呼ばれる検索された画像のヒストグラムを計算します。

2番目のステップは、R = M / Iを計算して射影R配列を取得し、R配列を使用してインデックスを作成して新しい画像Bを作成することです。B(x、y)= R [h(x、y)、s (x、y)]、ここで、hは色相、sは飽和です。最後に、条件B(x、y)= min [B(x、y)、1]によって計算されます。

3番目のステップは、楕円たたみ込みを計算することです。B= D ∗ B、Dは楕円たたみ込みカーネルです。

4番目のステップは、しきい値のセグメンテーションです。

次の例を使用して、プロセスを説明できます。

#python 3.7.4,opencv4.1 # https://blog.csdn.net/caimouse/article/details/51749579 # import numpy as np import cv2 from matplotlib import pyplot as plt #Read the picture, roi is the target image roi = cv2.imread('rose2.png') hsv = cv2.cvtColor(roi,cv2.COLOR_BGR2HSV) target = cv2.imread('rose1.png') hsvt = cv2.cvtColor(target,cv2.COLOR_BGR2HSV) #Use calcHist to calculate the histogram, or np.histogram2d. M = cv2.calcHist([hsv],[0, 1], None, [180, 256], [0, 180, 0, 256] ) I = cv2.calcHist([hsvt],[0, 1], None, [180, 256], [0, 180, 0, 256] ) I[I<= 0] = 1 R = M/I #Calculate the projection h,s,v = cv2.split(hsvt) B = R[h.ravel(),s.ravel()] B = np.minimum(B,1) B = B.reshape(hsvt.shape[:2]) # Calculate convolution with elliptical kernel disc = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5)) cv2.filter2D(B,-1,disc,B) B = np.uint8(B) cv2.normalize(B,B,0,255,cv2.NORM_MINMAX) #Threshold segmentation and operation ret,thresh = cv2.threshold(B,50,255,0) thresh = cv2.merge((thresh,thresh,thresh)) res = cv2.bitwise_and(target,thresh) cv2.imshow('target', target) cv2.imshow('thresh', thresh) cv2.imshow('res', res) cv2.waitKey(0) cv2.destroyAllWindows()

結果の出力は次のとおりです。

検索した画像を入力してください

出力画像

OpenCVに実装されているアルゴリズムを探しましょう。例は次のとおりです。

#python 3.7.4,opencv4.1 # https://blog.csdn.net/caimouse/article/details/51749579 # import numpy as np import cv2 from matplotlib import pyplot as plt #Read the picture, roi is the target image roi = cv2.imread('rose2.png') hsv = cv2.cvtColor(roi,cv2.COLOR_BGR2HSV) target = cv2.imread('rose1.png') hsvt = cv2.cvtColor(target,cv2.COLOR_BGR2HSV) #Use calcHist to calculate the histogram roihist = cv2.calcHist([hsv],[0, 1], None, [180, 256], [0, 180, 0, 256] ) # Normalize histogram and calculate the projection cv2.normalize(roihist,roihist,0,255,cv2.NORM_MINMAX) dst = cv2.calcBackProject([hsvt],[0,1],roihist,[0,180,0,256],1) # Calculate convolution with elliptical kernel disc = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5)) cv2.filter2D(dst,-1,disc,dst) #Threshold segmentation and operation ret,thresh = cv2.threshold(dst,50,255,0) thresh = cv2.merge((thresh,thresh,thresh)) res = cv2.bitwise_and(target,thresh) cv2.imshow('target', target) cv2.imshow('thresh', thresh) cv2.imshow('res', res) cv2.waitKey(0) cv2.destroyAllWindows()

結果の出力は次のとおりです。

https://blog.csdn.net/caimouse/article/details/51749579