2012-10-11 119 views
4

目標:我試圖使用視頻作爲輸入獲取虹膜的大小(寬度/半徑)。OpenCV虹膜檢測C++

我已經嘗試過HoughCircles,但它似乎並不精確,因爲虹膜圈看起來並不那麼準確。我已經有了什麼信息是眼睛瞳孔及其半徑的中心點。

Grayscale Eye

有人建議我找虹膜邊緣,試圖測量梯度幅度從瞳孔中心走出去開始。然後使用直方圖使用梯度最大值的累加來查找虹膜寬度。從具體的角度出發,我不確定從哪個方面來實現這一點。

我在眼睛ROI上使用了Sobel算子,嘗試獲得下面顯示的輸出的漸變。

Sobel Eye

Sobel圖像代碼:

void irisFind(Mat gradMat, Point2i pupCenter, int pupRad){ 

imshow("original", gradMat); 


Mat gradX; 
Mat gradY; 
Mat absGradX; 
Mat absGradY; 

GaussianBlur(gradMat, gradMat, Size(3, 3), 0, 0, BORDER_DEFAULT); 
equalizeHist(gradMat, gradMat); 

//Generate Gradient along x 
Sobel(gradMat, gradX, CV_16S, 1, 0, 3, 1, 0, BORDER_DEFAULT); 
convertScaleAbs(gradX, absGradX); 

//Generate Gradient along y 
Sobel(gradMat, gradY, CV_16S, 0, 1, 3, 1, 0, BORDER_DEFAULT); 
convertScaleAbs(gradY, absGradY); 

addWeighted(absGradX, .5, absGradY, .5, 0, gradMat); 

imshow("Sobel", gradMat); 
} 

我不完全知道接下來該怎麼繼續。任何建議或意見表示讚賞。如果我錯過了任何信息,或者我對某事有點模糊,請讓我知道。非常感謝提前!

編輯:我應該更好地解釋我的應用程序的上下文,所以我很抱歉。我正在測量來自視頻輸入幀的瞳孔擴大。我已經知道瞳孔中心點的位置和瞳孔的半徑。我試圖找到虹膜的大小,以便可以使用從眼睛到相機的距離的變化來補償瞳孔大小的誤解值,因爲如果眼睛接近相機,瞳孔當然會出現較大而沒有擴張。我也可以嘗試其他方法來解釋這個問題,比如眼角,但我認爲,因爲我已經有了幾個瞳孔特徵,所以我將從虹膜開始。

再次,遺憾的是之前遺漏了這些細節。謝謝!

+1

我已經知道霍夫圓變換我已經嘗試過了,它不執行不夠好,我用謝謝你雖然建議 – jmo

+0

我遇事理解爲什麼這是關於HoughCircles的另一個問題的重複,如果有人可以請讓我知道爲什麼這是這種情況,這樣我就不會在將來創建重複的問題,如果事實上是wh在我做了。但是,我特別說,我不想使用HoughCircles。 – jmo

+0

以上評論爲@Graviton。 – jmo

回答

2

澄清你談論你的問題建議:

「有人建議我找虹膜邊緣,試圖測量梯度幅度從瞳孔中心會啓動然後使用直方圖使用漸變最大值的累積來查找虹膜寬度,但我不確定從某個特定點開始實施此操作的方式。「

你可以具體做的是從你的瞳孔中心開始,並執行一個區域增長算法,在這個算法中,你的停止條件代替了beeing,一個太不同的灰度值,梯度一些僞代碼:。

initalize list of points with center of your pupil 
initialize a mask image to zero 
while list of point is not empty 
    point pt = pop() 
    set maskImage at pt to 255 
    for pt2 in pt neighbourhood 
     if (gradientMagnitude at pt2 < THRESHOLD and maskImage at pt2 == 0) 
      list of points.add (pt2) 
+0

感謝remi的建議。我現在不在,但會在幾天內嘗試這個,並讓你知道結果。看起來很有希望。謝謝! – jmo

+0

感謝您的幫助。這似乎以我需要的方式爲我工作。我不確定爲什麼當問題和接受的答案都不使用它時,爲什麼人們認爲這是對HoughCircles的重複問題。非常感謝! – jmo

+0

我同意,我不知道如何獲得高代表的用戶關注重新打開問題 – remi

2

我認爲你應該使用虹膜內有黑圈的事實。

這裏就是我在圖像上簡單的黑色分割後得到:

Segmented image

它似乎真正的虹膜是比這個黑圈大3〜4倍。所以,這裏的結果:

Result image

尋找一個源代碼?這是它:

int main() 
{ 
    Mat src = imread("input.jpg", CV_LOAD_IMAGE_GRAYSCALE), tmp; 

    imshow("Source", src); 

    double minVal = 0; 
    minMaxLoc(src, &minVal, NULL, NULL, NULL); 

    threshold(src, tmp, minVal + 10, 255, THRESH_BINARY_INV); 

    //(Optional) remove noise (small areas of white pixels) 
/* 
    Mat element = getStructuringElement(MORPH_ELLIPSE, Size(3, 3), Point(1, 1)); 
    erode(tmp, tmp, element); 
    dilate(tmp, tmp, element); 
*/ 
    vector<Vec4i> hierarchy; 
    vector<vector<Point2i> > contours; 
    findContours(tmp, contours, hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE); 

    //find contour with max area 
    int maxArea = 0; 
    Rect maxContourRect; 
    for (int i=0; i<contours.size(); i++) 
    { 
     int area = contourArea(contours[i]); 
     Rect rect = boundingRect(contours[i]); 
     double squareKoef = ((double) rect.width)/rect.height; 

     //check if contour is like square (shape) 
#define SQUARE_KOEF 1.5 
     if (area>maxArea && squareKoef < SQUARE_KOEF && squareKoef > 1.0/SQUARE_KOEF) 
     { 
      maxArea = area; 
      maxContourRect = rect; 
     } 
    } 

    if (maxArea == 0) 
    { 
     std::cout << "Iris not found!" << std::endl; 
    } 
    else 
    { 
     Rect drawRect = Rect(maxContourRect.x-maxContourRect.width, maxContourRect.y-maxContourRect.height, maxContourRect.width*3, maxContourRect.height*3); 

     rectangle(src, drawRect, Scalar(0), 1); 

     imshow("Dest", src); 
     waitKey(); 
    } 
} 
+0

阿斯特,謝謝你的建議。我可能應該更多地解釋我的應用程序的上下文。我實際上已經或多或少地實施了你的建議來獲得學生的半徑。但我需要一些更準確的東西,而不是一個近似值。無論如何謝謝你的詳細解答。 – jmo

+0

感謝您的鏈接。我剛讀過它。我知道我是新來張貼這裏,但如果有什麼具體的,我應該做的(或不做),也許你可以讓我知道。 – jmo