Skip to content

Instantly share code, notes, and snippets.

@esmitt
Last active November 2, 2023 09:01
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save esmitt/61edc8ed6ccbc7a7e857074299449990 to your computer and use it in GitHub Desktop.
Save esmitt/61edc8ed6ccbc7a7e857074299449990 to your computer and use it in GitHub Desktop.
Iris detection from an eye photo
# Numpy is needed because OpenCV images in python are actually numpy arrays.
import numpy
import cv2
class iris_detection():
def __init__(self, image_path):
'''
initialize the class and set the class attributes
'''
self._img = None
self._img_path = image_path
self._pupil = None
def load_image(self):
'''
load the image based on the path passed to the class
it should use the method cv2.imread to load the image
it should also detect if the file exists
'''
self._img = cv2.imread(self._img_path)
# If the image doesn't exists or is not valid then imread returns None
if type(self._img) is type(None):
return False
else:
return True
def convert_to_gray_scale(self):
self._img = cv2.cvtColor(self._img, cv2.COLOR_BGR2GRAY)
def detect_pupil(self):
'''
This method should use cv2.findContours and cv2.HoughCircles() function from cv2 library to find the pupil
and then set the coordinates for pupil circle coordinates
'''
# First binarize the image so that findContours can work correctly.
_, thresh = cv2.threshold(self._img, 100, 255, cv2.THRESH_BINARY)
# Now find the contours and then find the pupil in the contours.
contours, _, _ = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
c = cv2.HoughCircles(contours, cv2.HOUGH_GRADIENT, 2, self._img.shape[0]/2)
# Then mask the pupil from the image and store it's coordinates.
for l in c:
# OpenCV returns the circles as a list of lists of circles
for circle in l:
center = (circle[0], circle[1])
radius = circle[2]
cv2.circle(self._img, center, radius, (0, 0, 0), thickness = -1)
self._pupil = (center[0], center[1], radius)
def detect_iris(self):
'''
This method should use the background subtraction technique to isolate the iris from the original image
It should use the coordinates from the detect_pupil to get a larger circle using cv2.HoughCircles()
'''
_, t = cv2.threshold(self._img, 195, 255, cv2.THRESH_BINARY)
contours, _, _ = cv2.findContours(t, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Find the iris using the radius of the pupil as input.
c = cv2.HoughCircles(contours, cv2.HOUGH_GRADIENT, 2, self._pupil[2] * 2, param2 = 150)
for l in c:
for circle in l:
center = (self._pupil[0], self._pupil[1])
radius = circle[2]
# This creates a black image and draws an iris-sized white circle in it.
mask = numpy.zeros((self._img.shape[0], self._img.shape[1], 1), numpy.uint8)
cv2.circle(mask, center, radius, (255, 255, 255), thickness = -1)
# Mask the iris and crop everything outside of its radius.
self._img = cv2.bitwise_and(self._img, mask)
def start_detection(self):
'''
This is the main method that will be called to detect the iris
it will call all the previous methods in the following order:
load_image
convert_to_gray_scale
detect_pupil
detect_iris
then it should display the resulting image with the iris only
using the method cv2.imshow
'''
if(self.load_image()):
self.convert_to_gray_scale()
self.detect_pupil()
self.detect_iris()
cv2.imshow("Result", self._img)
cv2.waitKey(0)
else:
print('Image file "' + self._img_path + '" could not be loaded.')
#id = iris_detection('c:\\temp\\eye_image.jpg')
id = iris_detection('eye_image.jpg')
id.start_detection()
@woodytwoshoes
Copy link

woodytwoshoes commented Mar 26, 2019

I had to modify part of this code to get it to run

    NoneType = type(None)
    if type(self._img) == NoneType:
        return False
    else:
        return True

and now I have another problem.

I'm trying to run this code, but I get the error

File "C:/Users/wmj/Documents/Python Scripts/Biometrics/IRIS/Raw/Esmitt method/iris_detection.py", line 60, in detect_iris
for l in c:

TypeError: 'NoneType' object is not iterable

I am trying to solve this now.

@athrness
Copy link

athrness commented Apr 2, 2019

did u solve the problem?

@ToanVNET
Copy link

I had to modify part of this code to get it to run

    NoneType = type(None)
    if type(self._img) == NoneType:
        return False
    else:
        return True

and now I have another problem.

I'm trying to run this code, but I get the error

File "C:/Users/wmj/Documents/Python Scripts/Biometrics/IRIS/Raw/Esmitt method/iris_detection.py", line 60, in detect_iris
for l in c:

TypeError: 'NoneType' object is not iterable

I am trying to solve this now.

Replace "==" by "is" . This would be worked !

@hAbd0u
Copy link

hAbd0u commented Aug 1, 2020

Can you provide the photo you used to detect the iris?

@swathigowroju
Copy link

am always getting this error with contours...
contours, _, _ = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
ValueError: not enough values to unpack (expected 3, got 2)
Plz help...

@esmitt
Copy link
Author

esmitt commented Aug 10, 2020

Well, since opencv 3.2 source image is not modified by the function findContours . Maybe it depends of the version of your OpenCV

@hAbd0u
Copy link

hAbd0u commented Aug 20, 2020

@esmitt Too bad I have no experience in OpenCV.

@IAM-P-LP
Copy link

am always getting this error with contours... contours, _, _ = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) ValueError: not enough values to unpack (expected 3, got 2) Plz help...

Hi,
Incase you didnt solve the issue, please use contours,_ instead of the 3 variables.

@shashika18923
Copy link

shashika18923 commented Jan 20, 2022

Need help to solve that

Traceback (most recent call last):
File "c:\Users\MAC\Music\Iris-recognition-with-python-and-opencv-master\code\images\new.py", line 92, in
id.start_detection()
File "c:\Users\MAC\Music\Iris-recognition-with-python-and-opencv-master\code\images\new.py", line 83, in start_detection
self.detect_pupil()
File "c:\Users\MAC\Music\Iris-recognition-with-python-and-opencv-master\code\images\new.py", line 39, in detect_pupil
c = cv2.HoughCircles(contours, cv2.HOUGH_GRADIENT, 2, self._img.shape[0]/2)
cv2.error: OpenCV(4.5.5) 👎 error: (-5:Bad argument) in function 'HoughCircles'

Overload resolution failed:

  • image is not a numerical tuple
  • Expected Ptrcv::UMat for argument 'image'

@bware22
Copy link

bware22 commented Mar 1, 2022

Need help to solve that

Traceback (most recent call last): File "c:\Users\MAC\Music\Iris-recognition-with-python-and-opencv-master\code\images\new.py", line 92, in id.start_detection() File "c:\Users\MAC\Music\Iris-recognition-with-python-and-opencv-master\code\images\new.py", line 83, in start_detection self.detect_pupil() File "c:\Users\MAC\Music\Iris-recognition-with-python-and-opencv-master\code\images\new.py", line 39, in detect_pupil c = cv2.HoughCircles(contours, cv2.HOUGH_GRADIENT, 2, self._img.shape[0]/2) cv2.error: OpenCV(4.5.5) 👎 error: (-5:Bad argument) in function 'HoughCircles'

Overload resolution failed:

  • image is not a numerical tuple
  • Expected Ptrcv::UMat for argument 'image'

Was there ever a solution discovered for this bug? I'm running into it too, and I assume it'll happen again with detecting the iris later in the code.

@bware22
Copy link

bware22 commented Mar 17, 2022

def detect_pupil(self):
    '''
    This method should use cv2.findContours and cv2.HoughCircles() function from cv2 library to find the pupil
    and then set the coordinates for pupil circle coordinates
    '''
    # First binarize the image so that findContours can work correctly.
    _, thresh = cv2.threshold(self._img, 100, 255, cv2.THRESH_BINARY)
    # Now find the contours and then find the pupil in the contours.
    contours, hierarchy = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    # Make a copy image of the original and then use the drawContours function to actually apply the contours found in the previous step
    img_with_contours = np.copy(self._img)
    cv2.drawContours(img_with_contours, contours, -1, (0, 255, 0))
    c = cv2.HoughCircles(img_with_contours, cv2.HOUGH_GRADIENT, 2, self._img.shape[0] / 2, maxRadius=150)
    # Then mask the pupil from the image and store it's coordinates.
    for l in c:
        # OpenCV returns the circles as a list of lists of circles
        for circle in l:
            center = (int(circle[0]), int(circle[1]))
            radius = int(circle[2])
            cv2.circle(self._img, center, radius, (0, 0, 0), thickness=-1)
            self._pupil = (center[0], center[1], radius)

Here's the fix for the issue btw, solved it a few weeks back and forgot to come back with it. OpenCV changed since the original code so you need to take the output array from contours and draw them one with the drawContours function, I used a temporary image to make a copy in this instance. Note you'll also have to do the sames step for find Iris later down in the code.

@antoni27
Copy link

need help got the same problem with @swathigowroju

@bware22
Copy link

bware22 commented Mar 28, 2022

need help got the same problem with @swathigowroju

@antoni27 You need to delete the last variable throwaway.

contours, _, _ = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
Should be
contours, _ = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
Because findContours only returns two variables now in the most updated version of OpenCV

Also you'll need to use drawContours I'm pretty sure after that call, I can't fully remember since its been like two weeks since I tried working with this program. But just look up the documentation is pretty well written.

@antoni27
Copy link

i got the same problem now is there any solution yet?
thanks btw

@bware22
Copy link

bware22 commented Mar 31, 2022

i got the same problem now is there any solution yet? thanks btw

Which problem is that? Is it the same error? Show the error message and I'll try my best to help.

@abolfazl8131
Copy link

Hi this solution dosen't detect the iris properly! please submit the best allgorithm to do it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment