Пример #1
0
    def recalc_detectors(self, haar_file, lbp_file):
        self.haar_dtct = CascadeDetector(cascade_file=haar_file,
                                         min_size=self.min_size,
                                         min_neighbors=20,
                                         scale_factor=1.03,
                                         cascade_type='haar',
                                         thr=0.4,
                                         angles=self.hangles)

        self.lbp_dtct = CascadeDetector(cascade_file=lbp_file,
                                        min_size=self.min_size,
                                        min_neighbors=15,
                                        scale_factor=1.04,
                                        cascade_type='lbp',
                                        thr=0.4,
                                        angles=self.langles)
Пример #2
0
    def recalc_detectors(self, haar_file, lbp_file):
        self.haar_dtct = CascadeDetector(
            cascade_file=haar_file,
            min_size=self.min_size,
            min_neighbors=20,
            scale_factor=1.03,
            cascade_type="haar",
            thr=0.4,
            angles=self.hangles,
        )

        self.lbp_dtct = CascadeDetector(
            cascade_file=lbp_file,
            min_size=self.min_size,
            min_neighbors=15,
            scale_factor=1.04,
            cascade_type="lbp",
            thr=0.4,
            angles=self.langles,
        )
Пример #3
0
class CascadeFaceFinder(object):
    def __init__(self,
                 min_size=32,
                 drawn_target_res=360 * 360,
                 hangles=[0, -22, 22],
                 langles=[0, -45, -22, 22, 45],
                 haar_file='haarcascade_frontalface_default.xml',
                 lbp_file='lbpcascade_frontalface.xml'):
        '''
        finder = CascadeFaceFinder(min_size = 32, drawn_target_res = 360*360, hangles = [0], langles = [0,-45,-22,22,45], parts_threshold = 0)
        
        finder.get_faces_in_folder(input_folder, output_dir, drawn_folder, is_small_drawn)
        
        or
        
        finder.get_faces_in_photo(full_file, output_dir, drawn_folder, is_small_drawn)
        '''
        self.min_size = (min_size, min_size)
        self.drawn_target_res = drawn_target_res
        self._hangles = hangles
        self._langles = langles
        self.recalc_detectors(haar_file, lbp_file)

#         self.funnel = FaceFunnel()

    @property
    def hangles(self):
        return self._hangles

    @hangles.setter
    def hangles(self, hangles):
        self._hangles = hangles
        self.recalc_detectors()

    @property
    def langles(self):
        return self._langles

    @langles.setter
    def langles(self, langles):
        self._langles = langles
        self.recalc_detectors()

    def recalc_detectors(self, haar_file, lbp_file):
        self.haar_dtct = CascadeDetector(cascade_file=haar_file,
                                         min_size=self.min_size,
                                         min_neighbors=20,
                                         scale_factor=1.03,
                                         cascade_type='haar',
                                         thr=0.4,
                                         angles=self.hangles)

        self.lbp_dtct = CascadeDetector(cascade_file=lbp_file,
                                        min_size=self.min_size,
                                        min_neighbors=15,
                                        scale_factor=1.04,
                                        cascade_type='lbp',
                                        thr=0.4,
                                        angles=self.langles)

    def get_faces_list_in_photo(self, img):
        if self.hangles:
            haar_faces = self.haar_dtct.detectWithAngles(img, resolve=True)
        else:
            haar_faces = []
        lbp_faces = self.lbp_dtct.detectWithAngles(img, resolve=True)
        faces = resolve_boxes({
            'haar': haar_faces,
            'lbp': lbp_faces
        },
                              min_overlap=0.6)

        return faces

    def create_faces_file(self, fname, is_overwrite=False, target_file=None):
        '''
        Runs facial detection on fname (say a.jpg, or a.png), and creates a results file (a.faces.txt)
        
        target_file - override, and specify a specific target file
        is_overwrite - allow overwriting an existing results file
        '''
        faces = self.get_faces_list_in_photo(cv2.imread(fname))
        results_file = fname.rsplit(
            '.', 1)[0] + '.faces.txt' if target_file is None else target_file

        if os.path.exists(results_file) and not is_overwrite:
            print("Warning, faces result file", results_file, "exists")
        else:
            with open(results_file, 'w') as csvfile:
                csv_writer = csv.writer(csvfile, delimiter=',')
                header = ['x', 'y', 'dx', 'dy', 'score', 'angle', 'type']
                csv_writer.writerow(header)
                for face in faces:
                    csv_writer.writerow([
                        str(i) for i in [
                            int(face.x),
                            int(face.y),
                            int(face.dx),
                            int(face.dy), face.score, face.angle,
                            face.cascade_type
                        ]
                    ])
        return results_file

    def get_sub_images_from_file(self, original_image_file, faces_file):
        '''
        extracts all the face sub-images from an image file, based on the results in a faces file
        
        returns - the list of face images (numpy arrays)
        '''
        img = cv2.imread(original_image_file)
        faces_reader = csv.reader(open(faces_file))
        faces_reader.next()  # discard the headings
        padded_face_images = []
        for line in faces_reader:
            x, y, dx, dy, score, angle, cascade_type = line
            [x, y, dx, dy, score,
             angle] = [int(float(i)) for i in [x, y, dx, dy, score, angle]]
            face = CascadeResult(([x, y, dx, dy], score), cascade_type, angle)
            padded_face, bounding_box_in_padded_face, _, _ = extract_box(
                img, face, padding_factor=0.25)
            padded_face_images.append(padded_face)
        return padded_face_images

    def create_sub_images_from_file(self,
                                    original_image_file,
                                    faces_file,
                                    target_folder=None,
                                    img_type='png'):
        '''
        reads a faces file, created by "self.create_faces_file" and extracts padded faces from the original image
        The faces will be created in the same folder as the faces file, unless specified otherwise by "target_folder"
        
        returns - the list of face files (strings)
        '''
        target_folder = os.path.split(
            faces_file)[0] if target_folder is None else target_folder
        padded_face_images = self.get_sub_images_from_file(
            original_image_file, faces_file)

        base_image_name = os.path.split(faces_file)[1].split('.')[0]
        face_files = []
        for n_face, face_img in enumerate(padded_face_images):
            face_file = os.path.join(
                target_folder,
                base_image_name + '_face_%d.%s' % (n_face, img_type))
            cv2.imwrite(face_file, face_img)
            face_files.append(face_file)
        return face_files
Пример #4
0
class CascadeFaceFinder(object):
    def __init__(
        self,
        min_size=32,
        drawn_target_res=360 * 360,
        hangles=[0, -22, 22],
        langles=[0, -45, -22, 22, 45],
        haar_file="haarcascade_frontalface_default.xml",
        lbp_file="lbpcascade_frontalface.xml",
    ):
        """
        finder = CascadeFaceFinder(min_size = 32, drawn_target_res = 360*360, hangles = [0], langles = [0,-45,-22,22,45], parts_threshold = 0)
        
        finder.get_faces_in_folder(input_folder, output_dir, drawn_folder, is_small_drawn)
        
        or
        
        finder.get_faces_in_photo(full_file, output_dir, drawn_folder, is_small_drawn)
        """
        self.min_size = (min_size, min_size)
        self.drawn_target_res = drawn_target_res
        self._hangles = hangles
        self._langles = langles
        self.recalc_detectors(haar_file, lbp_file)

    #         self.funnel = FaceFunnel()

    @property
    def hangles(self):
        return self._hangles

    @hangles.setter
    def hangles(self, hangles):
        self._hangles = hangles
        self.recalc_detectors()

    @property
    def langles(self):
        return self._langles

    @langles.setter
    def langles(self, langles):
        self._langles = langles
        self.recalc_detectors()

    def recalc_detectors(self, haar_file, lbp_file):
        self.haar_dtct = CascadeDetector(
            cascade_file=haar_file,
            min_size=self.min_size,
            min_neighbors=20,
            scale_factor=1.03,
            cascade_type="haar",
            thr=0.4,
            angles=self.hangles,
        )

        self.lbp_dtct = CascadeDetector(
            cascade_file=lbp_file,
            min_size=self.min_size,
            min_neighbors=15,
            scale_factor=1.04,
            cascade_type="lbp",
            thr=0.4,
            angles=self.langles,
        )

    def get_faces_list_in_photo(self, img):
        if self.hangles:
            haar_faces = self.haar_dtct.detectWithAngles(img, resolve=True)
        else:
            haar_faces = []
        lbp_faces = self.lbp_dtct.detectWithAngles(img, resolve=True)
        faces = resolve_boxes({"haar": haar_faces, "lbp": lbp_faces}, min_overlap=0.6)

        return faces

    def create_faces_file(self, fname, is_overwrite=False, target_file=None):
        """
        Runs facial detection on fname (say a.jpg, or a.png), and creates a results file (a.faces.txt)
        
        target_file - override, and specify a specific target file
        is_overwrite - allow overwriting an existing results file
        """
        faces = self.get_faces_list_in_photo(cv2.imread(fname))
        results_file = fname.rsplit(".", 1)[0] + ".faces.txt" if target_file is None else target_file

        if os.path.exists(results_file) and not is_overwrite:
            print "Warning, faces result file", results_file, "exists"
        else:
            with open(results_file, "w") as csvfile:
                csv_writer = csv.writer(csvfile, delimiter=",")
                header = ["x", "y", "dx", "dy", "score", "angle", "type"]
                csv_writer.writerow(header)
                for face in faces:
                    csv_writer.writerow(
                        [
                            str(i)
                            for i in [
                                int(face.x),
                                int(face.y),
                                int(face.dx),
                                int(face.dy),
                                face.score,
                                face.angle,
                                face.cascade_type,
                            ]
                        ]
                    )
        return results_file

    def get_sub_images_from_file(self, original_image_file, faces_file):
        """
        extracts all the face sub-images from an image file, based on the results in a faces file
        
        returns - the list of face images (numpy arrays)
        """
        img = cv2.imread(original_image_file)
        faces_reader = csv.reader(open(faces_file))
        faces_reader.next()  # discard the headings
        padded_face_images = []
        for line in faces_reader:
            x, y, dx, dy, score, angle, cascade_type = line
            [x, y, dx, dy, score, angle] = [int(float(i)) for i in [x, y, dx, dy, score, angle]]
            face = CascadeResult(([x, y, dx, dy], score), cascade_type, angle)
            padded_face, bounding_box_in_padded_face, _, _ = extract_box(img, face, padding_factor=0.25)
            padded_face_images.append(padded_face)
        return padded_face_images

    def create_sub_images_from_file(self, original_image_file, faces_file, target_folder=None, img_type="png"):
        """
        reads a faces file, created by "self.create_faces_file" and extracts padded faces from the original image
        The faces will be created in the same folder as the faces file, unless specified otherwise by "target_folder"
        
        returns - the list of face files (strings)
        """
        target_folder = os.path.split(faces_file)[0] if target_folder is None else target_folder
        padded_face_images = self.get_sub_images_from_file(original_image_file, faces_file)

        base_image_name = os.path.split(faces_file)[1].split(".")[0]
        face_files = []
        for n_face, face_img in enumerate(padded_face_images):
            face_file = os.path.join(target_folder, base_image_name + "_face_%d.%s" % (n_face, img_type))
            cv2.imwrite(face_file, face_img)
            face_files.append(face_file)
        return face_files