Ejemplo n.º 1
0
    def backgroundDiff(self, img, Imask):
        #cv.Zero(self.Imaskt)
        cv.Zero(Imask)
        cv.CvtScale(img, self.Iscratch, 1, 0)
        cv.InRange(self.Iscratch, self.IlowF, self.IhiF, Imask)
        cv.SubRS(Imask, 255, Imask)
        cv.MorphologyEx(Imask, Imask, None, None, cv.CV_MOP_OPEN, 1)
        cv.MorphologyEx(Imask, Imask, None, None, cv.CV_MOP_CLOSE, 2)

        #######This stuff was for when it was 3 channel model, now only 1
        #######for backprojection
        #cv.Split(self.Iscratch, self.Igray1, self.Igray2, self.Igray3, None)
        #cv.InRange(self.Igray1, self.Ilow1, self.Ihi1, Imask)

        # cv.InRange(self.Igray2, self.Ilow2, self.Ihi2, self.Imaskt)
        # cv.Or(Imask, self.Imaskt, Imask)

        # cv.InRange(self.Igray3, self.Ilow3, self.Ihi3, self.Imaskt)
        # cv.Or(Imask, self.Imaskt, Imask)

        # cv.SubRS(Imask, 255, Imask)
        #cv.SaveImage('/home/mkillpack/Desktop/mask.png', Imask)
        #cv.Erode(Imask, Imask)

        return Imask
Ejemplo n.º 2
0
def max_contrast(image):
    """Maximise the contrast of an image using top and bottom hat filters."""
    size = cv.GetSize(image)
    bh = cv.CreateImage(size, cv.IPL_DEPTH_8U, 1)
    th = cv.CreateImage(size, cv.IPL_DEPTH_8U, 1)
    s1 = cv.CreateImage(size, cv.IPL_DEPTH_8U, 1)
    s2 = cv.CreateImage(size, cv.IPL_DEPTH_8U, 1)
    el = cv.CreateStructuringElementEx(3, 3, 1, 1, cv.CV_SHAPE_ELLIPSE)
    cv.MorphologyEx(image, th, None, el, cv.CV_MOP_TOPHAT, 1)
    cv.MorphologyEx(image, bh, None, el, cv.CV_MOP_BLACKHAT, 1)
    cv.Add(image, th, s1)
    cv.Sub(s1, bh, s2)
    return s2
Ejemplo n.º 3
0
 def morphology(self, image):
     """ remove noisy pixels by doing erode and dilate """
     cv.MorphologyEx(self.th,
                     self.temp,
                     None,
                     self.morpher_small,
                     cv.CV_MOP_OPEN,
                     iterations=1)
     cv.MorphologyEx(self.temp,
                     self.morphed,
                     None,
                     self.morpher,
                     cv.CV_MOP_CLOSE,
                     iterations=1)
     cv.Dilate(self.morphed, self.temp, self.morpher)
     cv.Copy(self.temp, self.morphed)
     return self.morphed
Ejemplo n.º 4
0
 def threshold_v2(self, frame):
     cv.Smooth(frame, frame, cv.CV_BLUR, 5, 5)
     cv.MorphologyEx(frame, frame, None, None, cv.CV_MOP_OPEN)
     cv.MorphologyEx(frame, frame, None, None, cv.CV_MOP_CLOSE)
     cv.Threshold(frame, frame, 10, 255, cv.CV_THRESH_BINARY_INV)
     return frame
Ejemplo n.º 5
0
def find_loop(input_data, IterationClosing=6):
    """
        This function detect support (or loop) and return the coordinates if there is a detection,
        and -1 if not.
        in : filename : string image Filename / Format accepted :
        in : IterationClosing : int : Number of iteration for closing contour procedure
        Out : tupple of coordiante : (string, coordinate X, coordinate Y) where string take value
             'Coord' or 'No loop detected depending if loop was detected or not. If no loop was
              detected coordinate X and coordinate y take the value -1.
     """
    #Definition variable Global
    global AIRE_MIN_REL
    global AIRE_MIN
    global NORM_IMG
    global NiteClosing
    global pointRef
    #Chargement image
    try:
        if type(input_data) == str:
            #Image filename is passed
            img_ipl = cv.LoadImageM(input_data)
        elif type(input_data) == np.ndarray:
            img_ipl = cv.fromarray(input_data)
        else:
            print "ERROR : Input image could not be opened, check format or path"
            return (
                "ERROR : Input image could not be opened, check format or path",
                -10, -10)
    except:
        print "ERROR : Input image could not be opened, check format or path"
        return (
            "ERROR : Input image could not be opened, check format or path",
            -10, -10)
    img_cont = img_ipl  # img used for
    NORM_IMG = img_ipl.width * img_ipl.height
    AIRE_MIN = NORM_IMG * AIRE_MIN_REL
    #traitement
    #Converting input image in Grey scale image
    img_gray_ini = cv.CreateImage((img_ipl.width, img_ipl.height), 8, 1)
    cv.CvtColor(img_ipl, img_gray_ini, cv.CV_BGR2GRAY)
    #Removing Offset from image
    img_gray_resize = cv.CreateImage(
        (img_ipl.width - 2 * Offset[0], img_ipl.height - 2 * Offset[1]), 8, 1)
    cv.SetImageROI(img_gray_ini,
                   (Offset[0], Offset[1], img_ipl.width - 2 * Offset[0],
                    img_ipl.height - 2 * Offset[1]))
    cv.Copy(img_gray_ini, img_gray_resize)
    #    #creat image used for treatment
    img_gray = cv.CreateImage((img_gray_resize.width, img_gray_resize.height),
                              8, 1)
    img_trait = cv.CreateImage((img_gray.width, img_gray.height), 8, 1)
    # image used for treatment is the same than img_gray_resize
    cv.Copy(img_gray_resize, img_gray)
    #Img is smooth with asymetric kernel
    cv.Smooth(img_gray, img_gray, param1=11, param2=9)
    cv.Canny(img_gray, img_trait, 40, 60)
    # Laplacian treatment
    # Creating buffer image
    img_lap_ini = cv.CreateImage((img_gray.width, img_gray.height), 32, 1)
    img_lap = cv.CreateImage((img_lap_ini.width - 2 * Offset[0],
                              img_lap_ini.height - 2 * Offset[1]), 32, 1)
    # Creating buffer img
    img_lap_tmp = cv.CreateImage((img_lap.width, img_lap.height), 32, 1)
    #Computing laplacian
    cv.Laplace(img_gray, img_lap_ini, 5)
    #Applying Offset to avoid border effect
    cv.SetImageROI(img_lap_ini,
                   (Offset[0], Offset[1], img_lap_ini.width - 2 * Offset[0],
                    img_lap_ini.height - 2 * Offset[1]))
    #Copying laplacian treated image to final laplacian image
    cv.Copy(img_lap_ini, img_lap)
    #Apply an asymetrique  smoothing
    cv.Smooth(img_lap, img_lap, param1=21, param2=11)
    #Define the Kernel for closing algorythme
    MKernel = cv.CreateStructuringElementEx(7, 3, 3, 1, cv.CV_SHAPE_RECT)
    # Closing contour procedure
    cv.MorphologyEx(img_lap, img_lap, img_lap_tmp, MKernel, cv.CV_MOP_CLOSE,
                    NiteClosing)
    # Conveting img in 8bit image
    img_lap8_ini = cv.CreateImage((img_lap.width, img_lap.height), 8, 1)
    cv.Convert(img_lap, img_lap8_ini)
    # Add white border to image
    mat_bord = WhiteBorder(np.asarray(img_lap8_ini[:]), XSize, YSize)
    img_lap8 = cv.CreateImage(
        (img_lap.width + 2 * XSize, img_lap.height + 2 * YSize), 8, 1)
    img_lap8 = cv.fromarray(mat_bord)
    #Compute threshold
    seuil_tmp = Seuil_var(img_lap8)
    #If Seuil_tmp is not null
    if seuil_tmp != 0:
        seuil = seuil_tmp
    #Else seuil is fixed to 20, which prevent from wrong positiv detection
    else:
        seuil = 20
    #Compute thresholded image
    img_lap_bi = cv.CreateImage((img_lap8.width, img_lap8.height), 8, 1)
    img_lap_color = cv.CreateImage((img_lap8.width, img_lap8.height), 8, 3)
    img_trait_lap = cv.CreateImage((img_lap8.width, img_lap8.height), 8, 1)
    #Compute thresholded image
    cv.Threshold(img_lap8, img_lap_bi, seuil, 255, cv.CV_THRESH_BINARY)
    #Gaussian smoothing on laplacian
    cv.Smooth(img_lap_bi, img_lap_bi, param1=11, param2=11)
    #Convert grayscale laplacian image to binarie image using "seuil" as threshold value
    cv.Threshold(img_lap_bi, img_lap_bi, 1, 255, cv.CV_THRESH_BINARY_INV)
    cv.CvtColor(img_lap_bi, img_lap_color, cv.CV_GRAY2BGR)
    #Compute edge in laplacian image
    cv.Canny(img_lap_bi, img_trait_lap, 0, 2)
    #Find contour
    seqlapbi = cv.FindContours(img_trait_lap, cv.CreateMemStorage(),
                               cv.CV_RETR_TREE, cv.CV_CHAIN_APPROX_SIMPLE)
    #contour is filtered
    try:
        contour_list = parcourt_contour(seqlapbi, img_lap_color)
    except:
        #      If error is traped then there is no loop detected
        return (0, 0, ("No loop detected", -1, -1))


#    If there contours's list is not empty
    NCont = len(contour_list)
    if (NCont > 0):
        #      The CvSeq is inversed : X(i) became i(X)
        indice = MapCont(contour_list[0], img_lap_color.width,
                         img_lap_color.height)
        #      The coordinate of target is computed in the traited image
        point_shift = integreCont(indice, contour_list[0])
        #      The coordinate in original image are computed taken into account Offset and white bordure
        point = (point_shift[0], point_shift[1] + 2 * Offset[0] - XSize,
                 point_shift[2] + 2 * Offset[1] - YSize)
    else:
        #Else no loop is detected
        point = ("No loop detected", -1, -1)
        Aire_Max = 0

    return point
Ejemplo n.º 6
0
# Otsu threshold
image = loadGreyscale()
cv.Threshold(image, image, threshold, color, cv.CV_THRESH_OTSU)
showWindow("Otsu threshold")

# Dilation
image = loadGreyscale()
element_shape = cv.CV_SHAPE_RECT
pos = 1
element = cv.CreateStructuringElementEx(pos * 2 + 1, pos * 2 + 1, pos, pos,
                                        element_shape)
cv.Dilate(image, image, element, 2)
showWindow("Dilate")

# Erosion
image = loadGreyscale()
cv.Erode(image, image, element, 2)
showWindow("Erode")

# Morphology
image = loadGreyscale()
cv.MorphologyEx(image, image, image, element, cv.CV_MOP_CLOSE, 2)
showWindow("Morphology")

# Laplace
image = loadGreyscale()
dst_16s2 = cv.CreateImage(cv.GetSize(image), cv.IPL_DEPTH_16S, 1)
cv.Laplace(image, dst_16s2)
cv.Convert(dst_16s2, image)
showWindow('Laplace')
Ejemplo n.º 7
0
#! /usr/bin/env python

from SimpleCV import Camera, Display, Image
import time
import matplotlib.pyplot as plt
import cv
import numpy as np

image = cv.LoadImage('/home/pi/Documents/Lab3/foto4.png',
                     cv.CV_LOAD_IMAGE_GRAYSCALE)

#Get edges
morphed = cv.CloneImage(image)
cv.MorphologyEx(image, morphed, None, None,
                cv.CV_MOP_GRADIENT)  # Apply a dilate - Erode

cv.Threshold(morphed, morphed, 30, 255, cv.CV_THRESH_BINARY_INV)

cv.ShowImage("Image", image)
cv.ShowImage("Morphed", morphed)

cv.WaitKey(0)
Ejemplo n.º 8
0
def back_project_hs(src, patch):
    # Convert to HSV
    hsv = cv.CreateImage(cv.GetSize(src), 8, 3)
    cv.CvtColor(src, hsv, cv.CV_BGR2HSV)
    hsv_patch= cv.CreateImage(cv.GetSize(patch), 8, 3)
    cv.CvtColor(patch, hsv_patch, cv.CV_BGR2HSV)

    # Extract the H and S planes
    h_plane = cv.CreateMat(src.rows, src.cols, cv.CV_8UC1)
    h_plane_img = cv.CreateImage(cv.GetSize(src), 8, 1)
    h_plane_patch = cv.CreateMat(patch.rows, patch.cols, cv.CV_8UC1)
    s_plane = cv.CreateMat(src.rows, src.cols, cv.CV_8UC1)
    s_plane_img = cv.CreateImage(cv.GetSize(src), 8, 1)
    s_plane_patch = cv.CreateMat(patch.rows, patch.cols, cv.CV_8UC1)
    v_plane = cv.CreateMat(src.rows, src.cols, cv.CV_8UC1)

    cv.Split(hsv, h_plane, s_plane, v_plane, None)
    cv.Split(hsv, h_plane_img, s_plane_img, None, None)
    cv.Split(hsv_patch, h_plane_patch, s_plane_patch, None, None)
    #cv.Split(src, h_plane, s_plane, v_plane, None)
    planes = [h_plane_patch, s_plane_patch]#, s_plane, v_plane]
    # planes = [s_plane_patch]#, s_plane, v_plane]

    h_bins = 30
    s_bins = 32
    hist_size = [h_bins, s_bins]
    # hue varies from 0 (~0 deg red) to 180 (~360 deg red again */
    h_ranges = [0, 180]
    s_ranges = [0, 255]
    # saturation varies from 0 (black-gray-white) to
    # 255 (pure spectrum color)
    ranges = [h_ranges, s_ranges]#, s_ranges, v_ranges]
    #ranges = [s_ranges]#, s_ranges, v_ranges]
    scale = 1
    hist = cv.CreateHist([h_bins, s_bins], cv.CV_HIST_ARRAY, ranges, 1)
    #hist = cv.CreateHist([s_bins], cv.CV_HIST_ARRAY, ranges, 1)
    cv.CalcHist([cv.GetImage(i) for i in planes], hist)
    
    (min_value, max_value, _, _) = cv.GetMinMaxHistValue(hist)

    #cv.NormalizeHist(hist, 20*250.0)
    print "min hist value is :", min_value
    print "max hist value is :", max_value

    back_proj_img = cv.CreateImage(cv.GetSize(src), 8, 1)

    #cv.NormalizeHist(hist, 2000)

    cv.CalcBackProject([h_plane_img, s_plane_img], back_proj_img, hist)
    back_modified = cv.CreateImage(cv.GetSize(src), 8, 1)
    back_modified2 = cv.CreateImage(cv.GetSize(src), 8, 1)

    # cv.Dilate(back_proj_img, back_proj_img)
    # cv.Erode(back_proj_img, back_proj_img)
    #cv.Smooth(back_proj_img, back_modified)
    
    #cv.AdaptiveThreshold(back_proj_img, back_modified, 255, adaptive_method=cv.CV_ADAPTIVE_THRESH_GAUSSIAN_C)
    #cv.Threshold(back_proj_img, back_modified, 250, 255, cv.CV_THRESH_BINARY)
    #cv.MorphologyEx(back_modified,back_modified2, None, None, cv.CV_MOP_CLOSE, 3)
    #cv.MorphologyEx(back_modified,back_modified2, None, None, cv.CV_MOP_CLOSE, 1)    
    # cv.MorphologyEx(back_proj_img,back_modified2, None, None, cv.CV_MOP_CLOSE, 1)
    #cv.MorphologyEx(back_modified2,back_modified2, None, None, cv.CV_MOP_OPEN, 2)    




    cv.MorphologyEx(back_proj_img,back_modified, None, None, cv.CV_MOP_OPEN, 1)
    cv.MorphologyEx(back_modified,back_modified, None, None, cv.CV_MOP_CLOSE, 2)    
    cv.Threshold(back_modified, back_modified, 250, 255, cv.CV_THRESH_BINARY)

    # cv.MorphologyEx(back_proj_img,back_modified2, None, None, cv.CV_MOP_CLOSE, 1)
    # cv.MorphologyEx(back_modified2,back_modified2, None, None, cv.CV_MOP_OPEN, 2)    




    #cv.FloodFill(back_modified, (320, 240), cv.Scalar(255), cv.Scalar(30), cv.Scalar(30), flags=8)

    # for i in xrange (10):
    #     cv.MorphologyEx(back_modified,back_modified, None, None, cv.CV_MOP_OPEN, 3)
    #     cv.MorphologyEx(back_modified,back_modified, None, None, cv.CV_MOP_CLOSE, 1)    

    
    #cv.SubRS(back_modified, 255, back_modified)

    # cv.CalcBackProject([s_plane_img], back_proj_img, hist)
    # cv.Scale(back_proj_img, back_proj_img, 30000)
    cv.ShowImage("back_projection", back_proj_img)
    cv.ShowImage("back_modified", back_modified)
    cv.ShowImage("back_modified2", back_modified2)

    cv.WaitKey(0)


    
    #return back_proj_img, hist
    return back_modified, hist
Ejemplo n.º 9
0
    def listen(self):
        bgimg = cv.CreateImage((self.background.width, self.background.height),
                               8, 3)
        img = cv.CreateImage((self.background.width, self.background.height),
                             8, 3)
        cv.Copy(self.background, bgimg)
        smallimg = cv.CreateImage((self.background.width / self.zoom,
                                   self.background.height / self.zoom), 8, 3)
        cv.GetRectSubPix(
            bgimg, smallimg,
            (self.background.width / (2 * self.zoom) + self.offset[0],
             self.background.height / (2 * self.zoom) + self.offset[1]))
        cv.Resize(smallimg, img)

        cv.Smooth(img, img, cv.CV_GAUSSIAN)
        if (self.cp != False):
            cv.Circle(img, self.zoomPt(int(self.cp.x), int(self.cp.y)), 3,
                      cv.RGB(0, 255, 0), -1)
        mask = thresholding.threshold(img,
                                      thresholding.CUSTOM,
                                      False,
                                      crop_rect=None,
                                      cam_info=None,
                                      listener=None,
                                      hue_interval=(self.hue_low, self.hue_up))

        cv.Not(mask, mask)
        new_img = cv.CloneImage(img)
        cv.SetZero(new_img)
        cv.Copy(img, new_img, mask)
        new_img = thresholding.sat_threshold(new_img, 50)
        cv.Line(img, (self.ch_x - 25, self.ch_y), (self.ch_x + 25, self.ch_y),
                cv.RGB(255, 255, 0))
        cv.Line(img, (self.ch_x, self.ch_y - 25), (self.ch_x, self.ch_y + 25),
                cv.RGB(255, 255, 0))

        image_gray = cv.CreateImage(cv.GetSize(new_img), 8, 1)
        cv.CvtColor(new_img, image_gray, cv.CV_RGB2GRAY)
        cv.MorphologyEx(image_gray, image_gray, None, None, cv.CV_MOP_OPEN, 1)
        storage = cv.CreateMemStorage(0)
        seq = cv.FindContours(image_gray, storage)
        points = []
        contour = seq
        centers = []
        ccs = []
        while contour:
            bound_rect = cv.BoundingRect(list(contour))
            area = cv.ContourArea(contour)
            cc = contour
            contour = contour.h_next()

            if area < 50 or area > 2500:
                continue
            ccs.append(cc)
            win, center, radius = cv.MinEnclosingCircle(cc)
            cv.DrawContours(new_img, cc, (0, 255, 0), (0, 255, 0), 0, 1)
            pt1 = (bound_rect[0], bound_rect[1])
            pt2 = (bound_rect[0] + bound_rect[2],
                   bound_rect[1] + bound_rect[3])
            points.append(pt1)
            points.append(pt2)
            cv.Circle(new_img, center, radius, (0, 0, 255))
            centers.append(center)
            #cv.Rectangle(new_img, pt1, pt2, cv.CV_RGB(255,0,0), 1)

            font = cv.InitFont(cv.CV_FONT_HERSHEY_PLAIN, 1, 1)
            cv.PutText(new_img, "%.2f" % area, pt1, font, (255, 255, 255))

        for cont1, cont2 in itertools.combinations(ccs, 2):
            if is_next_to(cont1, cont2):
                win, c1, r1 = cv.MinEnclosingCircle(cont1)
                win, c2, r2 = cv.MinEnclosingCircle(cont2)
                cv.Line(new_img, c1, c2, (255, 255, 0))
        #DRAW
        cv.ShowImage(self.name, new_img)
        #Do some funny business
        imgcs = {}
        satt = thresholding.sat_threshold(img, 50)
        for color in HueRanges.__dict__:
            if color == color.upper():
                img_c = thresholding.filter_color(satt, color)
                cv.ShowImage(color, img_c)
        cv.WaitKey(25)
Ejemplo n.º 10
0
            for j in xrange(len(res_dict['success'])):
                try:
                    #check for object before starting ...##########################
                    img = cv.LoadImageM(opt.batch_folder + '/object' +
                                        str(i).zfill(3) + '_try' +
                                        str(j).zfill(3) + '_before_pr2.png')
                    result = ha.compare_imgs(img, ha.background_noise[-1])

                    Imask = cv.CreateImage(cv.GetSize(ha.background_noise[0]),
                                           cv.IPL_DEPTH_8U, 1)
                    cv.Zero(Imask)
                    cv.Zero(ha.Imaskt)
                    back_img, hist = ha.back_project_hs(img)
                    Imask = ha.backgroundDiff(back_img, Imask)

                    cv.MorphologyEx(Imask, Imask, None, None, cv.CV_MOP_OPEN,
                                    1)
                    cv.MorphologyEx(Imask, Imask, None, None, cv.CV_MOP_CLOSE,
                                    2)

                    cv.ShowImage("final", Imask)
                    cv.WaitKey(-1)

                    is_object = False
                    loc_sum = float(cv.Sum(result)[0])
                    if loc_sum < avg + 5 * std:
                        res_dict['success'][j] = None
                        print "no object to start with!?"
                    else:
                        is_object = True
                        print "there's an object let's check for success ..."
# import  cv2.cv as cv
import cv

orig = cv.LoadImage('./demo1.jpg', cv.CV_LOAD_IMAGE_COLOR)
im = cv.CreateImage(cv.GetSize(orig), 8, 1)
cv.CvtColor(orig, im, cv.CV_BGR2GRAY)
#Keep the original in colour to draw contours in the end

cv.Threshold(im, im, 128, 255, cv.CV_THRESH_BINARY)
cv.ShowImage("Threshold 1", im)
cv.SaveImage("threshold1.jpg",im)

element = cv.CreateStructuringElementEx(5*2+1, 5*2+1, 5, 5, cv.CV_SHAPE_RECT)

cv.MorphologyEx(im, im, None, element, cv.CV_MOP_OPEN) #Open and close to make appear contours
cv.MorphologyEx(im, im, None, element, cv.CV_MOP_CLOSE)
cv.Threshold(im, im, 128, 255, cv.CV_THRESH_BINARY_INV)
cv.ShowImage("After MorphologyEx", im)
cv.SaveImage("after.jpg",im)
# --------------------------------

vals = cv.CloneImage(im) #Make a clone because FindContours can modify the image
contours=cv.FindContours(vals, cv.CreateMemStorage(0), cv.CV_RETR_LIST, cv.CV_CHAIN_APPROX_SIMPLE, (0,0))

_red = (0, 0, 255); #Red for external contours
_green = (0, 255, 0);# Gren internal contours
levels=2 #1 contours drawn, 2 internal contours as well, 3 ...
co=cv.DrawContours (orig, contours, _red, _green, levels, 2, cv.CV_FILLED) #Draw contours on the colour image
cv.SaveImage("save.jpg",orig)
# cv.SaveImage("co.jpg",co)
Ejemplo n.º 12
0
#make backprojection
cv.CalcArrBackProject([frameH, frameS], frameBP, hist)

cv.Normalize(frameBP, frameBP, 0, 255, 32)
cv.Smooth( frameBP, frameBlur, param1=31);
cv.Threshold(frameBlur, frameTh, 30, 255, cv.CV_THRESH_BINARY);
cv.Threshold(frameBP, frameThNoBlur, 30, 255, cv.CV_THRESH_BINARY);

cv.AdaptiveThreshold(frameBlur, frameAdapTh, 255, blockSize=101, adaptive_method=cv.CV_ADAPTIVE_THRESH_GAUSSIAN_C)

# do morhphological close operation
dia=15
center=(dia/2)+1
element = cv.CreateStructuringElementEx(dia, dia, center, center, cv.CV_SHAPE_ELLIPSE)
cv.MorphologyEx(frameTh, frameClosed, temp, element, cv.CV_MOP_CLOSE)
#cv.Dilate(frameTh, frameClosed, element, 1)

# find contours
cv.Copy(frameClosed, temp)
contours = cv.FindContours(temp, cv.CreateMemStorage(),
    mode=cv.CV_RETR_EXTERNAL, method=cv.CV_CHAIN_APPROX_SIMPLE, offset=(0, 0))

contour_iter = contours

# label the contours
head = left = right = None
blobs = []
while contour_iter:
    blob = Blob(contour_iter)
    if cv.PointPolygonTest(contour_iter, face_center, 0) > 0: