def testDetectFacesAndCreateFiles(self): ''' Go through two images, the first with 1 face, the second with 4 faces Assert that the detected faces are correct, and draw them. Also creates output images of the padded faces ''' fnames = ['./resources/cascade/janice2.jpg', './resources/cascade/albert4.jpg', './resources/cascade/albert5.jpg', './resources/cascade/david1.jpg'] for n_image in range(len(fnames)): fname = fnames[n_image] expected_result = expected_results[n_image] _, base_fname = os.path.split(fname) face_finder = CascadeFaceFinder(haar_file = '../resources/haarcascade_frontalface_default.xml', lbp_file = '../resources/lbpcascade_frontalface.xml') faces_file = face_finder.create_faces_file(fname, is_overwrite = True, target_file = './outputs/cascade/2/' + base_fname + '.faces.txt') # get the sub images sub_images = face_finder.get_sub_images_from_file(original_image_file = fname, faces_file = faces_file) for n_face, sub_image in enumerate(sub_images): cv2.imshow('face_%d' %n_face, sub_image) cv2.waitKey() # create sub images files sub_images_file = face_finder.create_sub_images_from_file(original_image_file = fname, faces_file = faces_file, target_folder = None) with open(faces_file,'r') as fid: for i in range(len(expected_result)): line = fid.readline()
def testDetectFacesAndCreateFiles(self): ''' Go through two images, the first with 1 face, the second with 4 faces Assert that the detected faces are correct, and draw them. Also creates output images of the padded faces ''' fnames = [ './resources/cascade/Fayssal_Mekdad_0002.jpg', './resources/cascade/family-home.png' ] expected_results = [ ['x,y,dx,dy,score,angle,type\n', '61,62,132,132,344,0.0,haar'], [ 'x,y,dx,dy,score,angle,type\n', '327,101,121,121,154,0.0,lbp\n', '237,106,113,113,139,0.0,lbp\n', '164,49,91,91,49,0.0,lbp\n', '434,86,94,94,95,0.0,lbp\n' ] ] for n_image in range(len(fnames)): fname = fnames[n_image] expected_result = expected_results[n_image] _, base_fname = os.path.split(fname) face_finder = CascadeFaceFinder( haar_file='../resources/haarcascade_frontalface_default.xml', lbp_file='../resources/lbpcascade_frontalface.xml') faces_file = face_finder.create_faces_file( fname, is_overwrite=True, target_file='./outputs/cascade/2/' + base_fname + '.faces.txt') # get the sub images sub_images = face_finder.get_sub_images_from_file( original_image_file=fname, faces_file=faces_file) for n_face, sub_image in enumerate(sub_images): cv2.imshow('face_%d' % n_face, sub_image) cv2.waitKey() # create sub images files sub_images_file = face_finder.create_sub_images_from_file( original_image_file=fname, faces_file=faces_file, target_folder=None) with open(faces_file, 'r') as fid: for i in range(len(expected_result)): line = fid.readline() self.assertEqual(line.strip(), expected_result[i].strip())
def __init__(self, haar_file = '../resources/haarcascade_frontalface_default.xml', lbp_file = '../resources/lbpcascade_frontalface.xml', fidu_model_file = '../resources/model_ang_0.txt', fidu_exec_dir = '../resources/'): ''' Constructor ''' self.face_finder = CascadeFaceFinder(haar_file = haar_file, lbp_file = lbp_file) self.aligner = AffineAligner(fidu_model_file = fidu_model_file) self.fidu_exec_dir = fidu_exec_dir self.valid_angles = [-45,-30,-15,0,15,30,45]
def testDetectFaces(self): ''' Go through two images, the first with 1 face, the second with 4 faces Assert that the detected faces are correct, and draw them. Also creates output images of the padded faces ''' fnames = ['./resources/cascade/Fayssal_Mekdad_0002.jpg', './resources/cascade/family-home.png'] expected_faces = [[],[]] expected_faces[0].append(CascadeResult(box_with_score = ([61,62,132,132], 344), cascade_type = 'haar', angle = 0.0)) expected_faces[1].append(CascadeResult(box_with_score = ([327,101,119,119], 244), cascade_type = 'haar', angle = 0.0)) expected_faces[1].append(CascadeResult(box_with_score = ([238,107,111,111], 135), cascade_type = 'lbp', angle = 0.0)) expected_faces[1].append(CascadeResult(box_with_score = ([163,48,93,93], 51), cascade_type = 'lbp', angle = 0.0)) expected_faces[1].append(CascadeResult(box_with_score = ([433,86,95,95], 92), cascade_type = 'lbp', angle = 0.0)) for n_images, fname in enumerate(fnames): _, base_fname = os.path.split(fname) img = cv2.imread(fname) gray_img = cv2.imread(fname, 0) face_finder = CascadeFaceFinder(haar_file = '../resources/haarcascade_frontalface_default.xml', lbp_file = '../resources/lbpcascade_frontalface.xml') faces = face_finder.get_faces_list_in_photo(gray_img) img_to_draw_on = img.copy() for n_face, face in enumerate(faces): self.assertAlmostEqual(face.overlap(expected_faces[n_images][n_face]) / face.area, 1.00, 0.01) draw_rect(img_to_draw_on, face) padded_face, bounding_box_in_padded_face, _, _ = extract_box(img, face, padding_factor = 0.25) new_face_file = os.path.join('./outputs/cascade/1/', base_fname.split('.')[0] + '.face.%d.png' %n_face) cv2.imwrite(new_face_file, padded_face) padded_face_loaded = cv2.imread(new_face_file) draw_rect(padded_face_loaded, bounding_box_in_padded_face) cv2.imshow('face %d' %n_face, padded_face_loaded) cv2.waitKey() cv2.imshow('faces detected', img_to_draw_on) cv2.waitKey()
def testDetectFacesAndCreateFiles(self): ''' Go through two images, the first with 1 face, the second with 4 faces Assert that the detected faces are correct, and draw them. Also creates output images of the padded faces ''' fnames = ['./resources/cascade/Fayssal_Mekdad_0002.jpg', './resources/cascade/family-home.png'] expected_results = [['x,y,dx,dy,score,angle,type\n', '61,62,132,132,344,0.0,haar'], ['x,y,dx,dy,score,angle,type\n', '327,101,121,121,154,0.0,lbp\n', '237,106,113,113,139,0.0,lbp\n', '164,49,91,91,49,0.0,lbp\n', '434,86,94,94,95,0.0,lbp\n'] ] for n_image in range(len(fnames)): fname = fnames[n_image] expected_result = expected_results[n_image] _, base_fname = os.path.split(fname) face_finder = CascadeFaceFinder(haar_file = '../resources/haarcascade_frontalface_default.xml', lbp_file = '../resources/lbpcascade_frontalface.xml') faces_file = face_finder.create_faces_file(fname, is_overwrite = True, target_file = './outputs/cascade/2/' + base_fname + '.faces.txt') # get the sub images sub_images = face_finder.get_sub_images_from_file(original_image_file = fname, faces_file = faces_file) for n_face, sub_image in enumerate(sub_images): cv2.imshow('face_%d' %n_face, sub_image) cv2.waitKey() # create sub images files sub_images_file = face_finder.create_sub_images_from_file(original_image_file = fname, faces_file = faces_file, target_folder = None) with open(faces_file,'r') as fid: for i in range(len(expected_result)): line = fid.readline() self.assertEqual(line.strip(), expected_result[i].strip())
def testDetectFaces(self): ''' Go through two images, the first with 1 face, the second with 4 faces Assert that the detected faces are correct, and draw them. Also creates output images of the padded faces ''' fnames = ['./resources/cascade/janice2.jpg', './resources/cascade/albert4.jpg', './resources/cascade/albert5.jpg', './resources/cascade/david1.jpg'] for n_images, fname in enumerate(fnames): _, base_fname = os.path.split(fname) img = cv2.imread(fname) gray_img = cv2.imread(fname, 0) face_finder = CascadeFaceFinder(haar_file = '../resources/haarcascade_frontalface_default.xml', lbp_file = '../resources/lbpcascade_frontalface.xml') faces = face_finder.get_faces_list_in_photo(gray_img) img_to_draw_on = img.copy() for n_face, face in enumerate(faces): draw_rect(img_to_draw_on, face) padded_face, bounding_box_in_padded_face, _, _ = extract_box(img, face, padding_factor = 0.25) new_face_file = os.path.join('./outputs/cascade/1/', base_fname.split('.')[0] + '.face.%d.png' %n_face) cv2.imwrite(new_face_file, padded_face) padded_face_loaded = cv2.imread(new_face_file) draw_rect(padded_face_loaded, bounding_box_in_padded_face) cv2.imshow('face %d' %n_face, padded_face_loaded) cv2.waitKey() cv2.imshow('faces detected', img_to_draw_on) cv2.waitKey()
def testDetectFaces(self): ''' Go through two images, the first with 1 face, the second with 4 faces Assert that the detected faces are correct, and draw them. Also creates output images of the padded faces ''' fnames = [ './resources/cascade/Fayssal_Mekdad_0002.jpg', './resources/cascade/family-home.png' ] expected_faces = [[], []] expected_faces[0].append( CascadeResult(box_with_score=([61, 62, 132, 132], 344), cascade_type='haar', angle=0.0)) expected_faces[1].append( CascadeResult(box_with_score=([327, 101, 119, 119], 244), cascade_type='haar', angle=0.0)) expected_faces[1].append( CascadeResult(box_with_score=([238, 107, 111, 111], 135), cascade_type='lbp', angle=0.0)) expected_faces[1].append( CascadeResult(box_with_score=([163, 48, 93, 93], 51), cascade_type='lbp', angle=0.0)) expected_faces[1].append( CascadeResult(box_with_score=([433, 86, 95, 95], 92), cascade_type='lbp', angle=0.0)) for n_images, fname in enumerate(fnames): _, base_fname = os.path.split(fname) img = cv2.imread(fname) gray_img = cv2.imread(fname, 0) face_finder = CascadeFaceFinder( haar_file='../resources/haarcascade_frontalface_default.xml', lbp_file='../resources/lbpcascade_frontalface.xml') faces = face_finder.get_faces_list_in_photo(gray_img) img_to_draw_on = img.copy() for n_face, face in enumerate(faces): self.assertAlmostEqual( face.overlap(expected_faces[n_images][n_face]) / face.area, 1.00, 0.01) draw_rect(img_to_draw_on, face) padded_face, bounding_box_in_padded_face, _, _ = extract_box( img, face, padding_factor=0.25) new_face_file = os.path.join( './outputs/cascade/1/', base_fname.split('.')[0] + '.face.%d.png' % n_face) cv2.imwrite(new_face_file, padded_face) padded_face_loaded = cv2.imread(new_face_file) draw_rect(padded_face_loaded, bounding_box_in_padded_face) cv2.imshow('face %d' % n_face, padded_face_loaded) cv2.waitKey() cv2.imshow('faces detected', img_to_draw_on) cv2.waitKey()
class CascadeFaceAligner(object): ''' classdocs ''' def __init__(self, haar_file = '../resources/haarcascade_frontalface_default.xml', lbp_file = '../resources/lbpcascade_frontalface.xml', fidu_model_file = '../resources/model_ang_0.txt', fidu_exec_dir = '../resources/'): ''' Constructor ''' self.face_finder = CascadeFaceFinder(haar_file = haar_file, lbp_file = lbp_file) self.aligner = AffineAligner(fidu_model_file = fidu_model_file) self.fidu_exec_dir = fidu_exec_dir self.valid_angles = [-45,-30,-15,0,15,30,45] def detect_faces(self, input_folder, output_folder, mark_dones = True): ''' mark_dones - if True, will create a hidden file, marking this file as done with a hidden file, starting with '.done.' ''' input_files1 = glob.glob(os.path.join(input_folder, '*.jpg')) input_files2 = glob.glob(os.path.join(input_folder, '*.png')) input_files = input_files1 + input_files2 N = len(input_files) for n_file, input_file in enumerate(input_files): a,b = os.path.split(input_file) done_file = os.path.join(a, '.done.' + b.rsplit('.',1)[0]) if os.path.exists(done_file): continue print ("... processing", input_file) target_faces_file = os.path.join( output_folder, os.path.split(input_file)[1].rsplit('.',1)[0] + '.faces.txt') faces_file = self.face_finder.create_faces_file( input_file, is_overwrite = False, target_file = target_faces_file ) sub_images_files = self.face_finder.create_sub_images_from_file( original_image_file = input_file, faces_file = faces_file, target_folder = output_folder, img_type = 'jpg') #touch open(done_file,'w').close() print ("Detected on %d / %d files" %(n_file, N)) def align_faces(self, input_images, output_path, fidu_max_size = None, fidu_min_size = None, is_align = True, is_draw_fidu = False, delete_no_fidu = False): ''' input_images - can be either a folder (all *.jpgs in it) or a list of filenames , fidu_max_size = None, fidu_min_size = None): ''' if type(input_images) == type(''): input_images = glob.glob(os.path.join(input_images, '*.jpg')) for input_image in input_images: detect_landmarks(fname = os.path.abspath(input_image), max_size = fidu_max_size, min_size = fidu_min_size, fidu_exec_dir = self.fidu_exec_dir) fidu_file = input_image.rsplit('.',1)[0] + '.cfidu' fidu_score, yaw_angle, fidu_points = read_fidu(fidu_file) if not (fidu_score is not None and yaw_angle in self.valid_angles): # skip face if delete_no_fidu: os.remove(fidu_file) os.remove(input_image) continue if is_align: # save the aligned image sub_img = cv2.imread(input_image) _, base_fname = os.path.split(input_image) aligned_img, R = self.aligner.align(sub_img, fidu_points) aligned_img_file = os.path.join(output_path, base_fname.rsplit('.',1)[0] + '.aligned.png') cv2.imwrite(aligned_img_file, aligned_img) # save a copy of the aligned image, with the landmarks drawn if is_draw_fidu: aligned_img_file = os.path.join(output_path, base_fname.rsplit('.',1)[0] + '.aligned.withpoints.png') fidu_points_in_aligned = unwarp_fidu(orig_fidu_points = fidu_points, unwarp_mat = R) draw_fidu(aligned_img, fidu_points_in_aligned, radius = 9, color = (255,0,0), thickness = 3) cv2.imwrite(aligned_img_file, aligned_img)
class CascadeFaceAligner(object): ''' classdocs ''' def __init__(self, haar_file = '../resources/haarcascade_frontalface_default.xml', lbp_file = '../resources/lbpcascade_frontalface.xml', fidu_model_file = '../resources/model_ang_0.txt', fidu_exec_dir = '../resources/'): ''' Constructor ''' self.face_finder = CascadeFaceFinder(haar_file = haar_file, lbp_file = lbp_file) self.aligner = AffineAligner(fidu_model_file = fidu_model_file) self.fidu_exec_dir = fidu_exec_dir self.valid_angles = [-45,-30,-15,0,15,30,45] def detect_faces(self, input_folder, output_folder, mark_dones = True): ''' mark_dones - if True, will create a hidden file, marking this file as done with a hidden file, starting with '.done.' ''' input_files1 = glob.glob(os.path.join(input_folder, '*.jpg')) input_files2 = glob.glob(os.path.join(input_folder, '*.png')) input_files = input_files1 + input_files2 N = len(input_files) for n_file, input_file in enumerate(input_files): a,b = os.path.split(input_file) done_file = os.path.join(a, '.done.' + b.rsplit('.',1)[0]) if os.path.exists(done_file): continue print "... processing", input_file target_faces_file = os.path.join( output_folder, os.path.split(input_file)[1].rsplit('.',1)[0] + '.faces.txt') faces_file = self.face_finder.create_faces_file( input_file, is_overwrite = False, target_file = target_faces_file ) sub_images_files = self.face_finder.create_sub_images_from_file( original_image_file = input_file, faces_file = faces_file, target_folder = output_folder, img_type = 'jpg') #touch open(done_file,'w').close() print "Detected on %d / %d files" %(n_file, N) def align_faces(self, input_images, output_path, fidu_max_size = None, fidu_min_size = None, is_align = True, is_draw_fidu = False, delete_no_fidu = False): ''' input_images - can be either a folder (all *.jpgs in it) or a list of filenames , fidu_max_size = None, fidu_min_size = None): ''' if type(input_images) == type(''): input_images = glob.glob(os.path.join(input_images, '*.jpg')) for input_image in input_images: detect_landmarks(fname = os.path.abspath(input_image), max_size = fidu_max_size, min_size = fidu_min_size, fidu_exec_dir = self.fidu_exec_dir) fidu_file = input_image.rsplit('.',1)[0] + '.cfidu' fidu_score, yaw_angle, fidu_points = read_fidu(fidu_file) if not (fidu_score is not None and yaw_angle in self.valid_angles): # skip face if delete_no_fidu: os.remove(fidu_file) os.remove(input_image) continue if is_align: # save the aligned image sub_img = cv2.imread(input_image) _, base_fname = os.path.split(input_image) aligned_img, R = self.aligner.align(sub_img, fidu_points) aligned_img_file = os.path.join(output_path, base_fname.rsplit('.',1)[0] + '.aligned.png') cv2.imwrite(aligned_img_file, aligned_img) # save a copy of the aligned image, with the landmarks drawn if is_draw_fidu: aligned_img_file = os.path.join(output_path, base_fname.rsplit('.',1)[0] + '.aligned.withpoints.png') fidu_points_in_aligned = unwarp_fidu(orig_fidu_points = fidu_points, unwarp_mat = R) draw_fidu(aligned_img, fidu_points_in_aligned, radius = 9, color = (255,0,0), thickness = 3) cv2.imwrite(aligned_img_file, aligned_img)