Exemple #1
0
    def generateTransforms(self, detection):
        # Transform the face
        affine = pv.AffineFromRect(detection, self.tile_size)

        w, h = self.tile_size

        if self.perturbations:
            # Randomly rotate, translate and scale the images
            center = pv.AffineTranslate(-0.5 * w, -0.5 * h, self.tile_size)
            rotate = pv.AffineRotate(random.uniform(-pi / 8, pi / 8),
                                     self.tile_size)
            scale = pv.AffineScale(random.uniform(0.9, 1.1), self.tile_size)
            translate = pv.AffineTranslate(random.uniform(-0.05 * w, 0.05 * w),
                                           random.uniform(-0.05 * h, 0.05 * h),
                                           self.tile_size)
            inv_center = pv.AffineTranslate(0.5 * w, 0.5 * h, self.tile_size)

            affine = inv_center * translate * scale * rotate * center * affine
            #affine = affine*center*rotate*scale*translate*inv_center

        lx = self.left_center.X() - self.subtile_size[0] / 2
        ly = self.left_center.Y() - self.subtile_size[1] / 2
        rx = self.right_center.X() - self.subtile_size[0] / 2
        ry = self.right_center.Y() - self.subtile_size[1] / 2

        laffine = pv.AffineFromRect(
            pv.Rect(lx, ly, self.subtile_size[0], self.subtile_size[1]),
            self.subtile_size) * affine
        raffine = pv.AffineFromRect(
            pv.Rect(rx, ry, self.subtile_size[0], self.subtile_size[1]),
            self.subtile_size) * affine
        return laffine, raffine
Exemple #2
0
    def annotateFrame(self,frame,color='white'):
        '''
        Renders optical flow information to the frame.
        
        @param frame: the frame that will be annotated
        @type frame: pv.Image
        @keyword type:
        @ktype type: "TRACKING" 
        
        '''
        w,h = self.tile_size
        rect = pv.Rect(0,0,w,h)
        affine = pv.AffineFromRect(rect,frame.size)
        for pt in affine.transformPoints(self.tracks[:self.n]):
            frame.annotatePoint(pt,color=color)

        for pt in affine.transformPoints(self.tracks[self.n:]):
            frame.annotatePoint(pt,color='red')
            
        for pt in affine.transformPoints(self.bad_points):
            frame.annotatePoint(pt,color='gray')
            
        
        if self.homography != None:
            matrix = pv.OpenCVToNumpy(self.homography)
            perspective = pv.PerspectiveTransform(matrix,frame.size)

            for pt in self.tracks[:self.n]:
                # Transform the point multiple times to amplify the track 
                # for visualization
                old = perspective.invertPoint(pt)
                old = perspective.invertPoint(old)
                old = perspective.invertPoint(old)
                frame.annotateLine(pt,old,color=color)
Exemple #3
0
    def extract(self, img, face_records):
        '''Extract a template that allows the face to be matched.'''
        # Compute the 512D vector that describes the face in img identified by
        #shape.

        im = pv.Image(img[:, :, ::-1])

        for face_record in face_records.face_records:
            rect = pt.rect_proto2pv(face_record.detection.location)
            x, y, w, h = rect.asTuple()

            # Extract view
            rect = pv.Rect()
            cx, cy = x + 0.5 * w, y + 0.5 * h
            tmp = 1.5 * max(w, h)
            cw, ch = tmp, tmp
            crop = pv.AffineFromRect(pv.CenteredRect(cx, cy, cw, ch),
                                     (256, 256))

            pvim = pv.Image(img[:, :, ::-1])  # convert rgb to bgr
            pvim = crop(pvim)
            view = pt.image_pv2proto(pvim)
            face_record.view.CopyFrom(view)

            tile = pvim.resize((224, 224))
            tile = tile.resize((112, 112))

            face_im = tile.asOpenCV2()
            face_im = face_im[:, :, ::-1]  # Convert BGR to RGB

            features = self.fr_model.get_embedding(face_im)
            face_descriptor = pv.meanUnit(features.flatten())

            face_record.template.data.CopyFrom(
                pt.vector_np2proto(face_descriptor))
 def _initialize(self,frame,rect):
     '''
     A private method that initializes the filter and prepares this 
     instance of a MOSSETrack to receive new frames.
     
     @param frame: A source video frame to _initialize from.
     @type frame: pv.Image
     @param rect: A rectangle defining the object to be tracked in "frame".
     @type rect: pv.Rect 
     '''
     start = time.time()
     self.rect = copy.deepcopy(rect)
     affine = pv.AffineFromRect(rect,self.tile_size)
     pt = affine.transformPoint(self.rect.center())
     if self.strategy == INIT_ONE_TRANSFORM:
         tmp = affine.transformImage(frame)
         self.filter.addTraining(tmp,pt)
         self.input = tmp
     elif self.strategy == INIT_NINE_TRANSFORM:
         for scale in [-1,0,1]:
             scale = pv.AffineRotate(scale*self.dscale,self.tile_size,center=pt)
             for rotate in [-1,0,1]:
                 rot = pv.AffineRotate(rotate*self.drotate,self.tile_size,center=pt)
                 pt = (scale*rot*affine).transformPoint(self.rect.center())
                 tmp = (scale*rot*affine).transformImage(frame)
                 self.filter.addTraining(tmp,pt)
         self.input = tmp
     self.corr = np.zeros(self.tile_size,dtype=np.float64)
     self.frame = 0
     stop = time.time()
     self.update_time = stop-start
     self.best_estimate = rect.center()
Exemple #5
0
    def detect(self, im):
        '''
        @returns: a list of tuples where each tuple contains (registered_image, detection_rect, left_eye, right_eye) 
        '''
        result = []

        rects = self.face_detector.detect(im)

        # Anotate Faces
        for rect in rects:

            # Transform the face
            affine = pv.AffineFromRect(rect, self.tile_size)
            cropped = affine.transformImage(im)

            for _ in range(self.n_iter):
                cropped = pv.meanStd(cropped)
                # Find the eyes
                data = cropped.asMatrix2D().flatten()
                data = np.array(data, 'd').flatten()

                data = self.normalize.normalizeVector(data)

                pleye = self.left_locator.predict(data)
                preye = self.right_locator.predict(data)

                pleye = affine.invertPoint(pleye)
                preye = affine.invertPoint(preye)

                # Seccond Pass
                affine = pv.AffineFromPoints(pleye, preye, self.left_eye,
                                             self.right_eye, self.tile_size)
                cropped = affine.transformImage(im)

            #affine = AffineFromPoints(pleye,preye,self.left_eye,self.right_eye,self.tile_size)
            #reg = affine.transformImage(im)
            reg = cropped

            if self.validate != None and not self.validate(reg):
                # Validate the face.
                if self.annotate:
                    im.annotateRect(rect, color='red')
                    im.annotatePoint(pleye, color='red')
                    im.annotatePoint(preye, color='red')
                continue

            if self.annotate:
                reg.annotatePoint(self.left_eye, color='green')
                reg.annotatePoint(self.right_eye, color='green')
                im.annotatePoint(pleye, color='green')
                im.annotatePoint(preye, color='green')
                im.annotateRect(rect, color='green')
            result.append((reg, rect, pleye, preye))

        return result
Exemple #6
0
    def addTraining(self, left_eye, right_eye, im):
        '''Train an eye detector givin a full image and the eye coordinates.'''

        # determine the face rect
        true_rect = face_from_eyes(left_eye, right_eye)

        # run the face detector
        rects = self.face_detector.detect(im)

        # find the best detection if there is one
        for pred_rect in rects:
            if is_success(pred_rect, true_rect):
                # Transform the face
                affine = pv.AffineFromRect(pred_rect, self.tile_size)

                w, h = self.tile_size

                if self.perturbations:
                    # Randomly rotate, translate and scale the images
                    center = pv.AffineTranslate(-0.5 * w, -0.5 * h,
                                                self.tile_size)
                    rotate = pv.AffineRotate(random.uniform(-pi / 8, pi / 8),
                                             self.tile_size)
                    scale = pv.AffineScale(random.uniform(0.9, 1.1),
                                           self.tile_size)
                    translate = pv.AffineTranslate(
                        random.uniform(-0.05 * w, 0.05 * w),
                        random.uniform(-0.05 * h, 0.05 * h), self.tile_size)
                    inv_center = pv.AffineTranslate(0.5 * w, 0.5 * h,
                                                    self.tile_size)

                    affine = inv_center * translate * scale * rotate * center * affine
                    #affine = affine*center*rotate*scale*translate*inv_center

                cropped = affine.transformImage(im)
                cropped = pv.meanStd(cropped)

                # Mark the eyes
                leye = affine.transformPoint(left_eye)
                reye = affine.transformPoint(right_eye)

                # Add training data to locators
                self.training_labels.append((leye, reye))

                self.normalize.addTraining(0.0, cropped)
                #self.left_locator.addTraining(cropped,leye)
                #self.right_locator.addTraining(cropped,reye)

                # Just use the first success
                return

        # The face was not detected
        self.detection_failures += 1
Exemple #7
0
    def test_from_rect(self):

        transform = pv.AffineFromRect(pv.Rect(100, 100, 300, 300), (100, 100))
        _ = transform.transformImage(self.test_image)
        #im_a.show()

        pt = transform.transformPoint(pv.Point(320, 240))
        self.assertAlmostEqual(pt.X(), 73.333333333333329)
        self.assertAlmostEqual(pt.Y(), 46.666666666666671)

        pt = transform.invertPoint(pv.Point(50., 50.))
        self.assertAlmostEqual(pt.X(), 250.0)
        self.assertAlmostEqual(pt.Y(), 250.0)
Exemple #8
0
    def extract(self,img,face_records):
        '''Extract a template that allows the face to be matched.'''
        # Compute the 128D vector that describes the face in img identified by
        # shape.  In general, if two face descriptor vectors have a Euclidean
        # distance between them less than 0.6 then they are from the same
        # person, otherwise they are from different people. Here we just print
        # the vector to the screen.
        
        # TODO: Make this an option
        JITTER_COUNT = 5
        
        for face_record in face_records.face_records:
            rect = pt.rect_proto2pv(face_record.detection.location)
            x,y,w,h = rect.asTuple()

            # Extract view
            rect = pv.Rect()
            cx,cy = x+0.5*w,y+0.5*h
            tmp = 1.5*max(w,h)
            cw,ch = tmp,tmp
            crop = pv.AffineFromRect(pv.CenteredRect(cx,cy,cw,ch),(256,256))
            #print (x,y,w,h,cx,cy,cw,ch,crop)
            pvim = pv.Image(img[:,:,::-1]) # convert rgb to bgr
            pvim = crop(pvim)
            view = pt.image_pv2proto(pvim)
            face_record.view.CopyFrom(view)
            
            # Extract landmarks
            l,t,r,b = [int(tmp) for tmp in [x,y,x+w,y+h]]
            d = dlib.rectangle(l,t,r,b)
            shape = self.shape_pred(img, d)
            #print('s',dir(shape))
            #print(shape.parts()[0])
            
            for i in range(len(shape.parts())):
                loc = shape.parts()[i]
                landmark = face_record.landmarks.add()
                landmark.landmark_id = "point_%02d"%i
                landmark.location.x = loc.x
                landmark.location.y = loc.y
            
            #print('fr',face_record)

            #print('shape:',face_records.face_records[0].landmarks)
            face_descriptor = self.face_rec.compute_face_descriptor(img, shape, JITTER_COUNT)
            face_descriptor = np.array(face_descriptor)
            
            vec = face_descriptor.flatten()
            face_record.template.data.CopyFrom(pt.vector_np2proto(vec))
Exemple #9
0
    def test_affine_Matrix3D(self):
        im = pv.Image(pv.BABOON)
        test_im = pv.Image(im.asMatrix3D())
        affine = pv.AffineFromRect(pv.CenteredRect(256,256,128,128),(64,64))

        # Transform the images
        im = affine(im)
        test_im = affine(test_im)

        # Correlate the resulting images
        vec1 = pv.unit(im.asMatrix3D().flatten())
        vec2 = pv.unit(test_im.asMatrix3D().flatten())
        score = np.dot(vec1,vec2)
        
        self.assertGreater(score, 0.998)
Exemple #10
0
    def extract(self, img, face_records):
        '''Extract a template that allows the face to be matched.'''
        # Compute the 512D vector that describes the face in img identified by
        #shape.
        #print(type(img),img.shape)
        img = img[:, :, ::
                  -1]  #convert from rgb to bgr. There is BGRtoRGB conversion in get_embedding

        for face_record in face_records.face_records:
            #print(face_record)
            if face_record.detection.score != -1:
                landmarks = np.zeros((5, 2), dtype=np.float)
                for i in range(0, len(face_record.landmarks)):
                    vals = face_record.landmarks[i]
                    landmarks[i, 0] = vals.location.x
                    landmarks[i, 1] = vals.location.y

                _img = self.preprocess.norm_crop(img, landmark=landmarks)
                #print(_img.shape)
                embedding = self.fr_model.get_embedding(_img).flatten()
                embedding_norm = np.linalg.norm(embedding)
                normed_embedding = embedding / embedding_norm
                #print(normed_embedding.shape)

                # Extract view
                x, y, w, h = pt.rect_proto2pv(
                    face_record.detection.location).asTuple()
                cx, cy = x + 0.5 * w, y + 0.5 * h
                tmp = 1.5 * max(w, h)
                cw, ch = tmp, tmp
                crop = pv.AffineFromRect(pv.CenteredRect(cx, cy, cw, ch),
                                         (256, 256))
                #print (x,y,w,h,cx,cy,cw,ch,crop)
                pvim = pv.Image(img[:, :, ::-1])  # convert rgb to bgr
                pvim = crop(pvim)
                view = pt.image_pv2proto(pvim)
                face_record.view.CopyFrom(view)

            else:
                normed_embedding = np.zeros(512, dtype=float)

            face_record.template.data.CopyFrom(
                pt.vector_np2proto(normed_embedding))
Exemple #11
0
    def locateEyes(self, im, face_rects, ilog=None):
        '''
        Finds the eyes in the image.  
        
        @param im: full sized image
        @param face_rects: list of rectangle which are the output from the cascade face detector.
        '''
        cvim = im.asOpenCVBW()

        faces = []

        for rect in face_rects:
            faceim = cv.GetSubRect(cvim, rect.asOpenCV())
            cv.Resize(faceim, self.bwtile)

            affine = pv.AffineFromRect(rect, (128, 128))

            #cv.cvCvtColor( self.cvtile, self.bwtile, cv.CV_BGR2GRAY )

            leye, reye, lcp, rcp = self.fel.locateEyes(self.bwtile)
            le = pv.Point(leye)
            re = pv.Point(reye)

            leye = affine.invertPoint(le)
            reye = affine.invertPoint(re)

            faces.append([rect, leye, reye])

            if ilog != None:
                ilog.log(pv.Image(self.bwtile), label="FaceDetection")
                lcp = pv.OpenCVToNumpy(lcp).transpose()
                lcp = lcp * (lcp > 0.0)
                rcp = pv.OpenCVToNumpy(rcp).transpose()
                rcp = rcp * (rcp > 0.0)
                ilog.log(pv.Image(lcp), label="Left_Corr")
                ilog.log(pv.Image(rcp), label="Right_Corr")
                tmp = pv.Image(self.bwtile)
                tmp.annotatePoint(le)
                tmp.annotatePoint(re)
                ilog.log(tmp, "EyeLocations")

        return faces
Exemple #12
0
 def crop(self, rect, size=None, interpolation=None, return_affine=False):
     '''
     Crops an image to the given rectangle. Rectangle parameters are rounded to nearest 
     integer values.  High quality resampling.  The default behavior is to use cv.GetSubRect
     to crop the image.  This returns a slice the OpenCV image so modifying the resulting
     image data will also modify the data in this image.  If a size is provide a new OpenCV
     image is created for that size and cv.Resize is used to copy the image data. If the 
     bounds of the rectangle are outside the image, an affine transform (pv.AffineFromRect)
     is used to produce the croped image to properly handle regions outside the image.
     In this case the downsampling quality may not be as good. #
     
     @param rect: a Rectangle defining the region to be cropped.
     @param size: a new size for the returned image.  If None the result is not resized.
     @param interpolation: None = Autoselect or one of CV_INTER_AREA, CV_INTER_NN, CV_INTER_LINEAR, CV_INTER_BICUBIC
     @param return_affine: If True, also return an affine transform that can be used to transform points.
     @returns: a cropped version of the image or if return affine a tuple of (image,affine)
     @rtype: pv.Image
     '''
     # Notes: pv.Rect(0,0,w,h) should return the entire image. Since pixel values
     # are indexed by zero this means that upper limits are not inclusive: x from [0,w)
     # and y from [0,h)
     x,y,w,h = rect.asTuple()
    
     x = int(np.round(x))
     y = int(np.round(y))
     w = int(np.round(w))
     h = int(np.round(h))
     
     # Check the bounds for cropping
     if size is None:
         size = (w,h)
     
     affine = pv.AffineFromRect(pv.Rect(x,y,w,h),size)
     im = affine(self)
     if return_affine:
         return im,affine
     else:
         return im
Exemple #13
0
    def findFaces(self, im):
        eye_processing = self.eye_menuitem.IsChecked()

        self.detect_time = time.time()
        rects = self.face_detector.detect(im)
        self.detect_time = time.time() - self.detect_time

        self.eye_time = time.time()
        if eye_processing:
            faces = self.fel.locateEyes(im, rects)
        else:
            faces = []
            for rect in rects:
                affine = pv.AffineFromRect(rect, (1, 1))
                leye = affine.invertPoint(AVE_LEFT_EYE)
                reye = affine.invertPoint(AVE_RIGHT_EYE)
                faces.append([rect, leye, reye])

        self.eye_time = time.time() - self.eye_time

        self.current_faces = faces

        return faces
Exemple #14
0
    def crop(self, rect, size=None, interpolation=None, return_affine=False):
        '''
        Crops an image to the given rectangle. Rectangle parameters are rounded to nearest 
        integer values.  High quality resampling.  The default behavior is to use cv.GetSubRect
        to crop the image.  This returns a slice the OpenCV image so modifying the resulting
        image data will also modify the data in this image.  If a size is provide a new OpenCV
        image is created for that size and cv.Resize is used to copy the image data. If the 
        bounds of the rectangle are outside the image, an affine transform (pv.AffineFromRect)
        is used to produce the croped image to properly handle regions outside the image.
        In this case the downsampling quality may not be as good. #
        
        @param rect: a Rectangle defining the region to be cropped.
        @param size: a new size for the returned image.  If None the result is not resized.
        @param interpolation: None = Autoselect or one of CV_INTER_AREA, CV_INTER_NN, CV_INTER_LINEAR, CV_INTER_BICUBIC
        @param return_affine: If True, also return an affine transform that can be used to transform points.
        @returns: a cropped version of the image or if return affine a tuple of (image,affine)
        @rtype: pv.Image
        '''
        # Notes: pv.Rect(0,0,w,h) should return the entire image. Since pixel values
        # are indexed by zero this means that upper limits are not inclusive: x from [0,w)
        # and y from [0,h)
        x, y, w, h = rect.asTuple()

        x = int(np.round(x))
        y = int(np.round(y))
        w = int(np.round(w))
        h = int(np.round(h))

        # Check the bounds for cropping
        if x < 0 or y < 0 or x + w > self.size[0] or y + h > self.size[1]:
            if size is None:
                size = (w, h)

            affine = pv.AffineFromRect(pv.Rect(x, y, w, h), size)
            im = affine(self)
            if return_affine:
                return im, affine
            else:
                return im

        # Get the image as opencv
        cvim = self.asOpenCV()

        # Set up ROI
        subim = cv.GetSubRect(cvim, (x, y, w, h))

        affine = pv.AffineTranslate(-x, -y, (w, h))

        if size is None:
            size = (w, h)

        # Copy to new image
        new_image = cv.CreateImage(size, cvim.depth, cvim.nChannels)
        if interpolation is None:

            if size[0] < w or size[1] < y:
                # Downsampling so use area interpolation
                interpolation = cv.CV_INTER_AREA
            else:
                # Upsampling so use linear
                interpolation = cv.CV_INTER_CUBIC

        # Resize to the correct size
        cv.Resize(subim, new_image, interpolation)

        affine = pv.AffineNonUniformScale(
            float(size[0]) / w,
            float(size[1]) / h, size) * affine

        # Return the result as a pv.Image
        if return_affine:
            return pv.Image(new_image), affine
        else:
            return pv.Image(new_image)
Exemple #15
0
    def raw_detections(self, im):
        '''
        Run the face detectors with additional quality parameters.
        '''
        W, H = im.size

        scale = 1.0 / self.prescale
        im = im.scale(self.prescale)

        faces = self.fd(im)
        faces = [[scale * rect, 'FACE'] for rect in faces]

        heads = self.hd(im)

        # Approximate face locations from head detections
        hfaces = []
        for each in heads:
            # Get the center of the head location
            x, y, w, _ = each.asCenteredTuple()
            y = y - 0.10 * w
            w = 0.33 * w
            hfaces.append([scale * pv.CenteredRect(x, y, w, w), 'HEAD'])

        # Compute when face and head detections overlap
        for face in faces:
            best_overlap = 0.0
            for head in hfaces:
                best_overlap = max(best_overlap, face[0].similarity(head[0]))
            if best_overlap > 0.7:
                face.append(1.0)
            else:
                face.append(0.0)

        # Compute when face and head detections overlap
        for head in hfaces:
            best_overlap = 0.0
            for face in faces:
                best_overlap = max(best_overlap, head[0].similarity(face[0]))
            if best_overlap > 0.7:
                head.append(1.0)
            else:
                head.append(0.0)

        detections = faces + hfaces

        # Compute some simple statistics
        for each in detections:
            tile = pv.AffineFromRect(self.prescale * each[0], (128, 128))(im)
            #tile.show()

            # face vs head detection
            each.append(1.0 * (each[1] == 'FACE'))

            # size relative to image
            each.append(np.sqrt(each[0].area()) / np.sqrt(W * H))
            each.append(np.sqrt(each[0].area()) / np.sqrt(W * H)**2)

            # scaled contrast
            each.append(tile.asMatrix2D().std() / 255.0)
            each.append((tile.asMatrix2D().std() / 255.0)**2)

            # scaled brightness
            each.append(tile.asMatrix2D().mean() / 255.0)
            each.append((tile.asMatrix2D().mean() / 255.0)**2)

            # relative rgb intensity
            rgb = tile.asMatrix3D()
            t = rgb.mean() + 0.001  # grand mean regularized

            # rgb relative to grand mean
            r = -1 + rgb[0, :, :].mean() / t
            g = -1 + rgb[1, :, :].mean() / t
            b = -1 + rgb[2, :, :].mean() / t

            # create a quadradic model with interactions for rgb
            each += [r, g, b, r * r, r * g, r * b, g * g, g * b, b * b]

        return detections
Exemple #16
0
def processDetections(each):
    im, results, options = each
    if results.done():
        recs = results.result().face_records
        i = 0

        for face in recs:
            global FACE_COUNT
            FACE_COUNT += 1
            # Filter faces based on min size
            size = min(face.detection.location.width,
                       face.detection.location.height)
            if size < options.min_size:
                continue

            # Filter faces based on attributes
            if not processAttributeFilter(face, options):
                continue

            # Process Detections
            if options.detections_csv is not None:
                global DETECTIONS_CSV
                global DETECTIONS_FILE
                import csv
                if DETECTIONS_CSV == None:
                    DETECTIONS_FILE = open(options.detections_csv, 'w')
                    DETECTIONS_CSV = csv.writer(DETECTIONS_FILE)
                    DETECTIONS_CSV.writerow([
                        'source', 'frame', 'detect_id', 'type', 'score', 'x',
                        'y', 'w', 'h'
                    ])

                DETECTIONS_CSV.writerow([
                    face.source, face.frame, i, face.detection.detection_class,
                    face.detection.score, face.detection.location.x,
                    face.detection.location.y, face.detection.location.width,
                    face.detection.location.height
                ]),
                DETECTIONS_FILE.flush()

            # Process Detections
            if options.attributes_csv is not None:
                global ATTRIBUTES_CSV
                global ATTRIBUTES_FILE
                import csv

                if ATTRIBUTES_CSV == None:
                    ATTRIBUTES_FILE = open(options.attributes_csv, 'w')
                    ATTRIBUTES_CSV = csv.writer(ATTRIBUTES_FILE)
                    ATTRIBUTES_CSV.writerow([
                        'source', 'frame', 'detect_id', 'type', 'score', 'x',
                        'y', 'w', 'h', 'attribute', 'value'
                    ])

                attributes = list(face.attributes)
                attributes.sort(key=lambda x: x.key)
                for attribute in attributes:
                    key = attribute.key
                    value = attribute.fvalue
                    ATTRIBUTES_CSV.writerow([
                        face.source,
                        face.frame,
                        i,
                        face.detection.detection_class,
                        face.detection.score,
                        face.detection.location.x,
                        face.detection.location.y,
                        face.detection.location.width,
                        face.detection.location.height,
                        key,
                        value,
                    ]),
                ATTRIBUTES_FILE.flush()

                # Save Images with Detections

                # Save Detected Faces
                face_out_dir = ""

            if options.face_log:
                if not os.path.exists(options.face_log):
                    os.makedirs(options.face_log, exist_ok=True)
                #print(face.detection.location)

                rect = pt.rect_proto2pv(face.detection.location)
                rect = rect.rescale(1.5)
                affine = pv.AffineFromRect(rect, (128, 128))
                try:
                    pvim = pv.Image(im[:, :, ::-1])
                    view = affine(pvim)
                    #print('Face',rect)
                    #print(view)
                    base_name, ext = os.path.splitext(
                        os.path.basename(face.source))
                    out_path = os.path.join(
                        options.face_log,
                        os.path.basename(base_name) + '_face_%03d' %
                        (face.detection.detection_id, ) + ext)

                    view.save(out_path)
                    print('Saving face:', out_path)
                except:
                    print("WARNING: Image not processed correctly:",
                          face.source)

                out_path = os.path.join(
                    options.face_log,
                    os.path.basename(base_name) + '_orig' + ext)

                if not os.path.lexists(out_path):
                    os.symlink(os.path.abspath(face.source), out_path)

                #print(options.face_log)
                #pass
            i += 1

        return False
    return True
Exemple #17
0
    def extract(self, img, face_records):
        '''Extract a template that allows the face to be matched.'''
        # Compute the 128D vector that describes the face in img identified by
        # shape.  In general, if two face descriptor vectors have a Euclidean
        # distance between them less than 0.6 then they are from the same
        # person, otherwise they are from different people. Here we just print
        # the vector to the screen.

        im = pv.Image(img[:, :, ::-1])

        for face_record in face_records.face_records:
            rect = pt.rect_proto2pv(face_record.detection.location)
            x, y, w, h = rect.asTuple()

            # Extract view
            rect = pv.Rect()
            cx, cy = x + 0.5 * w, y + 0.5 * h
            tmp = 1.5 * max(w, h)
            cw, ch = tmp, tmp
            crop = pv.AffineFromRect(pv.CenteredRect(cx, cy, cw, ch),
                                     (256, 256))

            pvim = pv.Image(img[:, :, ::-1])  # convert rgb to bgr
            pvim = crop(pvim)
            view = pt.image_pv2proto(pvim)
            face_record.view.CopyFrom(view)

            # Extract landmarks
            l, t, r, b = [int(tmp) for tmp in [x, y, x + w, y + h]]
            d = dlib.rectangle(l, t, r, b)
            shape = self.shape_pred(img, d)

            for i in range(len(shape.parts())):
                loc = shape.parts()[i]
                landmark = face_record.landmarks.add()
                landmark.landmark_id = "point_%02d" % i
                landmark.location.x = loc.x
                landmark.location.y = loc.y

            # Get detection rectangle and crop the face
            #rect = pt.rect_proto2pv(face_record.detection.location).rescale(1.5)
            #tile = im.crop(rect)
            tile = pvim.resize((224, 224))

            #tile.show(delay=1000)

            face_im = tile.asOpenCV2()
            face_im = face_im[:, :, ::-1]  # Convert BGR to RGB
            #mat_ = cv2.cvtColor(mat,cv2.COLOR_RGB2GRAY)
            #mat = cv2.cvtColor(mat_,cv2.COLOR_GRAY2RGB)

            #img = image.load_img('../image/ajb.jpg', target_size=(224, 224))

            from keras_vggface import utils
            from keras.preprocessing import image

            face_im = image.img_to_array(face_im)
            face_im = np.expand_dims(face_im, axis=0)
            face_im = utils.preprocess_input(face_im,
                                             version=2)  # or version=2

            # Needed in multithreaded applications
            with self.graph.as_default():
                tmp = self.recognizer.predict(face_im)

            face_descriptor = pv.meanUnit(tmp.flatten())

            #print('shape:',face_records.face_records[0].landmarks)
            #face_descriptor = self.face_rec.compute_face_descriptor(img, shape, JITTER_COUNT)
            #face_descriptor = np.array(face_descriptor)

            #vec = face_descriptor.flatten()
            face_record.template.data.CopyFrom(
                pt.vector_np2proto(face_descriptor))