forked from webmachinelearning/webnn-samples
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add selfie segmentation example using builtin TFLite Web (webmachinel…
…earning#163) * Update to 2023 Copyright * Add selfie segmentation example using builtin TFLite Web
- Loading branch information
Showing
41 changed files
with
1,834 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,3 @@ | ||
/common/component/component.js | ||
/common/component/component.js | ||
/selfie_segmentation/tflite-support/ | ||
/selfie_segmentation/lib/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
module.exports = { | ||
globals: { | ||
'importScripts': 'readonly', | ||
'tflite_model_runner_ModuleFactory': 'readonly', | ||
}, | ||
rules: { | ||
'new-cap': 0, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
## WebNN Selfie Segmentation Example | ||
|
||
This example demonstrates the [MediaPipe Selfie Segmentation](https://google.github.io/mediapipe/solutions/selfie_segmentation) using the TFLite Web XNNPACK delegate and WebNN delegate, which is built by [tflite-support](https://github.com/huningxin/tflite-support/tree/webnn_delegate_side_module). | ||
|
||
### Usage | ||
|
||
### Segment images | ||
|
||
Choose delegate and model, in a very few second you will see the predict result for the test image be presented on the page. Choose the backgrounds to experience variance portrait segmentation. | ||
|
||
You could also click 'Pick Image' button to choose your local image to segment it. | ||
|
||
### Segment video stream | ||
|
||
Here we segments every frame in a live camera, then combined the results. Click 'LIVE CAMERA' tab, allow the browser to use your local camera if there's a prompt, then you will see real-time segmentation results on the page. | ||
|
||
Switch delegate or model to check variance predict result. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
'use strict'; | ||
|
||
/* eslint max-len: ["error", {"code": 120}] */ | ||
|
||
// built-in webnn delegate | ||
importScripts('./tflite-support/tflite_model_runner_cc_simd.js'); | ||
|
||
let modelRunnerResult; | ||
let modelRunner; | ||
// Receive the message from the main thread | ||
onmessage = async (message) => { | ||
if (message) { | ||
// Load model or infer depends on the first data | ||
switch (message.data.action) { | ||
case 'load': { | ||
const loadStart = performance.now(); | ||
const modelPath = message.data.modelPath; | ||
// Load WASM module and model. | ||
const [module, modelArrayBuffer] = await Promise.all([ | ||
tflite_model_runner_ModuleFactory(), | ||
(await fetch(modelPath)).arrayBuffer(), | ||
]); | ||
// Load WASM module and model. | ||
const modelBytes = new Uint8Array(modelArrayBuffer); | ||
const offset = module._malloc(modelBytes.length); | ||
module.HEAPU8.set(modelBytes, offset); | ||
|
||
// Create model runner. | ||
modelRunnerResult = | ||
module.TFLiteWebModelRunner.CreateFromBufferAndOptions( | ||
offset, | ||
modelBytes.length, | ||
{ | ||
numThreads: 1, | ||
enableWebNNDelegate: message.data.enableWebNNDelegate, | ||
webNNDevicePreference: parseInt(message.data.webNNDevicePreference), | ||
}, | ||
); | ||
|
||
if (!modelRunnerResult.ok()) { | ||
throw new Error( | ||
`Failed to create TFLiteWebModelRunner: ${modelRunner.errorMessage()}`); | ||
} | ||
modelRunner = modelRunnerResult.value(); | ||
const loadFinishedMs = (performance.now() - loadStart).toFixed(2); | ||
postMessage(loadFinishedMs); | ||
break; | ||
} | ||
case 'compute': { | ||
// Get input and output info. | ||
|
||
const inputs = callAndDelete(modelRunner.GetInputs(), (results) => convertCppVectorToArray(results)); | ||
const input = inputs[0]; | ||
const outputs = callAndDelete(modelRunner.GetOutputs(), (results) => convertCppVectorToArray(results)); | ||
const output = outputs[0]; | ||
|
||
// Set input tensor data from the image (224 x 224 x 3). | ||
const inputBuffer = input.data(); | ||
inputBuffer.set(message.data.buffer); | ||
|
||
// Infer, get output tensor, and sort by logit values in reverse. | ||
const inferStart = performance.now(); | ||
modelRunner.Infer(); | ||
const inferTime = performance.now() - inferStart; | ||
console.log(`Infer time in worker: ${inferTime.toFixed(2)} ms`); | ||
|
||
let outputBuffer = output.data(); | ||
outputBuffer = outputBuffer.slice(0); | ||
postMessage({outputBuffer}, [outputBuffer.buffer]); | ||
break; | ||
} | ||
default: { | ||
break; | ||
} | ||
} | ||
} | ||
}; | ||
|
||
// Helper functions. | ||
|
||
// Converts the given c++ vector to a JS array. | ||
function convertCppVectorToArray(vector) { | ||
if (vector == null) return []; | ||
|
||
const result = []; | ||
for (let i = 0; i < vector.size(); i++) { | ||
const item = vector.get(i); | ||
result.push(item); | ||
} | ||
return result; | ||
} | ||
|
||
|
||
// Calls the given function with the given deletable argument, ensuring that | ||
// the argument gets deleted afterwards (even if the function throws an error). | ||
function callAndDelete(arg, func) { | ||
try { | ||
return func(arg); | ||
} finally { | ||
if (arg != null) arg.delete(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
Images under this folder are from https://unsplash.com/, which is licensed under the https://unsplash.com/license. | ||
|
||
Unsplash photos are made to be used freely. Our license reflects that. | ||
- All photos can be downloaded and used for free | ||
- Commercial and non-commercial purposes | ||
- No permission needed (though attribution is appreciated!) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.