import * as bodypix from '@tensorflow-models/body-pix' ; import * as tf from '@tensorflow/tfjs-core' ; import { getFrameSliceOptions } from '../utils/util' ; let model ; export const load = async ( ) => { model = await bodypix . load ( { architecture : 'MobileNetV1' , outputStride : 16 , multiplier : 0.5 , } ) ; await model . segmentMultiPerson ( tf . zeros ( [ 73 , 73 , 3 ] ) ) ; } ; export const dispose = ( ) => { model . dispose ( ) ; } ; export const isReady = ( ) => { return ! ! model ; } ; export const detectBodySegmentation = async ( frame , displaySize ) => { const temp = tf . browser . fromPixels ( { data : new Uint8Array ( frame . data ) , width : frame . width , height : frame . height , } , 4 ) ; const sliceOptions = getFrameSliceOptions ( frame . width , frame . height , displaySize . width , displaySize . height ) ; const pixels = await tf . tidy ( ( ) => { return tf . image . resizeBilinear ( tf . slice ( temp , sliceOptions . start , sliceOptions . size ) , [ displaySize . height , displaySize . width ] ) ; } ) ; const flipHorizontal = false ; const segmentation = await model . segmentPerson ( pixels , { flipHorizontal , internalResolution : 'medium' , segmentationThreshold : 0.5 } ) ; temp . dispose ( ) ; pixels . dispose ( ) ; return segmentation ; } ; export const toMaskImageData = ( segmentation , maskBackground = true ) => { const { width , height , data } = segmentation ; const bytes = new Uint8ClampedArray ( width * height * 4 ) ; for ( let i = 0 ; i < height * width ; ++ i ) { const shouldMask = maskBackground ? 1 - data [ i ] : data [ i ] ; const alpha = shouldMask * 200 ; const j = i * 4 ; bytes [ j + 0 ] = 0 ; bytes [ j + 1 ] = 0 ; bytes [ j + 2 ] = 0 ; bytes [ j + 3 ] = Math . round ( alpha ) ; } return { data : bytes , width : width , height : height } ; } ;