Beispiel #1
0
    def search(self, gallery_name, probes, max_results, threshold):
        ''' search the gallery using the index. '''

        score_type = self.score_type

        probe_mat = [
            pt.vector_proto2np(face_rec.template.data)
            for face_rec in probes.face_records
        ]
        probe_mat = np.array(probe_mat, dtype=np.float32)

        gal_mat = self.indexes[gallery_name]

        # Compute the distance
        if score_type == fsd.L1:
            scores = spat.distance_matrix(probe_mat, gal_mat, 1)
        elif score_type == fsd.L2:
            scores = spat.distance_matrix(probe_mat, gal_mat, 2)
        elif score_type == fsd.NEG_DOT:
            scores = -np.dot(probe_mat, gal_mat.T)
        else:
            NotImplementedError("ScoreType %s is not implemented." %
                                (score_type, ))

        face_ids = self.face_ids[gallery_name]

        for p in range(scores.shape[0]):
            #probe = probes.face_records[p]
            #out = result.probes.face_records[p].search_results
            matches = []
            for g in range(scores.shape[1]):
                score = scores[p, g]
                if score > threshold:
                    continue
                face = self.getFaceRecord(gallery_name, face_ids[g])
                matches.append([score, face])

            matches.sort(key=lambda x: x[0])

            if max_results > 0:
                matches = matches[:max_results]

            for score, face in matches:
                probes.face_records[p].search_results.face_records.add(
                ).CopyFrom(face)
                probes.face_records[p].search_results.face_records[
                    -1].score = score

        return probes
Beispiel #2
0
    def score(self, score_request):
        '''Compare templates to produce scores.'''
        score_type = self.scoreType()
        result = geo.Matrix()

        # Check that this is a known score type
        if score_type not in [fsd.L1, fsd.L2, fsd.NEG_DOT]:
            raise NotImplementedError("Score type <%s> not implemented." %
                                      (score_type, ))

        # Check to make sure the probe and gallery records are correct
        if min(len(score_request.face_probes.face_records),
               len(score_request.template_probes.templates)) != 0:
            raise ValueError(
                "probes argument cannot have both face_probes and template_probes defined."
            )
        if max(len(score_request.face_probes.face_records),
               len(score_request.template_probes.templates)) == 0:
            raise ValueError("no probe templates were found in the arguments.")
        if min(len(score_request.face_gallery.face_records),
               len(score_request.template_gallery.templates)) != 0:
            raise ValueError(
                "gallery argument cannot have both face_gallery and template_gallery defined."
            )
        if max(len(score_request.face_gallery.face_records),
               len(score_request.template_gallery.templates)) == 0:
            raise ValueError(
                "no gallery templates were found in the arguments.")

        # Generate probe and gallery matrices
        if len(score_request.face_probes.face_records) > len(
                score_request.template_probes.templates):
            probe_mat = [
                pt.vector_proto2np(face_rec.template.data)
                for face_rec in score_request.face_probes.face_records
            ]
        else:
            probe_mat = [
                pt.vector_proto2np(template.data)
                for template in score_request.template_probes.templates
            ]
        probe_mat = np.array(probe_mat, dtype=np.float32)

        if len(score_request.face_gallery.face_records) > len(
                score_request.template_gallery.templates):
            gal_mat = [
                pt.vector_proto2np(face_rec.template.data)
                for face_rec in score_request.face_gallery.face_records
            ]
        else:
            gal_mat = [
                pt.vector_proto2np(template.data)
                for template in score_request.template_gallery.templates
            ]
        gal_mat = np.array(gal_mat, dtype=np.float32)

        # Compute the distance
        if score_type == fsd.L1:
            dist_mat = spat.distance_matrix(probe_mat, gal_mat, 1)
        elif score_type == fsd.L2:
            dist_mat = spat.distance_matrix(probe_mat, gal_mat, 2)
        elif score_type == fsd.NEG_DOT:
            dist_mat = -np.dot(probe_mat, gal_mat.T)
        else:
            NotImplementedError("ScoreType %s is not implemented." %
                                (score_type, ))

        # Return the result
        return pt.matrix_np2proto(dist_mat)
Beispiel #3
0
    def addFaceToGallery(self, gallery_name, gallery_key, face):
        ''' Enrolls the faces in the gallery. '''
        import h5py

        global STORAGE

        replaced = 0
        print('Gallery name:', gallery_name)
        print(list(STORAGE.keys()))
        if gallery_name not in STORAGE:
            path = os.path.join(self.gallery_storage, gallery_name + '.h5')
            print('adding new gallery at ', path)
            STORAGE[gallery_name] = h5py.File(path, 'a')
            STORAGE[gallery_name].create_group('faces')
            STORAGE[gallery_name].create_group('sources')
            STORAGE[gallery_name].create_group('detections')
            STORAGE[gallery_name].create_group('tags')
            STORAGE[gallery_name].create_group('logs')

        enrolled = 0

        face_id = faro.generateFaceId(face)
        face.gallery_key = face_id

        enrolled += 1

        if face_id in STORAGE[gallery_name]['faces']:
            del STORAGE[gallery_name]['faces'][
                face_id]  # delete so it can be replaced.
            replaced += 1
        STORAGE[gallery_name]['faces'][face_id] = np.bytes_(
            face.SerializeToString())

        template = pt.vector_proto2np(face.template.data)
        temp_length = template.shape[0]
        print('template shape: ', template.shape)
        if 'templates' not in STORAGE[gallery_name]:
            # Create an empty dataset
            f = STORAGE[gallery_name]
            dset = f.create_dataset('templates',
                                    data=np.zeros((0, temp_length)),
                                    maxshape=(None, temp_length),
                                    dtype=np.float32)

        if 'facelist' not in STORAGE[gallery_name]:
            # Create an empty dataset
            f = STORAGE[gallery_name]
            dt = h5py.special_dtype(vlen=str)
            dset = f.create_dataset('facelist', (0, ),
                                    maxshape=(None, ),
                                    dtype=dt)

        # Append to the end
        dset = STORAGE[gallery_name]['templates']
        size = dset.shape
        print('dataset size 2:', size)
        dset.resize((size[0] + 1, size[1]))
        dset[-1, :] = template

        dset = STORAGE[gallery_name]['facelist']
        size = dset.shape
        dset.resize((size[0] + 1, ))
        dset[-1] = face_id

        STORAGE[gallery_name].flush()

        self.clearIndex(gallery_name)

        return enrolled, replaced
Beispiel #4
0
    def generateIndex(self, gallery_name):
        ''' Process the gallery to generate a fast index. '''
        import h5py

        #try:
        #    print("Gallery Names:",list(STORAGE[gallery_name]))
        #    self.clearIndex(gallery_name)
        #except:
        #    print("Problem clearing index.")

        if gallery_name not in STORAGE:
            raise ValueError("Unknown gallery: " + gallery_name)

        if gallery_name in self.indexes:
            # This seems to exist and be loaded into memory so just continue
            return

        if 'index' in STORAGE[gallery_name]:
            # Use the existing index
            self.indexes[gallery_name] = np.array(
                STORAGE[gallery_name]['index'], dtype=np.float32)
            self.face_ids[gallery_name] = list(
                STORAGE[gallery_name]['face_ids'])
            return

        else:
            # Generate the index
            start = time.time()

            gsize = self.size(gallery_name)

            dset = None

            print("Building Gallery Index...")
            i = 0
            for key in STORAGE[gallery_name]['faces']:
                i += 1
                if i % 1000 == 0: print("Scanning ", i, " of ", gsize)
                tmp = STORAGE[gallery_name]['faces'][key]
                face = FaceRecord()
                face.ParseFromString(np.array(tmp).tobytes())
                vec = pt.vector_proto2np(face.template.data)

                # Figure out the size of the vectors
                assert len(vec.shape) == 1
                cols = vec.shape[0]

                # Store into an h5 datasets to keep memory requirements low
                if dset is None:
                    try:
                        del STORAGE[gallery_name]['index']
                    except:
                        pass
                    dset = STORAGE[gallery_name].create_dataset(
                        "index", (0, cols), maxshape=(None, cols), dtype='f4')
                    dt = None
                    try:
                        dt = h5py.string_dtype()  # h5py > 2.10.0
                    except:
                        dt = h5py.special_dtype(vlen=str)  # h5py==2.9.0
                    try:
                        del STORAGE[gallery_name]['face_ids']
                    except:
                        pass
                    fset = STORAGE[gallery_name].create_dataset(
                        "face_ids", (0, ), maxshape=(None, ), dtype=dt)

                r, c = dset.shape
                dset.resize((r + 1, cols))
                dset[r, :] = vec
                fset.resize((r + 1, ))
                fset[r] = key

            stop = time.time()

            # save the index in memory
            self.indexes[gallery_name] = np.array(
                STORAGE[gallery_name]['index'], dtype=np.float32)
            self.face_ids[gallery_name] = list(
                STORAGE[gallery_name]['face_ids'])
            print("   Index Complete: %d faces in %0.3fs  Total Size: %s" %
                  (self.size(gallery_name), stop - start,
                   STORAGE[gallery_name]['index'].shape))
Beispiel #5
0
 def addTemplate(self, temp):
     self.faces.append(temp)
     self.vectors.append(pt.vector_proto2np(temp.template))
     self.vector_cache = None