def main(): args = get_args() depth = args.depth k = args.width img_size = 64 batch_size = 32 model = WideResNet(img_size, depth=depth, k=k)() model.load_weights("checkpoints168/weights.48-3.62.hdf5") dataset_root = Path(__file__).parent.joinpath("data", "wiki_db.mat") images, genders, ages, _, image_size, _ = load_data(dataset_root) pre_ages = [] faces = np.empty((batch_size, img_size, img_size, 3)) print("number of images: ", len(images)) for i, image in tqdm(enumerate(images)): faces[i % batch_size] = image if (i + 1) % batch_size == 0 or i == len(images) - 1: results = model.predict(faces) ages_out = np.arange(0, 101).reshape(101, 1) predicted_ages = results[1].dot(ages_out).flatten() pre_ages += list(predicted_ages) # len(ages) can be larger than len(image_names) due to the last batch, but it's ok. wiki_abs_error = 0.0 for i in range(len(ages)): wiki_abs_error += abs(pre_ages[i] - ages[i]) # print(str(image_paths[i])) print("MAE : {}".format(wiki_abs_error / len(ages)))
def age_gender_predict(faces): if len(faces) > 0: # モデルの設定 if os.isdir("model") == False: pre_model = "https://github.com/yu4u/age-gender-estimation/releases/download/v0.5/weights.28-3.73.hdf5" modhash = 'fbe63257a054c1c5466cfd7bf14646d6' weight_file = get_file("weights.28-3.73.hdf5", pre_model, cache_subdir="model", file_hash=modhash, cache_dir=str( Path(__file__).resolve().parent)) else: weight_file = "model/weights.28-3.73.hdf5" img_size = np.asarray(faces.shape)[1] model = WideResNet(img_size, depth=16, k=8)() model.load_weights(weight_file) # 予測 results = model.predict(faces) Genders = results[0] ages = np.arange(0, 101).reshape(101, 1) Ages = results[1].dot(ages).flatten() return Ages, Genders
def main(): args = get_args() depth = args.depth k = args.width weight_file = args.weight_file # load model and weights img_size = 64 batch_size = 32 model = WideResNet(img_size, depth=depth, k=k)() model.load_weights(weight_file) dataset_root = Path(__file__).parent.joinpath("appa-real", "appa-real-release") validation_image_dir = dataset_root.joinpath("test") gt_valid_path = dataset_root.joinpath("gt_avg_test.csv") image_paths = list(validation_image_dir.glob("*_face.jpg")) faces = np.empty((batch_size, img_size, img_size, 3)) ages = [] image_names = [] for i, image_path in tqdm(enumerate(image_paths)): faces[i % batch_size] = cv2.resize(cv2.imread(str(image_path), 1), (img_size, img_size)) image_names.append(image_path.name[:-9]) if (i + 1) % batch_size == 0 or i == len(image_paths) - 1: results = model.predict(faces) ages_out = np.arange(0, 101).reshape(101, 1) predicted_ages = results[1].dot(ages_out).flatten() ages += list(predicted_ages) print(len(ages)) print(len(image_names)) name2age = {image_names[i]: ages[i] for i in range(len(image_names))} df = pd.read_csv(str(gt_valid_path)) appa_abs_error = 0.0 real_abs_error = 0.0 epsilon_error = 0.0 count1 = 0 count2 = 0 iter = 0 for i, row in df.iterrows(): #iter += 1 difference1 = name2age[row.file_name] - row.apparent_age_avg difference2 = name2age[row.file_name] - row.real_age appa_abs_error += abs(difference1) real_abs_error += abs(difference2) epsilon_error += error(name2age[row.file_name], row.apparent_age_avg, 0.3) ''''if int(difference1) == 0: count1 += 1 if int(difference2) == 0: count2 += 1 if iter < 5: print("Predicted age: {}".format(name2age[row.file_name]))''' print("MAE Apparent: {}".format(appa_abs_error / len(image_names))) print("MAE Real: {}".format(real_abs_error / len(image_names))) print("\u03B5-error: {}".format(epsilon_error / len(image_names)))
def main(): # for face detection detector = dlib.get_frontal_face_detector() # load model and weights img_size = 64 model = WideResNet(img_size, depth=16, k=8)() model.load_weights( os.path.join("pretrained_models", "weights.18-4.06.hdf5")) # capture video cap = cv2.VideoCapture(0) cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) while True: # get video frame ret, img = cap.read() if not ret: print("error: failed to capture image") return -1 input_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img_h, img_w, _ = np.shape(input_img) # detect faces using dlib detector detected = detector(input_img, 1) faces = np.empty((len(detected), img_size, img_size, 3)) for i, d in enumerate(detected): x1, y1, x2, y2, w, h = d.left(), d.top( ), d.right() + 1, d.bottom() + 1, d.width(), d.height() xw1 = max(int(x1 - 0.4 * w), 0) yw1 = max(int(y1 - 0.4 * h), 0) xw2 = min(int(x2 + 0.4 * w), img_w - 1) yw2 = min(int(y2 + 0.4 * h), img_h - 1) cv2.rectangle(img, (x1, y1), (x2, y2), (255, 0, 0), 2) # cv2.rectangle(img, (xw1, yw1), (xw2, yw2), (255, 0, 0), 2) faces[i, :, :, :] = cv2.resize(img[yw1:yw2 + 1, xw1:xw2 + 1, :], (img_size, img_size)) # predict ages and genders of the detected faces results = model.predict(faces) predicted_genders = results[0] ages = np.arange(0, 101).reshape(101, 1) predicted_ages = results[1].dot(ages).flatten() # draw results for i, d in enumerate(detected): label = "{}, {}".format( int(predicted_ages[i]), "F" if predicted_genders[i][0] > 0.5 else "M") draw_label(img, (d.left(), d.top()), label) cv2.imshow("result", img) key = cv2.waitKey(30) if key == 27: break
def main(): args = get_args() depth = args.depth k = args.width weight_file = args.weight_file margin = args.margin image_dir = args.image_dir if not weight_file: weight_file = get_file("weights.28-3.73.hdf5", pretrained_model, cache_subdir="pretrained_models", file_hash=modhash, cache_dir=str(Path(__file__).resolve().parent)) # for face detection detector = dlib.get_frontal_face_detector() # load model and weights img_size = 64 model = WideResNet(img_size, depth=depth, k=k)() model.load_weights(weight_file) image_generator = yield_images_from_dir(image_dir) if image_dir else yield_images() for img in image_generator: input_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img_h, img_w, _ = np.shape(input_img) # detect faces using dlib detector detected = detector(input_img, 1) faces = np.empty((len(detected), img_size, img_size, 3)) if len(detected) > 0: for i, d in enumerate(detected): x1, y1, x2, y2, w, h = d.left(), d.top(), d.right() + 1, d.bottom() + 1, d.width(), d.height() xw1 = max(int(x1 - margin * w), 0) yw1 = max(int(y1 - margin * h), 0) xw2 = min(int(x2 + margin * w), img_w - 1) yw2 = min(int(y2 + margin * h), img_h - 1) cv2.rectangle(img, (x1, y1), (x2, y2), (255, 0, 0), 2) # cv2.rectangle(img, (xw1, yw1), (xw2, yw2), (255, 0, 0), 2) faces[i, :, :, :] = cv2.resize(img[yw1:yw2 + 1, xw1:xw2 + 1, :], (img_size, img_size)) # predict ages and genders of the detected faces results = model.predict(faces) predicted_genders = results[0] ages = np.arange(0, 101).reshape(101, 1) predicted_ages = results[1].dot(ages).flatten() # draw results for i, d in enumerate(detected): label = "{}, {}".format(int(predicted_ages[i]), "M" if predicted_genders[i][0] < 0.5 else "F") draw_label(img, (d.left(), d.top()), label) cv2.imshow("result", img) key = cv2.waitKey(-1) if image_dir else cv2.waitKey(30) if key == 27: # ESC break
class AgeGenderEstimator(object): def __init__(self, weights_file_path, img_size=64, depth=16, width=8): """ Estimate the age and gender of the incoming image :param weights_file_path: path to a pre-trained keras network """ weights_file_path = os.path.expanduser(weights_file_path) if not os.path.isfile(weights_file_path): raise IOError( "Weights file {}, no such file ..".format(weights_file_path)) self._model = None self._weights_file_path = weights_file_path self._img_size = img_size self._depth = depth self._width = width def estimate(self, np_images): """ Estimate the age and gender of the face on the image :param np_images a numpy array of BGR images of faces of which the gender and the age has to be estimated This is assumed to be segmented/cropped already! :returns List of estimated age and gender score ([female, male]) tuples """ # Model should be constructed in same thread as the inference if self._model is None: self._model = WideResNet(self._img_size, depth=self._depth, k=self._width)() self._model.load_weights(self._weights_file_path) faces = np.empty((len(np_images), self._img_size, self._img_size, 3)) for i, np_image in enumerate(np_images): if not isinstance(np_image, np.ndarray): raise ValueError( "np_image is not a numpy.ndarray but {t}".format( t=type(np_image))) if np_image.ndim != 3: # x, y, channel raise ValueError( "Shape of image is {sp}. Cannot classify this, shape must be (?, ?, 3). " "First 2 dimensions can are not constrained, " "but image must have 3 channels (B, G, R)".format( sp=np_image.shape)) faces[i, :, :, :] = cv2.resize(np_image, (self._img_size, self._img_size)) results = self._model.predict(faces) predicted_genders = results[0] ages = np.arange(0, 101).reshape(101, 1) predicted_ages = results[1].dot(ages).flatten() return zip(predicted_ages, predicted_genders)
def main(): args = get_args() depth = args.depth k = args.width weight_file = args.weight_file if not weight_file: weight_file = get_file("weights.18-4.06.hdf5", models, cache_subdir="models", file_hash=modhash, cache_dir=os.path.dirname(os.path.abspath(__file__))) # for face detection detector = dlib.get_frontal_face_detector() # load model and weights img_size = 64 model = WideResNet(img_size, depth=depth, k=k)() model.load_weights(weight_file) input_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img_height, img_weight, _ = np.shape(input_img) # detect faces using dlib detector detected = detector(input_img, 1) faces = np.empty((len(detected), img_size, img_size, 3)) if len(detected) > 0: for i, detection in enumerate(detected): x1, y1, x2, y2, weight, height = detection.left(), detection.top(), detection.right() + 1, detection.bottom() + 1, detection.width(), detection.height() xw1 = max(int(x1 - 0.4 * weight), 0) yw1 = max(int(y1 - 0.4 * height), 0) xw2 = min(int(x2 + 0.4 * weight), img_weight - 1) yw2 = min(int(y2 + 0.4 * height), img_height - 1) cv2.rectangle(img, (x1, y1), (x2, y2), (255, 0, 0), 2) faces[i, :, :, :] = cv2.resize(img[yw1:yw2 + 1, xw1:xw2 + 1, :], (img_size, img_size)) # result = [xw1, yw1, xw2, yw2] # print(result) # predict ages and genders of the detected faces results = model.predict(faces) predicted_genders = results[0] ages = np.arange(0, 101).reshape(101, 1) predicted_ages = results[1].dot(ages).flatten() # draw results for i, detection in enumerate(detected): label = "{}, {}".format(int(predicted_ages[i]), "F" if predicted_genders[i][0] > 0.5 else "M") draw_label(img, (detection.left(), detection.top()), label) cv2.imshow("result", img) key = cv2.waitKey(30) if key == 27: break
def main(): args = get_args() depth = args.depth k = args.width weight_file = args.weight_file if not weight_file: weight_file = get_file("weights.18-4.06.hdf5", pretrained_model, cache_subdir="pretrained_models", file_hash=modhash, cache_dir=os.path.dirname(os.path.abspath(__file__))) # for face detection detector = dlib.get_frontal_face_detector() # load model and weights img_size = 64 model = WideResNet(img_size, depth=depth, k=k)() model.load_weights(weight_file) for img in yield_images(): input_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img_h, img_w, _ = np.shape(input_img) # detect faces using dlib detector detected = detector(input_img, 1) faces = np.empty((len(detected), img_size, img_size, 3)) if len(detected) > 0: for i, d in enumerate(detected): x1, y1, x2, y2, w, h = d.left(), d.top(), d.right() + 1, d.bottom() + 1, d.width(), d.height() xw1 = max(int(x1 - 0.4 * w), 0) yw1 = max(int(y1 - 0.4 * h), 0) xw2 = min(int(x2 + 0.4 * w), img_w - 1) yw2 = min(int(y2 + 0.4 * h), img_h - 1) cv2.rectangle(img, (x1, y1), (x2, y2), (255, 0, 0), 2) # cv2.rectangle(img, (xw1, yw1), (xw2, yw2), (255, 0, 0), 2) faces[i, :, :, :] = cv2.resize(img[yw1:yw2 + 1, xw1:xw2 + 1, :], (img_size, img_size)) # predict ages and genders of the detected faces results = model.predict(faces) predicted_genders = results[0] ages = np.arange(0, 101).reshape(101, 1) predicted_ages = results[1].dot(ages).flatten() # draw results for i, d in enumerate(detected): label = "{}, {}".format(int(predicted_ages[i]), "F" if predicted_genders[i][0] > 0.5 else "M") draw_label(img, (d.left(), d.top()), label) cv2.imshow("result", img) key = cv2.waitKey(30) if key == 27: break
def main(): depth = 16 k = 8 margin = 0.4 male_num = 0 female_num = 0 weight_file = get_file("weights.28-3.73.hdf5", pretrained_model, cache_subdir="pretrained_models", file_hash=modhash, cache_dir=str(Path(__file__).resolve().parent)) detector = dlib.get_frontal_face_detector() img_size = 64 model = WideResNet(img_size, depth=depth, k=k)() model.load_weights(weight_file) image_generator = yield_images_from_dir(img_path) for img in image_generator: input_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img_h, img_w, _ = np.shape(input_img) detected = detector(input_img, 1) faces = np.empty((len(detected), img_size, img_size, 3)) if len(detected) > 0: for i, d in enumerate(detected): x1, y1, x2, y2, w, h = d.left(), d.top( ), d.right() + 1, d.bottom() + 1, d.width(), d.height() xw1 = max(int(x1 - margin * w), 0) yw1 = max(int(y1 - margin * h), 0) xw2 = min(int(x2 + margin * w), img_w - 1) yw2 = min(int(y2 + margin * h), img_h - 1) cv2.rectangle(img, (x1, y1), (x2, y2), (255, 0, 0), 2) faces[i, :, :, :] = cv2.resize( img[yw1:yw2 + 1, xw1:xw2 + 1, :], (img_size, img_size)) results = model.predict(faces) predicted_genders = results[0] for i, d in enumerate(detected): label = "{}".format( "M" if predicted_genders[i][0] < 0.5 else "F") draw_label(img, (d.left(), d.top()), label) if predicted_genders[i][0] < 0.5: male_num = male_num + 1 else: female_num = female_num + 1 print("woman : {0}, man : {1}".format(female_num, male_num), flush=True) answer = str(female_num) + "|" + str(male_num) return answer
def main(): args = get_args() depth = args.depth k = args.width weight_file = args.weight_file if not weight_file: weight_file = os.path.join("pretrained_models", "weights.18-4.06.hdf5") # for face detection detector = dlib.get_frontal_face_detector() # load model and weights img_size = 64 model = WideResNet(img_size, depth=depth, k=k)() model.load_weights(weight_file) for x in glob.glob("test/*.jpg"): img = cv2.imread(x, 3) # img = imutils.resize(img, width=400) input_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img_h, img_w, _ = np.shape(input_img) # detect faces using dlib detector detected = detector(input_img, 1) faces = np.empty((len(detected), img_size, img_size, 3)) for i, d in enumerate(detected): x1, y1, x2, y2, w, h = d.left(), d.top( ), d.right() + 1, d.bottom() + 1, d.width(), d.height() xw1 = max(int(x1 - 0.4 * w), 0) yw1 = max(int(y1 - 0.4 * h), 0) xw2 = min(int(x2 + 0.4 * w), img_w - 1) yw2 = min(int(y2 + 0.4 * h), img_h - 1) cv2.rectangle(img, (x1, y1), (x2, y2), (255, 0, 0), 2) # cv2.rectangle(img, (xw1, yw1), (xw2, yw2), (255, 0, 0), 2) faces[i, :, :, :] = cv2.resize(img[yw1:yw2 + 1, xw1:xw2 + 1, :], (img_size, img_size)) if len(detected) == 1: # predict ages and genders of the detected faces results = model.predict(faces) predicted_genders = "F" if results[0][0][0] > 0.5 else "M" ages = np.arange(0, 101).reshape(101, 1) predicted_ages = str(int(results[1][0].dot(ages).flatten()[0])) print(x + " est:" + predicted_ages + " " + predicted_genders + " debug:" + str(results[0][0][0]) + " " + str(results[0][0][1])) elif len(detected) > 1: print("multiple faces detected... not supported yet") else: print("no faces detected... skipping")
def main(): args = get_args() depth = args.depth k = args.width weight_file = args.weight_file if not weight_file: weight_file = get_file("weights.28-3.73.hdf5", pretrained_model, cache_subdir="pretrained_models", file_hash=modhash, cache_dir=os.path.dirname( os.path.abspath(__file__))) # load model and weights img_size = 64 batch_size = 32 model = WideResNet(img_size, depth=depth, k=k)() model.load_weights(weight_file) dataset_root = Path(__file__).parent.joinpath("appa-real", "appa-real-release") validation_image_dir = dataset_root.joinpath("valid") gt_valid_path = dataset_root.joinpath("gt_avg_valid.csv") image_paths = list(validation_image_dir.glob("*_face.jpg")) faces = np.empty((batch_size, img_size, img_size, 3)) ages = [] image_names = [] for i, image_path in tqdm(enumerate(image_paths)): faces[i % batch_size] = cv2.resize(cv2.imread(str(image_path), 1), (img_size, img_size)) image_names.append(image_path.name[:-9]) if (i + 1) % batch_size == 0 or i == len(image_paths) - 1: results = model.predict(faces) ages_out = np.arange(0, 101).reshape(101, 1) predicted_ages = results[1].dot(ages_out).flatten() ages += list(predicted_ages) # len(ages) can be larger than len(image_names) due to the last batch, but it's ok. name2age = {image_names[i]: ages[i] for i in range(len(image_names))} df = pd.read_csv(str(gt_valid_path)) appa_abs_error = 0.0 real_abs_error = 0.0 for i, row in df.iterrows(): appa_abs_error += abs(name2age[row.file_name] - row.apparent_age_avg) real_abs_error += abs(name2age[row.file_name] - row.real_age) print("MAE Apparent: {}".format(appa_abs_error / len(image_names))) print("MAE Real: {}".format(real_abs_error / len(image_names)))
def get_age_gender(im_path): args = get_args() depth = args.depth k = args.width weight_file = args.weight_file if not weight_file: weight_file = os.path.join("age_gender_estimation/pretrained_models", "weights.18-4.06.hdf5") # for face detection detector = dlib.get_frontal_face_detector() # load model and weights img_size = 64 model = WideResNet(img_size, depth=depth, k=k)() model.load_weights(weight_file) img = cv2.imread(im_path) input_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img_h, img_w, _ = np.shape(input_img) detected = detector(input_img, 1) faces = np.empty((len(detected), img_size, img_size, 3)) for i, d in enumerate(detected): x1, y1, x2, y2, w, h = d.left(), d.top( ), d.right() + 1, d.bottom() + 1, d.width(), d.height() xw1 = max(int(x1 - 0.4 * w), 0) yw1 = max(int(y1 - 0.4 * h), 0) xw2 = min(int(x2 + 0.4 * w), img_w - 1) yw2 = min(int(y2 + 0.4 * h), img_h - 1) cv2.rectangle(img, (x1, y1), (x2, y2), (255, 0, 0), 2) # cv2.rectangle(img, (xw1, yw1), (xw2, yw2), (255, 0, 0), 2) faces[i, :, :, :] = cv2.resize(img[yw1:yw2 + 1, xw1:xw2 + 1, :], (img_size, img_size)) if len(detected) > 0: # predict ages and genders of the detected faces results = model.predict(faces) predicted_genders = results[0] ages = np.arange(0, 101).reshape(101, 1) predicted_ages = results[1].dot(ages).flatten() #print predicted_ages #print predicted_genders genders = ['M' if x[1] > x[0] else 'F' for x in predicted_genders] return predicted_ages, genders
def main(): args = get_args() depth = args.depth k = args.width weight_file = args.weight_file if not weight_file: weight_file = get_file("weights.18-4.06.hdf5", pretrained_model, cache_subdir="pretrained_models", file_hash=modhash, cache_dir=os.path.dirname(os.path.abspath(__file__))) # load model and weights img_size = 64 batch_size = 32 model = WideResNet(img_size, depth=depth, k=k)() model.load_weights(weight_file) dataset_root = Path(__file__).parent.joinpath("appa-real", "appa-real-release") validation_image_dir = dataset_root.joinpath("valid") gt_valid_path = dataset_root.joinpath("gt_avg_valid.csv") image_paths = list(validation_image_dir.glob("*_face.jpg")) faces = np.empty((batch_size, img_size, img_size, 3)) ages = [] image_names = [] for i, image_path in tqdm(enumerate(image_paths)): faces[i % batch_size] = cv2.resize(cv2.imread(str(image_path), 1), (img_size, img_size)) image_names.append(image_path.name[:-9]) if (i + 1) % batch_size == 0 or i == len(image_paths) - 1: results = model.predict(faces) ages_out = np.arange(0, 101).reshape(101, 1) predicted_ages = results[1].dot(ages_out).flatten() ages += list(predicted_ages) # len(ages) can be larger than len(image_names) due to the last batch, but it's ok. name2age = {image_names[i]: ages[i] for i in range(len(image_names))} df = pd.read_csv(str(gt_valid_path)) appa_abs_error = 0.0 real_abs_error = 0.0 for i, row in df.iterrows(): appa_abs_error += abs(name2age[row.file_name] - row.apparent_age_avg) real_abs_error += abs(name2age[row.file_name] - row.real_age) print("MAE Apparent: {}".format(appa_abs_error / len(image_names))) print("MAE Real: {}".format(real_abs_error / len(image_names)))
def prediction(uploaded_file_url): depth = 16 k = 8 weight_file = "data/weights.18-4.06.hdf5" detector = dlib.get_frontal_face_detector() img_size = 64 model = WideResNet(img_size, depth=depth, k=k)() model.load_weights(weight_file) img = cv2.imread(uploaded_file_url[1:]) # cv2.imwrite("media/test2.jpg", img) input_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img_h, img_w, _ = np.shape(input_img) detected = detector(input_img, 1) faces = np.empty((len(detected), img_size, img_size, 3)) for i, d in enumerate(detected): x1, y1, x2, y2, w, h = d.left(), d.top( ), d.right() + 1, d.bottom() + 1, d.width(), d.height() xw1 = max(int(x1 - 0.4 * w), 0) yw1 = max(int(y1 - 0.4 * h), 0) xw2 = min(int(x2 + 0.4 * w), img_w - 1) yw2 = min(int(y2 + 0.4 * h), img_h - 1) # cv2.rectangle(img, (x1, y1), (x2, y2), (255, 0, 0), 2) # cv2.rectangle(img, (xw1, yw1), (xw2, yw2), (255, 0, 0), 2) faces[i, :, :, :] = cv2.resize(img[yw1:yw2 + 1, xw1:xw2 + 1, :], (img_size, img_size)) crop_img = img[yw1:yw2 + 1, xw1:xw2 + 1] if (i == 0): cv2.imwrite("media/avatar1.jpg", crop_img) if (i == 1): cv2.imwrite("media/avatar2.jpg", crop_img) # print img_h, img_w if len(detected) > 0: # predict ages and genders of the detected faces results = model.predict(faces) predicted_genders = results[0] ages = np.arange(0, 101).reshape(101, 1) predicted_ages = results[1].dot(ages).flatten() # draw results K.clear_session() labels = [] for i, d in enumerate(detected): label = "{}, {}".format(int(predicted_ages[i]), "F" if predicted_genders[i][0] > 0.5 else "M") labels.append(label) print labels return labels
def AgeEstimator(uImage): depth = 16 k = 8 weight_file = get_file("weights.18-4.06.hdf5", pretrained_model, cache_subdir="pretrained_models", file_hash=modhash, cache_dir=os.path.dirname( os.path.abspath(__file__))) detector = dlib.get_frontal_face_detector() img_size = 64 model = WideResNet(img_size, depth=depth, k=k)() model.load_weights(weight_file) image = Image.open(uImage).convert('RGB') image = np.array(image) img_h, img_w, _ = np.shape(image) detected = detector(image, 1) faces = np.empty((len(detected), img_size, img_size, 3)) print(faces) response = {} if len(detected) > 0: for i, d in enumerate(detected): x1, y1, x2, y2, w, h = d.left(), d.top( ), d.right() + 1, d.bottom() + 1, d.width(), d.height() xw1 = max(int(x1 - 0.4 * w), 0) yw1 = max(int(y1 - 0.4 * h), 0) xw2 = min(int(x2 + 0.4 * w), img_w - 1) yw2 = min(int(y2 + 0.4 * h), img_h - 1) cv2.rectangle(image, (x1, y1), (x2, y2), (255, 0, 0), 2) faces[i, :, :, :] = cv2.resize(image[yw1:yw2 + 1, xw1:xw2 + 1, :], (img_size, img_size)) results = model.predict(faces) predicted_genders = results[0] ages = np.arange(0, 101).reshape(101, 1) predicted_ages = results[1].dot(ages).flatten() for i, d in enumerate(detected): response[i] = {} response[i]["predicted_ages"] = "{}".format(int(predicted_ages[i])) response[i]["predicted_genders"] = "{}".format( "F" if predicted_genders[i][0] > 0.5 else "M") return response
def main(): args = get_args() depth = args.depth k = args.width weight_file = args.weight_file img_size = 64 batch_size = 32 model = WideResNet(img_size, depth=depth, k=k)() model.load_weights("checkpoints168/weights.48-3.62.hdf5") dataset_root = Path(__file__).parent.joinpath("data", "utk_with_margin") for region in range(5): # for age in range(10): # validation = '[{}-{}]_*_{}_*.jpg'.format(age*10, age*10+9, region) validation = '*_*_{}_*.jpg'.format(region) image_paths = list(dataset_root.glob(validation)) faces = np.empty((batch_size, img_size, img_size, 3)) ages = [] image_ages = [] for i, image_path in tqdm(enumerate(image_paths)): faces[i % batch_size] = cv2.resize(cv2.imread( str(image_path), 1), (img_size, img_size)) image_ages.append(int(image_path.name.split("_")[0])) if (i + 1) % batch_size == 0 or i == len(image_paths) - 1: results = model.predict(faces) ages_out = np.arange(0, 101).reshape(101, 1) predicted_ages = results[1].dot(ages_out).flatten() ages += list(predicted_ages) # len(ages) can be larger than len(image_names) due to the last batch, but it's ok. utk_abs_error = 0.0 for i in range(len(image_ages)): utk_abs_error += abs(image_ages[i]-ages[i]) print("Region (0-White,1-Black,2-Asian,3-Indian,4-Other): ", region) print("Number of ages:", len(ages)) print("Number of images: ", len(image_ages)) print("MAE : {}".format(utk_abs_error / len(image_ages)))
def gender_predict(face_location, img): depth = 16 k = 8 img_size = 64 margin = 0.4 input_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img_h, img_w, _ = np.shape(input_img) weight_file = './pretrained_models/weights.28-3.73.hdf5' model = WideResNet(img_size, depth=depth, k=k)() model.load_weights(weight_file) #x1, y1, x2, y2, w, h = face_location.left(), face_location.top(), face_location.right() + 1, face_location.bottom() + 1, face_location.width(), face_location.height() #left, top, right, bottom = face_location.left(), face_location.top(), face_location.right() + 1, face_location.bottom() top, right, bottom, left = face_location w = right - left h = bottom - top xw1 = max(int(left - margin * w), 0) yw1 = max(int(top - margin * h), 0) xw2 = min(int(right + margin * w), img_w - 1) yw2 = min(int(bottom + margin * h), img_h - 1) #取下待检测人脸 face = cv2.resize(img[yw1:yw2 + 1, xw1:xw2 + 1, :], (img_size, img_size)) face = np.expand_dims(face, 0) #传入代检测人脸 results = model.predict(face) #print(results[0][0][0]) if results[0][0][0] < 0.5: label = 'male' else: label = 'female' return label
class FaceCV(object): CASE_PATH = "haarcascade_frontalface_alt.xml" WRN_WEIGHTS_PATH = "weights.18-4.06.hdf5" def __new__(cls, weight_file=None, depth=16, width=8, face_size=64): if not hasattr(cls, 'instance'): cls.instance = super(FaceCV, cls).__new__(cls) return cls.instance def __init__(self, depth=16, width=8, face_size=64): self.face_size = face_size self.model = WideResNet(face_size, depth=depth, k=width)() model_dir = os.path.join(os.getcwd(), "pretrained_models").replace("//", "\\") fpath = get_file('weights.18-4.06.hdf5', self.WRN_WEIGHTS_PATH, cache_subdir=model_dir) self.model.load_weights(fpath) @classmethod def draw_label(cls, image, point, label, font=cv2.FONT_HERSHEY_SIMPLEX, font_scale=1, thickness=2): size = cv2.getTextSize(label, font, font_scale, thickness)[0] x, y = point cv2.rectangle(image, (x, y - size[1]), (x + size[0], y), (255, 0, 0), cv2.FILLED) cv2.putText(image, label, point, font, font_scale, (255, 255, 255), thickness) def crop_face(self, imgarray, section, margin=40, size=64): img_h, img_w, _ = imgarray.shape if section is None: section = [0, 0, img_w, img_h] (x, y, w, h) = section margin = int(min(w, h) * margin / 100) x_a = x - margin y_a = y - margin x_b = x + w + margin y_b = y + h + margin if x_a < 0: x_b = min(x_b - x_a, img_w - 1) x_a = 0 if y_a < 0: y_b = min(y_b - y_a, img_h - 1) y_a = 0 if x_b > img_w: x_a = max(x_a - (x_b - img_w), 0) x_b = img_w if y_b > img_h: y_a = max(y_a - (y_b - img_h), 0) y_b = img_h cropped = imgarray[y_a:y_b, x_a:x_b] resized_img = cv2.resize(cropped, (size, size), interpolation=cv2.INTER_AREA) resized_img = np.array(resized_img) return resized_img, (x_a, y_a, x_b - x_a, y_b - y_a) # f=None # res=str(type(f)) # print(res) # if res=="<class 'NoneType'>": # print("None ha") def detect_face(self): count = 0 detector = dlib.get_frontal_face_detector() import csv resultFile = open("final1.xls", 'a') wr = csv.writer(resultFile, dialect='excel') # wr.writerow(["Url","Class","Gender"]) for s3_file in your_bucket.objects.all(): # print(count) count = count + 1 if count > 2002991: flag = True url = u'https://{0}.s3.amazonaws.com/{1}'.format( "picpulse-imgs", s3_file.key) url = url.encode("ascii", errors="ignore").decode() # print(url) print(count) bol = file_exists(url) if bol == True: # url="https://picpulse-imgs.s3.amazonaws.com/102808803969032054.jpg" frame = url_to_image(url) res = "" res = str(type(frame)) # print(frame) if res == "<class 'NoneType'>": wr.writerow( [str(url), str("None"), str("None"), "None"]) else: faces = detector(frame, 1) input_img = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) img_h, img_w, _ = np.shape(input_img) face_imgs = np.empty( (len(faces), self.face_size, self.face_size, 3)) for i, d in enumerate(faces): x1, y1, x2, y2, w, h = d.left(), d.top(), d.right( ) + 1, d.bottom() + 1, d.width(), d.height() xw1 = max(int(x1 - 0.4 * w), 0) yw1 = max(int(y1 - 0.4 * h), 0) xw2 = min(int(x2 + 0.4 * w), img_w - 1) yw2 = min(int(y2 + 0.4 * h), img_h - 1) face_imgs[i, :, :, :] = cv2.resize( frame[yw1:yw2 + 1, xw1:xw2 + 1, :], (self.face_size, self.face_size)) if len(face_imgs) > 0: # predict ages and genders of the detected faces results = self.model.predict(face_imgs) predicted_genders = results[0] # print(count) ages = np.arange(0, 101).reshape(101, 1) predicted_ages = results[1].dot(ages).flatten() else: result = tfnet.return_predict(frame) # print(result) if len(result) > 0: # tl = (result[0]['topleft']['x'], result[0]['topleft']['y']) # br = (result[0]['bottomright']['x'], result[0]['bottomright']['y']) # data = json.loads(result) clist = [] for x in result: res = x['label'] clist.append(str(res)) # print(clist) # add the box and label and display it if "person" in clist: label = "person" # img = cv2.rectangle(frame, tl, br, (0, 255, 0), 7) # img = cv2.putText(img, label, tl, cv2.FONT_HERSHEY_COMPLEX, 1, (5, 5, 15), 2) # cv2.imwrite("results1/out1/frame%d.jpg" % count, img) wr.writerow([ str(url), str("no faces"), str("no gender"), "person" ]) else: wr.writerow([ str(url), str("no faces"), str("no gender"), "None" ]) for i, face in enumerate(faces): nn = predicted_ages[i] if nn > 0 and nn <= 12: predicted_g = "0-12" elif nn > 12 and nn <= 17: predicted_g = "13-17" elif nn > 17 and nn <= 32: predicted_g = "18-32" elif nn > 32 and nn <= 54: predicted_g = "33-54" elif nn > 33 and nn <= 54: predicted_g = "55+" label = "{},{}".format( predicted_g, "Female" if predicted_genders[i][0] > 0.5 else "Male") re = "Female" if predicted_genders[i][ 0] > 0.5 else "Male" # print(re) # self.draw_label(frame, (face.left(), face.top()), label) if flag == True: result = tfnet.return_predict(frame) flag = False # print(result) if len(result) > 0: # tl = (result[0]['topleft']['x'], result[0]['topleft']['y']) # br = (result[0]['bottomright']['x'], result[0]['bottomright']['y']) # data = json.loads(result) clist = [] for x in result: res = x['label'] clist.append(str(res)) # print(clist) # add the box and label and display it if "person" in clist: label = "person" # img = cv2.rectangle(frame, tl, br, (0, 255, 0), 7) # img = cv2.putText(img, label, tl, cv2.FONT_HERSHEY_COMPLEX, 1, (5, 5, 15), 2) # cv2.imwrite("results1/out1/frame%d.jpg" % count, img) wr.writerow([ str(url), str(predicted_g), str(re), "person" ]) else: wr.writerow([ str(url), str(predicted_g), str(re), "None" ]) else: wr.writerow([ str(url), str(predicted_g), str(re), "None" ]) # cv2.imshow('Keras Faces', frame) # count = count+1 # wr.writerow([str(url),str(predicted_g),str(re),"person"]) # cv2.imwrite("results/frame%d.jpg" % count, frame) else: print("invalid url")
class FaceCV(object): """ Singleton class for face recongnition task """ CASE_PATH = ".\\pretrained_models\\haarcascade_frontalface_alt.xml" WRN_WEIGHTS_PATH = "https://github.com/Tony607/Keras_age_gender/releases/download/V1.0/weights.18-4.06.hdf5" def __new__(cls, weight_file=None, depth=16, width=8, face_size=64): if not hasattr(cls, 'instance'): cls.instance = super(FaceCV, cls).__new__(cls) return cls.instance def __init__(self, depth=16, width=8, face_size=64): self.face_size = face_size self.model = WideResNet(face_size, depth=depth, k=width)() model_dir = os.path.join(os.getcwd(), "pretrained_models").replace("//", "\\") fpath = get_file('weights.18-4.06.hdf5', self.WRN_WEIGHTS_PATH, cache_subdir=model_dir) self.model.load_weights(fpath) @classmethod def draw_label(cls, image, point, label, font=cv2.FONT_HERSHEY_SIMPLEX, font_scale=1, thickness=2): size = cv2.getTextSize(label, font, font_scale, thickness)[0] x, y = point cv2.rectangle(image, (x, y - size[1]), (x + size[0], y), (255, 0, 0), cv2.FILLED) cv2.putText(image, label, point, font, font_scale, (255, 255, 255), thickness) def crop_face(self, imgarray, section, margin=40, size=64): """ :param imgarray: full image :param section: face detected area (x, y, w, h) :param margin: add some margin to the face detected area to include a full head :param size: the result image resolution with be (size x size) :return: resized image in numpy array with shape (size x size x 3) """ img_h, img_w, _ = imgarray.shape if section is None: section = [0, 0, img_w, img_h] (x, y, w, h) = section margin = int(min(w, h) * margin / 100) x_a = x - margin y_a = y - margin x_b = x + w + margin y_b = y + h + margin if x_a < 0: x_b = min(x_b - x_a, img_w - 1) x_a = 0 if y_a < 0: y_b = min(y_b - y_a, img_h - 1) y_a = 0 if x_b > img_w: x_a = max(x_a - (x_b - img_w), 0) x_b = img_w if y_b > img_h: y_a = max(y_a - (y_b - img_h), 0) y_b = img_h cropped = imgarray[y_a:y_b, x_a:x_b] resized_img = cv2.resize(cropped, (size, size), interpolation=cv2.INTER_AREA) resized_img = np.array(resized_img) return resized_img, (x_a, y_a, x_b - x_a, y_b - y_a) def detect_face(self): face_cascade = cv2.CascadeClassifier( '/Users/sanjanasrinivasareddy/Documents/girlsgeek/CommentSentiment/pretrained_models/haarcascade_frontalface_alt.xml' ) # 0 means the default video capture device in OS video_capture = cv2.VideoCapture(0) # infinite loop, break by key ESC c = 0 sum = 0 while c < 10: if not video_capture.isOpened(): sleep(5) # Capture frame-by-frame ret, frame = video_capture.read() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=10, minSize=(self.face_size, self.face_size)) # placeholder for cropped faces face_imgs = np.empty( (len(faces), self.face_size, self.face_size, 3)) for i, face in enumerate(faces): face_img, cropped = self.crop_face(frame, face, margin=40, size=self.face_size) (x, y, w, h) = cropped cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 200, 0), 2) face_imgs[i, :, :, :] = face_img if len(face_imgs) > 0: # predict ages and genders of the detected faces results = self.model.predict(face_imgs) predicted_genders = results[0] ages = np.arange(0, 101).reshape(101, 1) predicted_ages = results[1].dot(ages).flatten() print(predicted_ages) sum = sum + predicted_ages c = c + 1 print(c) # print(sum) # print(sum/c) # draw results for i, face in enumerate(faces): label = "{}, {}".format( int(predicted_ages[i]), "F" if predicted_genders[i][0] > 0.5 else "M") self.draw_label(frame, (face[0], face[1]), label) cv2.imshow('Keras Faces', frame) # if cv2.waitKey(5) == 27: # ESC key press # break return sum / c
class FaceCV(object): CASE_PATH = ".\\pretrained_models\\haarcascade_frontalface_alt.xml" WRN_WEIGHTS_PATH = ".\\pretrained_models\\weights.18-4.06.hdf5" def __new__(cls, weight_file=None, depth=16, width=8, face_size=64): if not hasattr(cls, 'instance'): cls.instance = super(FaceCV, cls).__new__(cls) return cls.instance def __init__(self, depth=16, width=8, face_size=64): self.face_size = face_size self.model = WideResNet(face_size, depth=depth, k=width)() model_dir = os.path.join(os.getcwd(), "pretrained_models").replace("//", "\\") fpath = get_file('weights.18-4.06.hdf5', self.WRN_WEIGHTS_PATH, cache_subdir=model_dir) self.model.load_weights(fpath) def draw_label(cls, image, point, label, font=cv2.FONT_HERSHEY_SIMPLEX, font_scale=1, thickness=2): cv2.putText(image, label, point, font, font_scale, (255, 0, 0), thickness) def crop_face(self, imgarray, section, margin=40, size=64): img_h, img_w, _ = imgarray.shape if section is None: section = [0, 0, img_w, img_h] (x, y, w, h) = section margin = int(min(w, h) * margin / 100) x_a = x - margin y_a = y - margin x_b = x + w + margin y_b = y + h + margin if x_a < 0: x_b = min(x_b - x_a, img_w - 1) x_a = 0 if y_a < 0: y_b = min(y_b - y_a, img_h - 1) y_a = 0 if x_b > img_w: x_a = max(x_a - (x_b - img_w), 0) x_b = img_w if y_b > img_h: y_a = max(y_a - (y_b - img_h), 0) y_b = img_h cropped = imgarray[y_a:y_b, x_a:x_b] resized_img = cv2.resize(cropped, (size, size), interpolation=cv2.INTER_AREA) resized_img = np.array(resized_img) return resized_img, (x_a, y_a, x_b - x_a, y_b - y_a) def detect_face(self): face_cascade = cv2.CascadeClassifier(self.CASE_PATH) video_capture = cv2.VideoCapture(0) while True: ret, frame = video_capture.read() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=10, minSize=(self.face_size, self.face_size)) if faces is not (): face_imgs = np.empty( (len(faces), self.face_size, self.face_size, 3)) for i, face in enumerate(faces): face_img, cropped = self.crop_face(frame, face, margin=40, size=self.face_size) (x, y, w, h) = cropped cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 200, 0), 2) face_imgs[i, :, :, :] = face_img if len(face_imgs) > 0: results = self.model.predict(face_imgs) predicted_genders = results[0] ages = np.arange(0, 101).reshape(101, 1) predicted_ages = results[1].dot(ages).flatten() for i, face in enumerate(faces): label = "{}, {}".format( int(predicted_ages[i]), "F" if predicted_genders[i][0] > 0.4 else "M") self.draw_label(frame, (face[0], face[1]), label) cv2.imshow('Keras Faces', frame) if cv2.waitKey(5) == 27: break video_capture.release() cv2.destroyAllWindows()
def main(): args = get_args() depth = args.depth k = args.width weight_file = args.weight_file if not weight_file: weight_file = os.path.join("data", "weights.18-4.06.hdf5") detector = dlib.get_frontal_face_detector() img_size = 64 model = WideResNet(img_size, depth=depth, k=k)() model.load_weights(weight_file) cap = cv2.VideoCapture(0) while True: ret, img = cap.read() if not ret: print("error: failed to capture image") return -1 input_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img_h, img_w, _ = np.shape(input_img) detected = detector(input_img, 1) print(detected) faces = np.empty((len(detected), img_size, img_size, 3)) print(faces) for i, d in enumerate(detected): x1, y1, x2, y2, w, h = d.left(), d.top( ), d.right() + 1, d.bottom() + 1, d.width(), d.height() xw1 = max(int(x1 - 0.4 * w), 0) yw1 = max(int(y1 - 0.4 * h), 0) xw2 = min(int(x2 + 0.4 * w), img_w - 1) yw2 = min(int(y2 + 0.4 * h), img_h - 1) cv2.rectangle(img, (x1, y1), (x2, y2), (255, 0, 0), 2) faces[i, :, :, :] = cv2.resize(img[yw1:yw2 + 1, xw1:xw2 + 1, :], (img_size, img_size)) if len(detected) > 0: res = model.predict(faces) predicted_genders = res[0] ages = np.arange(0, 101).reshape(101, 1) predicted_ages = res[1].dot(ages).flatten() for i, d in enumerate(detected): label = "{}, {}".format( int(predicted_ages[i]), "F" if predicted_genders[i][0] > 0.5 else "M") draw_label(img, (d.left(), d.top()), label) cv2.putText( img, "Estimated Age (Years): " + str(" %6.1f " % predicted_ages), (10, 230), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (200, 0, 0), 2) cv2.imshow("Age and Gender Estimation - Jair Ribeiro", img) key = cv2.waitKey(25) if key == 27: break
h = y1 - y0 if w > h: x0 = x0 + w // 2 - h // 2 w = h x1 = x0 + w else: y0 = y0 + h // 2 - w // 2 h = w y1 = y0 + h # 64 * 64 faces.append( cv2.resize(image_np[y0:y1, x0:x1, :], (img_size, img_size))) faces = np.array(faces) results = model.predict(faces) predicted_genders = results[0] ages = np.arange(0, 101).reshape(101, 1) predicted_ages = results[1].dot(ages).flatten() for i, d in enumerate(detected): label = '{}, {}'.format( int(predicted_ages[i]), 'F' if predicted_genders[i][0] > 0.5 else 'M') draw_label(image_np, (d.left(), d.top()), label) cv2.imshow('gender and age', cv2.cvtColor(image_np, cv2.COLOR_RGB2BGR)) if cv2.waitKey(25) & 0xFF == ord('q'): cap.release() cv2.destroyAllWindows()
class FaceCV(object): """ Singleton class for face recongnition task """ CASE_PATH = ".\\harcascade\\haarcascade_frontalface_alt.xml" WRN_WEIGHTS_PATH = ".\\model_weights\\weights.18-4.06.hdf5" def __new__(cls, weight_file=None, depth=16, width=8, face_size=64): if not hasattr(cls, 'instance'): cls.instance = super(FaceCV, cls).__new__(cls) return cls.instance def __init__(self, depth=16, width=8, face_size=64): self.face_size = face_size self.model = WideResNet(face_size, depth=depth, k=width)() model_dir = os.path.join(os.getcwd(), "model_weights").replace("//", "\\") fpath = get_file('weights.18-4.06.hdf5', self.WRN_WEIGHTS_PATH, cache_subdir=model_dir) self.model.load_weights(fpath) self.model._make_predict_function() @classmethod def draw_label(cls, image, point, label, font=cv2.FONT_HERSHEY_SIMPLEX, font_scale=1, thickness=2): size = cv2.getTextSize(label, font, font_scale, thickness)[0] x, y = point cv2.rectangle(image, (x, y - size[1]), (x + size[0], y), (255, 0, 0), cv2.FILLED) cv2.putText(image, label, point, font, font_scale, (255, 255, 255), thickness) def crop_face(self, imgarray, section, margin=40, size=64): """ :param imgarray: full image :param section: face detected area (x, y, w, h) :param margin: add some margin to the face detected area to include a full head :param size: the result image resolution with be (size x size) :return: resized image in numpy array with shape (size x size x 3) """ img_h, img_w, _ = imgarray.shape if section is None: section = [0, 0, img_w, img_h] (x, y, w, h) = section margin = int(min(w, h) * margin / 100) x_a = x - margin y_a = y - margin x_b = x + w + margin y_b = y + h + margin if x_a < 0: x_b = min(x_b - x_a, img_w - 1) x_a = 0 if y_a < 0: y_b = min(y_b - y_a, img_h - 1) y_a = 0 if x_b > img_w: x_a = max(x_a - (x_b - img_w), 0) x_b = img_w if y_b > img_h: y_a = max(y_a - (y_b - img_h), 0) y_b = img_h cropped = imgarray[y_a: y_b, x_a: x_b] resized_img = cv2.resize(cropped, (size, size), interpolation=cv2.INTER_AREA) resized_img = np.array(resized_img) return resized_img, (x_a, y_a, x_b - x_a, y_b - y_a) def detect_face(self,frame): age = 'Detecting...' gender = 'Detecting...' face_cascade = cv2.CascadeClassifier(self.CASE_PATH) with session1.as_default(): gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale( gray, scaleFactor=1.2, minNeighbors=10, minSize=(self.face_size, self.face_size) ) if faces is not(): # placeholder for cropped faces face_imgs = np.empty((len(faces), self.face_size, self.face_size, 3)) for i, face in enumerate(faces): face_img, cropped = self.crop_face(frame, face, margin=40, size=self.face_size) (x, y, w, h) = cropped cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 200, 0), 2) face_imgs[i, :, :, :] = face_img if len(face_imgs) > 0: # predict ages and genders of the detected faces results = self.model.predict(face_imgs) predicted_genders = results[0] ages = np.arange(0, 101).reshape(101, 1) predicted_ages = results[1].dot(ages).flatten() # draw results for i, face in enumerate(faces): label = "{}, {}".format(int(predicted_ages[i]-3), "F" if predicted_genders[i][0] > 0.5 else "M") self.draw_label(frame, (face[0], face[1]), label) print(int(predicted_ages[i])) if(predicted_genders[i][0] > 0.5): gender = "Female" else: gender = "Male" age = (int(predicted_ages[i])-3) return age , gender
def main(): args = get_args() depth = args.depth k = args.width weight_file = args.weight_file if not weight_file: weight_file = os.path.join("pretrained_models", "weights.18-4.06.hdf5") # for face detection detector = dlib.get_frontal_face_detector() # load model and weights img_size = 64 model = WideResNet(img_size, depth=depth, k=k)() model.load_weights(weight_file) # capture video cap = cv2.VideoCapture(0) cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) while True: # get video frame ret, img = cap.read() if not ret: print("error: failed to capture image") return -1 input_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img_h, img_w, _ = np.shape(input_img) # detect faces using dlib detector detected = detector(input_img, 1) faces = np.empty((len(detected), img_size, img_size, 3)) for i, d in enumerate(detected): x1, y1, x2, y2, w, h = d.left(), d.top(), d.right() + 1, d.bottom() + 1, d.width(), d.height() xw1 = max(int(x1 - 0.4 * w), 0) yw1 = max(int(y1 - 0.4 * h), 0) xw2 = min(int(x2 + 0.4 * w), img_w - 1) yw2 = min(int(y2 + 0.4 * h), img_h - 1) cv2.rectangle(img, (x1, y1), (x2, y2), (255, 0, 0), 2) # cv2.rectangle(img, (xw1, yw1), (xw2, yw2), (255, 0, 0), 2) faces[i,:,:,:] = cv2.resize(img[yw1:yw2 + 1, xw1:xw2 + 1, :], (img_size, img_size)) if len(detected) > 0: # predict ages and genders of the detected faces results = model.predict(faces) predicted_genders = results[0] ages = np.arange(0, 101).reshape(101, 1) predicted_ages = results[1].dot(ages).flatten() # draw results for i, d in enumerate(detected): label = "{}, {}".format(int(predicted_ages[i]), "F" if predicted_genders[i][0] > 0.5 else "M") draw_label(img, (d.left(), d.top()), label) cv2.imshow("result", img) key = cv2.waitKey(30) if key == 27: break
class FaceCV(object): """ Singleton class for face recongnition task """ CASE_PATH = "../model/haarcascade_frontalface_alt.xml" # WRN_WEIGHTS_PATH = "https://github.com/Tony607/Keras_age_gender/releases/download/V1.0/weights.18-4.06.hdf5" fpath = './pretrained_models/age_gender_weights.18-4.06.hdf5' def __new__(cls, weight_file=None, depth=16, width=8, face_size=64): if not hasattr(cls, 'instance'): cls.instance = super(FaceCV, cls).__new__(cls) return cls.instance def __init__(self, depth=16, width=8, face_size=64): self.face_size = face_size self.model = WideResNet(face_size, depth=depth, k=width)() # model_dir = os.path.join(os.getcwd(), "pretrained_models").replace("//", "\\") # fpath = get_file('age_gender_weights.18-4.06.hdf5', # self.WRN_WEIGHTS_PATH) self.model.load_weights(self.fpath) @classmethod def draw_label(cls, image, point, label, font=cv2.FONT_HERSHEY_SIMPLEX, font_scale=1, thickness=2): size = cv2.getTextSize(label, font, font_scale, thickness)[0] x, y = point cv2.rectangle(image, (x, y - size[1]), (x + size[0], y), (255, 0, 0), cv2.FILLED) cv2.putText(image, label, point, font, font_scale, (255, 255, 255), thickness) def crop_face(self, imgarray, section, margin=40, size=64): """ :param imgarray: full image :param section: face detected area (x, y, w, h) :param margin: add some margin to the face detected area to include a full head :param size: the result image resolution with be (size x size) :return: resized image in numpy array with shape (size x size x 3) """ img_h, img_w, _ = imgarray.shape if section is None: section = [0, 0, img_w, img_h] (x, y, w, h) = section margin = int(min(w, h) * margin / 100) x_a = x - margin y_a = y - margin x_b = x + w + margin y_b = y + h + margin if x_a < 0: x_b = min(x_b - x_a, img_w - 1) x_a = 0 if y_a < 0: y_b = min(y_b - y_a, img_h - 1) y_a = 0 if x_b > img_w: x_a = max(x_a - (x_b - img_w), 0) x_b = img_w if y_b > img_h: y_a = max(y_a - (y_b - img_h), 0) y_b = img_h cropped = imgarray[y_a:y_b, x_a:x_b] resized_img = cv2.resize(cropped, (size, size), interpolation=cv2.INTER_AREA) resized_img = np.array(resized_img) return resized_img, (x_a, y_a, x_b - x_a, y_b - y_a) def detect_face_one_image(self, img_path): face_cascade = cv2.CascadeClassifier(self.CASE_PATH) frame = cv2.imread(img_path) gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=10, minSize=(self.face_size, self.face_size)) # placeholder for cropped faces face_imgs = np.empty((len(faces), self.face_size, self.face_size, 3)) for i, face in enumerate(faces): face_img, cropped = self.crop_face(frame, face, margin=40, size=self.face_size) (x, y, w, h) = cropped cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 200, 0), 2) face_imgs[i, :, :, :] = face_img if len(face_imgs) > 0: # predict ages and genders of the detected faces results = self.model.predict(face_imgs) predicted_genders = results[0] ages = np.arange(0, 101).reshape(101, 1) predicted_ages = results[1].dot(ages).flatten() # draw results for i, face in enumerate(faces): label = "{}, {}".format( int(predicted_ages[i]), "F" if predicted_genders[i][0] > 0.5 else "M") self.draw_label(frame, (face[0], face[1]), label) cv2.imwrite('./sample.jpg', frame) cv2.imshow('Keras Faces', frame) cv2.waitKey() if cv2.waitKey(1) & 0xFF == ord('q'): # q key press cv2.destroyAllWindows() def detect_face_via_camera(self): face_cascade = cv2.CascadeClassifier(self.CASE_PATH) # 0 means the default video capture device in OS video_capture = cv2.VideoCapture(0) # infinite loop, break by key ESC while True: if not video_capture.isOpened(): sleep(5) # Capture frame-by-frame ret, frame = video_capture.read() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=10, minSize=(self.face_size, self.face_size)) # placeholder for cropped faces face_imgs = np.empty( (len(faces), self.face_size, self.face_size, 3)) for i, face in enumerate(faces): face_img, cropped = self.crop_face(frame, face, margin=40, size=self.face_size) (x, y, w, h) = cropped cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 200, 0), 2) face_imgs[i, :, :, :] = face_img if len(face_imgs) > 0: # predict ages and genders of the detected faces results = self.model.predict(face_imgs) predicted_genders = results[0] ages = np.arange(0, 101).reshape(101, 1) predicted_ages = results[1].dot(ages).flatten() # draw results for i, face in enumerate(faces): label = "{}, {}".format( int(predicted_ages[i]), "F" if predicted_genders[i][0] > 0.5 else "M") self.draw_label(frame, (face[0], face[1]), label) cv2.imshow('Keras Faces', frame) if cv2.waitKey(1) & 0xFF == ord('q'): # q key press break # When everything is done, release the capture video_capture.release() cv2.destroyAllWindows() def detect_face_via_video(self, vid_path): face_cascade = cv2.CascadeClassifier(self.CASE_PATH) # 0 means the default video capture device in OS video_capture = cv2.VideoCapture(vid_path) length = int(video_capture.get(cv2.CAP_PROP_FRAME_COUNT)) # Create an output movie file (make sure resolution/frame rate matches input video!) fourcc = cv2.VideoWriter_fourcc(*'XVID') output_movie = cv2.VideoWriter('output_1.avi', fourcc, 24.97, (1280, 720)) frame_number = 0 # infinite loop, break by key ESC while True: if not video_capture.isOpened(): sleep(5) # Capture frame-by-frame ret, frame = video_capture.read() frame_number += 1 # Quit when the input video file ends if not ret: break gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=10, minSize=(self.face_size, self.face_size)) # placeholder for cropped faces face_imgs = np.empty( (len(faces), self.face_size, self.face_size, 3)) for i, face in enumerate(faces): face_img, cropped = self.crop_face(frame, face, margin=40, size=self.face_size) (x, y, w, h) = cropped cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 200, 0), 2) face_imgs[i, :, :, :] = face_img if len(face_imgs) > 0: # predict ages and genders of the detected faces results = self.model.predict(face_imgs) predicted_genders = results[0] ages = np.arange(0, 101).reshape(101, 1) predicted_ages = results[1].dot(ages).flatten() # draw results for i, face in enumerate(faces): label = "{}, {}".format( int(predicted_ages[i]), "F" if predicted_genders[i][0] > 0.5 else "M") self.draw_label(frame, (face[0], face[1]), label) # Write the resulting image to the output video file print("Writing frame {} / {}".format(frame_number, length)) output_movie.write(frame) cv2.imshow('Keras Faces', frame) # if cv2.waitKey(5) == 27: # ESC key press if cv2.waitKey(1) & 0xFF == ord('q'): # q key press break # When everything is done, release the capture video_capture.release() cv2.destroyAllWindows()
def predict_gen_and_age(current_folder_post_fix, crop_with_mask_root_dir, save_result_root_dir): # face detection start_t = time.time() print('Start estimating age and gender...') crop_with_mask_dir = crop_with_mask_root_dir + current_folder_post_fix save_result_dir = save_result_root_dir + current_folder_post_fix if not os.path.exists(save_result_dir): os.makedirs(save_result_dir) file_lst = [ f for f in os.listdir(crop_with_mask_dir) if f.endswith(end_with_key_word) ] file_num = len(file_lst) # load model and weights. img_size = 64 faces = np.empty((file_num, img_size, img_size, 3)) depth = 16 k = 8 weight_file = '/home/amanda/Documents/age_gender_model/weights.18-4.06.hdf5' model = WideResNet(img_size, depth=depth, k=k)() model.load_weights(weight_file) img_height_lst = [] img_width_lst = [] for i, cur_im_name in enumerate(file_lst): if (i + 1) % 500 == 0: print('{} images out of {} images have been processed.'.format( i + 1, len(file_lst))) cur_im_path = os.path.join(crop_with_mask_dir, cur_im_name) img = cv2.imread(cur_im_path) img_h, img_w, _ = np.shape(img) img_height_lst.append(img_h) img_width_lst.append(img_w) faces[i, :, :, :] = cv2.resize(img[:, :, :], (img_size, img_size)) print('Start to make inferences...') results = model.predict(faces) predicted_genders = results[0] predicted_gender_prob = predicted_genders[:, 1] # the probability of being a male, (0, 1). predicted_gender_binary = [round(i) for i in predicted_gender_prob] ages = np.arange(0, 101).reshape(101, 1) predicted_ages = results[1].dot(ages).flatten() result_df = pd.DataFrame(columns=[ 'filename', 'age', 'gender binary', 'gender probability', 'img height', 'img width' ]) result_df['gender probability'] = predicted_gender_prob result_df['gender binary'] = predicted_gender_binary result_df['age'] = predicted_ages result_df['filename'] = file_lst result_df['img height'] = img_height_lst result_df['img width'] = img_width_lst file_name = 'gender_age_only_ind_' + current_folder_post_fix[:-1] + '.pkl' file_full_path = save_result_dir + file_name result_df.to_pickle(file_full_path) print( 'Age and gender estimation Done. Total time = {}'.format(time.time() - start_t)) K.clear_session()
if ret: for (i, face) in enumerate(faces): face_ag = cv2.resize(face, (64, 64), interpolation=cv2.INTER_AREA) preprocessed_faces_ag.append(face_ag) face_gray_emo = cv2.cvtColor(face, cv2.COLOR_BGR2GRAY) face_gray_emo = cv2.resize(face_gray_emo, (48, 48), interpolation=cv2.INTER_AREA) face_gray_emo = face_gray_emo.astype("float") / 255.0 face_gray_emo = img_to_array(face_gray_emo) face_gray_emo = np.expand_dims(face_gray_emo, axis=0) preprocessed_faces_emo.append(face_gray_emo) # make a prediction for Age and Gender results = model.predict(np.array(preprocessed_faces_ag)) predicted_genders = results[0] ages = np.arange(0, 101).reshape(101, 1) predicted_ages = results[1].dot(ages).flatten() # make a prediction for Emotion emo_labels = [] for (i, face) in enumerate(faces): preds = classifier.predict(preprocessed_faces_emo[i])[0] emo_labels.append(emotion_classes[preds.argmax()]) # draw results, for Age and Gender for (i, face) in enumerate(faces): label = "{}, {}, {}".format( int(predicted_ages[i]), "F" if predicted_genders[i][0] > 0.6 else "M", emo_labels[i])
class FaceCV(object): today = str(datetime.date.today()) count_0_9 = 0 count_10_19 = 0 count_20_29 = 0 count_30_39 = 0 count_40_49 = 0 count_50_59 = 0 count_60_69 = 0 count_70_79 = 0 count_80 = 0 count_F = 0 count_M = 0 df1 = pd.DataFrame(columns=[ '0-9', '10-19', '20-29', '30-39', '40-49', '50-59', '60-69', '70-79', '80+' ]) df2 = pd.DataFrame(columns=['Female', 'Male']) """ Singleton class for face recongnition task """ def __new__(cls, weight_file=None, depth=16, width=8, face_size=64): if not hasattr(cls, 'instance'): cls.instance = super(FaceCV, cls).__new__(cls) return cls.instance def __init__(self, depth=16, width=8, face_size=64): self.face_size = face_size self.model = WideResNet(face_size, depth=depth, k=width)() model_dir = os.path.join(os.getcwd(), "pretrained_models").replace("//", "\\") fpath = get_file( 'weights.18-4.06.hdf5', '/Users/lauradang/RyersonHacks/Gender-Recognition-and-Age-Estimator/pretrained_models/weights.18-4.06.hdf5', cache_subdir=model_dir) self.model.load_weights(fpath) @classmethod def draw_label(cls, image, point, label, font=cv2.FONT_HERSHEY_SIMPLEX, font_scale=1, thickness=2): size = cv2.getTextSize(label, font, font_scale, thickness)[0] x, y = point cv2.rectangle(image, (x, y - size[1]), (x + size[0], y), (255, 0, 0), cv2.FILLED) cv2.putText(image, label, point, font, font_scale, (255, 255, 255), thickness) def crop_face(self, imgarray, section, margin=40, size=64): """ :param imgarray: full image :param section: face detected area (x, y, w, h) :param margin: add some margin to the face detected area to include a full head :param size: the result image resolution with be (size x size) :return: resized image in numpy array with shape (size x size x 3) """ img_h, img_w, _ = imgarray.shape if section is None: section = [0, 0, img_w, img_h] (x, y, w, h) = section margin = int(min(w, h) * margin / 100) x_a = x - margin y_a = y - margin x_b = x + w + margin y_b = y + h + margin if x_a < 0: x_b = min(x_b - x_a, img_w - 1) x_a = 0 if y_a < 0: y_b = min(y_b - y_a, img_h - 1) y_a = 0 if x_b > img_w: x_a = max(x_a - (x_b - img_w), 0) x_b = img_w if y_b > img_h: y_a = max(y_a - (y_b - img_h), 0) y_b = img_h cropped = imgarray[y_a:y_b, x_a:x_b] resized_img = cv2.resize(cropped, (size, size), interpolation=cv2.INTER_AREA) resized_img = np.array(resized_img) return resized_img, (x_a, y_a, x_b - x_a, y_b - y_a) def detect_face(self): face_cascade = cv2.CascadeClassifier( '/Users/lauradang/RyersonHacks/Gender-Recognition-and-Age-Estimator/pretrained_models/haarcascade_frontalface_alt.xml' ) # 0 means the default video capture device in OS video_capture = cv2.VideoCapture(0) # infinite loop, break by key ESC while True: try: if not video_capture.isOpened(): sleep(5) # Capture frame-by-frame ret, frame = video_capture.read() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=10, minSize=(self.face_size, self.face_size)) if faces is not (): # placeholder for cropped faces face_imgs = np.empty( (len(faces), self.face_size, self.face_size, 3)) for i, face in enumerate(faces): face_img, cropped = self.crop_face(frame, face, margin=40, size=self.face_size) (x, y, w, h) = cropped cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 200, 0), 2) face_imgs[i, :, :, :] = face_img if len(face_imgs) > 0: # predict ages and genders of the detected faces results = self.model.predict(face_imgs) predicted_genders = results[0] ages = np.arange(0, 101).reshape(101, 1) predicted_ages = results[1].dot(ages).flatten() # draw results for i, face in enumerate(faces): label = "{}, {}".format( int(predicted_ages[i]), "F" if predicted_genders[i][0] > 0.5 else "M") self.draw_label(frame, (face[0], face[1]), label) data = label.split(", ") if data[1] == 'F': self.count_F += 1 if int(data[0]) >= 0 and int(data[0]) <= 9: self.count_0_9 += 1 elif int(data[0]) >= 10 and int(data[0]) <= 19: self.count_10_19 += 1 elif int(data[0]) >= 20 and int(data[0]) <= 29: self.count_20_29 += 1 elif int(data[0]) >= 30 and int(data[0]) <= 39: self.count_30_39 += 1 elif int(data[0]) >= 40 and int(data[0]) <= 49: self.count_40_49 += 1 elif int(data[0]) >= 50 and int(data[0]) <= 59: self.count_50_59 += 1 elif int(data[0]) >= 60 and int(data[0]) <= 69: self.count_60_69 += 1 elif int(data[0]) >= 70 and int(data[0]) <= 79: self.count_70_79 += 1 elif int(data[0]) >= 80: self.count_80 += 1 elif data[1] == 'M': self.count_M += 1 if int(data[0]) >= 0 and int(data[0]) <= 9: self.count_0_9 += 1 elif int(data[0]) >= 10 and int(data[0]) <= 19: self.count_10_19 += 1 elif int(data[0]) >= 20 and int(data[0]) <= 29: self.count_20_29 += 1 elif int(data[0]) >= 30 and int(data[0]) <= 39: self.count_30_39 += 1 elif int(data[0]) >= 40 and int(data[0]) <= 49: self.count_40_49 += 1 elif int(data[0]) >= 50 and int(data[0]) <= 59: self.count_50_59 += 1 elif int(data[0]) >= 60 and int(data[0]) <= 69: self.count_60_69 += 1 elif int(data[0]) >= 70 and int(data[0]) <= 79: self.count_70_79 += 1 elif int(data[0]) >= 80: self.count_80 += 1 cv2.imshow('Keras Faces', frame) if cv2.waitKey(1) & 0xFF == ord('q'): #press q to quit break except: break self.df1.loc[self.today, '0-9'] = self.count_0_9 self.df1.loc[self.today, '10-19'] = self.count_10_19 self.df1.loc[self.today, '20-29'] = self.count_20_29 self.df1.loc[self.today, '30-39'] = self.count_30_39 self.df1.loc[self.today, '40-49'] = self.count_40_49 self.df1.loc[self.today, '50-59'] = self.count_50_59 self.df1.loc[self.today, '60-69'] = self.count_60_69 self.df1.loc[self.today, '70-79'] = self.count_70_79 self.df1.loc[self.today, '80+'] = self.count_80 self.df2.loc[self.today, 'Female'] = self.count_F self.df2.loc[self.today, 'Male'] = self.count_M self.df1.to_excel('/Users/lauradang/RyersonHacks/data/age.xlsx') self.df2.to_excel('/Users/lauradang/RyersonHacks/data/gender.xlsx') # When everything is done, release the capture video_capture.release() cv2.destroyAllWindows()
class FaceImage(object): """ Singleton class for face recognition task """ CASE_PATH = "./models/haarcascade_frontalface_alt.xml" WRN_WEIGHTS_PATH = "https://github.com/Tony607/Keras_age_gender/releases/download/V1.0/weights.18-4.06.hdf5" def __new__(cls, weight_file=None, depth=16, width=8, face_size=64): if not hasattr(cls, 'instance'): cls.instance = super(FaceImage, cls).__new__(cls) return cls.instance def __init__(self, depth=16, width=8, face_size=64): self.face_size = face_size print("Loading WideResNet model...") self.model = WideResNet(face_size, depth=depth, k=width)() model_dir = os.path.join(os.getcwd(), "models").replace("//", "\\") fpath = get_file('weights.18-4.06.hdf5', self.WRN_WEIGHTS_PATH, cache_subdir=model_dir) self.model.load_weights(fpath) print("Loaded WideResNet model") # Load emotion models print("Loading emotion model...") self.emotion_model = emotion.load_model_dir("models") print("Loaded emotion model") if RECOGNIZE_FACES: print("Loading face recognizer...") self.face_recognizer = FaceRecognizer() print("Loaded face recognizer") @classmethod def draw_label_top(cls, image, point, label, font=cv2.FONT_HERSHEY_SIMPLEX, font_scale=1, thickness=2, alpha=OVERLAY_ALPHA): size = cv2.getTextSize(label, font, font_scale, thickness)[0] x, y = point overlay = image.copy() cv2.rectangle(overlay, (x, y - size[1]), (x + size[0], y), (255, 0, 0), cv2.FILLED) cv2.putText(overlay, label, point, font, font_scale, (255, 255, 255), thickness) cv2.addWeighted(overlay, alpha, image, 1 - alpha, 0, image) @classmethod def draw_label_bottom(cls, image, point, label, font=cv2.FONT_HERSHEY_SIMPLEX, font_scale=0.5, thickness=1, row_index=0, alpha=OVERLAY_ALPHA): size = cv2.getTextSize(label, font, font_scale, thickness)[0] point = (point[0], point[1] + (row_index * size[1])) x, y = point overlay = image.copy() cv2.rectangle(overlay, (x, y), (x + size[0], y + size[1]), (255, 0, 0), cv2.FILLED) point = x, y + size[1] cv2.putText(overlay, label, point, font, font_scale, (255, 255, 255), thickness) cv2.addWeighted(overlay, alpha, image, 1 - alpha, 0, image) def get_regular_face(self, img, bb): return img[bb.top():bb.bottom() + 1, bb.left():bb.right() + 1, :] def get_expanded_face(self, img, bb): img_h, img_w, _ = np.shape(img) x1, y1, x2, y2, w, h = bb.left(), bb.top( ), bb.right() + 1, bb.bottom() + 1, bb.width(), bb.height() xw1 = max(int(x1 - 0.4 * w), 0) yw1 = max(int(y1 - 0.4 * h), 0) xw2 = min(int(x2 + 0.4 * w), img_w - 1) yw2 = min(int(y2 + 0.4 * h), img_h - 1) return cv2.resize(img[yw1:yw2 + 1, xw1:xw2 + 1, :], (self.face_size, self.face_size)) def detect_face(self, img): # workaround for CV2 bug img = copy.deepcopy(img) # for face detection detector = dlib.get_frontal_face_detector() input_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img_h, img_w, _ = np.shape(input_img) # detect faces using dlib detector if RECOGNIZE_FACES == True: face_bbs, identities = self.face_recognizer.identify_image_faces( img) else: face_bbs = detector(input_img, 1) expanded_face_imgs = np.empty( (len(face_bbs), self.face_size, self.face_size, 3)) emotion2_results = [] # Get face images for i, bb in enumerate(face_bbs): x1, y1, x2, y2, w, h = bb.left(), bb.top( ), bb.right() + 1, bb.bottom() + 1, bb.width(), bb.height() expanded_face_imgs[i, :, :, :] = self.get_expanded_face(img, bb) reg_face = self.get_regular_face(img, bb) #reg_face = copy.deepcopy(reg_face) emotion2_results.append( emotion.emotionof(self.emotion_model, reg_face)[0]) if len(expanded_face_imgs) > 0: # predict ages and genders of the detected faces results = self.model.predict(expanded_face_imgs) predicted_genders = results[0] ages = np.arange(0, 101).reshape(101, 1) predicted_ages = results[1].dot(ages).flatten() # draw results for i, bb in enumerate(face_bbs): if RECOGNIZE_FACES == True: # Display name label1 = "{}".format(identities[i]) self.draw_label_bottom(img, (bb.left(), bb.bottom()), label1) ## Display age, gender and emotion if identities[i] == "Unknown" or "customer" in identities[i]: label2 = "{}, {}, {}".format( int(predicted_ages[i]), "F" if predicted_genders[i][0] > 0.5 else "M", emotion2_results[i]) else: label2 = "{}".format(emotion2_results[i]) self.draw_label_bottom(img, (bb.left(), bb.bottom() + 1), label2, row_index=1) else: ## Display age, gender and emotion label2 = "{}, {}, {}".format( int(predicted_ages[i]), "F" if predicted_genders[i][0] > 0.5 else "M", emotion2_results[i]) self.draw_label_bottom(img, (bb.left(), bb.bottom()), label2, row_index=0) # draw face rectangles for i, bb in enumerate(face_bbs): x1, y1, x2, y2, w, h = bb.left(), bb.top( ), bb.right() + 1, bb.bottom() + 1, bb.width(), bb.height() cv2.rectangle(img, (x1, y1), (x2, y2), (255, 0, 0), 2) return img
class FaceCV(object): CASE_PATH = "./pretrained_models/haarcascade_frontalface_alt.xml" WRN_WEIGHTS_PATH = "https://github.com/iamshreeram/human-gender-detection/releases/download/1.0/weights.hdf5" def __new__(cls, weight_file=None, depth=16, width=8, face_size=64): if not hasattr(cls, 'instance'): cls.instance = super(FaceCV, cls).__new__(cls) return cls.instance def __init__(self, depth=16, width=8, face_size=64): self.face_size = face_size self.model = WideResNet(face_size, depth=depth, k=width)() model_dir = os.path.join(os.getcwd(), "pretrained_models").replace("//", "\\") fpath = get_file('weights.hdf5',self.WRN_WEIGHTS_PATH,cache_subdir=model_dir) self.model.load_weights(fpath) @classmethod def draw_label(cls, image, point, label, font=cv2.FONT_HERSHEY_SIMPLEX, font_scale=1, thickness=2): size = cv2.getTextSize(label, font, font_scale, thickness)[0] x, y = point cv2.rectangle(image, (x, y - size[1]), (x + size[0], y), (0, 255, 0), cv2.FILLED) cv2.putText(image, label, point, font, font_scale, (255, 255, 255), thickness) def crop_face(self, imgarray, section, margin=40, size=64): """ :param imgarray: full image :param section: face detected area (x, y, w, h) :param margin: add some margin to the face detected area to include a full head :param size: the result image resolution with be (size x size) :return: resized image in numpy array with shape (size x size x 3) """ img_h, img_w, _ = imgarray.shape if section is None: section = [0, 0, img_w, img_h] (x, y, w, h) = section margin = int(min(w,h) * margin / 100) x_a = x - margin y_a = y - margin x_b = x + w + margin y_b = y + h + margin if x_a < 0: x_b = min(x_b - x_a, img_w-1) x_a = 0 if y_a < 0: y_b = min(y_b - y_a, img_h-1) y_a = 0 if x_b > img_w: x_a = max(x_a - (x_b - img_w), 0) x_b = img_w if y_b > img_h: y_a = max(y_a - (y_b - img_h), 0) y_b = img_h cropped = imgarray[y_a: y_b, x_a: x_b] resized_img = cv2.resize(cropped, (size, size), interpolation=cv2.INTER_AREA) resized_img = np.array(resized_img) return resized_img, (x_a, y_a, x_b - x_a, y_b - y_a) def detect_face(self): face_cascade = cv2.CascadeClassifier(self.CASE_PATH) # 0 means the default video capture device in OS video_capture = cv2.VideoCapture(-1) # infinite loop, break by key ESC while True: if not video_capture.isOpened(): sleep(5) # Capture frame-by-frame ret, frame = video_capture.read() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) print(face_cascade) faces = face_cascade.detectMultiScale( gray, scaleFactor=1.2, minNeighbors=10, minSize=(self.face_size, self.face_size) ) # placeholder for cropped faces face_imgs = np.empty((len(faces), self.face_size, self.face_size, 3)) for i, face in enumerate(faces): face_img, cropped = self.crop_face(frame, face, margin=40, size=self.face_size) (x, y, w, h) = cropped cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 200, 0), 2) face_imgs[i,:,:,:] = face_img if len(face_imgs) > 0: # predict ages and genders of the detected faces results = self.model.predict(face_imgs) predicted_genders = results[0] ages = np.arange(0, 101).reshape(101, 1) predicted_ages = results[1].dot(ages).flatten() # draw results for i, face in enumerate(faces): # label = "{}, {}".format(int(predicted_ages[i]),"F" if predicted_genders[i][0] > 0.5 else "M") # self.draw_label(frame, (face[0], face[1]), label) label = "{}".format("Female" if predicted_genders[i][0] > 0.5 else "Male") self.draw_label(frame, (face[0], face[1]), label) cv2.imshow('Gender Detector Engine', frame) if cv2.waitKey(5) == 27: # ESC key press break # When everything is done, release the capture video_capture.release() cv2.destroyAllWindows()
def main(): args = get_args() depth = args.depth k = args.width weight_file = args.weight_file margin = args.margin if not weight_file: weight_file = get_file("weights.28-3.73.hdf5", pretrained_model, cache_subdir="../../data/pretrained_models", file_hash=modhash, cache_dir=os.path.dirname( os.path.abspath(__file__))) # for face detection detector = dlib.get_frontal_face_detector() # load model and weights img_size = 64 model = WideResNet(img_size, depth=depth, k=k)() model.load_weights(weight_file) for img in yield_images(): name = str(img) img = img.img print(name) input_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img_h, img_w, _ = np.shape(input_img) # detect faces using dlib detector detected = detector(input_img, 1) faces = np.empty((len(detected), img_size, img_size, 3)) if len(detected) > 0: for i, d in enumerate(detected): x1, y1, x2, y2, w, h = d.left(), d.top( ), d.right() + 1, d.bottom() + 1, d.width(), d.height() xw1 = max(int(x1 - margin * w), 0) yw1 = max(int(y1 - margin * h), 0) xw2 = min(int(x2 + margin * w), img_w - 1) yw2 = min(int(y2 + margin * h), img_h - 1) cv2.rectangle(img, (x1, y1), (x2, y2), (255, 0, 0), 2) # cv2.rectangle(img, (xw1, yw1), (xw2, yw2), (255, 0, 0), 2) faces[i, :, :, :] = cv2.resize( img[yw1:yw2 + 1, xw1:xw2 + 1, :], (img_size, img_size)) # predict ages and genders of the detected faces results = model.predict(faces) predicted_genders = results[0] ages = np.arange(0, 101).reshape(101, 1) predicted_ages = results[1].dot(ages).flatten() # draw results #for i, d in enumerate(detected): # label = "{}, {}".format(int(predicted_ages[i]), # "F" if predicted_genders[i][0] > 0.5 else "M") # draw_label(img, (d.left(), d.top()), label) with open('results.csv', 'a') as csvfile: csvwriter = csv.writer(csvfile, delimiter=",") csvwriter.writerow([name, predicted_ages, predicted_genders]) #cv2.imshow("result", img) key = cv2.waitKey(30) if key == 27: break
class FaceCV(object): """ Singleton class for face recongnition task """ CASE_PATH = "https://github.com/Tony607/Keras_age_gender/blob/master/pretrained_models/haarcascade_frontalface_alt.xml" WRN_WEIGHTS_PATH = "https://github.com/Tony607/Keras_age_gender/releases/download/V1.0/weights.18-4.06.hdf5" def __new__(cls, weight_file=None, depth=16, width=8, face_size=256): if not hasattr(cls, 'instance'): cls.instance = super(FaceCV, cls).__new__(cls) return cls.instance def __init__(self, depth=16, width=8, face_size=64): self.face_size = face_size self.model = WideResNet(face_size, depth=depth, k=width)() model_dir = os.path.join(os.path.dirname(__file__), './models/') fpath = tf.keras.utils.get_file('weights.18-4.06.hdf5', self.WRN_WEIGHTS_PATH, cache_subdir=model_dir) self.model.load_weights(fpath) self.model.layers.pop() self.model.layers.pop() output_layer = self.model.layers[-1].output x_newfc = Dense(70, activation='softmax', name='classification')(output_layer) new_model = keras.Model(inputs=self.model.input, outputs=x_newfc) adam = Adam() new_model.compile(optimizer=adam, loss='categorical_crossentropy', metrics=['accuracy', 'crossentropy']) new_model.load_weights("./models/asian_weights.hdf5") self.model = new_model @classmethod def draw_label(cls, image, point, label, font=cv2.FONT_HERSHEY_SIMPLEX, font_scale=1, thickness=2): size = cv2.getTextSize(label, font, font_scale, thickness)[0] x, y = point cv2.rectangle(image, (x, y - size[1]), (x + size[0], y), (255, 0, 0), cv2.FILLED) cv2.putText(image, label, point, font, font_scale, (255, 255, 255), thickness) def crop_face(self, imgarray, section, margin=40, size=64): """ :param imgarray: full image :param section: face detected area (x, y, w, h) :param margin: add some margin to the face detected area to include a full head :param size: the result image resolution with be (size x size) :return: resized image in numpy array with shape (size x size x 3) """ img_h, img_w, _ = imgarray.shape if section is None: section = [0, 0, img_w, img_h] (x, y, w, h) = section margin = int(min(w,h) * margin ) x_a = x - margin y_a = y - margin x_b = x + w + margin y_b = y + h + margin if x_a < 0: x_b = min(x_b - x_a, img_w-1) x_a = 0 if y_a < 0: y_b = min(y_b - y_a, img_h-1) y_a = 0 if x_b > img_w: x_a = max(x_a - (x_b - img_w), 0) x_b = img_w if y_b > img_h: y_a = max(y_a - (y_b - img_h), 0) y_b = img_h cropped = imgarray[y_a: y_b, x_a: x_b] resized_img = cv2.resize(cropped, (size, size), interpolation=cv2.INTER_AREA) resized_img = np.array(resized_img) return resized_img, (x_a, y_a, x_b - x_a, y_b - y_a) def detect_face(self, image): # Create a face detector detector = dlib.get_frontal_face_detector() # Create a face aligner predictor = dlib.shape_predictor("./models/shape_predictor_68_face_landmarks.dat") fa = FaceAligner(predictor, desiredFaceHeight=64, desiredFaceWidth=64) # Get image directory image_name = image # Read, resize image and change to greyscale image = cv2.imread(image) image = imutils.resize(image, width=256) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # Cropped and aligned faces face_imgs = np.empty((1, self.face_size, self.face_size, 3)) faces = detector(gray, 2) (x, y, w, h) = rect_to_bb(faces[0]) faceOrig = imutils.resize(image[y:y + h, x:x + w], height=64, width=64) faceAligned = fa.align(image, gray, faces[0]) face_imgs[0, :, :, :] = faceAligned # Get results results = self.model.predict(face_imgs) ages = np.arange(0, 70).reshape(70, 1) predicted_ages = results[0].dot(ages).flatten() index = int(round(predicted_ages[0], 0)) return index
class AgeGenderPredictor: WRN_WEIGHTS_PATH = "https://github.com/Tony607/Keras_age_gender/releases/download/V1.0/weights.18-4.06.hdf5" def __new__(cls, weight_file=None, depth=16, width=8, face_size=64): if not hasattr(cls, 'instance'): cls.instance = super(AgeGenderPredictor, cls).__new__(cls) return cls.instance def __init__(self, depth=16, width=8, face_size=64): self.face_size = face_size self.model = WideResNet(face_size, depth=depth, k=width)() model_dir = os.path.join(os.getcwd(), "pretrained_models").replace("//", "\\") fpath = get_file('weights.18-4.06.hdf5', self.WRN_WEIGHTS_PATH, cache_subdir=model_dir) self.model.load_weights(fpath) self.prev_detections = [] @classmethod def draw_label(cls, image, point, label, font=cv2.FONT_HERSHEY_SIMPLEX, font_scale=1, thickness=2): size = cv2.getTextSize(label, font, font_scale, thickness)[0] x, y = point cv2.rectangle(image, (x, y - size[1]), (x + size[0], y), (255, 0, 0), cv2.FILLED) cv2.putText(image, label, point, font, font_scale, (255, 255, 255), thickness) def crop_face(self, imgarray, section, margin=60, size=64): """ :param imgarray: full image :param section: face detected area (x, y, w, h) :param margin: add some margin to the face detected area to include a full head :param size: the result image resolution with be (size x size) :return: resized image in numpy array with shape (size x size x 3) """ img_h, img_w, _ = imgarray.shape if section is None: section = [0, 0, img_w, img_h] (x, y, w, h) = section margin = int(min(w, h) * margin / 100) x_a = x - margin y_a = y - margin x_b = x + w + margin y_b = y + h + margin if x_a < 0: x_b = min(x_b - x_a, img_w - 1) x_a = 0 if y_a < 0: y_b = min(y_b - y_a, img_h - 1) y_a = 0 if x_b > img_w: x_a = max(x_a - (x_b - img_w), 0) x_b = img_w if y_b > img_h: y_a = max(y_a - (y_b - img_h), 0) y_b = img_h cropped = imgarray[y_a: y_b, x_a: x_b] resized_img = cv2.resize(cropped, (size, size), interpolation=cv2.INTER_AREA) resized_img = np.array(resized_img) return resized_img, (x_a, y_a, x_b - x_a, y_b - y_a) def detect_age_dender_by_faces(self, frame, faces, get_prev=False): if not get_prev: faces = [(face[0][0], face[0][1], face[1][0] - face[0][0], face[1][1] - face[0][1]) for face in faces] face_imgs = np.empty((len(faces), self.face_size, self.face_size, 3)) predicted_genders, predicted_ages = [], [] for i, face in enumerate(faces): face_img, cropped = self.crop_face(frame, face, margin=40, size=self.face_size) (x, y, w, h) = cropped cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 200, 0), 2) face_imgs[i, :, :, :] = face_img if len(face_imgs) > 0: # predict ages and genders of the detected faces results = self.model.predict(face_imgs) predicted_genders = results[0] ages = np.arange(0, 101).reshape(101, 1) predicted_ages = results[1].dot(ages).flatten() # draw results predicted_ages = [int(age) for age in predicted_ages] predicted_genders = ['female' if genders[0] > 0.5 else 'male' for genders in predicted_genders] for i, face in enumerate(faces): label = "{}, {}".format(predicted_ages[i], predicted_genders[i]) #self.draw_label(frame, (face[0], face[1]), label) self.prev_detections = tuple(zip(predicted_genders, predicted_ages)) return self.prev_detections
class FaceCV(object): """ Singleton class for face recongnition task """ CASE_PATH = os.path.join("pretrained_models", "haarcascade_frontalface_alt.xml") WRN_WEIGHTS_PATH = "https://github.com/Tony607/Keras_age_gender/releases/download/V1.0/weights.18-4.06.hdf5" def __new__(cls, weight_file=None, depth=16, width=8, face_size=64): if not hasattr(cls, 'instance'): cls.instance = super(FaceCV, cls).__new__(cls) return cls.instance def __init__(self, depth=16, width=8, face_size=64): self.face_size = face_size self.model = WideResNet(face_size, depth=depth, k=width)() model_dir = os.path.join(os.getcwd(), "pretrained_models").replace("//", "\\") fpath = get_file('weights.18-4.06.hdf5', self.WRN_WEIGHTS_PATH, cache_subdir=model_dir) self.model.load_weights(fpath) @classmethod def draw_label(cls, image, point, label, font=cv2.FONT_HERSHEY_SIMPLEX, font_scale=1, thickness=2): size = cv2.getTextSize(label, font, font_scale, thickness)[0] x, y = point cv2.rectangle(image, (x, y - size[1]), (x + size[0], y), (255, 0, 0), cv2.FILLED) cv2.putText(image, label, point, font, font_scale, (255, 255, 255), thickness) def crop_face(self, imgarray, section, margin=40, size=64): """ :param imgarray: full image :param section: face detected area (x, y, w, h) :param margin: add some margin to the face detected area to include a full head :param size: the result image resolution with be (size x size) :return: resized image in numpy array with shape (size x size x 3) """ img_h, img_w, _ = imgarray.shape if section is None: section = [0, 0, img_w, img_h] (x, y, w, h) = section margin = int(min(w, h) * margin / 100) x_a = x - margin y_a = y - margin x_b = x + w + margin y_b = y + h + margin if x_a < 0: x_b = min(x_b - x_a, img_w - 1) x_a = 0 if y_a < 0: y_b = min(y_b - y_a, img_h - 1) y_a = 0 if x_b > img_w: x_a = max(x_a - (x_b - img_w), 0) x_b = img_w if y_b > img_h: y_a = max(y_a - (y_b - img_h), 0) y_b = img_h cropped = imgarray[y_a:y_b, x_a:x_b] resized_img = cv2.resize(cropped, (size, size), interpolation=cv2.INTER_AREA) resized_img = np.array(resized_img) return resized_img, (x_a, y_a, x_b - x_a, y_b - y_a) def detect_face(self, frame, gray): face_cascade = cv2.CascadeClassifier(self.CASE_PATH) # gray = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY) faces = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=10, minSize=(self.face_size, self.face_size)) # placeholder for cropped faces face_imgs = np.empty((len(faces), self.face_size, self.face_size, 3)) for i, face in enumerate(faces): face_img, cropped = self.crop_face(frame, face, margin=40, size=self.face_size) (x, y, w, h) = cropped cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 200, 0), 2) face_imgs[i, :, :, :] = face_img if len(face_imgs) > 0: # predict ages and genders of the detected faces results = self.model.predict(face_imgs) predicted_genders = results[0] ages = np.arange(0, 101).reshape(101, 1) predicted_ages = results[1].dot(ages).flatten() # draw results for i, face in enumerate(faces): gender = "{}".format( "female" if predicted_genders[i][0] > 0.5 else "male") age = int(predicted_ages[i]) # label = "{}, {}".format(int(predicted_ages[i]), # "F" if predicted_genders[i][0] > 0.5 else "M") # self.draw_label(gray, (face[0], face[1]), label) return gender, age # cv2.imwrite('/home/james/Desktop/age-gender-detected.jpg',gray) # cv2.imshow('Keras Faces', frame) # if cv2.waitKey(5) == 27: # ESC key press # break # # When everything is done, release the capture # video_capture.release() # cv2.destroyAllWindows() # def get_args(): # parser = argparse.ArgumentParser(description="This script detects faces from web cam input, " # "and estimates age and gender for the detected faces.", # formatter_class=argparse.ArgumentDefaultsHelpFormatter) # parser.add_argument("--depth", type=int, default=16, # help="depth of network") # parser.add_argument("--width", type=int, default=8, # help="width of network") # args = parser.parse_args() # return args # def main(): # # args = get_args() # # depth = args.depth # # width = args.width # face = FaceCV(depth=16, width=8) # frame = cv2.imread('/home/james/Desktop/Jay Lal.jpg') # print(frame.shape) # face.detect_face(frame) # if __name__ == "__main__": # main()