Skip to content

Commit

Permalink
Added the final working version of the real-time demo for few-shot ad…
Browse files Browse the repository at this point in the history
…aptive gaze estimation for release.
  • Loading branch information
molchanovp committed Jan 6, 2020
1 parent 0f543a1 commit 7d34c1f
Show file tree
Hide file tree
Showing 13 changed files with 1,430 additions and 0 deletions.
39 changes: 39 additions & 0 deletions demo_final/KalmanFilter1D.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/usr/bin/env python3

# --------------------------------------------------------
# Copyright (C) 2020 NVIDIA Corporation. All rights reserved.
# NVIDIA Source Code License (1-Way Commercial)
# Code written by Pavlo Molchanov, Shalini De Mello.
# --------------------------------------------------------

import numpy as np

class Kalman1D(object):

def __init__(self, R=0.001**2, sz=100):
self.Q = 1e-5 # process variance
# allocate space for arrays
self.xhat = np.zeros(sz, dtype=complex) # a posteri estimate of x
self.P = np.zeros(sz, dtype=complex) # a posteri error estimate
self.xhatminus = np.zeros(sz, dtype=complex) # a priori estimate of x
self.Pminus = np.zeros(sz, dtype=complex) # a priori error estimate
self.K = np.zeros(sz, dtype=complex) # gain or blending factor
self.R = R # estimate of measurement variance, change to see effect
self.sz = sz
# intial guesses
self.xhat[0] = 0.0
self.P[0] = 1.0
self.k = 1

def update(self, val):
k = self.k % self.sz
km = (self.k-1) % self.sz
self.xhatminus[k] = self.xhat[km]
self.Pminus[k] = self.P[km] + self.Q

# measurement update
self.K[k] = self.Pminus[k]/( self.Pminus[k]+self.R )
self.xhat[k] = self.xhatminus[k]+self.K[k]*(val-self.xhatminus[k])
self.P[k] = (1-self.K[k])*self.Pminus[k]
self.k = self.k + 1
return self.xhat[k]
65 changes: 65 additions & 0 deletions demo_final/camera.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#!/usr/bin/env python3

# --------------------------------------------------------
# Copyright (C) 2020 NVIDIA Corporation. All rights reserved.
# NVIDIA Source Code License (1-Way Commercial)
# Code written by Shalini De Mello, Seonwook Park.
# --------------------------------------------------------

import cv2
import numpy as np
import pickle

def cam_calibrate(cam_idx, cap, cam_calib):

# termination criteria
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)

# prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
pts = np.zeros((6 * 9, 3), np.float32)
pts[:, :2] = np.mgrid[0:9, 0:6].T.reshape(-1, 2)

# capture calibration frames
obj_points = [] # 3d point in real world space
img_points = [] # 2d points in image plane.
frames = []
while True:
ret, frame = cap.read()

if ret:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
ret, corners = cv2.findChessboardCorners(gray, (9, 6), None)
if ret:
cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria)
# Draw and display the corners
frame_copy = frame.copy()
cv2.drawChessboardCorners(frame_copy, (9, 6), corners, ret)
cv2.imshow('points', frame_copy)

# s to save, c to continue, q to quit
if cv2.waitKey(0) & 0xFF == ord('s'):
img_points.append(corners)
obj_points.append(pts)
frames.append(frame)
elif cv2.waitKey(0) & 0xFF == ord('n'):
continue
elif cv2.waitKey(0) & 0xFF == ord('q'):
cv2.destroyAllWindows()
break

# compute calibration matrices
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(obj_points, img_points, frames[0].shape[0:2], None, None)

# check
error = 0.0
for i in range(len(frames)):
proj_imgpoints, _ = cv2.projectPoints(obj_points[i], rvecs[i], tvecs[i], mtx, dist)
error += (cv2.norm(img_points[i], proj_imgpoints, cv2.NORM_L2) / len(proj_imgpoints))
print("Camera calibrated successfully, total re-projection error: %f" % (error / len(frames)))

cam_calib['mtx'] = mtx
cam_calib['dist'] = dist
print("Camera parameters:")
print(cam_calib)

pickle.dump(cam_calib, open("calib_cam%d.pkl" % (cam_idx), "wb"))
48 changes: 48 additions & 0 deletions demo_final/face.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/usr/bin/env python3

# --------------------------------------------------------
# Copyright (C) 2020 NVIDIA Corporation. All rights reserved.
# NVIDIA Source Code License (1-Way Commercial)
# Code written by Seonwook Park, Shalini De Mello.
# --------------------------------------------------------

import sys
import cv2

sys.path.append("ext/mtcnn-pytorch/")
from src import detect_faces, show_bboxes
from PIL import Image

class face:

def detect(frame, scale = 1.0, use_max='SIZE'):

# detect face
frame_small = cv2.resize(frame, (0, 0), fx=scale, fy=scale)
frame_rgb = cv2.cvtColor(frame_small, cv2.COLOR_BGR2RGB)
pil_im = Image.fromarray(frame_rgb)
bounding_boxes, landmarks = detect_faces(pil_im, min_face_size=30.0)
dets = [x[:4] for x in bounding_boxes]
scores = [x[4] for x in bounding_boxes]

face_location = []
if len(dets) > 0:
max = 0
max_id = -1
for i, d in enumerate(dets):
if use_max == 'SCORE':
property = scores[i]
elif use_max == 'SIZE':
property = abs(dets[i][2] - dets[i][0]) * abs(dets[i][3] - dets[i][1])
if max < property:
max = property
max_id = i
if use_max == 'SCORE':
if max > -0.5:
face_location = dets[max_id]
else:
face_location = dets[max_id]
face_location = face_location * (1/scale)

return face_location

Loading

0 comments on commit 7d34c1f

Please sign in to comment.