Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
F
face
Project
Overview
Details
Activity
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
Иван Кубота
face
Commits
f0d19464
Commit
f0d19464
authored
May 21, 2018
by
vincent
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
face similarity example
parent
5d99dc01
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
247 additions
and
84 deletions
+247
-84
commons.js
examples/faceRecognition/public/commons.js
+49
-0
styles.css
examples/faceRecognition/public/styles.css
+34
-0
server.js
examples/faceRecognition/server.js
+7
-2
faceRecognition.html
examples/faceRecognition/views/faceRecognition.html
+29
-82
faceSimilarity.html
examples/faceRecognition/views/faceSimilarity.html
+128
-0
No files found.
examples/faceRecognition/public/commons.js
0 → 100644
View file @
f0d19464
const
classes
=
[
'amy'
,
'bernadette'
,
'howard'
,
'leonard'
,
'penny'
,
'raj'
,
'sheldon'
,
'stuart'
]
function
getImageUri
(
className
,
idx
)
{
return
`/
${
className
}
/
${
className
}${
idx
}
.png`
}
async
function
initNet
()
{
const
res
=
await
axios
.
get
(
'face_recognition_model.weights'
,
{
responseType
:
'arraybuffer'
})
const
weights
=
new
Float32Array
(
res
.
data
)
return
facerecognition
.
faceRecognitionNet
(
weights
)
}
function
bufferToImgSrc
(
buf
)
{
return
new
Promise
((
resolve
,
reject
)
=>
{
const
reader
=
new
window
.
FileReader
()
reader
.
onload
=
()
=>
resolve
(
reader
.
result
)
reader
.
onerror
=
reject
reader
.
readAsDataURL
(
buf
)
})
}
function
imgSrcToData
(
src
)
{
return
new
Promise
((
resolve
,
reject
)
=>
{
const
canvas
=
document
.
createElement
(
'canvas'
)
canvas
.
width
=
150
canvas
.
height
=
150
const
ctx
=
canvas
.
getContext
(
'2d'
)
const
img
=
new
Image
()
img
.
onload
=
function
()
{
ctx
.
drawImage
(
img
,
0
,
0
)
resolve
(
ctx
.
getImageData
(
0
,
0
,
150
,
150
))
}
img
.
onerror
=
reject
img
.
src
=
src
})
}
async
function
bufferToImageData
(
buf
)
{
return
imgSrcToData
(
await
bufferToImgSrc
(
buf
))
}
async
function
fetchImage
(
uri
)
{
return
(
await
axios
.
get
(
uri
,
{
responseType
:
'blob'
})).
data
}
function
round
(
num
)
{
return
Math
.
floor
(
num
*
100
)
/
100
}
\ No newline at end of file
examples/faceRecognition/public/styles.css
0 → 100644
View file @
f0d19464
.page-container
{
position
:
fixed
;
left
:
0
;
right
:
0
;
margin
:
auto
;
margin-top
:
20px
;
}
.center-content
{
display
:
flex
;
flex-direction
:
column
;
justify-content
:
center
;
align-items
:
center
;
}
.side-by-side
{
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
}
.bold
{
font-weight
:
bold
;
}
.margin
{
margin
:
20px
;
}
img
{
width
:
150px
;
height
:
150px
;
}
\ No newline at end of file
examples/faceRecognition/server.js
View file @
f0d19464
...
@@ -3,12 +3,16 @@ const path = require('path')
...
@@ -3,12 +3,16 @@ const path = require('path')
const
app
=
express
()
const
app
=
express
()
const
viewsDir
=
path
.
join
(
__dirname
,
'views'
)
app
.
use
(
express
.
static
(
path
.
join
(
__dirname
,
'../images'
)))
app
.
use
(
express
.
static
(
path
.
join
(
__dirname
,
'../images'
)))
app
.
use
(
express
.
static
(
path
.
join
(
__dirname
,
'../../weights'
)))
app
.
use
(
express
.
static
(
path
.
join
(
__dirname
,
'../../weights'
)))
app
.
use
(
express
.
static
(
path
.
join
(
__dirname
,
'../../dist'
)))
app
.
use
(
express
.
static
(
path
.
join
(
__dirname
,
'../../dist'
)))
app
.
use
(
express
.
static
(
path
.
join
(
__dirname
,
'./node_modules/axios/dist'
)))
app
.
use
(
express
.
static
(
path
.
join
(
__dirname
,
'./node_modules/axios/dist'
)))
app
.
use
(
express
.
static
(
path
.
join
(
__dirname
,
'views'
)))
app
.
use
(
express
.
static
(
viewsDir
))
app
.
use
(
express
.
static
(
path
.
join
(
__dirname
,
'./public'
)))
app
.
get
(
'/'
,
(
req
,
res
)
=>
res
.
sendFile
(
'./index.html'
))
app
.
get
(
'/'
,
(
req
,
res
)
=>
res
.
redirect
(
'/faceRecognition'
))
app
.
get
(
'/faceRecognition'
,
(
req
,
res
)
=>
res
.
sendFile
(
path
.
join
(
viewsDir
,
'faceRecognition.html'
)))
app
.
get
(
'/faceSimilarity'
,
(
req
,
res
)
=>
res
.
sendFile
(
path
.
join
(
viewsDir
,
'faceSimilarity.html'
)))
app
.
listen
(
3000
,
()
=>
console
.
log
(
'Listening on port 3000!'
))
app
.
listen
(
3000
,
()
=>
console
.
log
(
'Listening on port 3000!'
))
\ No newline at end of file
examples/faceRecognition/views/
index
.html
→
examples/faceRecognition/views/
faceRecognition
.html
View file @
f0d19464
...
@@ -3,25 +3,28 @@
...
@@ -3,25 +3,28 @@
<head>
<head>
<script
src=
"face-recognition.min.js"
></script>
<script
src=
"face-recognition.min.js"
></script>
<script
src=
"axios.min.js"
></script>
<script
src=
"axios.min.js"
></script>
<link
rel=
"stylesheet"
href=
"https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-beta/css/materialize.min.css"
>
<script
src=
"commons.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>
</head>
<style>
.center-content
{
display
:
flex
;
flex-direction
:
column
;
justify-content
:
center
;
align-items
:
center
;
}
.bold
{
font-weight
:
bold
;
}
</style>
<body>
<body>
<div
class=
"center-content col s12"
>
<div
class=
"center-content page-container"
>
<div
class=
"row"
>
<a
class=
"waves-effect waves-light btn"
href=
"faceSimilarity.html"
>
Go To Face Similarity Example
</a>
</div>
<div>
<div>
<div
class=
"row center-content"
>
<div
class=
"row center-content"
id=
"loader"
>
<input
disabled
value=
""
id=
"status"
type=
"text"
class=
"bold"
>
<input
disabled
value=
""
id=
"status"
type=
"text"
class=
"bold"
>
<div
class=
"progress"
>
<div
class=
"indeterminate"
></div>
</div>
</div>
</div>
<div
class=
"row center-content"
>
<div
class=
"row center-content"
>
<img
id=
"face"
src=
""
/>
<img
id=
"face"
src=
""
/>
...
@@ -67,7 +70,6 @@
...
@@ -67,7 +70,6 @@
</div>
</div>
<script>
<script>
const
classes
=
[
'amy'
,
'bernadette'
,
'howard'
,
'leonard'
,
'penny'
,
'raj'
,
'sheldon'
,
'stuart'
]
// for 150 x 150 sized face images 0.6 is a good threshold to
// for 150 x 150 sized face images 0.6 is a good threshold to
// judge whether two face descriptors are similar or not
// judge whether two face descriptors are similar or not
const
threshold
=
0.6
const
threshold
=
0.6
...
@@ -81,12 +83,12 @@
...
@@ -81,12 +83,12 @@
function
onSlower
()
{
function
onSlower
()
{
interval
=
Math
.
max
(
interval
+
100
,
0
)
interval
=
Math
.
max
(
interval
+
100
,
0
)
document
.
getElementById
(
'interval'
).
value
=
interval
$
(
'#interval'
).
val
(
interval
)
}
}
function
onFaster
()
{
function
onFaster
()
{
interval
=
Math
.
min
(
interval
-
100
,
2000
)
interval
=
Math
.
min
(
interval
-
100
,
2000
)
document
.
getElementById
(
'interval'
).
value
=
interval
$
(
'#interval'
).
val
(
interval
)
}
}
function
onToggleStop
()
{
function
onToggleStop
()
{
...
@@ -99,74 +101,19 @@
...
@@ -99,74 +101,19 @@
}
}
}
}
function
round
(
num
)
{
return
Math
.
floor
(
num
*
100
)
/
100
}
function
getImageUri
(
className
,
idx
)
{
return
`/
${
className
}
/
${
className
}${
idx
}
.png`
}
function
setStatusText
(
text
)
{
function
setStatusText
(
text
)
{
document
.
getElementById
(
'status'
).
value
=
text
$
(
'#status'
).
val
(
text
)
}
function
setPrediction
(
result
)
{
document
.
getElementById
(
'prediction'
).
value
=
result
}
}
function
displayTimeStats
(
timeInMs
)
{
function
displayTimeStats
(
timeInMs
)
{
document
.
getElementById
(
'time'
).
value
=
`
${
timeInMs
}
ms`
$
(
'#time'
).
val
(
`
${
timeInMs
}
ms`
)
document
.
getElementById
(
'fps'
).
value
=
`
${
round
(
1000
/
timeInMs
)}
`
$
(
'#fps'
).
val
(
`
${
round
(
1000
/
timeInMs
)}
`
)
}
function
getImg
()
{
return
document
.
getElementById
(
'face'
)
}
}
function
displayImage
(
src
)
{
function
displayImage
(
src
)
{
getImg
().
src
=
src
getImg
().
src
=
src
}
}
function
bufferToImgSrc
(
buf
)
{
return
new
Promise
((
resolve
,
reject
)
=>
{
const
reader
=
new
window
.
FileReader
()
reader
.
onload
=
()
=>
resolve
(
reader
.
result
)
reader
.
onerror
=
reject
reader
.
readAsDataURL
(
buf
)
})
}
function
imgSrcToData
(
src
)
{
return
new
Promise
((
resolve
,
reject
)
=>
{
const
canvas
=
document
.
createElement
(
'canvas'
)
canvas
.
width
=
150
canvas
.
height
=
150
const
ctx
=
canvas
.
getContext
(
'2d'
)
const
img
=
new
Image
()
img
.
onload
=
function
()
{
ctx
.
drawImage
(
img
,
0
,
0
)
resolve
(
ctx
.
getImageData
(
0
,
0
,
150
,
150
))
}
img
.
onerror
=
reject
img
.
src
=
src
})
}
async
function
bufferToImageData
(
buf
)
{
return
imgSrcToData
(
await
bufferToImgSrc
(
buf
))
}
async
function
fetchModelWeights
()
{
const
res
=
await
axios
.
get
(
'face_recognition_model.weights'
,
{
responseType
:
'arraybuffer'
})
return
new
Float32Array
(
res
.
data
)
}
async
function
fetchImage
(
uri
)
{
return
(
await
axios
.
get
(
uri
,
{
responseType
:
'blob'
})).
data
}
async
function
loadTrainingData
(
cb
)
{
async
function
loadTrainingData
(
cb
)
{
return
await
Promise
.
all
(
classes
.
map
(
return
await
Promise
.
all
(
classes
.
map
(
async
className
=>
({
async
className
=>
({
...
@@ -192,9 +139,10 @@
...
@@ -192,9 +139,10 @@
async
function
runFaceRecognition
()
{
async
function
runFaceRecognition
()
{
async
function
next
()
{
async
function
next
()
{
const
imgBuf
=
await
fetchImage
(
getImageUri
(
classes
[
currClassIdx
],
currImageIdx
))
const
imgBuf
=
await
fetchImage
(
getImageUri
(
classes
[
currClassIdx
],
currImageIdx
))
displayImage
(
await
bufferToImgSrc
(
imgBuf
))
const
imgEl
=
$
(
'#face'
).
get
(
0
)
imgEl
.
src
=
await
bufferToImgSrc
(
imgBuf
)
const
imageData
=
await
imgSrcToData
(
getImg
()
.
src
)
const
imageData
=
await
imgSrcToData
(
imgEl
.
src
)
const
ts
=
Date
.
now
()
const
ts
=
Date
.
now
()
const
result
=
await
net
.
forward
(
imageData
)
const
result
=
await
net
.
forward
(
imageData
)
...
@@ -202,7 +150,7 @@
...
@@ -202,7 +150,7 @@
const
descriptor
=
await
result
.
data
()
const
descriptor
=
await
result
.
data
()
const
bestMatch
=
getBestMatch
(
descriptor
)
const
bestMatch
=
getBestMatch
(
descriptor
)
setPrediction
(
`
${
bestMatch
.
distance
<
threshold
?
bestMatch
.
className
:
'unkown'
}
(
${
bestMatch
.
distance
}
)`
)
$
(
'#prediction'
).
val
(
`
${
bestMatch
.
distance
<
threshold
?
bestMatch
.
className
:
'unkown'
}
(
${
bestMatch
.
distance
}
)`
)
currImageIdx
=
currClassIdx
===
(
classes
.
length
-
1
)
currImageIdx
=
currClassIdx
===
(
classes
.
length
-
1
)
?
currImageIdx
+
1
?
currImageIdx
+
1
...
@@ -219,8 +167,7 @@
...
@@ -219,8 +167,7 @@
try
{
try
{
setStatusText
(
'loading model file...'
)
setStatusText
(
'loading model file...'
)
const
weights
=
await
fetchModelWeights
()
net
=
await
initNet
()
net
=
facerecognition
.
faceRecognitionNet
(
weights
)
setStatusText
(
'computing initial descriptors...'
)
setStatusText
(
'computing initial descriptors...'
)
const
trainImgDatas
=
await
loadTrainingData
()
const
trainImgDatas
=
await
loadTrainingData
()
...
@@ -230,8 +177,8 @@
...
@@ -230,8 +177,8 @@
className
className
})
})
))
))
$
(
'#loader'
).
hide
()
setStatusText
(
'running face recognition:'
)
runFaceRecognition
()
runFaceRecognition
()
}
catch
(
err
)
{
}
catch
(
err
)
{
console
.
error
(
err
)
console
.
error
(
err
)
...
...
examples/faceRecognition/views/faceSimilarity.html
0 → 100644
View file @
f0d19464
<!DOCTYPE html>
<html>
<head>
<script
src=
"face-recognition.min.js"
></script>
<script
src=
"axios.min.js"
></script>
<script
src=
"commons.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
class=
"center-content page-container"
>
<div
class=
"row"
>
<a
class=
"waves-effect waves-light btn"
href=
"faceRecognition"
>
Go To Face Recognition Example
</a>
</div>
<div>
<div
class=
"progress"
id=
"loader"
>
<div
class=
"indeterminate"
></div>
</div>
<div
class=
"row side-by-side"
>
<div
class=
"center-content"
>
<img
id=
"face1"
src=
""
class=
"margin"
/>
<div
id=
"selectList1"
class=
"input-field"
></div>
</div>
<div
class=
"center-content"
>
<img
id=
"face2"
src=
""
class=
"margin"
/>
<div
id=
"selectList2"
class=
"input-field"
></div>
</div>
</div>
<div
class=
"row"
>
<label
for=
"distance"
>
Distance:
</label>
<input
disabled
value=
"-"
id=
"distance"
type=
"text"
class=
"bold"
>
</div>
</div>
</div>
<script>
const
threshold
=
0.6
let
net
,
descriptors
=
{
desc1
:
null
,
desc2
:
null
}
function
renderSelectList
(
parent
)
{
const
select
=
document
.
createElement
(
'select'
)
parent
.
appendChild
(
select
)
classes
.
forEach
((
className
)
=>
{
const
optgroup
=
document
.
createElement
(
'optgroup'
)
optgroup
.
label
=
className
select
.
appendChild
(
optgroup
)
const
indices
=
[
1
,
2
,
3
,
4
,
5
]
indices
.
forEach
((
imageIdx
)
=>
{
const
option
=
document
.
createElement
(
'option'
)
option
.
innerHTML
=
`
${
className
}
${
imageIdx
}
`
option
.
value
=
getImageUri
(
className
,
imageIdx
)
optgroup
.
appendChild
(
option
)
})
})
}
function
updateResult
()
{
const
distance
=
round
(
facerecognition
.
euclideanDistance
(
descriptors
.
desc1
,
descriptors
.
desc2
))
let
text
=
distance
let
bgColor
=
'#ffffff'
if
(
distance
>
threshold
)
{
text
+=
' (no match)'
bgColor
=
'#ce7575'
}
$
(
'#distance'
).
val
(
text
)
$
(
'#distance'
).
css
(
'background-color'
,
bgColor
)
}
async
function
computeDescriptorFromSrc
(
imgEl
)
{
return
net
.
computeFaceDescriptor
(
await
imgSrcToData
(
imgEl
.
src
))
}
async
function
onSelectionChanged
(
which
)
{
const
selectElSelector
=
`#selectList
${
which
}
select`
const
imgElSelector
=
`#face
${
which
}
`
const
whichDesc
=
`desc
${
which
}
`
const
uri
=
$
(
selectElSelector
).
val
()
const
imgEl
=
$
(
imgElSelector
).
get
(
0
)
const
imgBuf
=
await
fetchImage
(
uri
)
imgEl
.
src
=
await
bufferToImgSrc
(
imgBuf
)
descriptors
[
whichDesc
]
=
await
computeDescriptorFromSrc
(
$
(
imgElSelector
).
get
(
0
))
}
async
function
run
()
{
$
(
'#selectList1 select'
).
val
(
getImageUri
(
'sheldon'
,
1
))
$
(
'#selectList1 select'
).
material_select
()
$
(
'#selectList2 select'
).
val
(
getImageUri
(
'howard'
,
1
))
$
(
'#selectList2 select'
).
material_select
()
net
=
await
initNet
()
$
(
'#loader'
).
hide
()
await
onSelectionChanged
(
1
)
await
onSelectionChanged
(
2
)
updateResult
()
}
$
(
document
).
ready
(
function
()
{
renderSelectList
(
$
(
'#selectList1'
).
get
(
0
))
renderSelectList
(
$
(
'#selectList2'
).
get
(
0
))
$
(
'select'
).
material_select
()
$
(
'#selectList1 select'
).
on
(
'change'
,
async
()
=>
{
await
onSelectionChanged
(
1
)
updateResult
()
})
$
(
'#selectList2 select'
).
on
(
'change'
,
async
()
=>
{
await
onSelectionChanged
(
2
)
updateResult
()
})
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