[実際のOpenCV特徴抽出と検出-Bilibili]https://b23.tv/7jCLk1L
コンテンツ
機能理解の小さな例
たとえば、次の図を参照してください。
画像はとてもシンプルです。画像の上部には、6つの小さな画像パッチがあります。問題は、元の画像でこれらのパッチの正確な場所を見つけることです。正しい結果をいくつ見つけることができますか?
- AとBは、多くの領域に広がる平らな表面です。これらのパッチの正確な場所を見つけるのは難しいです。
- CとDはより単純です。それらは建物の端です。おおよその場所を見つけることができますが、正確な場所はまだ難しいです。これは、パターンがエッジに沿ってどこでも同じであるためです。ただし、エッジでは状況が異なります。したがって、エッジは平坦な領域よりも優れた機能ですが、十分ではありません(ジグソーパズルのエッジの連続性を比較するのは良いことです)。
- 最後に、EとFは建物の特定のコーナーです。そして、それらを見つけるのは簡単です。角を曲がったところで、このパッチはどこに移動しても異なって見えるからです。したがって、それらは優れた機能と見なすことができます。そこで、理解を深めるために、より単純な(そして広く使用されている画像)に移ります。
- 青いパッチは、見つけて追跡するのが難しい平らな領域です。青いパッチをどこに動かしても同じように見えます。
- 黒のパッチにはエッジがあります。垂直に(つまり、グラデーションに沿って)移動すると変化します。エッジに沿って(エッジに平行に)移動すると、同じように見えます。
- 赤いパッチの場合、これはコーナーです。パッチをどこに移動しても見た目が違うので、ユニークです。
したがって、基本的に、変曲点は画像の優れた特徴と見なされます。(コーナーだけでなく、ブロブも優れた機能と見なされる場合があります)。
機能の検出:または、どのようにしてコーナーを見つけますか?直感的な方法:画像内で、周囲のすべての領域で最も移動する領域を(少しだけ)見つけます。
次の章では、これをコンピューター言語に投影します。したがって、これらの画像の特徴を見つけることを特徴検出と呼びます。機能の説明:他の画像で見つけられるように、コンピュータは機能の周囲の領域も説明する必要があります。いわゆる説明は**機能の説明**と呼ばれます。機能とその説明を取得したら、すべての画像で同じ機能を見つけて配置したり、つなぎ合わせたり、好きなことをしたりできます。
そのため、このモジュールでは、OpenCVのさまざまなアルゴリズムを調べて、機能の検索、説明、マッチングの実行などを行います。
ハリスコーナー検出
コーナーは、強度がすべての方向で大きく変化する画像内の領域です。これらのコーナーを見つける試みは、 ChrisHarris**と**MikeStephens**が1988年の論文「**CombinedCorner and Edge Detector 」で行ったため、現在はHarrisCornerDetectorと呼ばれています。彼はこの単純な考えを数学的な形に変えました。基本的に、すべての方向の(u、v)変位の強度の違いを見つけます。次のように表されます。
ウィンドウ関数は、長方形ウィンドウまたはガウスウィンドウのいずれかであり、以下の値が割り当てられます。
コーナー検出のために、この関数E(u、v)を最大化する必要があります。つまり、第2項を最大化する必要があります。上記の方程式にテイラー展開を適用し、いくつかの数学的ステップを使用して最終的な方程式を取得します。
の
ここで、IxとIyは、それぞれx方向とy方向の画像導関数です。(** cv.Sobel **()、二階導関数Laplaceを使用して簡単に見つけることができます)。
次に、主要部分があります。その後、彼らは、ウィンドウにコーナーを含めることができるかどうかを決定するスコア、基本的には方程式を作成しました。
の
したがって、これらの固有値の値は、領域がコーナー、エッジ、またはフラットのいずれであるかを決定します。
(Rコーナーレスポンス)
次の図で表すことができます。
したがって、ハリスコーナー検出の結果は、これらのスコアを持つグレースケール画像になります。
適切なしきい値は、画像の角を示します。
OpenCVでのハリスコーナー検出
この目的のために、OpenCVには関数** cv.cornerHarris()があります。
そのパラメータは次のとおりです。-
** img-入力画像。グレースケールおよびfloat32タイプである必要があります。
--blockSize- コーナー検出で考慮される近傍のサイズ-ksize- 使用さ れるSobel導関数のアパーチャパラメータ。--k- 式のハリス検出器の自由パラメーター。次の例を参照してください。
import numpy as np import cv2 as cv filename = 'chessboard.png' img = cv.imread(filename) gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY) gray = np.float32(gray) dst = cv.cornerHarris(gray,2,3,0.04) #result用于标记角点,并不重要 dst = cv.dilate(dst,None) #最佳值的阈值,它可能因图像而异。 img[dst>0.01*dst.max()]=[0,0,255] cv.imshow('dst',img) if cv.waitKey(0) & 0xff == 27: cv.destroyAllWindows()
次の3つの結果:
サブピクセル精度のコーナー
場合によっては、最も正確なコーナーを見つける必要があります。OpenCVには、検出されたコーナーをサブピクセル精度でさらに絞り込む関数cv.cornerSubPix()が付属しています。以下に例を示します。
- 最初にハリスポイントを見つけます。
- これらのコーナーの図心でそれらを調整します(おそらく、1つのコーナーに多数のピクセルがあるので、それらの図心を取得します)。
- ハリスの角は赤いピクセルでマークされ、洗練された角は緑のピクセルでマークされています。
- この関数では、反復をいつ停止するかについての条件を定義する必要があります。特定の反復回数または特定の精度のいずれか早い方の後で停止します。また、コーナーを検索するネイバーのサイズを定義する必要があります。
import numpy as np import cv2 as cv filename = 'chessboard2.jpg' img = cv.imread(filename) gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY) # 寻找哈里斯角 gray = np.float32(gray) dst = cv.cornerHarris(gray,2,3,0.04) dst = cv.dilate(dst,None) ret, dst = cv.threshold(dst,0.01*dst.max(),255,0) dst = np.uint8(dst) # 寻找质心 ret, labels, stats, centroids = cv.connectedComponentsWithStats(dst) # 定义停止和完善拐角的条件 criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 100, 0.001) corners = cv.cornerSubPix(gray,np.float32(centroids),(5,5),(-1,-1),criteria) # 绘制 res = np.hstack((centroids,corners)) res = np.int0(res) img[res[:,1],res[:,0]]=[0,0,255] img[res[:,3],res[:,2]] = [0,255,0] cv.imwrite('subpixel5.png',img)
結果は次のとおりです。視覚化のためにズームウィンドウにいくつかの重要な場所が表示されています。