web-dev-qa-db-ja.com

虹彩検出のためのOpenCVのHoughCirclesの正しい使用法/パラメーター値は何ですか?

私はこの主題について読んでいますが、HoughCircles(特にCV_HOUGH_GRADIENTの後のもの)の使用法とパラメーターについて「平易な英語」でアイデアを得ることができません。

アキュムレータのしきい値とは何ですか? 100の「投票」は正しい値ですか?

瞳孔を見つけて「マスク」し、Canny関数を使って作業しましたが、それ以上に苦労していて、問題はHoughCircles関数です。アイリスのサークルを見つけるのに失敗しているようで、理由はわかりません。

This is what I have so far. LEFT: masked pupil RIGHT: canny result

そして、これは私が取り組んでいる関数です:

def getRadius(area):
    r = 1.0
    r = math.sqrt(area/3.14)
    return (r)

def getIris(frame):
    grayImg = cv.CreateImage(cv.GetSize(frame), 8, 1)
    cv.CvtColor(frame,grayImg,cv.CV_BGR2GRAY)
    cv.Smooth(grayImg,grayImg,cv.CV_GAUSSIAN,9,9)
    cv.Canny(grayImg, grayImg, 32, 2)
    storage = cv.CreateMat(grayImg.width, 1, cv.CV_32FC3)
    minRad = int(getRadius(pupilArea))
    circles = cv.HoughCircles(grayImg, storage, cv.CV_HOUGH_GRADIENT, 2, 10,32,200,minRad, minRad*2)
    cv.ShowImage("output", grayImg)
    while circles:
        cv.DrawContours(frame, circles, (0,0,0), (0,0,0), 2)
        # this message is never shown, therefore I'm not detecting circles
        print "circle!"
        circles = circles.h_next()
    return (frame)
13
reefaktor

HoughCirclesはちょっとトリッキーかもしれません、私は このスレッド を調べることをお勧めします。私を含む多くの人々が;)、それを使用する方法について話し合います。重要なパラメータはparam2、いわゆるaccumulator thresholdです。基本的に、それが高いほど、あなたが得るサークルは少なくなります。そして、これらの円は正しい可能性が高くなります。最適な値は画像ごとに異なります。 param2でパラメータ検索を使用するのが最善の方法だと思います。つまり、基準が満たされるまで値を試し続けます(たとえば、2つの円がある、または重複しない円の最大数など)。 'param2'で二分探索を行うコードがあるので、すぐに基準を満たします。

もう1つの重要な要素は、前処理、ノイズの低減、画像の簡素化です。ぼかし/しきい値/キャニーのいくつかの組み合わせはこれに適しています。

とにかく、私はこれを取得します:

enter image description here

アップロードされた画像から、次のコードを使用します。

import cv
import numpy as np

def draw_circles(storage, output):
    circles = np.asarray(storage)
    for circle in circles:
        Radius, x, y = int(circle[0][3]), int(circle[0][0]), int(circle[0][4])
        cv.Circle(output, (x, y), 1, cv.CV_RGB(0, 255, 0), -1, 8, 0)
        cv.Circle(output, (x, y), Radius, cv.CV_RGB(255, 0, 0), 3, 8, 0)    

orig = cv.LoadImage('eyez.png')
processed = cv.LoadImage('eyez.png',cv.CV_LOAD_IMAGE_GRAYSCALE)
storage = cv.CreateMat(orig.width, 1, cv.CV_32FC3)
#use canny, as HoughCircles seems to prefer ring like circles to filled ones.
cv.Canny(processed, processed, 5, 70, 3)
#smooth to reduce noise a bit more
cv.Smooth(processed, processed, cv.CV_GAUSSIAN, 7, 7)

cv.HoughCircles(processed, storage, cv.CV_HOUGH_GRADIENT, 2, 32.0, 30, 550)
draw_circles(storage, orig)

cv.ShowImage("original with circles", orig)
cv.WaitKey(0)

更新

私はあなたの質問を少し読み間違えていることに気づきました!実際には、irisエッジを見つけたいと考えています。彼らは生徒ほど明確に定義されていません。したがって、可能な限りHoughCirclesを支援する必要があります。これは、次の方法で実行できます。

  1. 虹彩のサイズ範囲を指定します(瞳孔のサイズからもっともらしい範囲を計算できます)。
  2. 円の中心間の最小距離を増やす(2つの虹彩が重なることはないので、これを最小の虹彩サイズに安全に設定できます)

次に、param2で再度パラメータ検索を実行する必要があります。上記のコードの「HoughCircles」行を次のように置き換えます。

cv.HoughCircles(processed, storage, cv.CV_HOUGH_GRADIENT, 2, 100.0, 30, 150,100,140)

これを取得します:

enter image description here

それほど悪くはありません。

20
fraxel

私の代替案は、しきい値とブロブ分析を使用することです。キャニーエッジとハフ変換を使用するよりも、虹彩を検出する方が簡単です。

私のやり方は...最初にあなたはそれを閾値化します。白黒画像が(黒色の)アイリスとまつげのみを生成するまで、任意のしきい値を選択します。

次に、ブロブ分析値の最小長をXXに、最小幅をYYに入力して、虹彩とまつげを分離します。 XXとYYの値は、虹彩の長さと幅の値です。

1
Zulhilmi