Commit 16b7dc6c by vincent

implement drawFaceExpressions helper and use them in examples + nodejs face…

implement drawFaceExpressions helper and use them in examples + nodejs face expression recognition example
parent c77c4d0c
...@@ -38,25 +38,5 @@ function drawExpressions(dimensions, canvas, results, thresh, withBoxes = true) ...@@ -38,25 +38,5 @@ function drawExpressions(dimensions, canvas, results, thresh, withBoxes = true)
faceapi.drawDetection(canvas, resizedResults.map(det => det.detection), { withScore: false }) faceapi.drawDetection(canvas, resizedResults.map(det => det.detection), { withScore: false })
} }
resizedResults.forEach(res => { faceapi.drawFaceExpressions(canvas, resizedResults.map(({ detection, expressions }) => ({ position: detection.box, expressions })))
const { box, imageDims } = res.detection
const { expressions } = res
const sorted = expressions.sort((a, b) => b.probability - a.probability)
const resultsToDisplay = sorted.filter(expr => expr.probability > thresh)
let offset = (box.y + box.height + resultsToDisplay.length * 22) > imageDims.height
? - (resultsToDisplay.length * 22)
: 0
resultsToDisplay.forEach((expr, i) => {
const text = `${expr.expression} (${faceapi.round(expr.probability)})`
faceapi.drawText(
faceapi.getContext2dOrThrow($('#overlay').get(0)),
box.x,
box.y + box.height + i * 22 + offset,
text,
{ textColor: i === 0 ? 'red' : 'blue', fontSize: i === 0 ? 22 : 16 }
)
})
})
} }
\ No newline at end of file
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
right: 0; right: 0;
margin: auto; margin: auto;
margin-top: 20px; margin-top: 20px;
padding-left: 260px; padding-left: 280px;
display: inline-flex !important; display: inline-flex !important;
} }
......
...@@ -11,6 +11,7 @@ async function run() { ...@@ -11,6 +11,7 @@ async function run() {
faceapi.drawDetection(out, detections) faceapi.drawDetection(out, detections)
saveFile('faceDetection.jpg', out.toBuffer('image/jpeg')) saveFile('faceDetection.jpg', out.toBuffer('image/jpeg'))
console.log('done, saved results to out/faceDetection.jpg')
} }
run() run()
\ No newline at end of file
import { canvas, faceapi, faceDetectionNet, faceDetectionOptions, saveFile } from './commons';
async function run() {
await faceDetectionNet.loadFromDisk('../../weights')
await faceapi.nets.faceExpressionNet.loadFromDisk('../../weights')
const img = await canvas.loadImage('../images/surprised.jpg')
const results = await faceapi.detectAllFaces(img, faceDetectionOptions)
.withFaceExpressions()
const out = faceapi.createCanvasFromMedia(img) as any
faceapi.drawDetection(out, results.map(res => res.detection), { withScore: false })
faceapi.drawFaceExpressions(out, results.map(({ detection, expressions }) => ({ position: detection.box, expressions })))
saveFile('faceExpressionRecognition.jpg', out.toBuffer('image/jpeg'))
console.log('done, saved results to out/faceExpressionRecognition.jpg')
}
run()
\ No newline at end of file
...@@ -14,6 +14,7 @@ async function run() { ...@@ -14,6 +14,7 @@ async function run() {
faceapi.drawLandmarks(out, results.map(res => res.landmarks), { drawLines: true, color: 'red' }) faceapi.drawLandmarks(out, results.map(res => res.landmarks), { drawLines: true, color: 'red' })
saveFile('faceLandmarkDetection.jpg', out.toBuffer('image/jpeg')) saveFile('faceLandmarkDetection.jpg', out.toBuffer('image/jpeg'))
console.log('done, saved results to out/faceLandmarkDetection.jpg')
} }
run() run()
\ No newline at end of file
...@@ -38,6 +38,7 @@ async function run() { ...@@ -38,6 +38,7 @@ async function run() {
const outQuery = faceapi.createCanvasFromMedia(queryImage) as any const outQuery = faceapi.createCanvasFromMedia(queryImage) as any
faceapi.drawDetection(outQuery, queryBoxesWithText) faceapi.drawDetection(outQuery, queryBoxesWithText)
saveFile('queryImage.jpg', outQuery.toBuffer('image/jpeg')) saveFile('queryImage.jpg', outQuery.toBuffer('image/jpeg'))
console.log('done, saved results to out/queryImage.jpg')
} }
run() run()
\ No newline at end of file
import { drawText, env, getContext2dOrThrow, getDefaultDrawOptions, resolveInput, round } from 'tfjs-image-recognition-base';
import { IRect } from 'tfjs-tiny-yolov2';
import { DrawFaceExpressionsInput, DrawFaceExpressionsOptions } from './types';
export function drawFaceExpressions(
canvasArg: string | HTMLCanvasElement,
faceExpressions: DrawFaceExpressionsInput | DrawFaceExpressionsInput[],
options?: DrawFaceExpressionsOptions
) {
const canvas = resolveInput(canvasArg)
if (!(canvas instanceof env.getEnv().Canvas)) {
throw new Error('drawFaceExpressions - expected canvas to be of type: HTMLCanvasElement')
}
const drawOptions = Object.assign(
getDefaultDrawOptions(options),
(options || {})
)
const ctx = getContext2dOrThrow(canvas)
const {
primaryColor = 'red',
secondaryColor = 'blue',
primaryFontSize = 22,
secondaryFontSize = 16,
minConfidence = 0.2
} = drawOptions
const faceExpressionsArray = Array.isArray(faceExpressions)
? faceExpressions
: [faceExpressions]
faceExpressionsArray.forEach(({ position, expressions }) => {
const { x, y } = position
const height = (position as IRect).height || 0
const sorted = expressions.sort((a, b) => b.probability - a.probability)
const resultsToDisplay = sorted.filter(expr => expr.probability > minConfidence)
let offset = (y + height + resultsToDisplay.length * primaryFontSize) > canvas.height
? -(resultsToDisplay.length * primaryFontSize)
: 0
resultsToDisplay.forEach((expr, i) => {
const text = `${expr.expression} (${round(expr.probability)})`
drawText(
ctx,
x,
y + height + (i * primaryFontSize) + offset,
text,
{
textColor: i === 0 ? primaryColor : secondaryColor,
fontSize: i === 0 ? primaryFontSize : secondaryFontSize
}
)
})
})
}
\ No newline at end of file
export * from './drawContour' export * from './drawContour'
export * from './drawLandmarks' export * from './drawLandmarks'
export * from './drawFaceExpressions'
export * from './extractFaces' export * from './extractFaces'
export * from './extractFaceTensors' export * from './extractFaceTensors'
export * from './types' export * from './types'
\ No newline at end of file
import { IPoint, IRect } from 'tfjs-tiny-yolov2';
import { WithFaceExpressions } from '../factories/WithFaceExpressions';
export type DrawLandmarksOptions = { export type DrawLandmarksOptions = {
lineWidth?: number lineWidth?: number
color?: string, color?: string
drawLines?: boolean drawLines?: boolean
} }
export type DrawFaceExpressionsOptions = {
primaryColor?: string
secondaryColor?: string
primaryFontSize?: number
secondaryFontSize?: number
minConfidence?: number
}
export type DrawFaceExpressionsInput = WithFaceExpressions<{
position: IPoint | IRect
}>
\ 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