Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
F
face-api.js
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
allan
face-api.js
Commits
907ca4b7
Commit
907ca4b7
authored
May 07, 2019
by
vincent
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'age-gender' of
https://github.com/justadudewhohacks/face-api.js
into age-gender
parents
d2056b0c
aecac6c7
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
232 additions
and
0 deletions
+232
-0
commons.js
examples/examples-browser/public/js/commons.js
+4
-0
server.js
examples/examples-browser/server.js
+1
-0
webcamAgeAndGenderRecognition.html
...examples-browser/views/webcamAgeAndGenderRecognition.html
+227
-0
No files found.
examples/examples-browser/public/js/commons.js
View file @
907ca4b7
...
...
@@ -64,6 +64,10 @@ function renderNavBar(navbarId, exampleUri) {
uri
:
'webcam_face_expression_recognition'
,
name
:
'Webcam Face Expression Recognition'
},
{
uri
:
'webcam_age_and_gender_recognition'
,
name
:
'Webcam Age and Gender Recognition'
},
{
uri
:
'bbt_face_landmark_detection'
,
name
:
'BBT Face Landmark Detection'
...
...
examples/examples-browser/server.js
View file @
907ca4b7
...
...
@@ -26,6 +26,7 @@ app.get('/video_face_tracking', (req, res) => res.sendFile(path.join(viewsDir, '
app
.
get
(
'/webcam_face_detection'
,
(
req
,
res
)
=>
res
.
sendFile
(
path
.
join
(
viewsDir
,
'webcamFaceDetection.html'
)))
app
.
get
(
'/webcam_face_landmark_detection'
,
(
req
,
res
)
=>
res
.
sendFile
(
path
.
join
(
viewsDir
,
'webcamFaceLandmarkDetection.html'
)))
app
.
get
(
'/webcam_face_expression_recognition'
,
(
req
,
res
)
=>
res
.
sendFile
(
path
.
join
(
viewsDir
,
'webcamFaceExpressionRecognition.html'
)))
app
.
get
(
'/webcam_age_and_gender_recognition'
,
(
req
,
res
)
=>
res
.
sendFile
(
path
.
join
(
viewsDir
,
'webcamAgeAndGenderRecognition.html'
)))
app
.
get
(
'/bbt_face_landmark_detection'
,
(
req
,
res
)
=>
res
.
sendFile
(
path
.
join
(
viewsDir
,
'bbtFaceLandmarkDetection.html'
)))
app
.
get
(
'/bbt_face_similarity'
,
(
req
,
res
)
=>
res
.
sendFile
(
path
.
join
(
viewsDir
,
'bbtFaceSimilarity.html'
)))
app
.
get
(
'/bbt_face_matching'
,
(
req
,
res
)
=>
res
.
sendFile
(
path
.
join
(
viewsDir
,
'bbtFaceMatching.html'
)))
...
...
examples/examples-browser/views/webcamAgeAndGenderRecognition.html
0 → 100644
View file @
907ca4b7
<!DOCTYPE html>
<html>
<head>
<script
src=
"face-api.js"
></script>
<script
src=
"js/commons.js"
></script>
<script
src=
"js/faceDetectionControls.js"
></script>
<link
rel=
"stylesheet"
href=
"styles.css"
>
<link
rel=
"stylesheet"
href=
"https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/css/materialize.css"
>
<script
type=
"text/javascript"
src=
"https://code.jquery.com/jquery-2.1.1.min.js"
></script>
<script
src=
"https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"
></script>
</head>
<body>
<div
id=
"navbar"
></div>
<div
class=
"center-content page-container"
>
<div
class=
"progress"
id=
"loader"
>
<div
class=
"indeterminate"
></div>
</div>
<div
style=
"position: relative"
class=
"margin"
>
<video
onloadedmetadata=
"onPlay(this)"
id=
"inputVideo"
autoplay
muted
></video>
<canvas
id=
"overlay"
/>
</div>
<div
class=
"row side-by-side"
>
<!-- face_detector_selection_control -->
<div
id=
"face_detector_selection_control"
class=
"row input-field"
style=
"margin-right: 20px;"
>
<select
id=
"selectFaceDetector"
>
<option
value=
"ssd_mobilenetv1"
>
SSD Mobilenet V1
</option>
<option
value=
"tiny_face_detector"
>
Tiny Face Detector
</option>
<option
value=
"mtcnn"
>
MTCNN
</option>
</select>
<label>
Select Face Detector
</label>
</div>
<!-- face_detector_selection_control -->
<!-- check boxes -->
<div
class=
"row"
style=
"width: 220px;"
>
<input
type=
"checkbox"
id=
"hideBoundingBoxesCheckbox"
onchange=
"onChangeHideBoundingBoxes(event)"
/>
<label
for=
"hideBoundingBoxesCheckbox"
>
Hide Bounding Boxes
</label>
</div>
<!-- check boxes -->
<!-- fps_meter -->
<div
id=
"fps_meter"
class=
"row side-by-side"
>
<div>
<label
for=
"time"
>
Time:
</label>
<input
disabled
value=
"-"
id=
"time"
type=
"text"
class=
"bold"
>
<label
for=
"fps"
>
Estimated Fps:
</label>
<input
disabled
value=
"-"
id=
"fps"
type=
"text"
class=
"bold"
>
</div>
</div>
<!-- fps_meter -->
</div>
<!-- ssd_mobilenetv1_controls -->
<span
id=
"ssd_mobilenetv1_controls"
>
<div
class=
"row side-by-side"
>
<div
class=
"row"
>
<label
for=
"minConfidence"
>
Min Confidence:
</label>
<input
disabled
value=
"0.5"
id=
"minConfidence"
type=
"text"
class=
"bold"
>
</div>
<button
class=
"waves-effect waves-light btn"
onclick=
"onDecreaseMinConfidence()"
>
<i
class=
"material-icons left"
>
-
</i>
</button>
<button
class=
"waves-effect waves-light btn"
onclick=
"onIncreaseMinConfidence()"
>
<i
class=
"material-icons left"
>
+
</i>
</button>
</div>
</span>
<!-- ssd_mobilenetv1_controls -->
<!-- tiny_face_detector_controls -->
<span
id=
"tiny_face_detector_controls"
>
<div
class=
"row side-by-side"
>
<div
class=
"row input-field"
style=
"margin-right: 20px;"
>
<select
id=
"inputSize"
>
<option
value=
""
disabled
selected
>
Input Size:
</option>
<option
value=
"128"
>
128 x 128
</option>
<option
value=
"160"
>
160 x 160
</option>
<option
value=
"224"
>
224 x 224
</option>
<option
value=
"320"
>
320 x 320
</option>
<option
value=
"416"
>
416 x 416
</option>
<option
value=
"512"
>
512 x 512
</option>
<option
value=
"608"
>
608 x 608
</option>
</select>
<label>
Input Size
</label>
</div>
<div
class=
"row"
>
<label
for=
"scoreThreshold"
>
Score Threshold:
</label>
<input
disabled
value=
"0.5"
id=
"scoreThreshold"
type=
"text"
class=
"bold"
>
</div>
<button
class=
"waves-effect waves-light btn"
onclick=
"onDecreaseScoreThreshold()"
>
<i
class=
"material-icons left"
>
-
</i>
</button>
<button
class=
"waves-effect waves-light btn"
onclick=
"onIncreaseScoreThreshold()"
>
<i
class=
"material-icons left"
>
+
</i>
</button>
</div>
</span>
<!-- tiny_face_detector_controls -->
<!-- mtcnn_controls -->
<span
id=
"mtcnn_controls"
>
<div
class=
"row side-by-side"
>
<div
class=
"row"
>
<label
for=
"minFaceSize"
>
Minimum Face Size:
</label>
<input
disabled
value=
"20"
id=
"minFaceSize"
type=
"text"
class=
"bold"
>
</div>
<button
class=
"waves-effect waves-light btn"
onclick=
"onDecreaseMinFaceSize()"
>
<i
class=
"material-icons left"
>
-
</i>
</button>
<button
class=
"waves-effect waves-light btn"
onclick=
"onIncreaseMinFaceSize()"
>
<i
class=
"material-icons left"
>
+
</i>
</button>
</div>
</span>
<!-- mtcnn_controls -->
</body>
<script>
let
forwardTimes
=
[]
let
predictedAges
=
[]
let
withBoxes
=
true
function
onChangeHideBoundingBoxes
(
e
)
{
withBoxes
=
!
$
(
e
.
target
).
prop
(
'checked'
)
}
function
updateTimeStats
(
timeInMs
)
{
forwardTimes
=
[
timeInMs
].
concat
(
forwardTimes
).
slice
(
0
,
30
)
const
avgTimeInMs
=
forwardTimes
.
reduce
((
total
,
t
)
=>
total
+
t
)
/
forwardTimes
.
length
$
(
'#time'
).
val
(
`
${
Math
.
round
(
avgTimeInMs
)}
ms`
)
$
(
'#fps'
).
val
(
`
${
faceapi
.
round
(
1000
/
avgTimeInMs
)}
`
)
}
function
interpolateAgePredictions
(
age
)
{
predictedAges
=
[
age
].
concat
(
predictedAges
).
slice
(
0
,
30
)
const
avgPredictedAge
=
predictedAges
.
reduce
((
total
,
a
)
=>
total
+
a
)
/
predictedAges
.
length
return
avgPredictedAge
}
async
function
onPlay
()
{
const
videoEl
=
$
(
'#inputVideo'
).
get
(
0
)
if
(
videoEl
.
paused
||
videoEl
.
ended
||
!
isFaceDetectionModelLoaded
())
return
setTimeout
(()
=>
onPlay
())
const
options
=
getFaceDetectorOptions
()
const
ts
=
Date
.
now
()
const
result
=
await
faceapi
.
detectSingleFace
(
videoEl
,
options
)
.
withAgeAndGender
()
updateTimeStats
(
Date
.
now
()
-
ts
)
if
(
result
)
{
const
canvas
=
$
(
'#overlay'
).
get
(
0
)
const
dims
=
faceapi
.
matchDimensions
(
canvas
,
videoEl
,
true
)
const
resizedResult
=
faceapi
.
resizeResults
(
result
,
dims
)
if
(
withBoxes
)
{
faceapi
.
draw
.
drawDetections
(
canvas
,
resizedResult
)
}
const
{
age
,
gender
,
genderProbability
}
=
resizedResult
// interpolate gender predictions over last 30 frames
// to make the displayed age more stable
const
interpolatedAge
=
interpolateAgePredictions
(
age
)
new
faceapi
.
draw
.
DrawTextField
(
[
`
${
faceapi
.
round
(
interpolatedAge
,
0
)}
years`
,
`
${
gender
}
(
${
faceapi
.
round
(
genderProbability
)}
)`
],
result
.
detection
.
box
.
bottomLeft
).
draw
(
canvas
)
}
setTimeout
(()
=>
onPlay
())
}
async
function
run
()
{
// load face detection and face expression recognition models
await
changeFaceDetector
(
TINY_FACE_DETECTOR
)
await
faceapi
.
nets
.
ageGenderNet
.
load
(
'/'
)
changeInputSize
(
224
)
// try to access users webcam and stream the images
// to the video element
const
stream
=
await
navigator
.
mediaDevices
.
getUserMedia
({
video
:
{}
})
const
videoEl
=
$
(
'#inputVideo'
).
get
(
0
)
videoEl
.
srcObject
=
stream
}
function
updateResults
()
{}
$
(
document
).
ready
(
function
()
{
renderNavBar
(
'#navbar'
,
'webcam_age_and_gender_recognition'
)
initFaceDetectionControls
()
run
()
})
</script>
</body>
</html>
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment