Commit 8263bfd2 by vincent

face alignment example + align faces after face detection in face recognition…

face alignment example + align faces after face detection in face recognition with detection example
parent 93959e13
...@@ -101,6 +101,10 @@ function renderNavBar(navbarId, exampleUri) { ...@@ -101,6 +101,10 @@ function renderNavBar(navbarId, exampleUri) {
name: 'Detect and Draw Faces' name: 'Detect and Draw Faces'
}, },
{ {
uri: 'face_alignment',
name: 'Face Alignment'
},
{
uri: 'detect_and_recognize_faces', uri: 'detect_and_recognize_faces',
name: 'Detect and Recognize Faces' name: 'Detect and Recognize Faces'
} }
......
...@@ -18,6 +18,7 @@ app.get('/face_similarity', (req, res) => res.sendFile(path.join(viewsDir, 'face ...@@ -18,6 +18,7 @@ app.get('/face_similarity', (req, res) => res.sendFile(path.join(viewsDir, 'face
app.get('/face_landmarks', (req, res) => res.sendFile(path.join(viewsDir, 'faceLandmarks.html'))) app.get('/face_landmarks', (req, res) => res.sendFile(path.join(viewsDir, 'faceLandmarks.html')))
app.get('/detect_and_draw_faces', (req, res) => res.sendFile(path.join(viewsDir, 'detectAndDrawFaces.html'))) app.get('/detect_and_draw_faces', (req, res) => res.sendFile(path.join(viewsDir, 'detectAndDrawFaces.html')))
app.get('/detect_and_draw_landmarks', (req, res) => res.sendFile(path.join(viewsDir, 'detectAndDrawLandmarks.html'))) app.get('/detect_and_draw_landmarks', (req, res) => res.sendFile(path.join(viewsDir, 'detectAndDrawLandmarks.html')))
app.get('/face_alignment', (req, res) => res.sendFile(path.join(viewsDir, 'faceAlignment.html')))
app.get('/detect_and_recognize_faces', (req, res) => res.sendFile(path.join(viewsDir, 'detectAndRecognizeFaces.html'))) app.get('/detect_and_recognize_faces', (req, res) => res.sendFile(path.join(viewsDir, 'detectAndRecognizeFaces.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
...@@ -59,7 +59,7 @@ ...@@ -59,7 +59,7 @@
<script> <script>
let maxDistance = 0.8 let maxDistance = 0.8
let minConfidence = 0.7 let minConfidence = 0.7
let detectionNet, recognitionNet let detectionNet, recognitionNet, landmarkNet
let trainDescriptorsByClass = [] let trainDescriptorsByClass = []
function onIncreaseMinConfidence() { function onIncreaseMinConfidence() {
...@@ -95,16 +95,33 @@ ...@@ -95,16 +95,33 @@
const input = new faceapi.NetInput(inputImgEl) const input = new faceapi.NetInput(inputImgEl)
const detections = await detectionNet.locateFaces(input, minConfidence) const detections = await detectionNet.locateFaces(input, minConfidence)
const detectionsForSize = detections.map(det => det.forSize(width, height))
faceapi.drawDetection('overlay', detectionsForSize, { withScore: false })
const faceTensors = (await faceapi.extractFaceTensors(input, detections)) const faceTensors = (await faceapi.extractFaceTensors(input, detections))
const descriptors = await Promise.all(faceTensors.map(t => recognitionNet.computeFaceDescriptor(t)))
// detect landmarks and get the aligned face image bounding boxes
const alignedFaceBoxes = await Promise.all(faceTensors.map(
async (faceTensor, i) => {
const faceLandmarks = await landmarkNet.detectLandmarks(faceTensor)
return faceLandmarks.align(detections[i])
}
))
// free memory for face image tensors after we computed their descriptors // free memory for face image tensors after we computed their descriptors
faceTensors.forEach(t => t.dispose()) faceTensors.forEach(t => t.dispose())
const alignedFaceTensors = (await faceapi.extractFaceTensors(input, alignedFaceBoxes))
const descriptors = await Promise.all(alignedFaceTensors.map(
faceTensor => recognitionNet.computeFaceDescriptor(faceTensor)
))
// free memory for face image tensors after we computed their descriptors
alignedFaceTensors.forEach(t => t.dispose())
// draw detections
const detectionsForSize = detections.map(det => det.forSize(width, height))
faceapi.drawDetection('overlay', detectionsForSize, { withScore: false })
// draw the recognition results
descriptors.forEach((descriptor, i) => { descriptors.forEach((descriptor, i) => {
const bestMatch = getBestMatch(trainDescriptorsByClass, descriptor) const bestMatch = getBestMatch(trainDescriptorsByClass, descriptor)
const text = `${bestMatch.distance < maxDistance ? bestMatch.className : 'unkown'} (${bestMatch.distance})` const text = `${bestMatch.distance < maxDistance ? bestMatch.className : 'unkown'} (${bestMatch.distance})`
...@@ -128,6 +145,7 @@ ...@@ -128,6 +145,7 @@
async function run() { async function run() {
detectionNet = await initFaceDetectionNet() detectionNet = await initFaceDetectionNet()
recognitionNet = await initFaceRecognitionNet() recognitionNet = await initFaceRecognitionNet()
landmarkNet = await initFaceLandmarkNet()
trainDescriptorsByClass = await initTrainDescriptorsByClass(recognitionNet, 1) trainDescriptorsByClass = await initTrainDescriptorsByClass(recognitionNet, 1)
$('#loader').hide() $('#loader').hide()
onSelectionChanged($('#selectList select').val()) onSelectionChanged($('#selectList select').val())
......
<!DOCTYPE html>
<html>
<head>
<script src="face-api.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 id="navbar"></div>
<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 id="facesContainer"></div>
<div class="row side-by-side">
<div id="selectList"></div>
<div class="row">
<label for="minConfidence">Min Confidence:</label>
<input disabled value="0.7" 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>
</div>
<script>
let minConfidence = 0.7
let drawLines = true
let detectionNet, landmarkNet
function onIncreaseMinConfidence() {
minConfidence = Math.min(faceapi.round(minConfidence + 0.1), 1.0)
$('#minConfidence').val(minConfidence)
updateResults()
}
function onDecreaseMinConfidence() {
minConfidence = Math.max(faceapi.round(minConfidence - 0.1), 0.1)
$('#minConfidence').val(minConfidence)
updateResults()
}
async function updateResults() {
const inputImgEl = $('#inputImg').get(0)
const { width, height } = inputImgEl
const canvas = $('#overlay').get(0)
canvas.width = width
canvas.height = height
const input = new faceapi.NetInput(inputImgEl)
const locations = await detectionNet.locateFaces(input, minConfidence)
const faceImages = await faceapi.extractFaces(input.canvases[0], locations)
// detect landmarks and get the aligned face image bounding boxes
const alignedFaceBoxes = await Promise.all(faceImages.map(
async (faceCanvas, i) => {
const faceLandmarks = await landmarkNet.detectLandmarks(faceCanvas)
return faceLandmarks.align(locations[i])
}
))
const alignedFaceImages = await faceapi.extractFaces(input.canvases[0], alignedFaceBoxes)
$('#facesContainer').empty()
faceImages.forEach(async (faceCanvas, i) => {
$('#facesContainer').append(faceCanvas)
$('#facesContainer').append(alignedFaceImages[i])
})
}
async function onSelectionChanged(uri) {
const imgBuf = await fetchImage(uri)
$(`#inputImg`).get(0).src = (await faceapi.bufferToImage(imgBuf)).src
updateResults()
}
async function run() {
detectionNet = await initFaceDetectionNet()
landmarkNet = await initFaceLandmarkNet()
$('#loader').hide()
onSelectionChanged($('#selectList select').val())
}
$(document).ready(function() {
renderNavBar('#navbar', 'face_alignment')
renderImageSelectList(
'#selectList',
async (uri) => {
await onSelectionChanged(uri)
},
'bbt1.jpg'
)
run()
})
</script>
</body>
</html>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment