I've been reading about the subject but cannot get the idea in "plain English" about the usage and parameters for HoughCircles
(specially the ones after CV_HOUGH_GRADIENT
).
What's an accumulator threshold? Are 100 "votes" a right value?
I could find and "mask" the pupil, and worked my way through the Canny
function, but I'm struggling beyond that and my problem is the HoughCircles
function. There seems to be failing at finding the Iris' circle and I don't know why.
And this is the function I'm working on:
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)
In case of HOUGH_GRADIENT , it is the accumulator threshold for the circle centers at the detection stage. The smaller it is, the more false circles may be detected. Circles, corresponding to the larger accumulator values, will be returned first. minRadius. minimum circle radius.
Use the OpenCV function HoughCircles() to detect circles in an image.
Find circles in a shoe-printThe original picture (right) is first turned into a binary image (left) using a threshold and Gaussian filter. Then edges (mid) are found from it using canny edge detection. After this, all the edge points are used by the Circle Hough Transform to find underlying circle structure.
Syntax. cv2. HoughCircles(image, method, dp, minDist) Where Image is the image file converted to grey scale Method is the algorithm used to detct the circles. Dp is the inverse ratio of the accumulator resolution to the image resolution.
HoughCircles
can be kind of tricky, I suggest looking through this thread. Where a bunch of people, including me ;), discuss how to use it. The key parameter is param2
, the so-called accumulator threshold
. Basically, the higher it is the less circles you get. And these circles have a higher probability of being correct. The best value is different for every image. I think the best approach is to use a parameter search on param2
. Ie. keep on trying values until your criteria is met (such as: there are 2 circles, or max. number of circles that are non-overlapping, etc.). I have some code that does a binary search on 'param2', so it meet the criteria quickly.
The other crucial factor is pre-processing, try to reduce noise, and simplify the image. Some combination of blurring/thresholding/canny is good for this.
Anyhow, I get this:
From your uploded image, using this code:
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)
Update
I realise I somewhat miss-read your question! You actually want to find the iris edges. They are not so clearly defined, as the pupils. So we need to help HoughCircles
as much as possible. We can do this, by:
And then we need to do a param search on param2
again. Replacing the 'HoughCircles' line in the above code with this:
cv.HoughCircles(processed, storage, cv.CV_HOUGH_GRADIENT, 2, 100.0, 30, 150,100,140)
Gets us this:
Which isn't too bad.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With