I'm developing a proof of concept algorithm for iris-related biometrics. I'd like to be able to test it on a series of images, but in order to do so, I need to know the iris boundaries. Following the techniques used here, I've filtered and intelligently thresholded the image (Otsu's method), which leaves me just the dark circle of the pupil. I've attempted to use OpenCV's HoughCircles
method, but the non-C(++) documentation is sparse. Here is my code so far for this section.:
# Convert PIL to openCV type
cvImage = cv.CreateImageHeader(inputImage.size, cv.IPL_DEPTH_8U, 1)
cv.SetData(cvImage, inputImage.tostring())
self.cvSize = cv.GetSize(cvImage)
# Create storage for circles (there should only be one)
storage = cv.CreateMat(50, 1, cv.CV_32FC3)
# Get circles (why doesn't this work?)
circles = cv.HoughCircles(cvImage,storage,cv.CV_HOUGH_GRADIENT,2,(self.cvSize[0])/4,200,100);
The final line is the line in question. I followed several posts spread across the internet (most of which are for C/C++ or 5+ years old) and managed to come up with that line. It doesn't return any errors. How do I access the results? Do I access circles
or storage
. How do I access them? I've tried suggestions from this question, but, as the asker said, the cvMat
type isn't iterable, so it won't work. It seems like it would be less work to write my own Circular Hough Transform rather than deal with the sparse documentation of this library, but I think its something simple that I'm missing.
On a side note, how might I optimize the parameters to always return a fitting circle for a pupil in a reasonable amount of time?
The example of cv.HoughLines2
is totally different, because its memory storage is something like that:
storage2 = cv.CreateMemStorage(0)
That won't work with HoughCircles
. HoughCircles
can handle only cvMat
storages, for example:
storage = cv.CreateMat(image.width, 1, cv.CV_32FC3)
It is important, that it has only 1 row, and the represenation should be 32bit floating point with 3 channels.
For example, you have the following line of code:
circles=cv.HoughCircles(image,storage, cv.CV_HOUGH_GRADIENT, 100, 300,100,50)
Because of cvMat
the return of the function is NULL
, that means its None in Python (this is similar in C, there is no return, when storage is cvMat
).
That means, the only output is the storage. You can decode the structure with the numpy:
np.asarray(storage)
Here is my code to draw circles with the centerpoint and radius, which is the result of HoughCircles
.
for i in range(0,len(np.asarray(storage))):
cv.Circle(image, ( int(np.asarray(storage)[i][0][0]), int(np.asarray(storage)[i][0][1]) ), int(np.asarray(storage)[i][0][2]), cv.CV_RGB(255, 0, 0), 2, 8, 0 )
There is only one problem I couldn't solve yet: The X,Y coordinates of centerpoint and the radius is totally inaccurate, I don't know whats wrong with them, maybe you can find out.
Are you using OpenCV 2.3.x? It's documentation seems to suggest you would do something as follows:
circles = cv2.HoughCircles(circleImage, cv.CV_HOUGH_GRADIENT, 2, 32, 200, 100);
for (x, y, radius) in circles:
# do something with circle
NOTE: cv.HoughCircles may not be returning any circles (due to restrictive parameter settings), so you might check to make sure circles is not empty.
Here is a similar python example using cv.HoughLines...
Hope that helps!
Some solution:
grayImage = cv2.cvtColor(circleImage, cv.CV_BGR2GRAY)
circles = cv2.HoughCircles(grayImage, cv.CV_HOUGH_GRADIENT, 2, 80, None, 100, 100, 50, 150)
and:
all_circles = circles[0]
for circle in all_circles:
#circle[0] - x
#circle[1] - y
#circle[2] - radius
精彩评论