Created
March 3, 2017 08:11
-
-
Save allskyee/5ac6cb3c0200ed7e1c678ae33d06664c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python2 | |
# | |
# Example to run classifier on webcam stream. | |
# Brandon Amos & Vijayenthiran | |
# 2016/06/21 | |
# | |
# Chon Sky modified to generate aligned face images from webcam | |
# 2017/03/02 | |
# | |
# Copyright 2015-2016 Carnegie Mellon University | |
# | |
# Licensed under the Apache License, Version 2.0 (the "License"); | |
# you may not use this file except in compliance with the License. | |
# You may obtain a copy of the License at | |
# | |
# http://www.apache.org/licenses/LICENSE-2.0 | |
# | |
# Unless required by applicable law or agreed to in writing, software | |
# distributed under the License is distributed on an "AS IS" BASIS, | |
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
# See the License for the specific language governing permissions and | |
# limitations under the License. | |
# Contrib: allskyee | |
# This example file runs face detector & facial landmark detector | |
# to produce aligned facial images | |
# To run this file from the openface home dir: | |
# ./demo/aligned_face_webcam.py | |
# commonly used parameters --width 640 --height 480 --captureDevice 0 | |
# press 'r' to save an image of the face which should start with 0.jpg | |
# press 'q' to quit | |
import time | |
start = time.time() | |
import argparse | |
import cv2 | |
import os | |
import pickle | |
import numpy as np | |
np.set_printoptions(precision=2) | |
from sklearn.mixture import GMM | |
import openface | |
from threading import Thread, Lock | |
class WebcamVideoStream : | |
def __init__(self, src = 0, width = 320, height = 240) : | |
self.stream = cv2.VideoCapture(src) | |
self.stream.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, width) | |
self.stream.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, height) | |
(self.grabbed, self.frame) = self.stream.read() | |
self.started = False | |
self.read_lock = Lock() | |
def start(self) : | |
if self.started : | |
print "already started!!" | |
return None | |
self.started = True | |
self.thread = Thread(target=self.update, args=()) | |
self.thread.start() | |
return self | |
def update(self) : | |
while self.started : | |
(grabbed, frame) = self.stream.read() | |
self.read_lock.acquire() | |
self.grabbed, self.frame = grabbed, frame | |
self.read_lock.release() | |
def read(self) : | |
self.read_lock.acquire() | |
frame = self.frame.copy() | |
self.read_lock.release() | |
return frame | |
def stop(self) : | |
self.started = False | |
self.thread.join() | |
def __exit__(self, exc_type, exc_value, traceback) : | |
self.stream.release() | |
fileDir = os.path.dirname(os.path.realpath(__file__)) | |
modelDir = os.path.join(fileDir, '..', 'models') | |
dlibModelDir = os.path.join(modelDir, 'dlib') | |
openfaceModelDir = os.path.join(modelDir, 'openface') | |
def get_aligned_faces(bgrImg): | |
start = time.time() | |
if bgrImg is None: | |
raise Exception("Unable to load image/frame") | |
rgbImg = cv2.cvtColor(bgrImg, cv2.COLOR_BGR2RGB) | |
if args.verbose: | |
print(" + Original size: {}".format(rgbImg.shape)) | |
if args.verbose: | |
print("Loading the image took {} seconds.".format(time.time() - start)) | |
start = time.time() | |
# Get the largest face bounding box | |
# bb = align.getLargestFaceBoundingBox(rgbImg) #Bounding box | |
# Get all bounding boxes | |
bb = align.getAllFaceBoundingBoxes(rgbImg) | |
if bb is None: | |
# raise Exception("Unable to find a face: {}".format(imgPath)) | |
return None, None | |
if args.verbose: | |
print("Face detection took {} seconds.".format(time.time() - start)) | |
start = time.time() | |
alignedFaces = [] | |
for box in bb: | |
alignedFaces.append( | |
align.align( | |
args.imgDim, | |
rgbImg, | |
box, | |
landmarkIndices=openface.AlignDlib.OUTER_EYES_AND_NOSE)) | |
if alignedFaces is None: | |
raise Exception("Unable to align the frame") | |
if args.verbose: | |
print("Alignment took {} seconds.".format(time.time() - start)) | |
return bb, alignedFaces | |
#start = time.time() | |
#reps = [] | |
#for alignedFace in alignedFaces: | |
# reps.append(net.forward(alignedFace)) | |
#if args.verbose: | |
# print("Neural network forward pass took {} seconds.".format( | |
# time.time() - start)) | |
# print reps | |
#return reps | |
def infer(img, args): | |
with open(args.classifierModel, 'r') as f: | |
(le, clf) = pickle.load(f) # le - label and clf - classifer | |
reps = getRep(img) | |
persons = [] | |
confidences = [] | |
for rep in reps: | |
try: | |
rep = rep.reshape(1, -1) | |
except: | |
print "No Face detected" | |
return (None, None) | |
start = time.time() | |
predictions = clf.predict_proba(rep).ravel() | |
# print predictions | |
maxI = np.argmax(predictions) | |
# max2 = np.argsort(predictions)[-3:][::-1][1] | |
persons.append(le.inverse_transform(maxI)) | |
# print str(le.inverse_transform(max2)) + ": "+str( predictions [max2]) | |
# ^ prints the second prediction | |
confidences.append(predictions[maxI]) | |
if args.verbose: | |
print("Prediction took {} seconds.".format(time.time() - start)) | |
pass | |
# print("Predict {} with {:.2f} confidence.".format(person, confidence)) | |
if isinstance(clf, GMM): | |
dist = np.linalg.norm(rep - clf.means_[maxI]) | |
print(" + Distance from the mean: {}".format(dist)) | |
pass | |
return (persons, confidences) | |
if __name__ == '__main__': | |
parser = argparse.ArgumentParser() | |
parser.add_argument( | |
'--dlibFacePredictor', | |
type=str, | |
help="Path to dlib's face predictor.", | |
default=os.path.join( | |
dlibModelDir, | |
"shape_predictor_68_face_landmarks.dat")) | |
parser.add_argument('--imgDim', type=int, | |
help="Default image dimension.", default=96) | |
parser.add_argument( | |
'--captureDevice', | |
type=int, | |
default=0, | |
help='Capture device. 0 for latop webcam and 1 for usb webcam') | |
parser.add_argument('--width', type=int, default=320) | |
parser.add_argument('--height', type=int, default=240) | |
parser.add_argument('--verbose', action='store_true') | |
args = parser.parse_args() | |
align = openface.AlignDlib(args.dlibFacePredictor) | |
# Capture device. Usually 0 will be webcam and 1 will be usb cam. | |
vs = WebcamVideoStream(src = args.captureDevice, width = args.width, height = args.height).start() | |
confidenceList = [] | |
face_record_seq = 0 | |
while True: | |
#ret, frame = video_capture.read() | |
frame = vs.read() | |
bb, alignedFaces = get_aligned_faces(frame) | |
if bb != None : | |
#draw rectangles | |
for b in bb : | |
cv2.rectangle(frame, (b.left(), b.top()), (b.right(), b.bottom()), (255, 255, 0), 3) | |
cv2.imshow('', frame) | |
# quit the program on the press of key 'q' | |
k = cv2.waitKey(1) & 0xFF | |
if k == ord('q'): | |
break | |
if k == ord('r'): | |
for af in alignedFaces : | |
#print af.shape | |
bgr = cv2.cvtColor(af, cv2.COLOR_RGB2BGR) | |
fn = str(face_record_seq) + ".jpg" | |
cv2.imwrite(fn, bgr) | |
face_record_seq += 1 | |
cv2.imshow(fn, bgr) | |
print fn | |
# When everything is done, release the capture | |
vs.stop() | |
cv2.destroyAllWindows() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment