Exemple #1
0
def GetGlints(gray, thr):
    tempResultImg = cv2.cvtColor(
        gray, cv2.COLOR_GRAY2BGR)  #used to draw temporary results

    props = RegionProps()
    val, binI = cv2.threshold(
        gray, thr, 255, cv2.THRESH_BINARY)  #Using non inverted binary image

    #Combining opening and dialiting seems to be the best but is it ok that other glints are visible two?????!!!!!
    st7 = cv2.getStructuringElement(cv2.MORPH_CROSS, (7, 7))
    st9 = cv2.getStructuringElement(cv2.MORPH_CROSS, (7, 7))

    binI = cv2.morphologyEx(binI, cv2.MORPH_OPEN, st7)
    binI = cv2.morphologyEx(binI, cv2.MORPH_DILATE, st9, iterations=2)

    cv2.imshow("ThresholdGlints", binI)
    #Calculate blobs
    sliderVals = getSliderVals()  #Getting slider values
    contours, hierarchy = cv2.findContours(
        binI, cv2.RETR_LIST,
        cv2.CHAIN_APPROX_SIMPLE)  #Finding contours/candidates for pupil blob
    glints = []
    glintEllipses = []
    for cnt in contours:
        values = props.CalcContourProperties(
            cnt, ['Area', 'Length', 'Centroid', 'Extend', 'ConvexHull'
                  ])  #BUG - Add cnt.astype('int') in Windows
        if values['Area'] < sliderVals['maxSizeGlints'] and values[
                'Area'] > sliderVals['minSizeGlints']:
            glints.append(values)
            centroid = (int(values['Centroid'][0]), int(values['Centroid'][1]))
            cv2.circle(tempResultImg, centroid, 2, (0, 0, 255), 4)
            glintEllipses.append(cv2.fitEllipse(cnt))
    cv2.imshow("TempResults", tempResultImg)
    return glintEllipses
Exemple #2
0
def GetPupil(gray, thr):
    #tempResultImg = cv2.cvtColor(gray,cv2.COLOR_GRAY2BGR)

    props = RegionProps()
    val, binI = cv2.threshold(gray, thr, 255, cv2.THRESH_BINARY_INV)

    st3 = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))
    binI = cv2.morphologyEx(binI, cv2.MORPH_CLOSE, st3)
    binI = cv2.morphologyEx(binI, cv2.MORPH_OPEN, st3)

    cv2.imshow("ThresholdPupil",
               binI)  #display result in a window with sliders

    sliderVals = getSliderVals()
    contours, hierarchy = cv2.findContours(binI, cv2.RETR_LIST,
                                           cv2.CHAIN_APPROX_SIMPLE)
    pupils = []
    pupilEllipses = []
    for cnt in contours:
        if len(cnt) >= 5:
            values = props.CalcContourProperties(
                cnt, ['Area', 'Length', 'Centroid', 'Perimiter', 'Extend'])
            ellipse = cv2.fitEllipse(
                cnt)  # fitEllipse([center][height,width],[angle])
            if values['Area'] < sliderVals['maxSizePupil'] and values[
                    'Area'] > sliderVals['minSizePupil']:
                pupils.append(values)
                pupilEllipses.append(ellipse)
                #centroid = (int(values['Centroid'][0]),int(values['Centroid'][1]))
                #cv2.circle(tempResultImg,centroid, 2, (0,0,255),4)

    #cv2.imshow("TempResults",tempResultImg)#display the temporary image

    return pupils, pupilEllipses
Exemple #3
0
def GetGlints(gray, thr, maxSize):
    ''' Given a gray level image, gray and threshold
    value return a list of glint locations'''
    # YOUR IMPLEMENTATION HERE !!!!
    tempResultImg = cv2.cvtColor(
        gray, cv2.COLOR_GRAY2BGR)  #used to draw temporary results

    props = RegionProps()
    val, binI = cv2.threshold(gray, thr, 255, cv2.THRESH_BINARY)
    cv2.imshow("TempResults", tempResultImg)

    #kernel = np.ones((4, 4), np.uint8)
    #binI = cv2.dilate(binI, kernel, iterations = 1)
    #binI = cv2.erode(binI, kernel, iterations = 1)

    #cv2.imshow("Threshold",binI)
    #Calculate blobs
    contours, hierarchy = cv2.findContours(binI, cv2.RETR_LIST,
                                           cv2.CHAIN_APPROX_SIMPLE)
    glints = []
    # YOUR IMPLEMENTATION HERE !!!
    for con in contours:
        p = props.CalcContourProperties(con, ["Centroid", "Area"])
        if p["Area"] < maxSize:
            glints.append(p['Centroid'])
    return glints
Exemple #4
0
def GetGlints(gray, thr):
    #tempResultImg = cv2.cvtColor(gray,cv2.COLOR_GRAY2BGR)

    props = RegionProps()

    val, binI = cv2.threshold(gray, thr, 255, cv2.THRESH_BINARY)

    st7 = cv2.getStructuringElement(cv2.MORPH_CROSS, (7, 7))

    binI = cv2.morphologyEx(binI, cv2.MORPH_OPEN, st7)
    binI = cv2.morphologyEx(binI, cv2.MORPH_DILATE, st7, iterations=2)

    cv2.imshow("ThresholdGlints", binI)

    sliderVals = getSliderVals()
    contours, hierarchy = cv2.findContours(binI, cv2.RETR_LIST,
                                           cv2.CHAIN_APPROX_SIMPLE)
    glints = []
    for cnt in contours:
        values = props.CalcContourProperties(
            cnt, ['Area', 'Length', 'Centroid', 'Extend', 'ConvexHull'])
        if values['Area'] < sliderVals['maxSizeGlints'] and values[
                'Area'] > sliderVals['minSizeGlints']:
            centroid = (int(values['Centroid'][0]), int(values['Centroid'][1]))
            glints.append(centroid)
            #cv2.circle(tempResultImg,centroid, 2, (0,0,255),4)

    #cv2.imshow("TempResults",tempResultImg)

    return glints
Exemple #5
0
def GetPupil(gray, thr, minSize, maxSize):
    '''Given a gray level image, gray and threshold value return a list of pupil locations'''
    tempResultImg = cv2.cvtColor(
        gray, cv2.COLOR_GRAY2BGR)  #used to draw temporary results
    #cv2.imshow("TempResults",tempResultImg)

    props = RegionProps()
    val, binI = cv2.threshold(gray, thr, 255, cv2.THRESH_BINARY_INV)

    # Custom Morphology --
    kernel = np.ones((10, 10), np.uint8)
    binI = cv2.dilate(binI, kernel, iterations=1)
    binI = cv2.erode(binI, kernel, iterations=1)

    #cv2.imshow("Threshold",binI)
    #Calculate blobs
    contours, hierarchy = cv2.findContours(binI, cv2.RETR_LIST,
                                           cv2.CHAIN_APPROX_SIMPLE)
    pupils = []
    # YOUR IMPLEMENTATION HERE !!!
    for con in contours:
        if len(con) >= 5:
            p = props.CalcContourProperties(
                con, ["Area", "Boundingbox", "Centroid", "Extend"])
            if minSize < p["Area"] < maxSize \
            and p["Extend"] > 0.5:
                pupils.append(cv2.fitEllipse(con))

    return pupils
Exemple #6
0
def detectPupilKMeans(gray, K=2, distanceWeight=2, reSize=(40, 40)):
    ''' Detects the pupil in the image, gray, using k-means
            gray              : grays scale image
            K                 : Number of clusters
            distanceWeight    : Defines the weight of the position parameters
            reSize            : the size of the image to do k-means on
        '''
    #Resize for faster performance
    smallI = cv2.resize(gray, reSize)
    M, N = smallI.shape
    #Generate coordinates in a matrix
    X, Y = np.meshgrid(range(M), range(N))
    #Make coordinates and intensity into one vectors
    z = smallI.flatten()
    x = X.flatten()
    y = Y.flatten()
    O = len(x)
    #make a feature vectors containing (x,y,intensity)
    features = np.zeros((O, 3))
    features[:, 0] = z
    features[:, 1] = y / distanceWeight
    #Divide so that the distance of position weighs less than intensity
    features[:, 2] = x / distanceWeight
    features = np.array(features, 'f')
    # cluster data
    centroids, variance = kmeans(features, K)
    #use the found clusters to map
    label, distance = vq(features, centroids)
    # re-create image from
    labelIm = np.uint8(np.array(np.reshape(label, (M, N))))

    props = RegionProps()
    val, binI = cv2.threshold(labelIm, 2, 255, cv2.THRESH_BINARY_INV)
    contours, hierarchy = cv2.findContours(binI, cv2.RETR_LIST,
                                           cv2.CHAIN_APPROX_SIMPLE)
    pupils = []
    # YOUR IMPLEMENTATION HERE !!!
    for con in contours:
        p = props.CalcContourProperties(
            con, ["Area", "Boundingbox", "Centroid", "Extend"])
        if len(con > 5):
            pupils.append(con)

    labelIm = np.zeros((M, N))

    for pupil in pupils:
        for p in pupil:
            labelIm[p[0][0]][p[0][1]] = 1

    f = figure(1)
    imshow(labelIm)
    f.canvas.draw()
    f.show()
def GetGlints(gray, thr):
    tempResultImg = cv2.cvtColor(
        gray, cv2.COLOR_GRAY2BGR)  #used to draw temporary results

    props = RegionProps()

    #       Do inverted thresholding:
    val, binI = cv2.threshold(
        gray, thr, 255, cv2.THRESH_BINARY)  #Using non inverted binary image

    #       Do morphological operations open, dilate(to increase the area size from opening)
    st7 = cv2.getStructuringElement(cv2.MORPH_CROSS, (7, 7))
    st9 = cv2.getStructuringElement(cv2.MORPH_CROSS, (7, 7))

    binI = cv2.morphologyEx(binI, cv2.MORPH_OPEN, st7)
    binI = cv2.morphologyEx(binI, cv2.MORPH_DILATE, st9, iterations=2)

    cv2.imshow("ThresholdGlints", binI)

    #       Calculate blobs
    sliderVals = getSliderVals()  #Getting slider values
    contours, hierarchy = cv2.findContours(
        binI, cv2.RETR_LIST,
        cv2.CHAIN_APPROX_SIMPLE)  #Finding contours/candidates for pupil blob
    glints = []
    glintEllipses = []
    for cnt in contours:
        values = props.CalcContourProperties(
            cnt.astype('int'),
            ['Area', 'Length', 'Centroid', 'Extend', 'ConvexHull'
             ])  #BUG - Add cnt.astype('int') in Windows
        if len(cnt) >= 5:
            #       Calculate the ellipse the blob best fits in using cv2 tools
            ellipse = cv2.fitEllipse(cnt.astype(
                'int'))  # fitEllipse([center][height,width],[angle])


#       Filter blobs on area size
#+/-:   we haven't found the actual glints, but we get a very good list of candidates
        if values['Area'] < sliderVals['maxSizeGlints'] and values[
                'Area'] > sliderVals['minSizeGlints']:
            glints.append(values)
            centroid = (int(values['Centroid'][0]), int(values['Centroid'][1]))
            #cv2.circle(tempResultImg,centroid, 2, (0,0,255),4)
            glintEllipses.append(cv2.fitEllipse(cnt.astype('int')))
    cv2.imshow("TempResults", tempResultImg)
    return glintEllipses
Exemple #8
0
def GetIrisUsingThreshold(gray, thr):
    #
    #NOTE: Detecting Iris uses GlintsDetection UI for adjusting parameters. You eather run glints or iris detection in 'update' method.
    #
    #Assignment 1 part2 (2.1)
    #It is almost impossible to detect iris using threshold because I can't get threshold so that Iris becomes an ellipse. It always looks like croissant ;P.
    #
    tempResultImg = cv2.cvtColor(
        gray, cv2.COLOR_GRAY2BGR)  #used to draw temporary results

    props = RegionProps()
    val, binI = cv2.threshold(
        gray, thr, 255, cv2.THRESH_BINARY)  #Using non inverted binary image

    #
    #Applying morphology
    #Nothing seems to work here!!
    st7 = cv2.getStructuringElement(cv2.MORPH_CROSS, (13, 13))
    st9 = cv2.getStructuringElement(cv2.MORPH_CROSS, (7, 7))

    binI = cv2.morphologyEx(binI, cv2.MORPH_OPEN, st7)
    #binI= cv2.morphologyEx(binI, cv2.MORPH_CLOSE, st7)
    #binI = cv2.morphologyEx(binI, cv2.MORPH_DILATE, st9, iterations=2)

    cv2.imshow("ThresholdGlints", binI)
    #Calculate blobs
    sliderVals = getSliderVals()  #Getting slider values
    contours, hierarchy = cv2.findContours(
        binI, cv2.RETR_LIST,
        cv2.CHAIN_APPROX_SIMPLE)  #Finding contours/candidates for pupil blob
    irises = []
    irisEllipses = []
    for cnt in contours:
        values = props.CalcContourProperties(
            cnt, ['Area', 'Length', 'Centroid', 'Extend', 'ConvexHull'
                  ])  #BUG - Add cnt.astype('int') in Windows
        if values['Area'] < sliderVals['maxSizeGlints'] and values[
                'Area'] > sliderVals['minSizeGlints']:
            irises.append(values)
            centroid = (int(values['Centroid'][0]), int(values['Centroid'][1]))
            cv2.circle(tempResultImg, centroid, 2, (0, 0, 255), 4)
            irisEllipses.append(cv2.fitEllipse(cnt))
    cv2.imshow("TempResults", tempResultImg)
    return irisEllipses
Exemple #9
0
def GetIrisUsingThreshold(gray, thr):
    ''' Given a gray level image, gray and threshold
    value return a list of iris locations'''

    props = RegionProps()
    val, binI = cv2.threshold(gray, thr, 255, cv2.THRESH_BINARY_INV)

    cv2.imshow("Threshold", binI)
    #Calculate blobs
    contours, hierarchy = cv2.findContours(binI, cv2.RETR_LIST,
                                           cv2.CHAIN_APPROX_SIMPLE)
    iris = []
    for con in contours:
        if len(con) >= 5:
            p = props.CalcContourProperties(
                con, ["Area", "Boundingbox", "Centroid", "Extend"])
            if 200 < p["Area"] \
            and p["Extend"] > 0.3:
                iris.append(cv2.fitEllipse(con))

    return iris
Exemple #10
0
def GetPupil(gray, thr):
    tempResultImg = cv2.cvtColor(
        gray, cv2.COLOR_GRAY2BGR)  #used to draw temporary results

    props = RegionProps()
    val, binI = cv2.threshold(gray, thr, 255, cv2.THRESH_BINARY_INV)

    #Combining Closing and Opening to the thresholded image
    st7 = cv2.getStructuringElement(cv2.MORPH_CROSS, (7, 7))
    st9 = cv2.getStructuringElement(cv2.MORPH_CROSS, (9, 9))
    st15 = cv2.getStructuringElement(cv2.MORPH_CROSS, (15, 15))

    binI = cv2.morphologyEx(binI, cv2.MORPH_CLOSE, st9)  #Close
    binI = cv2.morphologyEx(binI, cv2.MORPH_OPEN, st15)  #Open
    binI = cv2.morphologyEx(binI, cv2.MORPH_DILATE, st7,
                            iterations=2)  #Dialite

    cv2.imshow("ThresholdPupil", binI)
    #Calculate blobs
    sliderVals = getSliderVals()  #Getting slider values
    contours, hierarchy = cv2.findContours(
        binI, cv2.RETR_LIST,
        cv2.CHAIN_APPROX_SIMPLE)  #Finding contours/candidates for pupil blob
    pupils = []
    pupilEllipses = []
    for cnt in contours:
        values = props.CalcContourProperties(
            cnt, ['Area', 'Length', 'Centroid', 'Extend', 'ConvexHull'
                  ])  #BUG - Add cnt.astype('int') in Windows
        if values['Area'] < sliderVals['maxSizePupil'] and values[
                'Area'] > sliderVals['minSizePupil'] and values['Extend'] < 0.9:
            pupils.append(values)
            centroid = (int(values['Centroid'][0]), int(values['Centroid'][1]))
            cv2.circle(tempResultImg, centroid, 2, (0, 0, 255), 4)
            pupilEllipses.append(cv2.fitEllipse(cnt))
    cv2.imshow("TempResults", tempResultImg)
    return pupilEllipses
Exemple #11
0
def detectPupilKMeans(gray, K, distanceWeight, reSize):
    ''' Detects the pupil in the image, gray, using k-means
gray : grays scale image
K : Number of clusters
distanceWeight : Defines the weight of the position parameters
reSize : the size of the image to do k-means on
'''
    #Resize for faster performance
    smallI = cv2.resize(gray, reSize)
    M, N = smallI.shape
    #Generate coordinates in a matrix
    X, Y = np.meshgrid(range(M), range(N))
    #Make coordinates and intensity into one vectors
    z = smallI.flatten()
    x = X.flatten()
    y = Y.flatten()
    O = len(x)
    #make a feature vectors containing (x,y,intensity)
    features = np.zeros((O, 3))
    features[:, 0] = z
    features[:, 1] = y / distanceWeight
    #Divide so that the distance of position weighs lessthan intensity
    features[:, 2] = x / distanceWeight
    features = np.array(features, 'f')
    # cluster data
    centroids, variance = kmeans(features, K)
    centroids.sort(
        axis=0)  # Sorting clusters according to intensity (ascending)
    pupilCluster = centroids[
        0]  #Choosing the lowest intesity cluster. pupilCluster[0] is threshold for finding pupil for later

    #Wiktor's way of BLOB detection which is not that accurate-----------------------------------
    tempResultImg = cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR)
    val, binI = cv2.threshold(gray, pupilCluster[0], 255,
                              cv2.THRESH_BINARY_INV)

    #Appplying morphology
    st7 = cv2.getStructuringElement(cv2.MORPH_CROSS, (7, 7))
    st15 = cv2.getStructuringElement(cv2.MORPH_CROSS, (15, 15))

    binI = cv2.morphologyEx(binI, cv2.MORPH_CLOSE, st15)  #Close
    binI = cv2.morphologyEx(binI, cv2.MORPH_OPEN, st7)

    #binI = cv2.morphologyEx(binI, cv2.MORPH_DILATE, st7, iterations=2) #Dialite

    cv2.imshow("ThresholdPupil", binI)

    sliderVals = getSliderVals()  #Getting slider values
    props = RegionProps()
    contours, hierarchy = cv2.findContours(
        binI, cv2.RETR_LIST,
        cv2.CHAIN_APPROX_SIMPLE)  #Finding contours/candidates for pupil blob
    pupils = []
    pupilEllipses = []
    for cnt in contours:
        values = props.CalcContourProperties(
            cnt, ['Area', 'Length', 'Centroid', 'Extend', 'ConvexHull'
                  ])  #BUG - Add cnt.astype('int') in Windows
        if values['Area'] < sliderVals['maxSizePupil'] and values[
                'Area'] > sliderVals['minSizePupil'] and values['Extend'] < 0.9:
            pupils.append(values)
            centroid = (int(values['Centroid'][0]), int(values['Centroid'][1]))
            cv2.circle(tempResultImg, centroid, 2, (0, 0, 255), 4)
            pupilEllipses.append(cv2.fitEllipse(cnt))
    cv2.imshow("TempResults", tempResultImg)
    #return pupilEllipses

    #--------------------------------------This snippet belongs to function detectPupilKmeans if there were any doubts-------
    #use the found clusters to map
    label, distance = vq(features, centroids)
    # re-create image from
    labelIm = np.array(np.reshape(label, (M, N)))
    '''This snippet is my try of applying BLOB detection on labelIm (ex 1.7) . I give up and I see no sense in doing that to be honest. Maybe I don't unerstand that.'''
    #Very ugly way of extracting pupil cluster on labelIm. It can be done in two lines I'm sure. I have no Idea why they made us do blob detection on labelIm anyway. I can have perfectly fine result on gray image using data I laready have
    #labelCopy = []
    #for a in labelIm:
    #    newBlock = []
    #    for b in a:
    #        if b !=0:
    #            b=255
    #        newBlock.append(b)
    #    labelCopy.append(newBlock)

    #Applying some morphology
    #labelCopy = np.array(labelCopy)
    #Here I get binary image showing only cluster containing pixels which intensity equals pupil intensity. Here we should continue with blob detection...
    ''' end snippet'''

    f = figure(1)
    imshow(labelIm)  #labelIm
    f.canvas.draw()
    f.show()
Exemple #12
0
def run(fileName, resultFile='eyeTrackingResults.avi'):
    ''' MAIN Method to load the image sequence and handle user inputs'''
    global imgOrig, frameNr, drawImg
    setupWindowSliders()
    props = RegionProps()
    cap, imgOrig, sequenceOK = getImageSequence(fileName)
    videoWriter = 0

    frameNr = 0
    if (sequenceOK):
        update(imgOrig)
    printUsage()
    frameNr = 0
    saveFrames = False

    while (sequenceOK):
        sliderVals = getSliderVals()
        frameNr = frameNr + 1
        ch = cv2.waitKey(1)
        #Select regions
        if (ch == ord('m')):
            if (not sliderVals['Running']):
                roiSelect = ROISelector(imgOrig)
                pts, regionSelected = roiSelect.SelectArea(
                    'Select left eye corner', (400, 200))
                if (regionSelected):
                    leftTemplate = imgOrig[pts[0][1]:pts[1][1],
                                           pts[0][0]:pts[1][0]]

        if ch == 27:
            break
        if (ch == ord('s')):
            if ((saveFrames)):
                videoWriter.release()
                saveFrames = False
                print "End recording"
            else:
                imSize = np.shape(imgOrig)
                videoWriter = cv2.VideoWriter(resultFile,
                                              cv.CV_FOURCC('D', 'I', 'V', '3'),
                                              15.0, (imSize[1], imSize[0]),
                                              True)  #Make a video writer
                saveFrames = True
                print "Recording..."

        if (ch == ord('q')):
            break
        if (ch == 32):  #Spacebar
            sliderVals = getSliderVals()
            cv2.setTrackbarPos('Stop/Start', 'ThresholdGlints',
                               not sliderVals['Running'])
            cv2.setTrackbarPos('Stop/Start', 'ThresholdPupil',
                               not sliderVals['Running'])
        if (ch == ord('r')):
            frameNr = 0
            sequenceOK = False
            cap, imgOrig, sequenceOK = getImageSequence(fileName)
            update(imgOrig)
            sequenceOK = True

        sliderVals = getSliderVals()
        if (sliderVals['Running']):
            sequenceOK, imgOrig = cap.read()
            if (sequenceOK):  #if there is an image
                update(imgOrig)
            if (saveFrames):
                videoWriter.write(drawImg)

    videoWriter.release
Exemple #13
0
def detectPupilKMeans(gray, K, distanceWeight, reSize):
    ''' Detects the pupil in the image, gray, using k-means
        gray : grays scale image
        K : Number of clusters
        distanceWeight : Defines the weight of the position parameters
        reSize : the size of the image to do k-means on
    '''
    gray2 = np.copy(gray)
    #Resize for faster performance
    smallI = cv2.resize(gray2, reSize)
    M, N = smallI.shape
    #Generate coordinates in a matrix
    X, Y = np.meshgrid(range(M), range(N))
    #Make coordinates and intensity into one vectors
    z = smallI.flatten()
    x = X.flatten()
    y = Y.flatten()
    O = len(x)
    #Make feature vectors containing (x,y,intensity)
    features = np.zeros((O, 3))
    features[:, 0] = z
    features[:,
             1] = y / distanceWeight  #Divide so that the distance of position weighs less than intensity
    features[:, 2] = x / distanceWeight
    features = np.array(features, 'f')
    #Cluster data
    centroids, variance = kmeans(features, K)
    centroids.sort(
        axis=0)  # Sorting clusters according to intensity (ascending)
    pupilCluster = centroids[
        0]  #Choosing the lowest intensity cluster. pupilCluster[0] is threshold for finding pupil for later

    # use the found clusters to map
    #label,distance = vq(features,centroids)
    # re-create image from
    #labelIm = np.array(np.reshape(label,(M,N)))

    # display the labeling
    #f = figure(1); imshow(labelIm); f.canvas.draw(); f.show()
    '''This snippet applies BLOB detection on labelIm (ex 1.7) .'''
    #labelCopy = []
    #for a in labelIm:
    #    newBlock = []
    #    for b in a:
    #        if b !=0:
    #            b=255
    #        newBlock.append(b)
    #    labelCopy.append(newBlock)

    #Applying some morphology
    #labelCopy = np.array(labelCopy)
    #Here I get binary image showing only cluster containing pixels which intensity equals pupil intensity. Here we should continue with blob detection...
    ''' end snippet'''

    #Do BLOB detection
    tempResultImg = cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR)
    val, binI = cv2.threshold(gray, pupilCluster[0], 255,
                              cv2.THRESH_BINARY_INV)

    #Appplying morphology
    st3 = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))

    binI = cv2.morphologyEx(binI, cv2.MORPH_CLOSE, st3)
    binI = cv2.morphologyEx(binI, cv2.MORPH_OPEN, st3)

    cv2.imshow("ThresholdPupil", binI)

    sliderVals = getSliderVals()
    props = RegionProps()
    contours, hierarchy = cv2.findContours(
        binI, cv2.RETR_LIST,
        cv2.CHAIN_APPROX_SIMPLE)  #Finding contours/candidates for pupil blob
    pupils = []
    pupilEllipses = []
    for cnt in contours:
        values = props.CalcContourProperties(cnt.astype('int'), [
            'Area', 'Length', 'Perimiter', 'Centroid', 'Extend', 'ConvexHull'
        ])
        if len(cnt) >= 5 and values['Area'] < sliderVals[
                'maxSizePupil'] and values['Area'] > sliderVals['minSizePupil']:
            centroid = (int(values['Centroid'][0]), int(values['Centroid'][1]))
            pupils.append(values)
            pupilEllipses.append(cv2.fitEllipse(cnt.astype('int')))
            cv2.circle(tempResultImg, centroid, 2, (0, 0, 255), 4)

    cv2.imshow("TempResults", tempResultImg)

    return pupils, pupilEllipses
def GetPupil(gray, thr):
    tempResultImg = cv2.cvtColor(
        gray, cv2.COLOR_GRAY2BGR)  #used to draw temporary results

    #       Blur the image (with a gausian filter, but ideally box filter (all 1s)), then apply histogram equalization to increase the contrast
    #+/-:   threshold works better, but relying on the angle of ellipses decreases
    #       grayBlured=cv2.GaussianBlur(gray, (41,41),0)
    #       grayBlured=cv2.equalizeHist(grayBlured)

    #       Do inverted thresholding:
    props = RegionProps()
    val, binI = cv2.threshold(gray, thr, 255,
                              cv2.THRESH_BINARY_INV)  #use grayBlurred?

    #       Do morphological operations close, open and dialite(to increase the area size from opening)
    #+/-:   remove noise or small objects, but remaining objects will be rounder and relying on the angle of the ellipses decreases
    #Combining Closing and Opening to the thresholded image
    st7 = cv2.getStructuringElement(cv2.MORPH_CROSS, (7, 7))
    st9 = cv2.getStructuringElement(cv2.MORPH_CROSS, (9, 9))
    st15 = cv2.getStructuringElement(cv2.MORPH_CROSS, (15, 15))

    binI = cv2.morphologyEx(binI, cv2.MORPH_CLOSE, st9)  #Close
    binI = cv2.morphologyEx(binI, cv2.MORPH_OPEN, st15)  #Open
    binI = cv2.morphologyEx(binI, cv2.MORPH_DILATE, st7,
                            iterations=2)  #Dialite

    cv2.imshow("ThresholdPupil", binI)
    #Calculate blobs
    sliderVals = getSliderVals()  #Getting slider values
    #       Gather the remaining blobs for analysis
    contours, hierarchy = cv2.findContours(
        binI, cv2.RETR_LIST,
        cv2.CHAIN_APPROX_SIMPLE)  #Finding contours/candidates for pupil blob
    pupils = []  #used to store center of blobs
    pupilEllipses = []  #used to store ellipses
    for cnt in contours:
        if len(cnt) >= 5:

            values = props.CalcContourProperties(cnt, [
                'Area', 'Length', 'Centroid', 'Perimiter', 'Extend',
                'ConvexHull'
            ])  #BUG - Add cnt.astype('int') in Windows
            #       Calculate circularity to eliminate pupil candidates... unfortunately, the perimeter using a function from SIGBTools seems inaccurate and calculating it might be hard, therefore improvise by using the angle of the ellipse
            #       circularity=values['Perimiter']/(2*math.sqrt(math.pi*values['Area']))
            #print circularity
            #       Calculate the ellipse the blob best fits in using cv2 tools
            ellipse = cv2.fitEllipse(cnt.astype(
                'int'))  # fitEllipse([center][height,width],[angle])
            #print ellipse,ellipse[2]
            #       Filter blobs both on area size and angle of the ellipse
            #+/-    we filter ellipses with angle between 80-100 degrees, but this doesn't mean circularity (e.g. a blob in the form of a cat/snake eye has also 90 degrees), but it suffices in our case... even circularity doesn't mean 100% correctness
            if values['Area'] < sliderVals['maxSizePupil'] and values[
                    'Area'] > sliderVals['minSizePupil'] and ellipse[
                        2] > 80 and ellipse[2] < 100:
                pupils.append(values)
                centroid = (int(values['Centroid'][0]),
                            int(values['Centroid'][1]))
                pupilEllipses.append(ellipse)
    cv2.imshow("TempResults", tempResultImg)

    return pupilEllipses