Setup a feature to allow the use of EmilianaVT's featureExtracotor
will need to test it, it seems to work better than I rememebr, if it keeps working that good I might juse make it the default
This commit is contained in:
parent
18b7c03cc6
commit
76390857f8
6 changed files with 56 additions and 23 deletions
Binary file not shown.
|
|
@ -1,22 +1,39 @@
|
|||
import numpy as np
|
||||
import time
|
||||
import math
|
||||
import emilianaFeature
|
||||
|
||||
def angle(p1, p2):
|
||||
p1 = np.array(p1)
|
||||
p2 = np.array(p2)
|
||||
a = np.arctan2(*(p2 - p1)[::-1])
|
||||
return (a % (2 * np.pi))
|
||||
|
||||
def rotate(origin, point, a):
|
||||
a = -a
|
||||
ox, oy = origin
|
||||
px, py = point
|
||||
|
||||
qx = ox + math.cos(a) * (px - ox) - math.sin(a) * (py - oy)
|
||||
qy = oy + math.sin(a) * (px - ox) + math.cos(a) * (py - oy)
|
||||
return qx, qy
|
||||
|
||||
class FeatureExtractor():
|
||||
def __init__(self, max_feature_updates=0):
|
||||
self.eye_l = Feature(max_feature_updates=max_feature_updates)
|
||||
self.eye_r = Feature(max_feature_updates=max_feature_updates)
|
||||
self.eyebrow_updown_l = Feature(max_feature_updates=max_feature_updates)
|
||||
self.eyebrow_updown_r = Feature(max_feature_updates=max_feature_updates)
|
||||
self.eyebrow_quirk_l = Feature(threshold=0.05, max_feature_updates=max_feature_updates)
|
||||
self.eyebrow_quirk_r = Feature(threshold=0.05, max_feature_updates=max_feature_updates)
|
||||
self.eyebrow_steepness_l = Feature(threshold=0.05, max_feature_updates=max_feature_updates)
|
||||
self.eyebrow_steepness_r = Feature(threshold=0.05, max_feature_updates=max_feature_updates)
|
||||
self.mouth_corner_updown_l = Feature(max_feature_updates=max_feature_updates)
|
||||
self.mouth_corner_updown_r = Feature(max_feature_updates=max_feature_updates)
|
||||
self.mouth_corner_inout_l = Feature(threshold=0.02, max_feature_updates=max_feature_updates)
|
||||
self.mouth_corner_inout_r = Feature(threshold=0.02, max_feature_updates=max_feature_updates)
|
||||
self.mouth_open = Feature(max_feature_updates=max_feature_updates)
|
||||
self.mouth_wide = Feature(threshold=0.02, max_feature_updates=max_feature_updates)
|
||||
self.eye_l = emilianaFeature.Feature(max_feature_updates=max_feature_updates)
|
||||
self.eye_r = emilianaFeature.Feature(max_feature_updates=max_feature_updates)
|
||||
self.eyebrow_updown_l = emilianaFeature.Feature(max_feature_updates=max_feature_updates)
|
||||
self.eyebrow_updown_r = emilianaFeature.Feature(max_feature_updates=max_feature_updates)
|
||||
self.eyebrow_quirk_l = emilianaFeature.Feature(threshold=0.05, max_feature_updates=max_feature_updates)
|
||||
self.eyebrow_quirk_r = emilianaFeature.Feature(threshold=0.05, max_feature_updates=max_feature_updates)
|
||||
self.eyebrow_steepness_l = emilianaFeature.Feature(threshold=0.05, max_feature_updates=max_feature_updates)
|
||||
self.eyebrow_steepness_r = emilianaFeature.Feature(threshold=0.05, max_feature_updates=max_feature_updates)
|
||||
self.mouth_corner_updown_l = emilianaFeature.Feature(max_feature_updates=max_feature_updates)
|
||||
self.mouth_corner_updown_r = emilianaFeature.Feature(max_feature_updates=max_feature_updates)
|
||||
self.mouth_corner_inout_l = emilianaFeature.Feature(threshold=0.02, max_feature_updates=max_feature_updates)
|
||||
self.mouth_corner_inout_r = emilianaFeature.Feature(threshold=0.02, max_feature_updates=max_feature_updates)
|
||||
self.mouth_open = emilianaFeature.Feature(max_feature_updates=max_feature_updates)
|
||||
self.mouth_wide = emilianaFeature.Feature(threshold=0.02, max_feature_updates=max_feature_updates)
|
||||
|
||||
def align_points(self, a, b, pts):
|
||||
a = tuple(a)
|
||||
|
|
|
|||
14
face.py
14
face.py
|
|
@ -1,9 +1,11 @@
|
|||
import numpy as np
|
||||
import math
|
||||
import featureExtractor
|
||||
import emilianaFeatureExtractor
|
||||
|
||||
class FaceInfo():
|
||||
def __init__(self, id, tracker):
|
||||
def __init__(self, id, tracker, featureType):
|
||||
self.featureType = featureType
|
||||
self.id = id
|
||||
self.tracker = tracker
|
||||
self.face_3d = np.array([
|
||||
|
|
@ -100,7 +102,11 @@ class FaceInfo():
|
|||
self.pts_3d = None
|
||||
self.eye_blink = None
|
||||
self.pnp_error = 0
|
||||
self.features = featureExtractor.FeatureExtractor()
|
||||
if self.featureType == 0:
|
||||
self.features = featureExtractor.FeatureExtractor()
|
||||
else:
|
||||
self.features = emilianaFeatureExtractor.FeatureExtractor()
|
||||
|
||||
self.current_features = {}
|
||||
self.contour = np.zeros((21,3))
|
||||
self.update_contour()
|
||||
|
|
@ -140,4 +146,6 @@ class FaceInfo():
|
|||
|
||||
self.pts_3d = self.normalize_pts3d(self.pts_3d)
|
||||
self.current_features = self.features.update(self.pts_3d[:, 0:2])
|
||||
self.eye_blink = [self.current_features["eye_r"],self.current_features["eye_l"] ]
|
||||
self.eye_blink = []
|
||||
self.eye_blink.append(1 - min(max(0, -self.current_features["eye_r"]), 1))
|
||||
self.eye_blink.append(1 - min(max(0, -self.current_features["eye_l"]), 1))
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@ parser.add_argument("-d", "--detection-threshold", type=float, help="Set minimum
|
|||
parser.add_argument("-s", "--silent", type=int, help="Set this to 1 to prevent text output on the console", default=0)
|
||||
parser.add_argument("--model", type=int, help="This can be used to select the tracking model. Higher numbers are models with better tracking quality, but slower speed, except for model 4, which is wink optimized.", default=3, choices=[0, 1, 2, 3, 4])
|
||||
parser.add_argument("--preview", type=int, help="Preview the frames sent to the tracker", default=0)
|
||||
parser.add_argument("--feature-type", type=int, help="Sets which version of feature extraction is used. 0 is my new version that works well for me and allows for some customization, 1 is EmilianaVT's version aka, normal OpenSeeFace operation", default=0, choices=[0, 1])
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
|
|
@ -48,6 +50,7 @@ height = args.height
|
|||
width = args.width
|
||||
previewFlag = (args.preview == 1)
|
||||
mirror_input = args.mirror_input
|
||||
featureType = args.feature_type
|
||||
|
||||
#I make a minor tweak to the framerate to help the camera out
|
||||
#it's an inpercetible amount of time per frame
|
||||
|
|
@ -110,7 +113,7 @@ peak_camera_latency = 0.0
|
|||
total_camera_latency = 0.0
|
||||
failures = 0
|
||||
|
||||
tracker = Tracker(width, height, messageQueue, threshold=args.threshold, silent=silent, model_type=args.model, detection_threshold=args.detection_threshold)
|
||||
tracker = Tracker(width, height, messageQueue, featureType, threshold=args.threshold, silent=silent, model_type=args.model, detection_threshold=args.detection_threshold)
|
||||
|
||||
#don't start until the webcam is ready
|
||||
while frameQueue.qsize() < 1:
|
||||
|
|
|
|||
|
|
@ -77,10 +77,10 @@ class FeatureExtractor():
|
|||
|
||||
f_pts = self.align_points(pts[42], pts[45], pts[[43, 44, 47, 46]])
|
||||
f = (f_pts[0][1]/2 + f_pts[1][1]/2) - (f_pts[2][1]/2 + f_pts[3][1]/2)
|
||||
features["eye_l"] = self.eye_l.update(f)
|
||||
features["eye_l"] = -self.eye_l.update(f)
|
||||
f_pts = self.align_points(pts[36], pts[39], pts[[37, 38, 41, 40]])
|
||||
f = (f_pts[0][1]/2 + f_pts[1][1]/2) - (f_pts[2][1]/2 + f_pts[3][1]/2)
|
||||
features["eye_r"] = self.eye_r.update(f)
|
||||
features["eye_r"] = -self.eye_r.update(f)
|
||||
|
||||
f = ((pts[22][1]/2 + pts[26][1]/2) - (pts[42][1]/2 + pts[45][1]/2))/norm_distance_y
|
||||
features["eyebrow_updown_l"] = self.eyebrow_updown_l.update(f)
|
||||
|
|
|
|||
11
tracker.py
11
tracker.py
|
|
@ -6,6 +6,7 @@ import eyes
|
|||
import landmarks
|
||||
import face
|
||||
import featureExtractor
|
||||
import emilianaFeatureExtractor
|
||||
|
||||
|
||||
#this file is so much smaller than it used to be, lol
|
||||
|
|
@ -33,12 +34,16 @@ def clamp_to_im(pt, w, h): #8 times per frame, but that only accounts for 0.005m
|
|||
return (int(x),int(y+1))
|
||||
|
||||
class Tracker():
|
||||
def __init__(self, width, height, messageQueue, model_type=3, detection_threshold=0.6, threshold=0.6, silent=False):
|
||||
def __init__(self, width, height, messageQueue, featureType, model_type=3, detection_threshold=0.6, threshold=0.6, silent=False):
|
||||
|
||||
self.FaceDetector = facedetection.FaceDetector(detection_threshold = detection_threshold)
|
||||
self.EyeTracker = eyes.EyeTracker()
|
||||
self.Landmarks = landmarks.Landmarks(width, height, model_type, threshold)
|
||||
self.FeatureExtractor = featureExtractor.FeatureExtractor()
|
||||
if featureType == 0:
|
||||
self.FeatureExtractor = featureExtractor.FeatureExtractor()
|
||||
else:
|
||||
self.FeatureExtractor = emilianaFeatureExtractor.FeatureExtractor()
|
||||
|
||||
|
||||
# Image normalization constants
|
||||
self.mean = np.float32(np.array([-2.1179, -2.0357, -1.8044]))
|
||||
|
|
@ -52,7 +57,7 @@ class Tracker():
|
|||
self.threshold = threshold
|
||||
|
||||
self.faces = []
|
||||
self.face_info = [face.FaceInfo(0, self)]
|
||||
self.face_info = [face.FaceInfo(0, self, featureType)]
|
||||
self.messageQueue = messageQueue
|
||||
|
||||
def preprocess(self, im):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue