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
e908bbd8
Commit
e908bbd8
authored
Apr 27, 2019
by
vincent
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
init age gender example + some fixes
parent
7cbd7500
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
194 additions
and
6 deletions
+194
-6
commons.js
examples/examples-browser/public/js/commons.js
+4
-0
server.js
examples/examples-browser/server.js
+1
-0
ageAndGenderRecognition.html
examples/examples-browser/views/ageAndGenderRecognition.html
+183
-0
AgeGenderNet.ts
src/ageGenderNet/AgeGenderNet.ts
+6
-6
No files found.
examples/examples-browser/public/js/commons.js
View file @
e908bbd8
...
...
@@ -36,6 +36,10 @@ function renderNavBar(navbarId, exampleUri) {
uri
:
'face_expression_recognition'
,
name
:
'Face Expression Recognition'
},
{
uri
:
'age_and_gender_recognition'
,
name
:
'Age and Gender Recognition'
},
{
uri
:
'face_recognition'
,
name
:
'Face Recognition'
...
...
examples/examples-browser/server.js
View file @
e908bbd8
...
...
@@ -19,6 +19,7 @@ app.get('/', (req, res) => res.redirect('/face_detection'))
app
.
get
(
'/face_detection'
,
(
req
,
res
)
=>
res
.
sendFile
(
path
.
join
(
viewsDir
,
'faceDetection.html'
)))
app
.
get
(
'/face_landmark_detection'
,
(
req
,
res
)
=>
res
.
sendFile
(
path
.
join
(
viewsDir
,
'faceLandmarkDetection.html'
)))
app
.
get
(
'/face_expression_recognition'
,
(
req
,
res
)
=>
res
.
sendFile
(
path
.
join
(
viewsDir
,
'faceExpressionRecognition.html'
)))
app
.
get
(
'/age_and_gender_recognition'
,
(
req
,
res
)
=>
res
.
sendFile
(
path
.
join
(
viewsDir
,
'ageAndGenderRecognition.html'
)))
app
.
get
(
'/face_extraction'
,
(
req
,
res
)
=>
res
.
sendFile
(
path
.
join
(
viewsDir
,
'faceExtraction.html'
)))
app
.
get
(
'/face_recognition'
,
(
req
,
res
)
=>
res
.
sendFile
(
path
.
join
(
viewsDir
,
'faceRecognition.html'
)))
app
.
get
(
'/video_face_tracking'
,
(
req
,
res
)
=>
res
.
sendFile
(
path
.
join
(
viewsDir
,
'videoFaceTracking.html'
)))
...
...
examples/examples-browser/views/ageAndGenderRecognition.html
0 → 100644
View file @
e908bbd8
<!DOCTYPE html>
<html>
<head>
<script
src=
"face-api.js"
></script>
<script
src=
"js/commons.js"
></script>
<script
src=
"js/drawing.js"
></script>
<script
src=
"js/faceDetectionControls.js"
></script>
<script
src=
"js/imageSelectionControls.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"
>
<img
id=
"inputImg"
src=
""
style=
"max-width: 800px;"
/>
<canvas
id=
"overlay"
/>
</div>
<div
class=
"row side-by-side"
>
<!-- image_selection_control -->
<div
id=
"selectList"
></div>
<div
class=
"row"
>
<label
for=
"imgUrlInput"
>
Get image from URL:
</label>
<input
id=
"imgUrlInput"
type=
"text"
class=
"bold"
>
</div>
<button
class=
"waves-effect waves-light btn"
onclick=
"loadImageFromUrl()"
>
Ok
</button>
<!-- image_selection_control -->
</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 -->
</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=
"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>
window
.
net
=
new
faceapi
.
AgeGenderNet
()
async
function
updateResults
()
{
if
(
!
isFaceDetectionModelLoaded
())
{
return
}
const
inputImgEl
=
$
(
'#inputImg'
).
get
(
0
)
const
options
=
getFaceDetectorOptions
()
const
result
=
await
faceapi
.
detectSingleFace
(
inputImgEl
,
options
)
if
(
!
result
)
return
const
face
=
(
await
faceapi
.
extractFaces
(
inputImgEl
,
[
result
]))[
0
]
const
{
age
,
gender
,
genderProbability
}
=
await
window
.
net
.
predictAgeAndGender
(
face
)
console
.
log
(
'age'
,
age
)
console
.
log
(
'gender'
,
gender
,
genderProbability
)
}
async
function
run
()
{
// load face detection and face expression recognition models
await
changeFaceDetector
(
SSD_MOBILENETV1
)
const
weights
=
await
faceapi
.
fetchNetWeights
(
'tmp/age_gender.weights'
)
console
.
log
(
weights
.
length
)
await
window
.
net
.
load
(
weights
)
// start processing image
updateResults
()
}
$
(
document
).
ready
(
function
()
{
renderNavBar
(
'#navbar'
,
'age_and_gender_recognition'
)
initImageSelectionControls
(
'happy.jpg'
,
true
)
initFaceDetectionControls
()
run
()
})
</script>
</body>
</html>
\ No newline at end of file
src/ageGenderNet/AgeGenderNet.ts
View file @
e908bbd8
...
...
@@ -34,9 +34,9 @@ export class AgeGenderNet extends NeuralNetwork<NetParams> {
?
this
.
faceFeatureExtractor
.
forwardInput
(
input
)
:
input
const
bottleneckFeatures2d
=
bottleneckFeatures
.
as2D
(
bottleneckFeatures
.
shape
[
0
],
-
1
)
const
age
=
fullyConnectedLayer
(
bottleneckFeatures2
d
,
params
.
fc
.
age
).
as1D
()
const
gender
=
fullyConnectedLayer
(
bottleneckFeatures2
d
,
params
.
fc
.
gender
)
const
pooled
=
tf
.
avgPool
(
bottleneckFeatures
,
[
7
,
7
],
[
2
,
2
],
'valid'
)
.
as2D
(
bottleneckFeatures
.
shape
[
0
],
-
1
)
const
age
=
fullyConnectedLayer
(
poole
d
,
params
.
fc
.
age
).
as1D
()
const
gender
=
fullyConnectedLayer
(
poole
d
,
params
.
fc
.
gender
)
return
{
age
,
gender
}
})
}
...
...
@@ -53,8 +53,8 @@ export class AgeGenderNet extends NeuralNetwork<NetParams> {
public
async
predictAgeAndGender
(
input
:
TNetInput
):
Promise
<
{
age
:
number
,
gender
:
string
,
genderProbability
:
number
}
>
{
const
netInput
=
await
toNetInput
(
input
)
const
out
=
await
this
.
forwardInput
(
netInput
)
const
age
=
await
out
.
age
.
data
()[
0
]
as
number
const
probMale
=
await
out
.
gender
.
data
()[
0
]
as
number
const
age
=
(
await
out
.
age
.
data
())[
0
]
const
probMale
=
(
await
out
.
gender
.
data
())[
0
]
const
isMale
=
probMale
>
0.5
const
gender
=
isMale
?
'male'
:
'female'
...
...
@@ -93,7 +93,7 @@ export class AgeGenderNet extends NeuralNetwork<NetParams> {
protected
extractParams
(
weights
:
Float32Array
)
{
const
classifierWeightSize
=
(
512
*
1
)
+
(
512
*
2
)
const
classifierWeightSize
=
(
512
*
1
+
1
)
+
(
512
*
2
+
2
)
const
featureExtractorWeights
=
weights
.
slice
(
0
,
weights
.
length
-
classifierWeightSize
)
const
classifierWeights
=
weights
.
slice
(
weights
.
length
-
classifierWeightSize
)
...
...
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