OpenCV-Pythonチュートリアル-4.10.4。逆投影ヒストグラム



Opencv Python Tutorials 4



OpenCV-Pythonチュートリアル(4.0.0)

OpenCV-Pythonチュートリアルの公式英語チュートリアル
GitHub:中国語の翻訳
それが助けになるなら、お願いします GitHub スタープロジェクトでは、出所を教えてください。

目的:

  • ヒストグラムの逆投影を学習する

理論

これは、Michael J. Swain、Dana H.Ballardの論文「カラーヒストグラムによるインデックス作成」で提案されました。



簡単に言えば、画像のセグメンテーションや画像内の関心のあるオブジェクトの検索に正確に使用されるものは何ですか。簡単に言えば、入力画像と同じサイズ(ただし単一チャネル)の画像を作成します。各ピクセルは、そのピクセルがオブジェクトに属する確率に対応します。より単純な世界では、出力画像により、関心のあるオブジェクトが他のオブジェクトよりも白くなります。これは直感的な説明です。 (私はもうそれをすることができません)。ヒストグラム逆投影は、カムシフトアルゴリズムなどと組み合わされます。どうすればいいですか?のアノグラムを作成します

私たちは何をしますか?関心のあるオブジェクト(この場合は、地面、プレーヤーを離れるなど)を含む画像のヒストグラムを作成します。より良い結果を得るには、オブジェクトを可能な限り画像に塗りつぶす必要があります。オブジェクトの色はグレースケール強度よりもオブジェクトを定義するためのより良い方法であるため、カラーヒストグラムはグレーヒストグラムよりも人気があります。次に、ターゲットを見つけるために必要なテスト画像にヒストグラムを「逆投影」します。つまり、地面に属する各ピクセルの確率を計算して表示します。適切なしきい値で得られた出力は、私たちに基礎を提供するだけです



Numpyのアルゴリズム

  1. まず、検索するオブジェクト(「M」に設定)と検索する画像(「I」に設定)のカラーヒストグラムを計算する必要があります。
import numpy as np import cv2 as cvfrom matplotlib import pyplot as plt #roi is the object or region of object we need to find roi = cv.imread('rose_red.png') hsv = cv.cvtColor(roi,cv.COLOR_BGR2HSV) #target is the image we search in target = cv.imread('rose.png') hsvt = cv.cvtColor(target,cv.COLOR_BGR2HSV) # Find the histograms using calcHist. Can be done with np.histogram2d also M = cv.calcHist([hsv],[0, 1], None, [180, 256], [0, 180, 0, 256] ) I = cv.calcHist([hsvt],[0, 1], None, [180, 256], [0, 180, 0, 256] )
  1. 比率を見つけるR = M I R = frac {M} {I}。次に、Rを逆投影し、Rをパレットとして使用し、各ピクセルを対応するターゲット確率として新しい画像を作成します。つまり、B(x、y)= R [h(x、y)、s(x、y)]です。ここで、hは色相、sは(x、y)でのピクセルの彩度です。次に、条件B(x、y)= min [B(x、y)、1]が適用されます。
h,s,v = cv.split(hsvt) B = R[h.ravel(),s.ravel()] B = np.minimum(B,1) B = B.reshape(hsvt.shape[:2])
  1. これで、ディスクが畳み込まれ、B = D * Bになります。ここで、Dは畳み込みカーネルです。
disc = cv.getStructuringElement(cv.MORPH_ELLIPSE,(5,5)) cv.filter2D(B,-1,disc,B) B = np.uint8(B) cv.normalize(B,B,0,255,cv.NORM_MINMAX)
  1. 最大強度の位置により、オブジェクトの位置がわかります。画像内の領域が予想される場合は、適切な値をしきい値処理すると、良好な結果が得られます。
ret,thresh = cv.threshold(B,50,255,0)

OpenCVでの逆投影

OpenCVは組み込み関数cv.calcBackProject()を提供します。そのパラメータとcv.calcHist()関数はほとんど同じです。その引数の1つはヒストグラムです。これは、オブジェクトのヒストグラムであり、これを見つける必要があります。さらに、オブジェクトヒストグラムは、バックプロジェクト関数に渡される前に正規化する必要があります。確率画像を返します。次に、画像をディスク畳み込みカーネルで畳み込み、しきい値を適用します。これが私のコードと出力です:

import numpy as np import cv2 as cv roi = cv.imread('rose_red.png') hsv = cv.cvtColor(roi,cv.COLOR_BGR2HSV) target = cv.imread('rose.png') hsvt = cv.cvtColor(target,cv.COLOR_BGR2HSV) # calculating object histogram roihist = cv.calcHist([hsv],[0, 1], None, [180, 256], [0, 180, 0, 256] ) # normalize histogram and apply backprojection cv.normalize(roihist,roihist,0,255,cv.NORM_MINMAX) dst = cv.calcBackProject([hsvt],[0,1],roihist,[0,180,0,256],1) # Now convolute with circular disc disc = cv.getStructuringElement(cv.MORPH_ELLIPSE,(5,5)) cv.filter2D(dst,-1,disc,dst) # threshold and binary AND ret,thresh = cv.threshold(dst,50,255,0) thresh = cv.merge((thresh,thresh,thresh)) res = cv.bitwise_and(target,thresh) res = np.vstack((target,thresh,res)) cv.imwrite('res.jpg',res)

以下は私が使用した例です。青い長方形の内側の領域をサンプルオブジェクトとして使用し、地面全体を抽出したいと思います。

image56