@tensorflow-models/facemesh
Advanced tools
Comparing version 0.0.3 to 0.0.4
"use strict"; | ||
/** | ||
* @license | ||
* Copyright 2020 Google LLC. All Rights Reserved. | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
* ============================================================================= | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const tf = require("@tensorflow/tfjs-core"); | ||
function disposeBox(box) { | ||
if (box != null && box.startPoint != null) { | ||
box.startEndTensor.dispose(); | ||
box.startPoint.dispose(); | ||
box.endPoint.dispose(); | ||
} | ||
} | ||
exports.disposeBox = disposeBox; | ||
function createBox(startEndTensor, startPoint, endPoint) { | ||
return { | ||
startEndTensor, | ||
startPoint: startPoint != null ? startPoint : | ||
tf.slice(startEndTensor, [0, 0], [-1, 2]), | ||
endPoint: endPoint != null ? endPoint : | ||
tf.slice(startEndTensor, [0, 2], [-1, 2]) | ||
}; | ||
} | ||
exports.createBox = createBox; | ||
var tf = require("@tensorflow/tfjs-core"); | ||
function scaleBoxCoordinates(box, factor) { | ||
const newStart = tf.mul(box.startPoint, factor); | ||
const newEnd = tf.mul(box.endPoint, factor); | ||
return createBox(tf.concat2d([newStart, newEnd], 1)); | ||
var startPoint = [box.startPoint[0] * factor[0], box.startPoint[1] * factor[1]]; | ||
var endPoint = [box.endPoint[0] * factor[0], box.endPoint[1] * factor[1]]; | ||
return { startPoint: startPoint, endPoint: endPoint }; | ||
} | ||
exports.scaleBoxCoordinates = scaleBoxCoordinates; | ||
function getBoxSize(box) { | ||
return tf.tidy(() => { | ||
const diff = tf.sub(box.endPoint, box.startPoint); | ||
return tf.abs(diff); | ||
}); | ||
return [ | ||
Math.abs(box.endPoint[0] - box.startPoint[0]), | ||
Math.abs(box.endPoint[1] - box.startPoint[1]) | ||
]; | ||
} | ||
exports.getBoxSize = getBoxSize; | ||
function getBoxCenter(box) { | ||
return tf.tidy(() => { | ||
const halfSize = tf.div(tf.sub(box.endPoint, box.startPoint), 2); | ||
return tf.add(box.startPoint, halfSize); | ||
}); | ||
return [ | ||
box.startPoint[0] + (box.endPoint[0] - box.startPoint[0]) / 2, | ||
box.startPoint[1] + (box.endPoint[1] - box.startPoint[1]) / 2 | ||
]; | ||
} | ||
exports.getBoxCenter = getBoxCenter; | ||
function cutBoxFromImageAndResize(box, image, cropSize) { | ||
const height = image.shape[1]; | ||
const width = image.shape[2]; | ||
const xyxy = box.startEndTensor; | ||
return tf.tidy(() => { | ||
const yxyx = tf.concat2d([ | ||
xyxy.slice([0, 1], [-1, 1]), xyxy.slice([0, 0], [-1, 1]), | ||
xyxy.slice([0, 3], [-1, 1]), xyxy.slice([0, 2], [-1, 1]) | ||
], 0); | ||
const roundedCoords = tf.div(yxyx.transpose(), [height, width, height, width]); | ||
return tf.image.cropAndResize(image, roundedCoords, [0], cropSize); | ||
}); | ||
var h = image.shape[1]; | ||
var w = image.shape[2]; | ||
var boxes = [[ | ||
box.startPoint[1] / h, box.startPoint[0] / w, box.endPoint[1] / h, | ||
box.endPoint[0] / w | ||
]]; | ||
return tf.image.cropAndResize(image, boxes, [0], cropSize); | ||
} | ||
exports.cutBoxFromImageAndResize = cutBoxFromImageAndResize; | ||
function enlargeBox(box, factor = 1.5) { | ||
return tf.tidy(() => { | ||
const center = getBoxCenter(box); | ||
const size = getBoxSize(box); | ||
const newSize = tf.mul(tf.div(size, 2), factor); | ||
const newStart = tf.sub(center, newSize); | ||
const newEnd = tf.add(center, newSize); | ||
return createBox(tf.concat2d([newStart, newEnd], 1), newStart, newEnd); | ||
}); | ||
/** | ||
* Enlarges the box by the provided factor. | ||
* @param box An object with startPoint and endPoint properties describing the | ||
* outlines of the box to be enlarged. | ||
* @param factor optional The enlargement factor. Defaults to 1.5 | ||
*/ | ||
function enlargeBox(box, factor) { | ||
if (factor === void 0) { factor = 1.5; } | ||
var center = getBoxCenter(box); | ||
var size = getBoxSize(box); | ||
var newHalfSize = [factor * size[0] / 2, factor * size[1] / 2]; | ||
var startPoint = [center[0] - newHalfSize[0], center[1] - newHalfSize[1]]; | ||
var endPoint = [center[0] + newHalfSize[0], center[1] + newHalfSize[1]]; | ||
return { startPoint: startPoint, endPoint: endPoint, landmarks: box.landmarks }; | ||
} | ||
exports.enlargeBox = enlargeBox; | ||
//# sourceMappingURL=box.js.map |
@@ -17,2 +17,2 @@ /** | ||
*/ | ||
import{slice,add,div,sub,mul,concat2d,Tensor,tidy,concat,tensor1d,tensor2d,sigmoid,image,browser,env,reshape,stack,abs}from"@tensorflow/tfjs-core";import{loadGraphModel}from"@tensorflow/tfjs-converter";const disposeBox=e=>{e.startEndTensor.dispose(),e.startPoint.dispose(),e.endPoint.dispose()},createBox=e=>({startEndTensor:e,startPoint:slice(e,[0,0],[-1,2]),endPoint:slice(e,[0,2],[-1,2])}),scaleBox=(e,t)=>{const s=mul(e.startPoint,t),o=mul(e.endPoint,t),n=concat2d([s,o],1);return createBox(n)},ANCHORS_CONFIG={strides:[8,16],anchors:[2,6]},NUM_LANDMARKS=6;function generateAnchors(e,t,s){const o=[];for(let n=0;n<s.strides.length;n++){const i=s.strides[n],r=Math.floor((t+i-1)/i),a=Math.floor((e+i-1)/i),c=s.anchors[n];for(let e=0;e<r;e++){const t=i*(e+.5);for(let e=0;e<a;e++){const s=i*(e+.5);for(let e=0;e<c;e++)o.push([s,t])}}}return o}function decodeBounds(e,t,s){const o=slice(e,[0,1],[-1,2]),n=add(o,t),i=slice(e,[0,3],[-1,2]),r=div(i,s),a=div(n,s),c=div(r,2),l=sub(a,c),d=add(a,c),h=mul(l,s),u=mul(d,s);return concat2d([h,u],1)}function getInputTensorDimensions(e){return e instanceof Tensor?[e.shape[0],e.shape[1]]:[e.height,e.width]}function flipFaceHorizontal(e,t){let s,o,n;if(e.topLeft instanceof Tensor&&e.bottomRight instanceof Tensor){const[i,r]=tidy(()=>[concat([sub(t-1,e.topLeft.slice(0,1)),e.topLeft.slice(1,1)]),concat([sub(t-1,e.bottomRight.slice(0,1)),e.bottomRight.slice(1,1)])]);s=i,o=r,null!=e.landmarks&&(n=tidy(()=>{const s=sub(tensor1d([t-1,0]),e.landmarks),o=tensor1d([1,-1]);return mul(s,o)}))}else{const[i,r]=e.topLeft,[a,c]=e.bottomRight;s=[t-1-i,r],o=[t-1-a,c],null!=e.landmarks&&(n=e.landmarks.map(e=>[t-1-e[0],e[1]]))}const i={topLeft:s,bottomRight:o};return null!=n&&(i.landmarks=n),null!=e.probability&&(i.probability=e.probability instanceof Tensor?e.probability.clone():e.probability),i}function scaleBoxFromPrediction(e,t){return tidy(()=>{let s;return s=e.hasOwnProperty("box")?e.box:e,scaleBox(s,t).startEndTensor.squeeze()})}class BlazeFaceModel{constructor(e,t,s,o,n,i){this.blazeFaceModel=e,this.width=t,this.height=s,this.maxFaces=o,this.anchorsData=generateAnchors(t,s,ANCHORS_CONFIG),this.anchors=tensor2d(this.anchorsData),this.inputSizeData=[t,s],this.inputSize=tensor1d([t,s]),this.iouThreshold=n,this.scoreThreshold=i}async getBoundingBoxes(e,t,s=!0){const[o,n,i]=tidy(()=>{const t=e.resizeBilinear([this.width,this.height]),s=mul(sub(t.div(255),.5),2),o=this.blazeFaceModel.predict(s).squeeze(),n=decodeBounds(o,this.anchors,this.inputSize),i=slice(o,[0,0],[-1,1]);return[o,n,sigmoid(i).squeeze()]}),r=console.warn;console.warn=(()=>{});const a=image.nonMaxSuppression(n,i,this.maxFaces,this.iouThreshold,this.scoreThreshold);console.warn=r;const c=await a.array();a.dispose();let l=c.map(e=>slice(n,[e,0],[1,-1]));t||(l=await Promise.all(l.map(async e=>{const t=await e.array();return e.dispose(),t})));const d=e.shape[1],h=e.shape[2];let u;u=t?div([h,d],this.inputSize):[h/this.inputSizeData[0],d/this.inputSizeData[1]];const p=[];for(let e=0;e<l.length;e++){const n=l[e],r=tidy(()=>{const r=createBox(n instanceof Tensor?n:tensor2d(n));if(!s)return r;const a=c[e];let l;return l=t?this.anchors.slice([a,0],[1,2]):this.anchorsData[a],{box:r,landmarks:slice(o,[a,NUM_LANDMARKS-1],[1,-1]).squeeze().reshape([NUM_LANDMARKS,-1]),probability:slice(i,[a],[1]),anchor:l}});p.push(r)}return n.dispose(),i.dispose(),o.dispose(),{boxes:p,scaleFactor:u}}async estimateFaces(e,t=!1,s=!1,o=!0){const[,n]=getInputTensorDimensions(e),i=tidy(()=>(e instanceof Tensor||(e=browser.fromPixels(e)),e.toFloat().expandDims(0))),{boxes:r,scaleFactor:a}=await this.getBoundingBoxes(i,t,o);return i.dispose(),t?r.map(e=>{const t=scaleBoxFromPrediction(e,a);let i={topLeft:t.slice([0],[2]),bottomRight:t.slice([2],[2])};if(o){const{landmarks:t,probability:s,anchor:o}=e,n=t.add(o).mul(a);i.landmarks=n,i.probability=s}return s&&(i=flipFaceHorizontal(i,n)),i}):Promise.all(r.map(async e=>{const t=scaleBoxFromPrediction(e,a);let i;if(o){const[s,o,n]=await Promise.all([e.landmarks,t,e.probability].map(async e=>e.array())),r=e.anchor,[c,l]=a,d=s.map(e=>[(e[0]+r[0])*c,(e[1]+r[1])*l]);i={topLeft:o.slice(0,2),bottomRight:o.slice(2),landmarks:d,probability:n},disposeBox(e.box),e.landmarks.dispose(),e.probability.dispose()}else{const e=await t.array();i={topLeft:e.slice(0,2),bottomRight:e.slice(2)}}return t.dispose(),s&&(i=flipFaceHorizontal(i,n)),i}))}}const BLAZEFACE_MODEL_URL="https://tfhub.dev/tensorflow/tfjs-model/blazeface/1/default/1";async function load({maxFaces:e=10,inputWidth:t=128,inputHeight:s=128,iouThreshold:o=.3,scoreThreshold:n=.75}={}){const i=await loadGraphModel(BLAZEFACE_MODEL_URL,{fromTFHub:!0});return new BlazeFaceModel(i,t,s,e,o,n)}const MESH_ANNOTATIONS={silhouette:[10,338,297,332,284,251,389,356,454,323,361,288,397,365,379,378,400,377,152,148,176,149,150,136,172,58,132,93,234,127,162,21,54,103,67,109],lipsUpperOuter:[61,185,40,39,37,0,267,269,270,409,291],lipsLowerOuter:[146,91,181,84,17,314,405,321,375,291],lipsUpperInner:[78,191,80,81,82,13,312,311,310,415,308],lipsLowerInner:[78,95,88,178,87,14,317,402,318,324,308],rightEyeUpper0:[246,161,160,159,158,157,173],rightEyeLower0:[33,7,163,144,145,153,154,155,133],rightEyeUpper1:[247,30,29,27,28,56,190],rightEyeLower1:[130,25,110,24,23,22,26,112,243],rightEyeUpper2:[113,225,224,223,222,221,189],rightEyeLower2:[226,31,228,229,230,231,232,233,244],rightEyeLower3:[143,111,117,118,119,120,121,128,245],rightEyebrowUpper:[156,70,63,105,66,107,55,193],rightEyebrowLower:[35,124,46,53,52,65],leftEyeUpper0:[466,388,387,386,385,384,398],leftEyeLower0:[263,249,390,373,374,380,381,382,362],leftEyeUpper1:[467,260,259,257,258,286,414],leftEyeLower1:[359,255,339,254,253,252,256,341,463],leftEyeUpper2:[342,445,444,443,442,441,413],leftEyeLower2:[446,261,448,449,450,451,452,453,464],leftEyeLower3:[372,340,346,347,348,349,350,357,465],leftEyebrowUpper:[383,300,293,334,296,336,285,417],leftEyebrowLower:[265,353,276,283,282,295],midwayBetweenEyes:[168],noseTip:[1],noseBottom:[2],noseRightCorner:[98],noseLeftCorner:[327],rightCheek:[205],leftCheek:[425]};function disposeBox$1(e){null!=e&&null!=e.startPoint&&(e.startEndTensor.dispose(),e.startPoint.dispose(),e.endPoint.dispose())}function createBox$1(e,t,s){return{startEndTensor:e,startPoint:null!=t?t:slice(e,[0,0],[-1,2]),endPoint:null!=s?s:slice(e,[0,2],[-1,2])}}function scaleBoxCoordinates(e,t){const s=mul(e.startPoint,t),o=mul(e.endPoint,t);return createBox$1(concat2d([s,o],1))}function getBoxSize(e){return tidy(()=>{const t=sub(e.endPoint,e.startPoint);return abs(t)})}function getBoxCenter(e){return tidy(()=>{const t=div(sub(e.endPoint,e.startPoint),2);return add(e.startPoint,t)})}function cutBoxFromImageAndResize(e,t,s){const o=t.shape[1],n=t.shape[2],i=e.startEndTensor;return tidy(()=>{const e=concat2d([i.slice([0,1],[-1,1]),i.slice([0,0],[-1,1]),i.slice([0,3],[-1,1]),i.slice([0,2],[-1,1])],0),r=div(e.transpose(),[o,n,o,n]);return image.cropAndResize(t,r,[0],s)})}function enlargeBox(e,t=1.5){return tidy(()=>{const s=getBoxCenter(e),o=getBoxSize(e),n=mul(div(o,2),t),i=sub(s,n),r=add(s,n);return createBox$1(concat2d([i,r],1),i,r)})}const LANDMARKS_COUNT=468,UPDATE_REGION_OF_INTEREST_IOU_THRESHOLD=.25;class Pipeline{constructor(e,t,s,o,n,i){this.regionsOfInterest=[],this.runsWithoutFaceDetector=0,this.boundingBoxDetector=e,this.meshDetector=t,this.meshWidth=s,this.meshHeight=o,this.maxContinuousChecks=n,this.maxFaces=i}async predict(e){if(this.shouldUpdateRegionsOfInterest()){const t=!0,s=!1,{boxes:o,scaleFactor:n}=await this.boundingBoxDetector.getBoundingBoxes(e,t,s);if(0===o.length)return n.dispose(),this.clearAllRegionsOfInterest(),null;const i=o.map(e=>enlargeBox(scaleBoxCoordinates(e,n)));o.forEach(disposeBox$1),this.updateRegionsOfInterest(i),this.runsWithoutFaceDetector=0}else this.runsWithoutFaceDetector++;return tidy(()=>this.regionsOfInterest.map((t,s)=>{const o=cutBoxFromImageAndResize(t,e,[this.meshHeight,this.meshWidth]).div(255),[,n,i]=this.meshDetector.predict(o),r=reshape(i,[-1,3]),a=div(getBoxSize(t),[this.meshWidth,this.meshHeight]),c=mul(r,a.concat(tensor2d([1],[1,1]),1)).add(t.startPoint.concat(tensor2d([0],[1,1]),1)),l=this.calculateLandmarksBoundingBox(c);return disposeBox$1(this.regionsOfInterest[s]),this.regionsOfInterest[s]=l,{coords:r,scaledCoords:c,box:l,flag:n.squeeze()}}))}updateRegionsOfInterest(e){for(let t=0;t<e.length;t++){const s=e[t],o=this.regionsOfInterest[t];let n=0;if(o&&o.startPoint){const[e,t,i,r]=s.startEndTensor.arraySync()[0],[a,c,l,d]=o.startEndTensor.arraySync()[0],h=Math.max(e,a),u=Math.max(t,c),p=(Math.min(i,l)-h)*(Math.min(r,d)-u);n=p/((i-e)*(r-t)+(l-a)*(d-t)-p)}n>UPDATE_REGION_OF_INTEREST_IOU_THRESHOLD?disposeBox$1(s):(this.regionsOfInterest[t]=s,disposeBox$1(o))}for(let t=e.length;t<this.regionsOfInterest.length;t++)disposeBox$1(this.regionsOfInterest[t]);this.regionsOfInterest=this.regionsOfInterest.slice(0,e.length)}clearRegionOfInterest(e){null!=this.regionsOfInterest[e]&&(disposeBox$1(this.regionsOfInterest[e]),this.regionsOfInterest=[...this.regionsOfInterest.slice(0,e),...this.regionsOfInterest.slice(e+1)])}clearAllRegionsOfInterest(){for(let e=0;e<this.regionsOfInterest.length;e++)disposeBox$1(this.regionsOfInterest[e]);this.regionsOfInterest=[]}shouldUpdateRegionsOfInterest(){const e=this.regionsOfInterest.length,t=0===e;return 1===this.maxFaces||t?t:e!==this.maxFaces&&this.runsWithoutFaceDetector>=this.maxContinuousChecks}calculateLandmarksBoundingBox(e){const t=e.slice([0,0],[LANDMARKS_COUNT,1]),s=e.slice([0,1],[LANDMARKS_COUNT,1]);return enlargeBox(createBox$1(stack([t.min(),s.min(),t.max(),s.max()]).expandDims(0)))}}const UV_COORDS=[[.499976992607117,.652534008026123],[.500025987625122,.547487020492554],[.499974012374878,.602371990680695],[.482113003730774,.471979022026062],[.500150978565216,.527155995368958],[.499909996986389,.498252987861633],[.499523013830185,.40106201171875],[.289712011814117,.380764007568359],[.499954998493195,.312398016452789],[.499987006187439,.269918978214264],[.500023007392883,.107050001621246],[.500023007392883,.666234016418457],[.5000159740448,.679224014282227],[.500023007392883,.692348003387451],[.499976992607117,.695277988910675],[.499976992607117,.70593398809433],[.499976992607117,.719385027885437],[.499976992607117,.737019002437592],[.499967992305756,.781370997428894],[.499816000461578,.562981009483337],[.473773002624512,.573909997940063],[.104906998574734,.254140973091125],[.365929991006851,.409575998783112],[.338757991790771,.41302502155304],[.311120003461838,.409460008144379],[.274657994508743,.389131009578705],[.393361985683441,.403706014156342],[.345234006643295,.344011008739471],[.370094001293182,.346076011657715],[.319321990013123,.347265005111694],[.297903001308441,.353591024875641],[.24779200553894,.410809993743896],[.396889001131058,.842755019664764],[.280097991228104,.375599980354309],[.106310002505779,.399955987930298],[.2099249958992,.391353011131287],[.355807989835739,.534406006336212],[.471751004457474,.65040397644043],[.474155008792877,.680191993713379],[.439785003662109,.657229006290436],[.414617002010345,.66654098033905],[.450374007225037,.680860996246338],[.428770989179611,.682690978050232],[.374971002340317,.727805018424988],[.486716985702515,.547628998756409],[.485300987958908,.527395009994507],[.257764995098114,.314490020275116],[.401223003864288,.455172002315521],[.429818987846375,.548614978790283],[.421351999044418,.533740997314453],[.276895999908447,.532056987285614],[.483370006084442,.499586999416351],[.33721199631691,.282882988452911],[.296391993761063,.293242990970612],[.169294998049736,.193813979625702],[.447580009698868,.302609980106354],[.392390012741089,.353887975215912],[.354490011930466,.696784019470215],[.067304998636246,.730105042457581],[.442739009857178,.572826027870178],[.457098007202148,.584792017936707],[.381974011659622,.694710969924927],[.392388999462128,.694203019142151],[.277076005935669,.271932005882263],[.422551989555359,.563233017921448],[.385919004678726,.281364023685455],[.383103013038635,.255840003490448],[.331431001424789,.119714021682739],[.229923993349075,.232002973556519],[.364500999450684,.189113974571228],[.229622006416321,.299540996551514],[.173287004232407,.278747975826263],[.472878992557526,.666198015213013],[.446828007698059,.668527007102966],[.422762006521225,.673889994621277],[.445307999849319,.580065965652466],[.388103008270264,.693961024284363],[.403039008378983,.706539988517761],[.403629004955292,.693953037261963],[.460041999816895,.557139039039612],[.431158006191254,.692366003990173],[.452181994915009,.692366003990173],[.475387006998062,.692366003990173],[.465828001499176,.779190003871918],[.472328990697861,.736225962638855],[.473087012767792,.717857003211975],[.473122000694275,.704625964164734],[.473033010959625,.695277988910675],[.427942007780075,.695277988910675],[.426479011774063,.703539967536926],[.423162013292313,.711845993995667],[.4183090031147,.720062971115112],[.390094995498657,.639572978019714],[.013953999616206,.560034036636353],[.499913990497589,.58014702796936],[.413199990987778,.69539999961853],[.409626007080078,.701822996139526],[.468080013990402,.601534962654114],[.422728985548019,.585985004901886],[.463079988956451,.593783974647522],[.37211999297142,.47341400384903],[.334562003612518,.496073007583618],[.411671012639999,.546965003013611],[.242175996303558,.14767599105835],[.290776997804642,.201445996761322],[.327338010072708,.256527006626129],[.399509996175766,.748921036720276],[.441727995872498,.261676013469696],[.429764986038208,.187834024429321],[.412198007106781,.108901023864746],[.288955003023148,.398952007293701],[.218936994671822,.435410976409912],[.41278201341629,.398970007896423],[.257135003805161,.355440020561218],[.427684992551804,.437960982322693],[.448339998722076,.536936044692993],[.178560003638268,.45755398273468],[.247308000922203,.457193970680237],[.286267012357712,.467674970626831],[.332827985286713,.460712015628815],[.368755996227264,.447206974029541],[.398963987827301,.432654976844788],[.476410001516342,.405806005001068],[.189241006970406,.523923993110657],[.228962004184723,.348950982093811],[.490725994110107,.562400996685028],[.404670000076294,.485132992267609],[.019469000399113,.401564002037048],[.426243007183075,.420431017875671],[.396993011236191,.548797011375427],[.266469985246658,.376977026462555],[.439121007919312,.51895797252655],[.032313998788595,.644356966018677],[.419054001569748,.387154996395111],[.462783008813858,.505746960639954],[.238978996872902,.779744982719421],[.198220998048782,.831938028335571],[.107550002634525,.540755033493042],[.183610007166862,.740257024765015],[.134409993886948,.333683013916016],[.385764002799988,.883153975009918],[.490967005491257,.579378008842468],[.382384985685349,.508572995662689],[.174399003386497,.397670984268188],[.318785011768341,.39623498916626],[.343364000320435,.400596976280212],[.396100014448166,.710216999053955],[.187885001301765,.588537991046906],[.430987000465393,.944064974784851],[.318993002176285,.898285031318665],[.266247987747192,.869701027870178],[.500023007392883,.190576016902924],[.499976992607117,.954452991485596],[.366169989109039,.398822009563446],[.393207013607025,.39553701877594],[.410373002290726,.391080021858215],[.194993004202843,.342101991176605],[.388664990663528,.362284004688263],[.365961998701096,.355970978736877],[.343364000320435,.355356991291046],[.318785011768341,.35834002494812],[.301414996385574,.363156020641327],[.058132998645306,.319076001644135],[.301414996385574,.387449026107788],[.499987989664078,.618434011936188],[.415838003158569,.624195992946625],[.445681989192963,.566076993942261],[.465844005346298,.620640993118286],[.49992299079895,.351523995399475],[.288718998432159,.819945991039276],[.335278987884521,.852819979190826],[.440512001514435,.902418971061707],[.128294005990028,.791940987110138],[.408771991729736,.373893976211548],[.455606997013092,.451801002025604],[.499877005815506,.908990025520325],[.375436991453171,.924192011356354],[.11421000212431,.615022003650665],[.448662012815475,.695277988910675],[.4480200111866,.704632043838501],[.447111994028091,.715808033943176],[.444831997156143,.730794012546539],[.430011987686157,.766808986663818],[.406787008047104,.685672998428345],[.400738000869751,.681069016456604],[.392399996519089,.677703022956848],[.367855995893478,.663918972015381],[.247923001646996,.601333022117615],[.452769994735718,.420849978923798],[.43639200925827,.359887003898621],[.416164010763168,.368713974952698],[.413385987281799,.692366003990173],[.228018000721931,.683571994304657],[.468268007040024,.352671027183533],[.411361992359161,.804327011108398],[.499989002943039,.469825029373169],[.479153990745544,.442654013633728],[.499974012374878,.439637005329132],[.432112008333206,.493588984012604],[.499886006116867,.866917014122009],[.49991300702095,.821729004383087],[.456548988819122,.819200992584229],[.344549000263214,.745438992977142],[.37890899181366,.574010014533997],[.374292999505997,.780184984207153],[.319687992334366,.570737957954407],[.357154995203018,.604269981384277],[.295284003019333,.621580958366394],[.447750002145767,.862477004528046],[.410986006259918,.508723020553589],[.31395098567009,.775308012962341],[.354128003120422,.812552988529205],[.324548006057739,.703992962837219],[.189096003770828,.646299958229065],[.279776990413666,.71465802192688],[.1338230073452,.682700991630554],[.336768001317978,.644733011722565],[.429883986711502,.466521978378296],[.455527991056442,.548622965812683],[.437114000320435,.558896005153656],[.467287987470627,.529924988746643],[.414712011814117,.335219979286194],[.37704598903656,.322777986526489],[.344107985496521,.320150971412659],[.312875986099243,.32233202457428],[.283526003360748,.333190023899078],[.241245999932289,.382785975933075],[.102986000478268,.468762993812561],[.267612010240555,.424560010433197],[.297879010438919,.433175981044769],[.333433985710144,.433878004550934],[.366427004337311,.426115989685059],[.396012008190155,.416696012020111],[.420121014118195,.41022801399231],[.007561000064015,.480777025222778],[.432949006557465,.569517970085144],[.458638995885849,.479089021682739],[.473466008901596,.545744001865387],[.476087987422943,.563830018043518],[.468472003936768,.555056989192963],[.433990985155106,.582361996173859],[.483518004417419,.562983989715576],[.482482999563217,.57784903049469],[.42645001411438,.389798998832703],[.438998997211456,.39649498462677],[.450067013502121,.400434017181396],[.289712011814117,.368252992630005],[.276670008897781,.363372981548309],[.517862021923065,.471948027610779],[.710287988185883,.380764007568359],[.526226997375488,.573909997940063],[.895093023777008,.254140973091125],[.634069979190826,.409575998783112],[.661242008209229,.41302502155304],[.688880026340485,.409460008144379],[.725341975688934,.389131009578705],[.606630027294159,.40370500087738],[.654766023159027,.344011008739471],[.629905998706818,.346076011657715],[.680678009986877,.347265005111694],[.702096998691559,.353591024875641],[.75221198797226,.410804986953735],[.602918028831482,.842862963676453],[.719901978969574,.375599980354309],[.893692970275879,.399959981441498],[.790081977844238,.391354024410248],[.643998026847839,.534487962722778],[.528249025344849,.65040397644043],[.525849997997284,.680191040039062],[.560214996337891,.657229006290436],[.585384011268616,.66654098033905],[.549625992774963,.680860996246338],[.57122802734375,.682691991329193],[.624852001667023,.72809898853302],[.513050019741058,.547281980514526],[.51509702205658,.527251958847046],[.742246985435486,.314507007598877],[.598631024360657,.454979002475739],[.570338010787964,.548575043678284],[.578631997108459,.533622980117798],[.723087012767792,.532054007053375],[.516445994377136,.499638974666595],[.662801027297974,.282917976379395],[.70362401008606,.293271005153656],[.830704987049103,.193813979625702],[.552385985851288,.302568018436432],[.607609987258911,.353887975215912],[.645429015159607,.696707010269165],[.932694971561432,.730105042457581],[.557260990142822,.572826027870178],[.542901992797852,.584792017936707],[.6180260181427,.694710969924927],[.607590973377228,.694203019142151],[.722943007946014,.271963000297546],[.577413976192474,.563166975975037],[.614082992076874,.281386971473694],[.616907000541687,.255886018276215],[.668509006500244,.119913995265961],[.770092010498047,.232020974159241],[.635536015033722,.189248979091644],[.77039098739624,.299556016921997],[.826722025871277,.278755009174347],[.527121007442474,.666198015213013],[.553171992301941,.668527007102966],[.577238023281097,.673889994621277],[.554691970348358,.580065965652466],[.611896991729736,.693961024284363],[.59696102142334,.706539988517761],[.596370995044708,.693953037261963],[.539958000183105,.557139039039612],[.568841993808746,.692366003990173],[.547818005084991,.692366003990173],[.52461302280426,.692366003990173],[.534089982509613,.779141008853912],[.527670979499817,.736225962638855],[.526912987232208,.717857003211975],[.526877999305725,.704625964164734],[.526966989040375,.695277988910675],[.572058022022247,.695277988910675],[.573521018028259,.703539967536926],[.57683801651001,.711845993995667],[.581691026687622,.720062971115112],[.609944999217987,.639909982681274],[.986046016216278,.560034036636353],[.5867999792099,.69539999961853],[.590372025966644,.701822996139526],[.531915009021759,.601536989212036],[.577268004417419,.585934996604919],[.536915004253387,.593786001205444],[.627542972564697,.473352015018463],[.665585994720459,.495950996875763],[.588353991508484,.546862006187439],[.757824003696442,.14767599105835],[.709249973297119,.201507985591888],[.672684013843536,.256581008434296],[.600408971309662,.74900496006012],[.55826598405838,.261672019958496],[.570303976535797,.187870979309082],[.588165998458862,.109044015407562],[.711045026779175,.398952007293701],[.781069993972778,.435405015945435],[.587247014045715,.398931980133057],[.742869973182678,.355445981025696],[.572156012058258,.437651991844177],[.55186802148819,.536570012569427],[.821442008018494,.457556009292603],[.752701997756958,.457181990146637],[.71375697851181,.467626988887787],[.66711300611496,.460672974586487],[.631101012229919,.447153985500336],[.6008620262146,.432473003864288],[.523481011390686,.405627012252808],[.810747981071472,.523926019668579],[.771045982837677,.348959028720856],[.509127020835876,.562718033790588],[.595292985439301,.485023975372314],[.980530977249146,.401564002037048],[.573499977588654,.420000016689301],[.602994978427887,.548687994480133],[.733529984951019,.376977026462555],[.560611009597778,.519016981124878],[.967685997486115,.644356966018677],[.580985009670258,.387160003185272],[.537728011608124,.505385041236877],[.760966002941132,.779752969741821],[.801778972148895,.831938028335571],[.892440974712372,.54076099395752],[.816350996494293,.740260004997253],[.865594983100891,.333687007427216],[.614073991775513,.883246004581451],[.508952975273132,.579437971115112],[.617941975593567,.508316040039062],[.825608015060425,.397674977779388],[.681214988231659,.39623498916626],[.656635999679565,.400596976280212],[.603900015354156,.710216999053955],[.81208598613739,.588539004325867],[.56801301240921,.944564998149872],[.681007981300354,.898285031318665],[.733752012252808,.869701027870178],[.633830010890961,.398822009563446],[.606792986392975,.39553701877594],[.589659988880157,.391062021255493],[.805015981197357,.342108011245728],[.611334979534149,.362284004688263],[.634037971496582,.355970978736877],[.656635999679565,.355356991291046],[.681214988231659,.35834002494812],[.698584973812103,.363156020641327],[.941866993904114,.319076001644135],[.698584973812103,.387449026107788],[.584177017211914,.624107003211975],[.554318010807037,.566076993942261],[.534153997898102,.62064003944397],[.711217999458313,.819975018501282],[.664629995822906,.852871000766754],[.559099972248077,.902631998062134],[.871706008911133,.791940987110138],[.591234028339386,.373893976211548],[.544341027736664,.451583981513977],[.624562978744507,.924192011356354],[.88577002286911,.615028977394104],[.551338016986847,.695277988910675],[.551980018615723,.704632043838501],[.552887976169586,.715808033943176],[.555167973041534,.730794012546539],[.569944024085999,.767035007476807],[.593203008174896,.685675978660583],[.599261999130249,.681069016456604],[.607599973678589,.677703022956848],[.631937980651855,.663500010967255],[.752032995223999,.601315021514893],[.547226011753082,.420395016670227],[.563543975353241,.359827995300293],[.583841025829315,.368713974952698],[.586614012718201,.692366003990173],[.771915018558502,.683578014373779],[.531597018241882,.352482974529266],[.588370978832245,.804440975189209],[.52079701423645,.442565023899078],[.567984998226166,.493479013442993],[.543282985687256,.819254994392395],[.655317008495331,.745514988899231],[.621008992195129,.574018001556396],[.625559985637665,.78031200170517],[.680198013782501,.570719003677368],[.64276397228241,.604337990283966],[.704662978649139,.621529996395111],[.552012026309967,.862591981887817],[.589071989059448,.508637011051178],[.685944974422455,.775357007980347],[.645735025405884,.812640011310577],[.675342977046967,.703978002071381],[.810858011245728,.646304965019226],[.72012197971344,.714666962623596],[.866151988506317,.682704985141754],[.663187026977539,.644596993923187],[.570082008838654,.466325998306274],[.544561982154846,.548375964164734],[.562758982181549,.558784961700439],[.531987011432648,.530140042304993],[.585271000862122,.335177004337311],[.622952997684479,.32277899980545],[.655896008014679,.320163011550903],[.687132000923157,.322345972061157],[.716481983661652,.333200991153717],[.758756995201111,.382786989212036],[.897013008594513,.468769013881683],[.732392013072968,.424547016620636],[.70211398601532,.433162987232208],[.66652500629425,.433866024017334],[.633504986763,.426087975502014],[.603875994682312,.416586995124817],[.579657971858978,.409945011138916],[.992439985275269,.480777025222778],[.567192018032074,.569419980049133],[.54136598110199,.478899002075195],[.526564002037048,.546118021011353],[.523913025856018,.563830018043518],[.531529009342194,.555056989192963],[.566035985946655,.582329034805298],[.51631098985672,.563053965568542],[.5174720287323,.577877044677734],[.573594987392426,.389806985855103],[.560697972774506,.395331978797913],[.549755990505219,.399751007556915],[.710287988185883,.368252992630005],[.723330020904541,.363372981548309]],FACEMESH_GRAPHMODEL_PATH="https://tfhub.dev/mediapipe/tfjs-model/facemesh/1/default/1",MESH_MODEL_INPUT_WIDTH=192,MESH_MODEL_INPUT_HEIGHT=192;async function load$1({maxContinuousChecks:e=5,detectionConfidence:t=.9,maxFaces:s=10,iouThreshold:o=.3,scoreThreshold:n=.75}={}){const[i,r]=await Promise.all([loadDetectorModel(s,o,n),loadMeshModel()]);return new FaceMesh(i,r,e,t,s)}async function loadDetectorModel(e,t,s){return load({maxFaces:e,iouThreshold:t,scoreThreshold:s})}async function loadMeshModel(){return loadGraphModel(FACEMESH_GRAPHMODEL_PATH,{fromTFHub:!0})}function getInputTensorDimensions$1(e){return e instanceof Tensor?[e.shape[0],e.shape[1]]:[e.height,e.width]}function flipFaceHorizontal$1(e,t){if(e.mesh instanceof Tensor){const[s,o,n,i]=tidy(()=>{const s=tensor1d([t-1,0,0]),o=tensor1d([1,-1,1]);return tidy(()=>[concat([sub(t-1,e.boundingBox.topLeft.slice(0,1)),e.boundingBox.topLeft.slice(1,1)]),concat([sub(t-1,e.boundingBox.bottomRight.slice(0,1)),e.boundingBox.bottomRight.slice(1,1)]),sub(s,e.mesh).mul(o),sub(s,e.scaledMesh).mul(o)])});return Object.assign({},e,{boundingBox:{topLeft:s,bottomRight:o},mesh:n,scaledMesh:i})}return Object.assign({},e,{boundingBox:{topLeft:[t-1-e.boundingBox.topLeft[0],e.boundingBox.topLeft[1]],bottomRight:[t-1-e.boundingBox.bottomRight[0],e.boundingBox.bottomRight[1]]},mesh:e.mesh.map(e=>{const s=e.slice(0);return s[0]=t-1-e[0],s}),scaledMesh:e.scaledMesh.map(e=>{const s=e.slice(0);return s[0]=t-1-e[0],s})})}class FaceMesh{constructor(e,t,s,o,n){this.pipeline=new Pipeline(e,t,MESH_MODEL_INPUT_WIDTH,MESH_MODEL_INPUT_HEIGHT,s,n),this.detectionConfidence=o}static getAnnotations(){return MESH_ANNOTATIONS}static getUVCoords(){return UV_COORDS}async estimateFaces(e,t=!1,s=!1){const[,o]=getInputTensorDimensions$1(e),n=tidy(()=>(e instanceof Tensor||(e=browser.fromPixels(e)),e.toFloat().expandDims(0))),i=env().get("WEBGL_PACK_DEPTHWISECONV");env().set("WEBGL_PACK_DEPTHWISECONV",!0);const r=await this.pipeline.predict(n);return env().set("WEBGL_PACK_DEPTHWISECONV",i),n.dispose(),null!=r&&r.length>0?Promise.all(r.map(async(e,n)=>{const{coords:i,scaledCoords:r,box:a,flag:c}=e;let l=[c];t||(l=l.concat([i,r,a.startPoint,a.endPoint]));const d=await Promise.all(l.map(async e=>e.array())),h=d[0];if(c.dispose(),h<this.detectionConfidence&&this.pipeline.clearRegionOfInterest(n),t){const e={faceInViewConfidence:h,mesh:i,scaledMesh:r,boundingBox:{topLeft:a.startPoint.squeeze(),bottomRight:a.endPoint.squeeze()}};return s?flipFaceHorizontal$1(e,o):e}const[u,p,f,m]=d.slice(1);r.dispose(),i.dispose();let g={faceInViewConfidence:h,boundingBox:{topLeft:f,bottomRight:m},mesh:u,scaledMesh:p};s&&(g=flipFaceHorizontal$1(g,o));const b={};for(const e in MESH_ANNOTATIONS)b[e]=MESH_ANNOTATIONS[e].map(e=>g.scaledMesh[e]);return g.annotations=b,g})):[]}}export{load$1 as load,FaceMesh}; | ||
import{tensor2d as t,tensor1d as e,tidy as n,mul as o,sub as r,concat2d as i,slice as s,sigmoid as a,image as c,div as u,Tensor as h,browser as l,add as f,concat as d,reshape as p,env as m,getBackend as b}from"@tensorflow/tfjs-core";import{loadGraphModel as g}from"@tensorflow/tfjs-converter";var P=function(){return(P=Object.assign||function(t){for(var e,n=1,o=arguments.length;n<o;n++)for(var r in e=arguments[n])Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t}).apply(this,arguments)};function y(t,e,n,o){return new(n||(n=Promise))((function(r,i){function s(t){try{c(o.next(t))}catch(t){i(t)}}function a(t){try{c(o.throw(t))}catch(t){i(t)}}function c(t){var e;t.done?r(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(s,a)}c((o=o.apply(t,e||[])).next())}))}function v(t,e){var n,o,r,i,s={label:0,sent:function(){if(1&r[0])throw r[1];return r[1]},trys:[],ops:[]};return i={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(i){return function(a){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;s;)try{if(n=1,o&&(r=2&i[0]?o.return:i[0]?o.throw||((r=o.return)&&r.call(o),0):o.next)&&!(r=r.call(o,i[1])).done)return r;switch(o=0,r&&(i=[2&i[0],r.value]),i[0]){case 0:case 1:r=i;break;case 4:return s.label++,{value:i[1],done:!1};case 5:s.label++,o=i[1],i=[0];continue;case 7:i=s.ops.pop(),s.trys.pop();continue;default:if(!(r=s.trys,(r=r.length>0&&r[r.length-1])||6!==i[0]&&2!==i[0])){s=0;continue}if(3===i[0]&&(!r||i[1]>r[0]&&i[1]<r[3])){s.label=i[1];break}if(6===i[0]&&s.label<r[1]){s.label=r[1],r=i;break}if(r&&s.label<r[2]){s.label=r[2],s.ops.push(i);break}r[2]&&s.ops.pop(),s.trys.pop();continue}i=e.call(t,s)}catch(t){i=[6,t],o=0}finally{n=r=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}([i,a])}}}const w=t=>({startEndTensor:t,startPoint:s(t,[0,0],[-1,2]),endPoint:s(t,[0,2],[-1,2])}),x={strides:[8,16],anchors:[2,6]};function E(t,i){let s,a,c;if(t.topLeft instanceof h&&t.bottomRight instanceof h){const[u,h]=n(()=>[d([r(i-1,t.topLeft.slice(0,1)),t.topLeft.slice(1,1)]),d([r(i-1,t.bottomRight.slice(0,1)),t.bottomRight.slice(1,1)])]);s=u,a=h,null!=t.landmarks&&(c=n(()=>{const n=r(e([i-1,0]),t.landmarks),s=e([1,-1]);return o(n,s)}))}else{const[e,n]=t.topLeft,[o,r]=t.bottomRight;s=[i-1-e,n],a=[i-1-o,r],null!=t.landmarks&&(c=t.landmarks.map(t=>[i-1-t[0],t[1]]))}const u={topLeft:s,bottomRight:a};return null!=c&&(u.landmarks=c),null!=t.probability&&(u.probability=t.probability instanceof h?t.probability.clone():t.probability),u}function L(t,e){return n(()=>{let n;return n=t.hasOwnProperty("box")?t.box:t,((t,e)=>{const n=o(t.startPoint,e),r=o(t.endPoint,e),s=i([n,r],1);return w(s)})(n,e).startEndTensor.squeeze()})}class M{constructor(n,o,r,i,s,a){this.blazeFaceModel=n,this.width=o,this.height=r,this.maxFaces=i,this.anchorsData=function(t,e,n){const o=[];for(let r=0;r<n.strides.length;r++){const i=n.strides[r],s=Math.floor((e+i-1)/i),a=Math.floor((t+i-1)/i),c=n.anchors[r];for(let t=0;t<s;t++){const e=i*(t+.5);for(let t=0;t<a;t++){const n=i*(t+.5);for(let t=0;t<c;t++)o.push([n,e])}}}return o}(o,r,x),this.anchors=t(this.anchorsData),this.inputSizeData=[o,r],this.inputSize=e([o,r]),this.iouThreshold=s,this.scoreThreshold=a}async getBoundingBoxes(e,l,d=!0){const[p,m,b]=n(()=>{const t=e.resizeBilinear([this.width,this.height]),n=o(r(t.div(255),.5),2),c=this.blazeFaceModel.predict(n).squeeze(),h=function(t,e,n){const a=s(t,[0,1],[-1,2]),c=f(a,e),h=s(t,[0,3],[-1,2]),l=u(h,n),d=u(c,n),p=u(l,2),m=r(d,p),b=f(d,p),g=o(m,n),P=o(b,n);return i([g,P],1)}(c,this.anchors,this.inputSize),l=s(c,[0,0],[-1,1]);return[c,h,a(l).squeeze()]}),g=console.warn;console.warn=()=>{};const P=c.nonMaxSuppression(m,b,this.maxFaces,this.iouThreshold,this.scoreThreshold);console.warn=g;const y=await P.array();P.dispose();let v=y.map(t=>s(m,[t,0],[1,-1]));l||(v=await Promise.all(v.map(async t=>{const e=await t.array();return t.dispose(),e})));const x=e.shape[1],E=e.shape[2];let L;L=l?u([E,x],this.inputSize):[E/this.inputSizeData[0],x/this.inputSizeData[1]];const M=[];for(let e=0;e<v.length;e++){const o=v[e],r=n(()=>{const n=w(o instanceof h?o:t(o));if(!d)return n;const r=y[e];let i;return i=l?this.anchors.slice([r,0],[1,2]):this.anchorsData[r],{box:n,landmarks:s(p,[r,5],[1,-1]).squeeze().reshape([6,-1]),probability:s(b,[r],[1]),anchor:i}});M.push(r)}return m.dispose(),b.dispose(),p.dispose(),{boxes:M,scaleFactor:L}}async estimateFaces(t,e=!1,o=!1,r=!0){const[,i]=function(t){return t instanceof h?[t.shape[0],t.shape[1]]:[t.height,t.width]}(t),s=n(()=>(t instanceof h||(t=l.fromPixels(t)),t.toFloat().expandDims(0))),{boxes:a,scaleFactor:c}=await this.getBoundingBoxes(s,e,r);return s.dispose(),e?a.map(t=>{const e=L(t,c);let n={topLeft:e.slice([0],[2]),bottomRight:e.slice([2],[2])};if(r){const{landmarks:e,probability:o,anchor:r}=t,i=e.add(r).mul(c);n.landmarks=i,n.probability=o}return o&&(n=E(n,i)),n}):Promise.all(a.map(async t=>{const e=L(t,c);let n;if(r){const[o,r,i]=await Promise.all([t.landmarks,e,t.probability].map(async t=>t.array())),s=t.anchor,[a,u]=c,h=o.map(t=>[(t[0]+s[0])*a,(t[1]+s[1])*u]);n={topLeft:r.slice(0,2),bottomRight:r.slice(2),landmarks:h,probability:i},(t=>{t.startEndTensor.dispose(),t.startPoint.dispose(),t.endPoint.dispose()})(t.box),t.landmarks.dispose(),t.probability.dispose()}else{const t=await e.array();n={topLeft:t.slice(0,2),bottomRight:t.slice(2)}}return e.dispose(),o&&(n=E(n,i)),n}))}}async function k({maxFaces:t=10,inputWidth:e=128,inputHeight:n=128,iouThreshold:o=.3,scoreThreshold:r=.75}={}){const i=await g("https://tfhub.dev/tensorflow/tfjs-model/blazeface/1/default/1",{fromTFHub:!0});return new M(i,e,n,t,o,r)}var O={silhouette:[10,338,297,332,284,251,389,356,454,323,361,288,397,365,379,378,400,377,152,148,176,149,150,136,172,58,132,93,234,127,162,21,54,103,67,109],lipsUpperOuter:[61,185,40,39,37,0,267,269,270,409,291],lipsLowerOuter:[146,91,181,84,17,314,405,321,375,291],lipsUpperInner:[78,191,80,81,82,13,312,311,310,415,308],lipsLowerInner:[78,95,88,178,87,14,317,402,318,324,308],rightEyeUpper0:[246,161,160,159,158,157,173],rightEyeLower0:[33,7,163,144,145,153,154,155,133],rightEyeUpper1:[247,30,29,27,28,56,190],rightEyeLower1:[130,25,110,24,23,22,26,112,243],rightEyeUpper2:[113,225,224,223,222,221,189],rightEyeLower2:[226,31,228,229,230,231,232,233,244],rightEyeLower3:[143,111,117,118,119,120,121,128,245],rightEyebrowUpper:[156,70,63,105,66,107,55,193],rightEyebrowLower:[35,124,46,53,52,65],leftEyeUpper0:[466,388,387,386,385,384,398],leftEyeLower0:[263,249,390,373,374,380,381,382,362],leftEyeUpper1:[467,260,259,257,258,286,414],leftEyeLower1:[359,255,339,254,253,252,256,341,463],leftEyeUpper2:[342,445,444,443,442,441,413],leftEyeLower2:[446,261,448,449,450,451,452,453,464],leftEyeLower3:[372,340,346,347,348,349,350,357,465],leftEyebrowUpper:[383,300,293,334,296,336,285,417],leftEyebrowLower:[265,353,276,283,282,295],midwayBetweenEyes:[168],noseTip:[1],noseBottom:[2],noseRightCorner:[98],noseLeftCorner:[327],rightCheek:[205],leftCheek:[425]};function B(t){return[Math.abs(t.endPoint[0]-t.startPoint[0]),Math.abs(t.endPoint[1]-t.startPoint[1])]}function I(t){return[t.startPoint[0]+(t.endPoint[0]-t.startPoint[0])/2,t.startPoint[1]+(t.endPoint[1]-t.startPoint[1])/2]}function C(t,e){void 0===e&&(e=1.5);var n=I(t),o=B(t),r=[e*o[0]/2,e*o[1]/2];return{startPoint:[n[0]-r[0],n[1]-r[1]],endPoint:[n[0]+r[0],n[1]+r[1]],landmarks:t.landmarks}}function R(t,e){var n,o=Math.PI/2-Math.atan2(-(e[1]-t[1]),e[0]-t[0]);return(n=o)-2*Math.PI*Math.floor((n+Math.PI)/(2*Math.PI))}function F(t,e){return[[1,0,t],[0,1,e],[0,0,1]]}function T(t,e){for(var n=0,o=0;o<t.length;o++)n+=t[o]*e[o];return n}function D(t,e){for(var n=[],o=0;o<t.length;o++)n.push(t[o][e]);return n}function z(t,e){for(var n=[],o=t.length,r=0;r<o;r++){n.push([]);for(var i=0;i<o;i++)n[r].push(T(t[r],D(e,i)))}return n}function S(t,e){var n=Math.cos(t),o=Math.sin(t),r=[[n,-o,0],[o,n,0],[0,0,1]],i=z(F(e[0],e[1]),r);return z(i,F(-e[0],-e[1]))}var W=[1,168],U=[3,2],H=function(){function e(t,e,n,o,r,i){this.regionsOfInterest=[],this.runsWithoutFaceDetector=0,this.boundingBoxDetector=t,this.meshDetector=e,this.meshWidth=n,this.meshHeight=o,this.maxContinuousChecks=r,this.maxFaces=i}return e.prototype.transformRawCoords=function(t,e,n,o){var r,i,s,a,c=this,u=B({startPoint:e.startPoint,endPoint:e.endPoint}),h=[u[0]/this.meshWidth,u[1]/this.meshHeight],l=t.map((function(t){return[h[0]*(t[0]-c.meshWidth/2),h[1]*(t[1]-c.meshHeight/2),t[2]]})),f=S(n,[0,0]),d=l.map((function(t){return function(t,e){return[T(t,e[0]),T(t,e[1])]}(t,f).concat([t[2]])})),p=(i=[[(r=o)[0][0],r[1][0]],[r[0][1],r[1][1]]],s=[r[0][2],r[1][2]],a=[-T(i[0],s),-T(i[1],s)],[i[0].concat(a[0]),i[1].concat(a[1]),[0,0,1]]),m=I({startPoint:e.startPoint,endPoint:e.endPoint}).concat([1]),b=[T(m,p[0]),T(m,p[1])];return d.map((function(t){return[t[0]+b[0],t[1]+b[1],t[2]]}))},e.prototype.predict=function(e){return y(this,void 0,void 0,(function(){var o,r,i,s,a=this;return v(this,(function(u){switch(u.label){case 0:return this.shouldUpdateRegionsOfInterest()?(!1,!0,[4,this.boundingBoxDetector.getBoundingBoxes(e,!1,!0)]):[3,2];case 1:return o=u.sent(),r=o.boxes,i=o.scaleFactor,0===r.length?(this.regionsOfInterest=[],[2,null]):(s=r.map((function(t){var e,n,o={startPoint:t.box.startPoint.squeeze().arraySync(),endPoint:t.box.endPoint.squeeze().arraySync()},r=C((n=i,{startPoint:[(e=o).startPoint[0]*n[0],e.startPoint[1]*n[1]],endPoint:[e.endPoint[0]*n[0],e.endPoint[1]*n[1]]}));return P({},r,{landmarks:t.landmarks.arraySync()})})),r.forEach((function(t){null!=t&&null!=t.startPoint&&(t.startEndTensor.dispose(),t.startPoint.dispose(),t.endPoint.dispose())})),this.updateRegionsOfInterest(s),this.runsWithoutFaceDetector=0,[3,3]);case 2:this.runsWithoutFaceDetector++,u.label=3;case 3:return[2,n((function(){return a.regionsOfInterest.map((function(n,o){var r;if(468===n.landmarks.length){var i=W[0],s=W[1];r=R(n.landmarks[i],n.landmarks[s])}else{i=U[0],s=U[1];r=R(n.landmarks[i],n.landmarks[s])}var u=I({startPoint:n.startPoint,endPoint:n.endPoint}),h=[u[0]/e.shape[2],u[1]/e.shape[1]],l=c.rotateWithOffset(e,r,0,h),f=S(-r,u),d=function(t,e,n){var o=e.shape[1],r=e.shape[2],i=[[t.startPoint[1]/o,t.startPoint[0]/r,t.endPoint[1]/o,t.endPoint[0]/r]];return c.cropAndResize(e,i,[0],n)}({startPoint:n.startPoint,endPoint:n.endPoint},l,[a.meshHeight,a.meshWidth]).div(255),m=a.meshDetector.predict(d),b=m[1],g=m[2],y=p(g,[-1,3]),v=y.arraySync(),w=a.transformRawCoords(v,n,r,f),x=t(w),E=a.calculateLandmarksBoundingBox(w);return a.regionsOfInterest[o]=P({},E,{landmarks:x.arraySync()}),{coords:y,scaledCoords:x,box:E,flag:b.squeeze()}}))}))]}}))}))},e.prototype.updateRegionsOfInterest=function(t){for(var e=0;e<t.length;e++){var n=t[e],o=this.regionsOfInterest[e],r=0;if(o&&o.startPoint){var i=n.startPoint,s=i[0],a=i[1],c=n.endPoint,u=c[0],h=c[1],l=o.startPoint,f=l[0],d=l[1],p=o.endPoint,m=p[0],b=p[1],g=Math.max(s,f),P=Math.max(a,d),y=(Math.min(u,m)-g)*(Math.min(h,b)-P);r=y/((u-s)*(h-a)+(m-f)*(b-a)-y)}r<.25&&(this.regionsOfInterest[e]=n)}this.regionsOfInterest=this.regionsOfInterest.slice(0,t.length)},e.prototype.clearRegionOfInterest=function(t){null!=this.regionsOfInterest[t]&&(this.regionsOfInterest=this.regionsOfInterest.slice(0,t).concat(this.regionsOfInterest.slice(t+1)))},e.prototype.shouldUpdateRegionsOfInterest=function(){var t=this.regionsOfInterest.length,e=0===t;return 1===this.maxFaces||e?e:t!==this.maxFaces&&this.runsWithoutFaceDetector>=this.maxContinuousChecks},e.prototype.calculateLandmarksBoundingBox=function(t){var e=t.map((function(t){return t[0]})),n=t.map((function(t){return t[1]})),o={startPoint:[Math.min.apply(Math,e),Math.min.apply(Math,n)],endPoint:[Math.max.apply(Math,e),Math.max.apply(Math,n)]};return C({startPoint:o.startPoint,endPoint:o.endPoint})},e}(),j=[[.499976992607117,.652534008026123],[.500025987625122,.547487020492554],[.499974012374878,.602371990680695],[.482113003730774,.471979022026062],[.500150978565216,.527155995368958],[.499909996986389,.498252987861633],[.499523013830185,.40106201171875],[.289712011814117,.380764007568359],[.499954998493195,.312398016452789],[.499987006187439,.269918978214264],[.500023007392883,.107050001621246],[.500023007392883,.666234016418457],[.5000159740448,.679224014282227],[.500023007392883,.692348003387451],[.499976992607117,.695277988910675],[.499976992607117,.70593398809433],[.499976992607117,.719385027885437],[.499976992607117,.737019002437592],[.499967992305756,.781370997428894],[.499816000461578,.562981009483337],[.473773002624512,.573909997940063],[.104906998574734,.254140973091125],[.365929991006851,.409575998783112],[.338757991790771,.41302502155304],[.311120003461838,.409460008144379],[.274657994508743,.389131009578705],[.393361985683441,.403706014156342],[.345234006643295,.344011008739471],[.370094001293182,.346076011657715],[.319321990013123,.347265005111694],[.297903001308441,.353591024875641],[.24779200553894,.410809993743896],[.396889001131058,.842755019664764],[.280097991228104,.375599980354309],[.106310002505779,.399955987930298],[.2099249958992,.391353011131287],[.355807989835739,.534406006336212],[.471751004457474,.65040397644043],[.474155008792877,.680191993713379],[.439785003662109,.657229006290436],[.414617002010345,.66654098033905],[.450374007225037,.680860996246338],[.428770989179611,.682690978050232],[.374971002340317,.727805018424988],[.486716985702515,.547628998756409],[.485300987958908,.527395009994507],[.257764995098114,.314490020275116],[.401223003864288,.455172002315521],[.429818987846375,.548614978790283],[.421351999044418,.533740997314453],[.276895999908447,.532056987285614],[.483370006084442,.499586999416351],[.33721199631691,.282882988452911],[.296391993761063,.293242990970612],[.169294998049736,.193813979625702],[.447580009698868,.302609980106354],[.392390012741089,.353887975215912],[.354490011930466,.696784019470215],[.067304998636246,.730105042457581],[.442739009857178,.572826027870178],[.457098007202148,.584792017936707],[.381974011659622,.694710969924927],[.392388999462128,.694203019142151],[.277076005935669,.271932005882263],[.422551989555359,.563233017921448],[.385919004678726,.281364023685455],[.383103013038635,.255840003490448],[.331431001424789,.119714021682739],[.229923993349075,.232002973556519],[.364500999450684,.189113974571228],[.229622006416321,.299540996551514],[.173287004232407,.278747975826263],[.472878992557526,.666198015213013],[.446828007698059,.668527007102966],[.422762006521225,.673889994621277],[.445307999849319,.580065965652466],[.388103008270264,.693961024284363],[.403039008378983,.706539988517761],[.403629004955292,.693953037261963],[.460041999816895,.557139039039612],[.431158006191254,.692366003990173],[.452181994915009,.692366003990173],[.475387006998062,.692366003990173],[.465828001499176,.779190003871918],[.472328990697861,.736225962638855],[.473087012767792,.717857003211975],[.473122000694275,.704625964164734],[.473033010959625,.695277988910675],[.427942007780075,.695277988910675],[.426479011774063,.703539967536926],[.423162013292313,.711845993995667],[.4183090031147,.720062971115112],[.390094995498657,.639572978019714],[.013953999616206,.560034036636353],[.499913990497589,.58014702796936],[.413199990987778,.69539999961853],[.409626007080078,.701822996139526],[.468080013990402,.601534962654114],[.422728985548019,.585985004901886],[.463079988956451,.593783974647522],[.37211999297142,.47341400384903],[.334562003612518,.496073007583618],[.411671012639999,.546965003013611],[.242175996303558,.14767599105835],[.290776997804642,.201445996761322],[.327338010072708,.256527006626129],[.399509996175766,.748921036720276],[.441727995872498,.261676013469696],[.429764986038208,.187834024429321],[.412198007106781,.108901023864746],[.288955003023148,.398952007293701],[.218936994671822,.435410976409912],[.41278201341629,.398970007896423],[.257135003805161,.355440020561218],[.427684992551804,.437960982322693],[.448339998722076,.536936044692993],[.178560003638268,.45755398273468],[.247308000922203,.457193970680237],[.286267012357712,.467674970626831],[.332827985286713,.460712015628815],[.368755996227264,.447206974029541],[.398963987827301,.432654976844788],[.476410001516342,.405806005001068],[.189241006970406,.523923993110657],[.228962004184723,.348950982093811],[.490725994110107,.562400996685028],[.404670000076294,.485132992267609],[.019469000399113,.401564002037048],[.426243007183075,.420431017875671],[.396993011236191,.548797011375427],[.266469985246658,.376977026462555],[.439121007919312,.51895797252655],[.032313998788595,.644356966018677],[.419054001569748,.387154996395111],[.462783008813858,.505746960639954],[.238978996872902,.779744982719421],[.198220998048782,.831938028335571],[.107550002634525,.540755033493042],[.183610007166862,.740257024765015],[.134409993886948,.333683013916016],[.385764002799988,.883153975009918],[.490967005491257,.579378008842468],[.382384985685349,.508572995662689],[.174399003386497,.397670984268188],[.318785011768341,.39623498916626],[.343364000320435,.400596976280212],[.396100014448166,.710216999053955],[.187885001301765,.588537991046906],[.430987000465393,.944064974784851],[.318993002176285,.898285031318665],[.266247987747192,.869701027870178],[.500023007392883,.190576016902924],[.499976992607117,.954452991485596],[.366169989109039,.398822009563446],[.393207013607025,.39553701877594],[.410373002290726,.391080021858215],[.194993004202843,.342101991176605],[.388664990663528,.362284004688263],[.365961998701096,.355970978736877],[.343364000320435,.355356991291046],[.318785011768341,.35834002494812],[.301414996385574,.363156020641327],[.058132998645306,.319076001644135],[.301414996385574,.387449026107788],[.499987989664078,.618434011936188],[.415838003158569,.624195992946625],[.445681989192963,.566076993942261],[.465844005346298,.620640993118286],[.49992299079895,.351523995399475],[.288718998432159,.819945991039276],[.335278987884521,.852819979190826],[.440512001514435,.902418971061707],[.128294005990028,.791940987110138],[.408771991729736,.373893976211548],[.455606997013092,.451801002025604],[.499877005815506,.908990025520325],[.375436991453171,.924192011356354],[.11421000212431,.615022003650665],[.448662012815475,.695277988910675],[.4480200111866,.704632043838501],[.447111994028091,.715808033943176],[.444831997156143,.730794012546539],[.430011987686157,.766808986663818],[.406787008047104,.685672998428345],[.400738000869751,.681069016456604],[.392399996519089,.677703022956848],[.367855995893478,.663918972015381],[.247923001646996,.601333022117615],[.452769994735718,.420849978923798],[.43639200925827,.359887003898621],[.416164010763168,.368713974952698],[.413385987281799,.692366003990173],[.228018000721931,.683571994304657],[.468268007040024,.352671027183533],[.411361992359161,.804327011108398],[.499989002943039,.469825029373169],[.479153990745544,.442654013633728],[.499974012374878,.439637005329132],[.432112008333206,.493588984012604],[.499886006116867,.866917014122009],[.49991300702095,.821729004383087],[.456548988819122,.819200992584229],[.344549000263214,.745438992977142],[.37890899181366,.574010014533997],[.374292999505997,.780184984207153],[.319687992334366,.570737957954407],[.357154995203018,.604269981384277],[.295284003019333,.621580958366394],[.447750002145767,.862477004528046],[.410986006259918,.508723020553589],[.31395098567009,.775308012962341],[.354128003120422,.812552988529205],[.324548006057739,.703992962837219],[.189096003770828,.646299958229065],[.279776990413666,.71465802192688],[.1338230073452,.682700991630554],[.336768001317978,.644733011722565],[.429883986711502,.466521978378296],[.455527991056442,.548622965812683],[.437114000320435,.558896005153656],[.467287987470627,.529924988746643],[.414712011814117,.335219979286194],[.37704598903656,.322777986526489],[.344107985496521,.320150971412659],[.312875986099243,.32233202457428],[.283526003360748,.333190023899078],[.241245999932289,.382785975933075],[.102986000478268,.468762993812561],[.267612010240555,.424560010433197],[.297879010438919,.433175981044769],[.333433985710144,.433878004550934],[.366427004337311,.426115989685059],[.396012008190155,.416696012020111],[.420121014118195,.41022801399231],[.007561000064015,.480777025222778],[.432949006557465,.569517970085144],[.458638995885849,.479089021682739],[.473466008901596,.545744001865387],[.476087987422943,.563830018043518],[.468472003936768,.555056989192963],[.433990985155106,.582361996173859],[.483518004417419,.562983989715576],[.482482999563217,.57784903049469],[.42645001411438,.389798998832703],[.438998997211456,.39649498462677],[.450067013502121,.400434017181396],[.289712011814117,.368252992630005],[.276670008897781,.363372981548309],[.517862021923065,.471948027610779],[.710287988185883,.380764007568359],[.526226997375488,.573909997940063],[.895093023777008,.254140973091125],[.634069979190826,.409575998783112],[.661242008209229,.41302502155304],[.688880026340485,.409460008144379],[.725341975688934,.389131009578705],[.606630027294159,.40370500087738],[.654766023159027,.344011008739471],[.629905998706818,.346076011657715],[.680678009986877,.347265005111694],[.702096998691559,.353591024875641],[.75221198797226,.410804986953735],[.602918028831482,.842862963676453],[.719901978969574,.375599980354309],[.893692970275879,.399959981441498],[.790081977844238,.391354024410248],[.643998026847839,.534487962722778],[.528249025344849,.65040397644043],[.525849997997284,.680191040039062],[.560214996337891,.657229006290436],[.585384011268616,.66654098033905],[.549625992774963,.680860996246338],[.57122802734375,.682691991329193],[.624852001667023,.72809898853302],[.513050019741058,.547281980514526],[.51509702205658,.527251958847046],[.742246985435486,.314507007598877],[.598631024360657,.454979002475739],[.570338010787964,.548575043678284],[.578631997108459,.533622980117798],[.723087012767792,.532054007053375],[.516445994377136,.499638974666595],[.662801027297974,.282917976379395],[.70362401008606,.293271005153656],[.830704987049103,.193813979625702],[.552385985851288,.302568018436432],[.607609987258911,.353887975215912],[.645429015159607,.696707010269165],[.932694971561432,.730105042457581],[.557260990142822,.572826027870178],[.542901992797852,.584792017936707],[.6180260181427,.694710969924927],[.607590973377228,.694203019142151],[.722943007946014,.271963000297546],[.577413976192474,.563166975975037],[.614082992076874,.281386971473694],[.616907000541687,.255886018276215],[.668509006500244,.119913995265961],[.770092010498047,.232020974159241],[.635536015033722,.189248979091644],[.77039098739624,.299556016921997],[.826722025871277,.278755009174347],[.527121007442474,.666198015213013],[.553171992301941,.668527007102966],[.577238023281097,.673889994621277],[.554691970348358,.580065965652466],[.611896991729736,.693961024284363],[.59696102142334,.706539988517761],[.596370995044708,.693953037261963],[.539958000183105,.557139039039612],[.568841993808746,.692366003990173],[.547818005084991,.692366003990173],[.52461302280426,.692366003990173],[.534089982509613,.779141008853912],[.527670979499817,.736225962638855],[.526912987232208,.717857003211975],[.526877999305725,.704625964164734],[.526966989040375,.695277988910675],[.572058022022247,.695277988910675],[.573521018028259,.703539967536926],[.57683801651001,.711845993995667],[.581691026687622,.720062971115112],[.609944999217987,.639909982681274],[.986046016216278,.560034036636353],[.5867999792099,.69539999961853],[.590372025966644,.701822996139526],[.531915009021759,.601536989212036],[.577268004417419,.585934996604919],[.536915004253387,.593786001205444],[.627542972564697,.473352015018463],[.665585994720459,.495950996875763],[.588353991508484,.546862006187439],[.757824003696442,.14767599105835],[.709249973297119,.201507985591888],[.672684013843536,.256581008434296],[.600408971309662,.74900496006012],[.55826598405838,.261672019958496],[.570303976535797,.187870979309082],[.588165998458862,.109044015407562],[.711045026779175,.398952007293701],[.781069993972778,.435405015945435],[.587247014045715,.398931980133057],[.742869973182678,.355445981025696],[.572156012058258,.437651991844177],[.55186802148819,.536570012569427],[.821442008018494,.457556009292603],[.752701997756958,.457181990146637],[.71375697851181,.467626988887787],[.66711300611496,.460672974586487],[.631101012229919,.447153985500336],[.6008620262146,.432473003864288],[.523481011390686,.405627012252808],[.810747981071472,.523926019668579],[.771045982837677,.348959028720856],[.509127020835876,.562718033790588],[.595292985439301,.485023975372314],[.980530977249146,.401564002037048],[.573499977588654,.420000016689301],[.602994978427887,.548687994480133],[.733529984951019,.376977026462555],[.560611009597778,.519016981124878],[.967685997486115,.644356966018677],[.580985009670258,.387160003185272],[.537728011608124,.505385041236877],[.760966002941132,.779752969741821],[.801778972148895,.831938028335571],[.892440974712372,.54076099395752],[.816350996494293,.740260004997253],[.865594983100891,.333687007427216],[.614073991775513,.883246004581451],[.508952975273132,.579437971115112],[.617941975593567,.508316040039062],[.825608015060425,.397674977779388],[.681214988231659,.39623498916626],[.656635999679565,.400596976280212],[.603900015354156,.710216999053955],[.81208598613739,.588539004325867],[.56801301240921,.944564998149872],[.681007981300354,.898285031318665],[.733752012252808,.869701027870178],[.633830010890961,.398822009563446],[.606792986392975,.39553701877594],[.589659988880157,.391062021255493],[.805015981197357,.342108011245728],[.611334979534149,.362284004688263],[.634037971496582,.355970978736877],[.656635999679565,.355356991291046],[.681214988231659,.35834002494812],[.698584973812103,.363156020641327],[.941866993904114,.319076001644135],[.698584973812103,.387449026107788],[.584177017211914,.624107003211975],[.554318010807037,.566076993942261],[.534153997898102,.62064003944397],[.711217999458313,.819975018501282],[.664629995822906,.852871000766754],[.559099972248077,.902631998062134],[.871706008911133,.791940987110138],[.591234028339386,.373893976211548],[.544341027736664,.451583981513977],[.624562978744507,.924192011356354],[.88577002286911,.615028977394104],[.551338016986847,.695277988910675],[.551980018615723,.704632043838501],[.552887976169586,.715808033943176],[.555167973041534,.730794012546539],[.569944024085999,.767035007476807],[.593203008174896,.685675978660583],[.599261999130249,.681069016456604],[.607599973678589,.677703022956848],[.631937980651855,.663500010967255],[.752032995223999,.601315021514893],[.547226011753082,.420395016670227],[.563543975353241,.359827995300293],[.583841025829315,.368713974952698],[.586614012718201,.692366003990173],[.771915018558502,.683578014373779],[.531597018241882,.352482974529266],[.588370978832245,.804440975189209],[.52079701423645,.442565023899078],[.567984998226166,.493479013442993],[.543282985687256,.819254994392395],[.655317008495331,.745514988899231],[.621008992195129,.574018001556396],[.625559985637665,.78031200170517],[.680198013782501,.570719003677368],[.64276397228241,.604337990283966],[.704662978649139,.621529996395111],[.552012026309967,.862591981887817],[.589071989059448,.508637011051178],[.685944974422455,.775357007980347],[.645735025405884,.812640011310577],[.675342977046967,.703978002071381],[.810858011245728,.646304965019226],[.72012197971344,.714666962623596],[.866151988506317,.682704985141754],[.663187026977539,.644596993923187],[.570082008838654,.466325998306274],[.544561982154846,.548375964164734],[.562758982181549,.558784961700439],[.531987011432648,.530140042304993],[.585271000862122,.335177004337311],[.622952997684479,.32277899980545],[.655896008014679,.320163011550903],[.687132000923157,.322345972061157],[.716481983661652,.333200991153717],[.758756995201111,.382786989212036],[.897013008594513,.468769013881683],[.732392013072968,.424547016620636],[.70211398601532,.433162987232208],[.66652500629425,.433866024017334],[.633504986763,.426087975502014],[.603875994682312,.416586995124817],[.579657971858978,.409945011138916],[.992439985275269,.480777025222778],[.567192018032074,.569419980049133],[.54136598110199,.478899002075195],[.526564002037048,.546118021011353],[.523913025856018,.563830018043518],[.531529009342194,.555056989192963],[.566035985946655,.582329034805298],[.51631098985672,.563053965568542],[.5174720287323,.577877044677734],[.573594987392426,.389806985855103],[.560697972774506,.395331978797913],[.549755990505219,.399751007556915],[.710287988185883,.368252992630005],[.723330020904541,.363372981548309]];function q(t){var e=void 0===t?{}:t,n=e.maxContinuousChecks,o=void 0===n?5:n,r=e.detectionConfidence,i=void 0===r?.9:r,s=e.maxFaces,a=void 0===s?10:s,c=e.iouThreshold,u=void 0===c?.3:c,h=e.scoreThreshold,l=void 0===h?.75:h;return y(this,void 0,void 0,(function(){var t,e,n;return v(this,(function(r){switch(r.label){case 0:return[4,Promise.all([V(a,u,l),_()])];case 1:return t=r.sent(),e=t[0],n=t[1],[2,new G(e,n,o,i,a)]}}))}))}function V(t,e,n){return y(this,void 0,void 0,(function(){return v(this,(function(o){return[2,k({maxFaces:t,iouThreshold:e,scoreThreshold:n})]}))}))}function _(){return y(this,void 0,void 0,(function(){return v(this,(function(t){return[2,g("https://tfhub.dev/mediapipe/tfjs-model/facemesh/1/default/1",{fromTFHub:!0})]}))}))}function A(t,o){if(t.mesh instanceof h){var i=n((function(){var i=e([o-1,0,0]),s=e([1,-1,1]);return n((function(){return[d([r(o-1,t.boundingBox.topLeft.slice(0,1)),t.boundingBox.topLeft.slice(1,1)]),d([r(o-1,t.boundingBox.bottomRight.slice(0,1)),t.boundingBox.bottomRight.slice(1,1)]),r(i,t.mesh).mul(s),r(i,t.scaledMesh).mul(s)]}))})),s=i[0],a=i[1],c=i[2],u=i[3];return Object.assign({},t,{boundingBox:{topLeft:s,bottomRight:a},mesh:c,scaledMesh:u})}return Object.assign({},t,{boundingBox:{topLeft:[o-1-t.boundingBox.topLeft[0],t.boundingBox.topLeft[1]],bottomRight:[o-1-t.boundingBox.bottomRight[0],t.boundingBox.bottomRight[1]]},mesh:t.mesh.map((function(t){var e=t.slice(0);return e[0]=o-1-t[0],e})),scaledMesh:t.scaledMesh.map((function(t){var e=t.slice(0);return e[0]=o-1-t[0],e}))})}var G=function(){function t(t,e,n,o,r){this.pipeline=new H(t,e,192,192,n,r),this.detectionConfidence=o}return t.getAnnotations=function(){return O},t.getUVCoords=function(){return j},t.prototype.estimateFaces=function(t,o,r){return void 0===o&&(o=!1),void 0===r&&(r=!1),y(this,void 0,void 0,(function(){var i,s,a,c,u,f=this;return v(this,(function(d){switch(d.label){case 0:return i=function(t){return t instanceof h?[t.shape[0],t.shape[1]]:[t.height,t.width]}(t),s=i[1],a=n((function(){return t instanceof h||(t=l.fromPixels(t)),t.toFloat().expandDims(0)})),"webgl"!==b()?[3,2]:(u=m().get("WEBGL_PACK_DEPTHWISECONV"),m().set("WEBGL_PACK_DEPTHWISECONV",!0),[4,this.pipeline.predict(a)]);case 1:return c=d.sent(),m().set("WEBGL_PACK_DEPTHWISECONV",u),[3,4];case 2:return[4,this.pipeline.predict(a)];case 3:c=d.sent(),d.label=4;case 4:return a.dispose(),null!=c&&c.length>0?[2,Promise.all(c.map((function(t,n){return y(f,void 0,void 0,(function(){var i,a,c,u,h,l,f,d,p,m,b,g,P,w,x=this;return v(this,(function(E){switch(E.label){case 0:return i=t.coords,a=t.scaledCoords,c=t.box,u=t.flag,h=[u],o||(h=h.concat([i,a])),[4,Promise.all(h.map((function(t){return y(x,void 0,void 0,(function(){return v(this,(function(e){return[2,t.array()]}))}))})))];case 1:if(l=E.sent(),f=l[0],u.dispose(),f<this.detectionConfidence&&this.pipeline.clearRegionOfInterest(n),o)return d={faceInViewConfidence:f,mesh:i,scaledMesh:a,boundingBox:{topLeft:e(c.startPoint),bottomRight:e(c.endPoint)}},r?[2,A(d,s)]:[2,d];for(w in p=l.slice(1),m=p[0],b=p[1],a.dispose(),i.dispose(),g={faceInViewConfidence:f,boundingBox:{topLeft:c.startPoint,bottomRight:c.endPoint},mesh:m,scaledMesh:b},r&&(g=A(g,s)),P={},O)P[w]=O[w].map((function(t){return g.scaledMesh[t]}));return g.annotations=P,[2,g]}}))}))})))]:[2,[]]}}))}))},t}();export{G as FaceMesh,q as load}; |
@@ -17,2 +17,2 @@ /** | ||
*/ | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("@tensorflow/tfjs-core"),require("@tensorflow/tfjs-converter")):"function"==typeof define&&define.amd?define(["exports","@tensorflow/tfjs-core","@tensorflow/tfjs-converter"],e):e(t.facemesh={},t.tf,t.tf)}(this,function(t,e,s){"use strict";const n=t=>{t.startEndTensor.dispose(),t.startPoint.dispose(),t.endPoint.dispose()},o=t=>({startEndTensor:t,startPoint:e.slice(t,[0,0],[-1,2]),endPoint:e.slice(t,[0,2],[-1,2])}),i=(t,s)=>{const n=e.mul(t.startPoint,s),i=e.mul(t.endPoint,s),r=e.concat2d([n,i],1);return o(r)},r={strides:[8,16],anchors:[2,6]},a=6;function c(t,s){let n,o,i;if(t.topLeft instanceof e.Tensor&&t.bottomRight instanceof e.Tensor){const[r,a]=e.tidy(()=>[e.concat([e.sub(s-1,t.topLeft.slice(0,1)),t.topLeft.slice(1,1)]),e.concat([e.sub(s-1,t.bottomRight.slice(0,1)),t.bottomRight.slice(1,1)])]);n=r,o=a,null!=t.landmarks&&(i=e.tidy(()=>{const n=e.sub(e.tensor1d([s-1,0]),t.landmarks),o=e.tensor1d([1,-1]);return e.mul(n,o)}))}else{const[e,r]=t.topLeft,[a,c]=t.bottomRight;n=[s-1-e,r],o=[s-1-a,c],null!=t.landmarks&&(i=t.landmarks.map(t=>[s-1-t[0],t[1]]))}const r={topLeft:n,bottomRight:o};return null!=i&&(r.landmarks=i),null!=t.probability&&(r.probability=t.probability instanceof e.Tensor?t.probability.clone():t.probability),r}function l(t,s){return e.tidy(()=>{let e;return e=t.hasOwnProperty("box")?t.box:t,i(e,s).startEndTensor.squeeze()})}class h{constructor(t,s,n,o,i,a){this.blazeFaceModel=t,this.width=s,this.height=n,this.maxFaces=o,this.anchorsData=function(t,e,s){const n=[];for(let o=0;o<s.strides.length;o++){const i=s.strides[o],r=Math.floor((e+i-1)/i),a=Math.floor((t+i-1)/i),c=s.anchors[o];for(let t=0;t<r;t++){const e=i*(t+.5);for(let t=0;t<a;t++){const s=i*(t+.5);for(let t=0;t<c;t++)n.push([s,e])}}}return n}(s,n,r),this.anchors=e.tensor2d(this.anchorsData),this.inputSizeData=[s,n],this.inputSize=e.tensor1d([s,n]),this.iouThreshold=i,this.scoreThreshold=a}async getBoundingBoxes(t,s,n=!0){const[i,r,c]=e.tidy(()=>{const s=t.resizeBilinear([this.width,this.height]),n=e.mul(e.sub(s.div(255),.5),2),o=this.blazeFaceModel.predict(n).squeeze(),i=function(t,s,n){const o=e.slice(t,[0,1],[-1,2]),i=e.add(o,s),r=e.slice(t,[0,3],[-1,2]),a=e.div(r,n),c=e.div(i,n),l=e.div(a,2),h=e.sub(c,l),d=e.add(c,l),u=e.mul(h,n),f=e.mul(d,n);return e.concat2d([u,f],1)}(o,this.anchors,this.inputSize),r=e.slice(o,[0,0],[-1,1]);return[o,i,e.sigmoid(r).squeeze()]}),l=console.warn;console.warn=(()=>{});const h=e.image.nonMaxSuppression(r,c,this.maxFaces,this.iouThreshold,this.scoreThreshold);console.warn=l;const d=await h.array();h.dispose();let u=d.map(t=>e.slice(r,[t,0],[1,-1]));s||(u=await Promise.all(u.map(async t=>{const e=await t.array();return t.dispose(),e})));const f=t.shape[1],p=t.shape[2];let m;m=s?e.div([p,f],this.inputSize):[p/this.inputSizeData[0],f/this.inputSizeData[1]];const g=[];for(let t=0;t<u.length;t++){const r=u[t],l=e.tidy(()=>{const l=o(r instanceof e.Tensor?r:e.tensor2d(r));if(!n)return l;const h=d[t];let u;return u=s?this.anchors.slice([h,0],[1,2]):this.anchorsData[h],{box:l,landmarks:e.slice(i,[h,a-1],[1,-1]).squeeze().reshape([a,-1]),probability:e.slice(c,[h],[1]),anchor:u}});g.push(l)}return r.dispose(),c.dispose(),i.dispose(),{boxes:g,scaleFactor:m}}async estimateFaces(t,s=!1,o=!1,i=!0){const[,r]=function(t){return t instanceof e.Tensor?[t.shape[0],t.shape[1]]:[t.height,t.width]}(t),a=e.tidy(()=>(t instanceof e.Tensor||(t=e.browser.fromPixels(t)),t.toFloat().expandDims(0))),{boxes:h,scaleFactor:d}=await this.getBoundingBoxes(a,s,i);return a.dispose(),s?h.map(t=>{const e=l(t,d);let s={topLeft:e.slice([0],[2]),bottomRight:e.slice([2],[2])};if(i){const{landmarks:e,probability:n,anchor:o}=t,i=e.add(o).mul(d);s.landmarks=i,s.probability=n}return o&&(s=c(s,r)),s}):Promise.all(h.map(async t=>{const e=l(t,d);let s;if(i){const[o,i,r]=await Promise.all([t.landmarks,e,t.probability].map(async t=>t.array())),a=t.anchor,[c,l]=d,h=o.map(t=>[(t[0]+a[0])*c,(t[1]+a[1])*l]);s={topLeft:i.slice(0,2),bottomRight:i.slice(2),landmarks:h,probability:r},n(t.box),t.landmarks.dispose(),t.probability.dispose()}else{const t=await e.array();s={topLeft:t.slice(0,2),bottomRight:t.slice(2)}}return e.dispose(),o&&(s=c(s,r)),s}))}}const d="https://tfhub.dev/tensorflow/tfjs-model/blazeface/1/default/1";const u={silhouette:[10,338,297,332,284,251,389,356,454,323,361,288,397,365,379,378,400,377,152,148,176,149,150,136,172,58,132,93,234,127,162,21,54,103,67,109],lipsUpperOuter:[61,185,40,39,37,0,267,269,270,409,291],lipsLowerOuter:[146,91,181,84,17,314,405,321,375,291],lipsUpperInner:[78,191,80,81,82,13,312,311,310,415,308],lipsLowerInner:[78,95,88,178,87,14,317,402,318,324,308],rightEyeUpper0:[246,161,160,159,158,157,173],rightEyeLower0:[33,7,163,144,145,153,154,155,133],rightEyeUpper1:[247,30,29,27,28,56,190],rightEyeLower1:[130,25,110,24,23,22,26,112,243],rightEyeUpper2:[113,225,224,223,222,221,189],rightEyeLower2:[226,31,228,229,230,231,232,233,244],rightEyeLower3:[143,111,117,118,119,120,121,128,245],rightEyebrowUpper:[156,70,63,105,66,107,55,193],rightEyebrowLower:[35,124,46,53,52,65],leftEyeUpper0:[466,388,387,386,385,384,398],leftEyeLower0:[263,249,390,373,374,380,381,382,362],leftEyeUpper1:[467,260,259,257,258,286,414],leftEyeLower1:[359,255,339,254,253,252,256,341,463],leftEyeUpper2:[342,445,444,443,442,441,413],leftEyeLower2:[446,261,448,449,450,451,452,453,464],leftEyeLower3:[372,340,346,347,348,349,350,357,465],leftEyebrowUpper:[383,300,293,334,296,336,285,417],leftEyebrowLower:[265,353,276,283,282,295],midwayBetweenEyes:[168],noseTip:[1],noseBottom:[2],noseRightCorner:[98],noseLeftCorner:[327],rightCheek:[205],leftCheek:[425]};function f(t){null!=t&&null!=t.startPoint&&(t.startEndTensor.dispose(),t.startPoint.dispose(),t.endPoint.dispose())}function p(t,s,n){return{startEndTensor:t,startPoint:null!=s?s:e.slice(t,[0,0],[-1,2]),endPoint:null!=n?n:e.slice(t,[0,2],[-1,2])}}function m(t){return e.tidy(()=>{const s=e.sub(t.endPoint,t.startPoint);return e.abs(s)})}function g(t,s=1.5){return e.tidy(()=>{const n=function(t){return e.tidy(()=>{const s=e.div(e.sub(t.endPoint,t.startPoint),2);return e.add(t.startPoint,s)})}(t),o=m(t),i=e.mul(e.div(o,2),s),r=e.sub(n,i),a=e.add(n,i);return p(e.concat2d([r,a],1),r,a)})}const b=468,y=.25;class x{constructor(t,e,s,n,o,i){this.regionsOfInterest=[],this.runsWithoutFaceDetector=0,this.boundingBoxDetector=t,this.meshDetector=e,this.meshWidth=s,this.meshHeight=n,this.maxContinuousChecks=o,this.maxFaces=i}async predict(t){if(this.shouldUpdateRegionsOfInterest()){const s=!0,n=!1,{boxes:o,scaleFactor:i}=await this.boundingBoxDetector.getBoundingBoxes(t,s,n);if(0===o.length)return i.dispose(),this.clearAllRegionsOfInterest(),null;const r=o.map(t=>g(function(t,s){const n=e.mul(t.startPoint,s),o=e.mul(t.endPoint,s);return p(e.concat2d([n,o],1))}(t,i)));o.forEach(f),this.updateRegionsOfInterest(r),this.runsWithoutFaceDetector=0}else this.runsWithoutFaceDetector++;return e.tidy(()=>this.regionsOfInterest.map((s,n)=>{const o=function(t,s,n){const o=s.shape[1],i=s.shape[2],r=t.startEndTensor;return e.tidy(()=>{const t=e.concat2d([r.slice([0,1],[-1,1]),r.slice([0,0],[-1,1]),r.slice([0,3],[-1,1]),r.slice([0,2],[-1,1])],0),a=e.div(t.transpose(),[o,i,o,i]);return e.image.cropAndResize(s,a,[0],n)})}(s,t,[this.meshHeight,this.meshWidth]).div(255),[,i,r]=this.meshDetector.predict(o),a=e.reshape(r,[-1,3]),c=e.div(m(s),[this.meshWidth,this.meshHeight]),l=e.mul(a,c.concat(e.tensor2d([1],[1,1]),1)).add(s.startPoint.concat(e.tensor2d([0],[1,1]),1)),h=this.calculateLandmarksBoundingBox(l);return f(this.regionsOfInterest[n]),this.regionsOfInterest[n]=h,{coords:a,scaledCoords:l,box:h,flag:i.squeeze()}}))}updateRegionsOfInterest(t){for(let e=0;e<t.length;e++){const s=t[e],n=this.regionsOfInterest[e];let o=0;if(n&&n.startPoint){const[t,e,i,r]=s.startEndTensor.arraySync()[0],[a,c,l,h]=n.startEndTensor.arraySync()[0],d=Math.max(t,a),u=Math.max(e,c),f=(Math.min(i,l)-d)*(Math.min(r,h)-u);o=f/((i-t)*(r-e)+(l-a)*(h-e)-f)}o>y?f(s):(this.regionsOfInterest[e]=s,f(n))}for(let e=t.length;e<this.regionsOfInterest.length;e++)f(this.regionsOfInterest[e]);this.regionsOfInterest=this.regionsOfInterest.slice(0,t.length)}clearRegionOfInterest(t){null!=this.regionsOfInterest[t]&&(f(this.regionsOfInterest[t]),this.regionsOfInterest=[...this.regionsOfInterest.slice(0,t),...this.regionsOfInterest.slice(t+1)])}clearAllRegionsOfInterest(){for(let t=0;t<this.regionsOfInterest.length;t++)f(this.regionsOfInterest[t]);this.regionsOfInterest=[]}shouldUpdateRegionsOfInterest(){const t=this.regionsOfInterest.length,e=0===t;return 1===this.maxFaces||e?e:t!==this.maxFaces&&this.runsWithoutFaceDetector>=this.maxContinuousChecks}calculateLandmarksBoundingBox(t){const s=t.slice([0,0],[b,1]),n=t.slice([0,1],[b,1]);return g(p(e.stack([s.min(),n.min(),s.max(),n.max()]).expandDims(0)))}}const w=[[.499976992607117,.652534008026123],[.500025987625122,.547487020492554],[.499974012374878,.602371990680695],[.482113003730774,.471979022026062],[.500150978565216,.527155995368958],[.499909996986389,.498252987861633],[.499523013830185,.40106201171875],[.289712011814117,.380764007568359],[.499954998493195,.312398016452789],[.499987006187439,.269918978214264],[.500023007392883,.107050001621246],[.500023007392883,.666234016418457],[.5000159740448,.679224014282227],[.500023007392883,.692348003387451],[.499976992607117,.695277988910675],[.499976992607117,.70593398809433],[.499976992607117,.719385027885437],[.499976992607117,.737019002437592],[.499967992305756,.781370997428894],[.499816000461578,.562981009483337],[.473773002624512,.573909997940063],[.104906998574734,.254140973091125],[.365929991006851,.409575998783112],[.338757991790771,.41302502155304],[.311120003461838,.409460008144379],[.274657994508743,.389131009578705],[.393361985683441,.403706014156342],[.345234006643295,.344011008739471],[.370094001293182,.346076011657715],[.319321990013123,.347265005111694],[.297903001308441,.353591024875641],[.24779200553894,.410809993743896],[.396889001131058,.842755019664764],[.280097991228104,.375599980354309],[.106310002505779,.399955987930298],[.2099249958992,.391353011131287],[.355807989835739,.534406006336212],[.471751004457474,.65040397644043],[.474155008792877,.680191993713379],[.439785003662109,.657229006290436],[.414617002010345,.66654098033905],[.450374007225037,.680860996246338],[.428770989179611,.682690978050232],[.374971002340317,.727805018424988],[.486716985702515,.547628998756409],[.485300987958908,.527395009994507],[.257764995098114,.314490020275116],[.401223003864288,.455172002315521],[.429818987846375,.548614978790283],[.421351999044418,.533740997314453],[.276895999908447,.532056987285614],[.483370006084442,.499586999416351],[.33721199631691,.282882988452911],[.296391993761063,.293242990970612],[.169294998049736,.193813979625702],[.447580009698868,.302609980106354],[.392390012741089,.353887975215912],[.354490011930466,.696784019470215],[.067304998636246,.730105042457581],[.442739009857178,.572826027870178],[.457098007202148,.584792017936707],[.381974011659622,.694710969924927],[.392388999462128,.694203019142151],[.277076005935669,.271932005882263],[.422551989555359,.563233017921448],[.385919004678726,.281364023685455],[.383103013038635,.255840003490448],[.331431001424789,.119714021682739],[.229923993349075,.232002973556519],[.364500999450684,.189113974571228],[.229622006416321,.299540996551514],[.173287004232407,.278747975826263],[.472878992557526,.666198015213013],[.446828007698059,.668527007102966],[.422762006521225,.673889994621277],[.445307999849319,.580065965652466],[.388103008270264,.693961024284363],[.403039008378983,.706539988517761],[.403629004955292,.693953037261963],[.460041999816895,.557139039039612],[.431158006191254,.692366003990173],[.452181994915009,.692366003990173],[.475387006998062,.692366003990173],[.465828001499176,.779190003871918],[.472328990697861,.736225962638855],[.473087012767792,.717857003211975],[.473122000694275,.704625964164734],[.473033010959625,.695277988910675],[.427942007780075,.695277988910675],[.426479011774063,.703539967536926],[.423162013292313,.711845993995667],[.4183090031147,.720062971115112],[.390094995498657,.639572978019714],[.013953999616206,.560034036636353],[.499913990497589,.58014702796936],[.413199990987778,.69539999961853],[.409626007080078,.701822996139526],[.468080013990402,.601534962654114],[.422728985548019,.585985004901886],[.463079988956451,.593783974647522],[.37211999297142,.47341400384903],[.334562003612518,.496073007583618],[.411671012639999,.546965003013611],[.242175996303558,.14767599105835],[.290776997804642,.201445996761322],[.327338010072708,.256527006626129],[.399509996175766,.748921036720276],[.441727995872498,.261676013469696],[.429764986038208,.187834024429321],[.412198007106781,.108901023864746],[.288955003023148,.398952007293701],[.218936994671822,.435410976409912],[.41278201341629,.398970007896423],[.257135003805161,.355440020561218],[.427684992551804,.437960982322693],[.448339998722076,.536936044692993],[.178560003638268,.45755398273468],[.247308000922203,.457193970680237],[.286267012357712,.467674970626831],[.332827985286713,.460712015628815],[.368755996227264,.447206974029541],[.398963987827301,.432654976844788],[.476410001516342,.405806005001068],[.189241006970406,.523923993110657],[.228962004184723,.348950982093811],[.490725994110107,.562400996685028],[.404670000076294,.485132992267609],[.019469000399113,.401564002037048],[.426243007183075,.420431017875671],[.396993011236191,.548797011375427],[.266469985246658,.376977026462555],[.439121007919312,.51895797252655],[.032313998788595,.644356966018677],[.419054001569748,.387154996395111],[.462783008813858,.505746960639954],[.238978996872902,.779744982719421],[.198220998048782,.831938028335571],[.107550002634525,.540755033493042],[.183610007166862,.740257024765015],[.134409993886948,.333683013916016],[.385764002799988,.883153975009918],[.490967005491257,.579378008842468],[.382384985685349,.508572995662689],[.174399003386497,.397670984268188],[.318785011768341,.39623498916626],[.343364000320435,.400596976280212],[.396100014448166,.710216999053955],[.187885001301765,.588537991046906],[.430987000465393,.944064974784851],[.318993002176285,.898285031318665],[.266247987747192,.869701027870178],[.500023007392883,.190576016902924],[.499976992607117,.954452991485596],[.366169989109039,.398822009563446],[.393207013607025,.39553701877594],[.410373002290726,.391080021858215],[.194993004202843,.342101991176605],[.388664990663528,.362284004688263],[.365961998701096,.355970978736877],[.343364000320435,.355356991291046],[.318785011768341,.35834002494812],[.301414996385574,.363156020641327],[.058132998645306,.319076001644135],[.301414996385574,.387449026107788],[.499987989664078,.618434011936188],[.415838003158569,.624195992946625],[.445681989192963,.566076993942261],[.465844005346298,.620640993118286],[.49992299079895,.351523995399475],[.288718998432159,.819945991039276],[.335278987884521,.852819979190826],[.440512001514435,.902418971061707],[.128294005990028,.791940987110138],[.408771991729736,.373893976211548],[.455606997013092,.451801002025604],[.499877005815506,.908990025520325],[.375436991453171,.924192011356354],[.11421000212431,.615022003650665],[.448662012815475,.695277988910675],[.4480200111866,.704632043838501],[.447111994028091,.715808033943176],[.444831997156143,.730794012546539],[.430011987686157,.766808986663818],[.406787008047104,.685672998428345],[.400738000869751,.681069016456604],[.392399996519089,.677703022956848],[.367855995893478,.663918972015381],[.247923001646996,.601333022117615],[.452769994735718,.420849978923798],[.43639200925827,.359887003898621],[.416164010763168,.368713974952698],[.413385987281799,.692366003990173],[.228018000721931,.683571994304657],[.468268007040024,.352671027183533],[.411361992359161,.804327011108398],[.499989002943039,.469825029373169],[.479153990745544,.442654013633728],[.499974012374878,.439637005329132],[.432112008333206,.493588984012604],[.499886006116867,.866917014122009],[.49991300702095,.821729004383087],[.456548988819122,.819200992584229],[.344549000263214,.745438992977142],[.37890899181366,.574010014533997],[.374292999505997,.780184984207153],[.319687992334366,.570737957954407],[.357154995203018,.604269981384277],[.295284003019333,.621580958366394],[.447750002145767,.862477004528046],[.410986006259918,.508723020553589],[.31395098567009,.775308012962341],[.354128003120422,.812552988529205],[.324548006057739,.703992962837219],[.189096003770828,.646299958229065],[.279776990413666,.71465802192688],[.1338230073452,.682700991630554],[.336768001317978,.644733011722565],[.429883986711502,.466521978378296],[.455527991056442,.548622965812683],[.437114000320435,.558896005153656],[.467287987470627,.529924988746643],[.414712011814117,.335219979286194],[.37704598903656,.322777986526489],[.344107985496521,.320150971412659],[.312875986099243,.32233202457428],[.283526003360748,.333190023899078],[.241245999932289,.382785975933075],[.102986000478268,.468762993812561],[.267612010240555,.424560010433197],[.297879010438919,.433175981044769],[.333433985710144,.433878004550934],[.366427004337311,.426115989685059],[.396012008190155,.416696012020111],[.420121014118195,.41022801399231],[.007561000064015,.480777025222778],[.432949006557465,.569517970085144],[.458638995885849,.479089021682739],[.473466008901596,.545744001865387],[.476087987422943,.563830018043518],[.468472003936768,.555056989192963],[.433990985155106,.582361996173859],[.483518004417419,.562983989715576],[.482482999563217,.57784903049469],[.42645001411438,.389798998832703],[.438998997211456,.39649498462677],[.450067013502121,.400434017181396],[.289712011814117,.368252992630005],[.276670008897781,.363372981548309],[.517862021923065,.471948027610779],[.710287988185883,.380764007568359],[.526226997375488,.573909997940063],[.895093023777008,.254140973091125],[.634069979190826,.409575998783112],[.661242008209229,.41302502155304],[.688880026340485,.409460008144379],[.725341975688934,.389131009578705],[.606630027294159,.40370500087738],[.654766023159027,.344011008739471],[.629905998706818,.346076011657715],[.680678009986877,.347265005111694],[.702096998691559,.353591024875641],[.75221198797226,.410804986953735],[.602918028831482,.842862963676453],[.719901978969574,.375599980354309],[.893692970275879,.399959981441498],[.790081977844238,.391354024410248],[.643998026847839,.534487962722778],[.528249025344849,.65040397644043],[.525849997997284,.680191040039062],[.560214996337891,.657229006290436],[.585384011268616,.66654098033905],[.549625992774963,.680860996246338],[.57122802734375,.682691991329193],[.624852001667023,.72809898853302],[.513050019741058,.547281980514526],[.51509702205658,.527251958847046],[.742246985435486,.314507007598877],[.598631024360657,.454979002475739],[.570338010787964,.548575043678284],[.578631997108459,.533622980117798],[.723087012767792,.532054007053375],[.516445994377136,.499638974666595],[.662801027297974,.282917976379395],[.70362401008606,.293271005153656],[.830704987049103,.193813979625702],[.552385985851288,.302568018436432],[.607609987258911,.353887975215912],[.645429015159607,.696707010269165],[.932694971561432,.730105042457581],[.557260990142822,.572826027870178],[.542901992797852,.584792017936707],[.6180260181427,.694710969924927],[.607590973377228,.694203019142151],[.722943007946014,.271963000297546],[.577413976192474,.563166975975037],[.614082992076874,.281386971473694],[.616907000541687,.255886018276215],[.668509006500244,.119913995265961],[.770092010498047,.232020974159241],[.635536015033722,.189248979091644],[.77039098739624,.299556016921997],[.826722025871277,.278755009174347],[.527121007442474,.666198015213013],[.553171992301941,.668527007102966],[.577238023281097,.673889994621277],[.554691970348358,.580065965652466],[.611896991729736,.693961024284363],[.59696102142334,.706539988517761],[.596370995044708,.693953037261963],[.539958000183105,.557139039039612],[.568841993808746,.692366003990173],[.547818005084991,.692366003990173],[.52461302280426,.692366003990173],[.534089982509613,.779141008853912],[.527670979499817,.736225962638855],[.526912987232208,.717857003211975],[.526877999305725,.704625964164734],[.526966989040375,.695277988910675],[.572058022022247,.695277988910675],[.573521018028259,.703539967536926],[.57683801651001,.711845993995667],[.581691026687622,.720062971115112],[.609944999217987,.639909982681274],[.986046016216278,.560034036636353],[.5867999792099,.69539999961853],[.590372025966644,.701822996139526],[.531915009021759,.601536989212036],[.577268004417419,.585934996604919],[.536915004253387,.593786001205444],[.627542972564697,.473352015018463],[.665585994720459,.495950996875763],[.588353991508484,.546862006187439],[.757824003696442,.14767599105835],[.709249973297119,.201507985591888],[.672684013843536,.256581008434296],[.600408971309662,.74900496006012],[.55826598405838,.261672019958496],[.570303976535797,.187870979309082],[.588165998458862,.109044015407562],[.711045026779175,.398952007293701],[.781069993972778,.435405015945435],[.587247014045715,.398931980133057],[.742869973182678,.355445981025696],[.572156012058258,.437651991844177],[.55186802148819,.536570012569427],[.821442008018494,.457556009292603],[.752701997756958,.457181990146637],[.71375697851181,.467626988887787],[.66711300611496,.460672974586487],[.631101012229919,.447153985500336],[.6008620262146,.432473003864288],[.523481011390686,.405627012252808],[.810747981071472,.523926019668579],[.771045982837677,.348959028720856],[.509127020835876,.562718033790588],[.595292985439301,.485023975372314],[.980530977249146,.401564002037048],[.573499977588654,.420000016689301],[.602994978427887,.548687994480133],[.733529984951019,.376977026462555],[.560611009597778,.519016981124878],[.967685997486115,.644356966018677],[.580985009670258,.387160003185272],[.537728011608124,.505385041236877],[.760966002941132,.779752969741821],[.801778972148895,.831938028335571],[.892440974712372,.54076099395752],[.816350996494293,.740260004997253],[.865594983100891,.333687007427216],[.614073991775513,.883246004581451],[.508952975273132,.579437971115112],[.617941975593567,.508316040039062],[.825608015060425,.397674977779388],[.681214988231659,.39623498916626],[.656635999679565,.400596976280212],[.603900015354156,.710216999053955],[.81208598613739,.588539004325867],[.56801301240921,.944564998149872],[.681007981300354,.898285031318665],[.733752012252808,.869701027870178],[.633830010890961,.398822009563446],[.606792986392975,.39553701877594],[.589659988880157,.391062021255493],[.805015981197357,.342108011245728],[.611334979534149,.362284004688263],[.634037971496582,.355970978736877],[.656635999679565,.355356991291046],[.681214988231659,.35834002494812],[.698584973812103,.363156020641327],[.941866993904114,.319076001644135],[.698584973812103,.387449026107788],[.584177017211914,.624107003211975],[.554318010807037,.566076993942261],[.534153997898102,.62064003944397],[.711217999458313,.819975018501282],[.664629995822906,.852871000766754],[.559099972248077,.902631998062134],[.871706008911133,.791940987110138],[.591234028339386,.373893976211548],[.544341027736664,.451583981513977],[.624562978744507,.924192011356354],[.88577002286911,.615028977394104],[.551338016986847,.695277988910675],[.551980018615723,.704632043838501],[.552887976169586,.715808033943176],[.555167973041534,.730794012546539],[.569944024085999,.767035007476807],[.593203008174896,.685675978660583],[.599261999130249,.681069016456604],[.607599973678589,.677703022956848],[.631937980651855,.663500010967255],[.752032995223999,.601315021514893],[.547226011753082,.420395016670227],[.563543975353241,.359827995300293],[.583841025829315,.368713974952698],[.586614012718201,.692366003990173],[.771915018558502,.683578014373779],[.531597018241882,.352482974529266],[.588370978832245,.804440975189209],[.52079701423645,.442565023899078],[.567984998226166,.493479013442993],[.543282985687256,.819254994392395],[.655317008495331,.745514988899231],[.621008992195129,.574018001556396],[.625559985637665,.78031200170517],[.680198013782501,.570719003677368],[.64276397228241,.604337990283966],[.704662978649139,.621529996395111],[.552012026309967,.862591981887817],[.589071989059448,.508637011051178],[.685944974422455,.775357007980347],[.645735025405884,.812640011310577],[.675342977046967,.703978002071381],[.810858011245728,.646304965019226],[.72012197971344,.714666962623596],[.866151988506317,.682704985141754],[.663187026977539,.644596993923187],[.570082008838654,.466325998306274],[.544561982154846,.548375964164734],[.562758982181549,.558784961700439],[.531987011432648,.530140042304993],[.585271000862122,.335177004337311],[.622952997684479,.32277899980545],[.655896008014679,.320163011550903],[.687132000923157,.322345972061157],[.716481983661652,.333200991153717],[.758756995201111,.382786989212036],[.897013008594513,.468769013881683],[.732392013072968,.424547016620636],[.70211398601532,.433162987232208],[.66652500629425,.433866024017334],[.633504986763,.426087975502014],[.603875994682312,.416586995124817],[.579657971858978,.409945011138916],[.992439985275269,.480777025222778],[.567192018032074,.569419980049133],[.54136598110199,.478899002075195],[.526564002037048,.546118021011353],[.523913025856018,.563830018043518],[.531529009342194,.555056989192963],[.566035985946655,.582329034805298],[.51631098985672,.563053965568542],[.5174720287323,.577877044677734],[.573594987392426,.389806985855103],[.560697972774506,.395331978797913],[.549755990505219,.399751007556915],[.710287988185883,.368252992630005],[.723330020904541,.363372981548309]],P="https://tfhub.dev/mediapipe/tfjs-model/facemesh/1/default/1",E=192,O=192;function I(t,s){if(t.mesh instanceof e.Tensor){const[n,o,i,r]=e.tidy(()=>{const n=e.tensor1d([s-1,0,0]),o=e.tensor1d([1,-1,1]);return e.tidy(()=>[e.concat([e.sub(s-1,t.boundingBox.topLeft.slice(0,1)),t.boundingBox.topLeft.slice(1,1)]),e.concat([e.sub(s-1,t.boundingBox.bottomRight.slice(0,1)),t.boundingBox.bottomRight.slice(1,1)]),e.sub(n,t.mesh).mul(o),e.sub(n,t.scaledMesh).mul(o)])});return Object.assign({},t,{boundingBox:{topLeft:n,bottomRight:o},mesh:i,scaledMesh:r})}return Object.assign({},t,{boundingBox:{topLeft:[s-1-t.boundingBox.topLeft[0],t.boundingBox.topLeft[1]],bottomRight:[s-1-t.boundingBox.bottomRight[0],t.boundingBox.bottomRight[1]]},mesh:t.mesh.map(t=>{const e=t.slice(0);return e[0]=s-1-t[0],e}),scaledMesh:t.scaledMesh.map(t=>{const e=t.slice(0);return e[0]=s-1-t[0],e})})}class L{constructor(t,e,s,n,o){this.pipeline=new x(t,e,E,O,s,o),this.detectionConfidence=n}static getAnnotations(){return u}static getUVCoords(){return w}async estimateFaces(t,s=!1,n=!1){const[,o]=function(t){return t instanceof e.Tensor?[t.shape[0],t.shape[1]]:[t.height,t.width]}(t),i=e.tidy(()=>(t instanceof e.Tensor||(t=e.browser.fromPixels(t)),t.toFloat().expandDims(0))),r=e.env().get("WEBGL_PACK_DEPTHWISECONV");e.env().set("WEBGL_PACK_DEPTHWISECONV",!0);const a=await this.pipeline.predict(i);return e.env().set("WEBGL_PACK_DEPTHWISECONV",r),i.dispose(),null!=a&&a.length>0?Promise.all(a.map(async(t,e)=>{const{coords:i,scaledCoords:r,box:a,flag:c}=t;let l=[c];s||(l=l.concat([i,r,a.startPoint,a.endPoint]));const h=await Promise.all(l.map(async t=>t.array())),d=h[0];if(c.dispose(),d<this.detectionConfidence&&this.pipeline.clearRegionOfInterest(e),s){const t={faceInViewConfidence:d,mesh:i,scaledMesh:r,boundingBox:{topLeft:a.startPoint.squeeze(),bottomRight:a.endPoint.squeeze()}};return n?I(t,o):t}const[f,p,m,g]=h.slice(1);r.dispose(),i.dispose();let b={faceInViewConfidence:d,boundingBox:{topLeft:m,bottomRight:g},mesh:f,scaledMesh:p};n&&(b=I(b,o));const y={};for(const t in u)y[t]=u[t].map(t=>b.scaledMesh[t]);return b.annotations=y,b})):[]}}t.load=async function({maxContinuousChecks:t=5,detectionConfidence:e=.9,maxFaces:n=10,iouThreshold:o=.3,scoreThreshold:i=.75}={}){const[r,a]=await Promise.all([async function(t,e,n){return async function({maxFaces:t=10,inputWidth:e=128,inputHeight:n=128,iouThreshold:o=.3,scoreThreshold:i=.75}={}){const r=await s.loadGraphModel(d,{fromTFHub:!0});return new h(r,e,n,t,o,i)}({maxFaces:t,iouThreshold:e,scoreThreshold:n})}(n,o,i),async function(){return s.loadGraphModel(P,{fromTFHub:!0})}()]);return new L(r,a,t,e,n)},t.FaceMesh=L,Object.defineProperty(t,"__esModule",{value:!0})}); | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("@tensorflow/tfjs-core"),require("@tensorflow/tfjs-converter")):"function"==typeof define&&define.amd?define(["exports","@tensorflow/tfjs-core","@tensorflow/tfjs-converter"],e):e((t=t||self).facemesh={},t.tf,t.tf)}(this,(function(t,e,n){"use strict";var o=function(){return(o=Object.assign||function(t){for(var e,n=1,o=arguments.length;n<o;n++)for(var r in e=arguments[n])Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t}).apply(this,arguments)};function r(t,e,n,o){return new(n||(n=Promise))((function(r,i){function s(t){try{c(o.next(t))}catch(t){i(t)}}function a(t){try{c(o.throw(t))}catch(t){i(t)}}function c(t){var e;t.done?r(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(s,a)}c((o=o.apply(t,e||[])).next())}))}function i(t,e){var n,o,r,i,s={label:0,sent:function(){if(1&r[0])throw r[1];return r[1]},trys:[],ops:[]};return i={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(i){return function(a){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;s;)try{if(n=1,o&&(r=2&i[0]?o.return:i[0]?o.throw||((r=o.return)&&r.call(o),0):o.next)&&!(r=r.call(o,i[1])).done)return r;switch(o=0,r&&(i=[2&i[0],r.value]),i[0]){case 0:case 1:r=i;break;case 4:return s.label++,{value:i[1],done:!1};case 5:s.label++,o=i[1],i=[0];continue;case 7:i=s.ops.pop(),s.trys.pop();continue;default:if(!(r=s.trys,(r=r.length>0&&r[r.length-1])||6!==i[0]&&2!==i[0])){s=0;continue}if(3===i[0]&&(!r||i[1]>r[0]&&i[1]<r[3])){s.label=i[1];break}if(6===i[0]&&s.label<r[1]){s.label=r[1],r=i;break}if(r&&s.label<r[2]){s.label=r[2],s.ops.push(i);break}r[2]&&s.ops.pop(),s.trys.pop();continue}i=e.call(t,s)}catch(t){i=[6,t],o=0}finally{n=r=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}([i,a])}}}const s=t=>({startEndTensor:t,startPoint:e.slice(t,[0,0],[-1,2]),endPoint:e.slice(t,[0,2],[-1,2])}),a={strides:[8,16],anchors:[2,6]};function c(t,n){let o,r,i;if(t.topLeft instanceof e.Tensor&&t.bottomRight instanceof e.Tensor){const[s,a]=e.tidy(()=>[e.concat([e.sub(n-1,t.topLeft.slice(0,1)),t.topLeft.slice(1,1)]),e.concat([e.sub(n-1,t.bottomRight.slice(0,1)),t.bottomRight.slice(1,1)])]);o=s,r=a,null!=t.landmarks&&(i=e.tidy(()=>{const o=e.sub(e.tensor1d([n-1,0]),t.landmarks),r=e.tensor1d([1,-1]);return e.mul(o,r)}))}else{const[e,s]=t.topLeft,[a,c]=t.bottomRight;o=[n-1-e,s],r=[n-1-a,c],null!=t.landmarks&&(i=t.landmarks.map(t=>[n-1-t[0],t[1]]))}const s={topLeft:o,bottomRight:r};return null!=i&&(s.landmarks=i),null!=t.probability&&(s.probability=t.probability instanceof e.Tensor?t.probability.clone():t.probability),s}function u(t,n){return e.tidy(()=>{let o;return o=t.hasOwnProperty("box")?t.box:t,((t,n)=>{const o=e.mul(t.startPoint,n),r=e.mul(t.endPoint,n),i=e.concat2d([o,r],1);return s(i)})(o,n).startEndTensor.squeeze()})}class h{constructor(t,n,o,r,i,s){this.blazeFaceModel=t,this.width=n,this.height=o,this.maxFaces=r,this.anchorsData=function(t,e,n){const o=[];for(let r=0;r<n.strides.length;r++){const i=n.strides[r],s=Math.floor((e+i-1)/i),a=Math.floor((t+i-1)/i),c=n.anchors[r];for(let t=0;t<s;t++){const e=i*(t+.5);for(let t=0;t<a;t++){const n=i*(t+.5);for(let t=0;t<c;t++)o.push([n,e])}}}return o}(n,o,a),this.anchors=e.tensor2d(this.anchorsData),this.inputSizeData=[n,o],this.inputSize=e.tensor1d([n,o]),this.iouThreshold=i,this.scoreThreshold=s}async getBoundingBoxes(t,n,o=!0){const[r,i,a]=e.tidy(()=>{const n=t.resizeBilinear([this.width,this.height]),o=e.mul(e.sub(n.div(255),.5),2),r=this.blazeFaceModel.predict(o).squeeze(),i=function(t,n,o){const r=e.slice(t,[0,1],[-1,2]),i=e.add(r,n),s=e.slice(t,[0,3],[-1,2]),a=e.div(s,o),c=e.div(i,o),u=e.div(a,2),h=e.sub(c,u),l=e.add(c,u),d=e.mul(h,o),f=e.mul(l,o);return e.concat2d([d,f],1)}(r,this.anchors,this.inputSize),s=e.slice(r,[0,0],[-1,1]);return[r,i,e.sigmoid(s).squeeze()]}),c=console.warn;console.warn=()=>{};const u=e.image.nonMaxSuppression(i,a,this.maxFaces,this.iouThreshold,this.scoreThreshold);console.warn=c;const h=await u.array();u.dispose();let l=h.map(t=>e.slice(i,[t,0],[1,-1]));n||(l=await Promise.all(l.map(async t=>{const e=await t.array();return t.dispose(),e})));const d=t.shape[1],f=t.shape[2];let p;p=n?e.div([f,d],this.inputSize):[f/this.inputSizeData[0],d/this.inputSizeData[1]];const m=[];for(let t=0;t<l.length;t++){const i=l[t],c=e.tidy(()=>{const c=s(i instanceof e.Tensor?i:e.tensor2d(i));if(!o)return c;const u=h[t];let l;return l=n?this.anchors.slice([u,0],[1,2]):this.anchorsData[u],{box:c,landmarks:e.slice(r,[u,5],[1,-1]).squeeze().reshape([6,-1]),probability:e.slice(a,[u],[1]),anchor:l}});m.push(c)}return i.dispose(),a.dispose(),r.dispose(),{boxes:m,scaleFactor:p}}async estimateFaces(t,n=!1,o=!1,r=!0){const[,i]=function(t){return t instanceof e.Tensor?[t.shape[0],t.shape[1]]:[t.height,t.width]}(t),s=e.tidy(()=>(t instanceof e.Tensor||(t=e.browser.fromPixels(t)),t.toFloat().expandDims(0))),{boxes:a,scaleFactor:h}=await this.getBoundingBoxes(s,n,r);return s.dispose(),n?a.map(t=>{const e=u(t,h);let n={topLeft:e.slice([0],[2]),bottomRight:e.slice([2],[2])};if(r){const{landmarks:e,probability:o,anchor:r}=t,i=e.add(r).mul(h);n.landmarks=i,n.probability=o}return o&&(n=c(n,i)),n}):Promise.all(a.map(async t=>{const e=u(t,h);let n;if(r){const[o,r,i]=await Promise.all([t.landmarks,e,t.probability].map(async t=>t.array())),s=t.anchor,[a,c]=h,u=o.map(t=>[(t[0]+s[0])*a,(t[1]+s[1])*c]);n={topLeft:r.slice(0,2),bottomRight:r.slice(2),landmarks:u,probability:i},(t=>{t.startEndTensor.dispose(),t.startPoint.dispose(),t.endPoint.dispose()})(t.box),t.landmarks.dispose(),t.probability.dispose()}else{const t=await e.array();n={topLeft:t.slice(0,2),bottomRight:t.slice(2)}}return e.dispose(),o&&(n=c(n,i)),n}))}}async function l({maxFaces:t=10,inputWidth:e=128,inputHeight:o=128,iouThreshold:r=.3,scoreThreshold:i=.75}={}){const s=await n.loadGraphModel("https://tfhub.dev/tensorflow/tfjs-model/blazeface/1/default/1",{fromTFHub:!0});return new h(s,e,o,t,r,i)}var d={silhouette:[10,338,297,332,284,251,389,356,454,323,361,288,397,365,379,378,400,377,152,148,176,149,150,136,172,58,132,93,234,127,162,21,54,103,67,109],lipsUpperOuter:[61,185,40,39,37,0,267,269,270,409,291],lipsLowerOuter:[146,91,181,84,17,314,405,321,375,291],lipsUpperInner:[78,191,80,81,82,13,312,311,310,415,308],lipsLowerInner:[78,95,88,178,87,14,317,402,318,324,308],rightEyeUpper0:[246,161,160,159,158,157,173],rightEyeLower0:[33,7,163,144,145,153,154,155,133],rightEyeUpper1:[247,30,29,27,28,56,190],rightEyeLower1:[130,25,110,24,23,22,26,112,243],rightEyeUpper2:[113,225,224,223,222,221,189],rightEyeLower2:[226,31,228,229,230,231,232,233,244],rightEyeLower3:[143,111,117,118,119,120,121,128,245],rightEyebrowUpper:[156,70,63,105,66,107,55,193],rightEyebrowLower:[35,124,46,53,52,65],leftEyeUpper0:[466,388,387,386,385,384,398],leftEyeLower0:[263,249,390,373,374,380,381,382,362],leftEyeUpper1:[467,260,259,257,258,286,414],leftEyeLower1:[359,255,339,254,253,252,256,341,463],leftEyeUpper2:[342,445,444,443,442,441,413],leftEyeLower2:[446,261,448,449,450,451,452,453,464],leftEyeLower3:[372,340,346,347,348,349,350,357,465],leftEyebrowUpper:[383,300,293,334,296,336,285,417],leftEyebrowLower:[265,353,276,283,282,295],midwayBetweenEyes:[168],noseTip:[1],noseBottom:[2],noseRightCorner:[98],noseLeftCorner:[327],rightCheek:[205],leftCheek:[425]};function f(t){return[Math.abs(t.endPoint[0]-t.startPoint[0]),Math.abs(t.endPoint[1]-t.startPoint[1])]}function p(t){return[t.startPoint[0]+(t.endPoint[0]-t.startPoint[0])/2,t.startPoint[1]+(t.endPoint[1]-t.startPoint[1])/2]}function m(t,e){void 0===e&&(e=1.5);var n=p(t),o=f(t),r=[e*o[0]/2,e*o[1]/2];return{startPoint:[n[0]-r[0],n[1]-r[1]],endPoint:[n[0]+r[0],n[1]+r[1]],landmarks:t.landmarks}}function b(t,e){var n,o=Math.PI/2-Math.atan2(-(e[1]-t[1]),e[0]-t[0]);return(n=o)-2*Math.PI*Math.floor((n+Math.PI)/(2*Math.PI))}function g(t,e){return[[1,0,t],[0,1,e],[0,0,1]]}function y(t,e){for(var n=0,o=0;o<t.length;o++)n+=t[o]*e[o];return n}function P(t,e){for(var n=[],o=0;o<t.length;o++)n.push(t[o][e]);return n}function v(t,e){for(var n=[],o=t.length,r=0;r<o;r++){n.push([]);for(var i=0;i<o;i++)n[r].push(y(t[r],P(e,i)))}return n}function w(t,e){var n=Math.cos(t),o=Math.sin(t),r=[[n,-o,0],[o,n,0],[0,0,1]],i=v(g(e[0],e[1]),r);return v(i,g(-e[0],-e[1]))}var x=[1,168],M=[3,2],E=function(){function t(t,e,n,o,r,i){this.regionsOfInterest=[],this.runsWithoutFaceDetector=0,this.boundingBoxDetector=t,this.meshDetector=e,this.meshWidth=n,this.meshHeight=o,this.maxContinuousChecks=r,this.maxFaces=i}return t.prototype.transformRawCoords=function(t,e,n,o){var r,i,s,a,c=this,u=f({startPoint:e.startPoint,endPoint:e.endPoint}),h=[u[0]/this.meshWidth,u[1]/this.meshHeight],l=t.map((function(t){return[h[0]*(t[0]-c.meshWidth/2),h[1]*(t[1]-c.meshHeight/2),t[2]]})),d=w(n,[0,0]),m=l.map((function(t){return function(t,e){return[y(t,e[0]),y(t,e[1])]}(t,d).concat([t[2]])})),b=(i=[[(r=o)[0][0],r[1][0]],[r[0][1],r[1][1]]],s=[r[0][2],r[1][2]],a=[-y(i[0],s),-y(i[1],s)],[i[0].concat(a[0]),i[1].concat(a[1]),[0,0,1]]),g=p({startPoint:e.startPoint,endPoint:e.endPoint}).concat([1]),P=[y(g,b[0]),y(g,b[1])];return m.map((function(t){return[t[0]+P[0],t[1]+P[1],t[2]]}))},t.prototype.predict=function(t){return r(this,void 0,void 0,(function(){var n,r,s,a,c=this;return i(this,(function(i){switch(i.label){case 0:return this.shouldUpdateRegionsOfInterest()?(!1,!0,[4,this.boundingBoxDetector.getBoundingBoxes(t,!1,!0)]):[3,2];case 1:return n=i.sent(),r=n.boxes,s=n.scaleFactor,0===r.length?(this.regionsOfInterest=[],[2,null]):(a=r.map((function(t){var e,n,r={startPoint:t.box.startPoint.squeeze().arraySync(),endPoint:t.box.endPoint.squeeze().arraySync()},i=m((n=s,{startPoint:[(e=r).startPoint[0]*n[0],e.startPoint[1]*n[1]],endPoint:[e.endPoint[0]*n[0],e.endPoint[1]*n[1]]}));return o({},i,{landmarks:t.landmarks.arraySync()})})),r.forEach((function(t){null!=t&&null!=t.startPoint&&(t.startEndTensor.dispose(),t.startPoint.dispose(),t.endPoint.dispose())})),this.updateRegionsOfInterest(a),this.runsWithoutFaceDetector=0,[3,3]);case 2:this.runsWithoutFaceDetector++,i.label=3;case 3:return[2,e.tidy((function(){return c.regionsOfInterest.map((function(n,r){var i;if(468===n.landmarks.length){var s=x[0],a=x[1];i=b(n.landmarks[s],n.landmarks[a])}else{s=M[0],a=M[1];i=b(n.landmarks[s],n.landmarks[a])}var u=p({startPoint:n.startPoint,endPoint:n.endPoint}),h=[u[0]/t.shape[2],u[1]/t.shape[1]],l=e.image.rotateWithOffset(t,i,0,h),d=w(-i,u),f=function(t,n,o){var r=n.shape[1],i=n.shape[2],s=[[t.startPoint[1]/r,t.startPoint[0]/i,t.endPoint[1]/r,t.endPoint[0]/i]];return e.image.cropAndResize(n,s,[0],o)}({startPoint:n.startPoint,endPoint:n.endPoint},l,[c.meshHeight,c.meshWidth]).div(255),m=c.meshDetector.predict(f),g=m[1],y=m[2],P=e.reshape(y,[-1,3]),v=P.arraySync(),E=c.transformRawCoords(v,n,i,d),L=e.tensor2d(E),k=c.calculateLandmarksBoundingBox(E);return c.regionsOfInterest[r]=o({},k,{landmarks:L.arraySync()}),{coords:P,scaledCoords:L,box:k,flag:g.squeeze()}}))}))]}}))}))},t.prototype.updateRegionsOfInterest=function(t){for(var e=0;e<t.length;e++){var n=t[e],o=this.regionsOfInterest[e],r=0;if(o&&o.startPoint){var i=n.startPoint,s=i[0],a=i[1],c=n.endPoint,u=c[0],h=c[1],l=o.startPoint,d=l[0],f=l[1],p=o.endPoint,m=p[0],b=p[1],g=Math.max(s,d),y=Math.max(a,f),P=(Math.min(u,m)-g)*(Math.min(h,b)-y);r=P/((u-s)*(h-a)+(m-d)*(b-a)-P)}r<.25&&(this.regionsOfInterest[e]=n)}this.regionsOfInterest=this.regionsOfInterest.slice(0,t.length)},t.prototype.clearRegionOfInterest=function(t){null!=this.regionsOfInterest[t]&&(this.regionsOfInterest=this.regionsOfInterest.slice(0,t).concat(this.regionsOfInterest.slice(t+1)))},t.prototype.shouldUpdateRegionsOfInterest=function(){var t=this.regionsOfInterest.length,e=0===t;return 1===this.maxFaces||e?e:t!==this.maxFaces&&this.runsWithoutFaceDetector>=this.maxContinuousChecks},t.prototype.calculateLandmarksBoundingBox=function(t){var e=t.map((function(t){return t[0]})),n=t.map((function(t){return t[1]})),o={startPoint:[Math.min.apply(Math,e),Math.min.apply(Math,n)],endPoint:[Math.max.apply(Math,e),Math.max.apply(Math,n)]};return m({startPoint:o.startPoint,endPoint:o.endPoint})},t}(),L=[[.499976992607117,.652534008026123],[.500025987625122,.547487020492554],[.499974012374878,.602371990680695],[.482113003730774,.471979022026062],[.500150978565216,.527155995368958],[.499909996986389,.498252987861633],[.499523013830185,.40106201171875],[.289712011814117,.380764007568359],[.499954998493195,.312398016452789],[.499987006187439,.269918978214264],[.500023007392883,.107050001621246],[.500023007392883,.666234016418457],[.5000159740448,.679224014282227],[.500023007392883,.692348003387451],[.499976992607117,.695277988910675],[.499976992607117,.70593398809433],[.499976992607117,.719385027885437],[.499976992607117,.737019002437592],[.499967992305756,.781370997428894],[.499816000461578,.562981009483337],[.473773002624512,.573909997940063],[.104906998574734,.254140973091125],[.365929991006851,.409575998783112],[.338757991790771,.41302502155304],[.311120003461838,.409460008144379],[.274657994508743,.389131009578705],[.393361985683441,.403706014156342],[.345234006643295,.344011008739471],[.370094001293182,.346076011657715],[.319321990013123,.347265005111694],[.297903001308441,.353591024875641],[.24779200553894,.410809993743896],[.396889001131058,.842755019664764],[.280097991228104,.375599980354309],[.106310002505779,.399955987930298],[.2099249958992,.391353011131287],[.355807989835739,.534406006336212],[.471751004457474,.65040397644043],[.474155008792877,.680191993713379],[.439785003662109,.657229006290436],[.414617002010345,.66654098033905],[.450374007225037,.680860996246338],[.428770989179611,.682690978050232],[.374971002340317,.727805018424988],[.486716985702515,.547628998756409],[.485300987958908,.527395009994507],[.257764995098114,.314490020275116],[.401223003864288,.455172002315521],[.429818987846375,.548614978790283],[.421351999044418,.533740997314453],[.276895999908447,.532056987285614],[.483370006084442,.499586999416351],[.33721199631691,.282882988452911],[.296391993761063,.293242990970612],[.169294998049736,.193813979625702],[.447580009698868,.302609980106354],[.392390012741089,.353887975215912],[.354490011930466,.696784019470215],[.067304998636246,.730105042457581],[.442739009857178,.572826027870178],[.457098007202148,.584792017936707],[.381974011659622,.694710969924927],[.392388999462128,.694203019142151],[.277076005935669,.271932005882263],[.422551989555359,.563233017921448],[.385919004678726,.281364023685455],[.383103013038635,.255840003490448],[.331431001424789,.119714021682739],[.229923993349075,.232002973556519],[.364500999450684,.189113974571228],[.229622006416321,.299540996551514],[.173287004232407,.278747975826263],[.472878992557526,.666198015213013],[.446828007698059,.668527007102966],[.422762006521225,.673889994621277],[.445307999849319,.580065965652466],[.388103008270264,.693961024284363],[.403039008378983,.706539988517761],[.403629004955292,.693953037261963],[.460041999816895,.557139039039612],[.431158006191254,.692366003990173],[.452181994915009,.692366003990173],[.475387006998062,.692366003990173],[.465828001499176,.779190003871918],[.472328990697861,.736225962638855],[.473087012767792,.717857003211975],[.473122000694275,.704625964164734],[.473033010959625,.695277988910675],[.427942007780075,.695277988910675],[.426479011774063,.703539967536926],[.423162013292313,.711845993995667],[.4183090031147,.720062971115112],[.390094995498657,.639572978019714],[.013953999616206,.560034036636353],[.499913990497589,.58014702796936],[.413199990987778,.69539999961853],[.409626007080078,.701822996139526],[.468080013990402,.601534962654114],[.422728985548019,.585985004901886],[.463079988956451,.593783974647522],[.37211999297142,.47341400384903],[.334562003612518,.496073007583618],[.411671012639999,.546965003013611],[.242175996303558,.14767599105835],[.290776997804642,.201445996761322],[.327338010072708,.256527006626129],[.399509996175766,.748921036720276],[.441727995872498,.261676013469696],[.429764986038208,.187834024429321],[.412198007106781,.108901023864746],[.288955003023148,.398952007293701],[.218936994671822,.435410976409912],[.41278201341629,.398970007896423],[.257135003805161,.355440020561218],[.427684992551804,.437960982322693],[.448339998722076,.536936044692993],[.178560003638268,.45755398273468],[.247308000922203,.457193970680237],[.286267012357712,.467674970626831],[.332827985286713,.460712015628815],[.368755996227264,.447206974029541],[.398963987827301,.432654976844788],[.476410001516342,.405806005001068],[.189241006970406,.523923993110657],[.228962004184723,.348950982093811],[.490725994110107,.562400996685028],[.404670000076294,.485132992267609],[.019469000399113,.401564002037048],[.426243007183075,.420431017875671],[.396993011236191,.548797011375427],[.266469985246658,.376977026462555],[.439121007919312,.51895797252655],[.032313998788595,.644356966018677],[.419054001569748,.387154996395111],[.462783008813858,.505746960639954],[.238978996872902,.779744982719421],[.198220998048782,.831938028335571],[.107550002634525,.540755033493042],[.183610007166862,.740257024765015],[.134409993886948,.333683013916016],[.385764002799988,.883153975009918],[.490967005491257,.579378008842468],[.382384985685349,.508572995662689],[.174399003386497,.397670984268188],[.318785011768341,.39623498916626],[.343364000320435,.400596976280212],[.396100014448166,.710216999053955],[.187885001301765,.588537991046906],[.430987000465393,.944064974784851],[.318993002176285,.898285031318665],[.266247987747192,.869701027870178],[.500023007392883,.190576016902924],[.499976992607117,.954452991485596],[.366169989109039,.398822009563446],[.393207013607025,.39553701877594],[.410373002290726,.391080021858215],[.194993004202843,.342101991176605],[.388664990663528,.362284004688263],[.365961998701096,.355970978736877],[.343364000320435,.355356991291046],[.318785011768341,.35834002494812],[.301414996385574,.363156020641327],[.058132998645306,.319076001644135],[.301414996385574,.387449026107788],[.499987989664078,.618434011936188],[.415838003158569,.624195992946625],[.445681989192963,.566076993942261],[.465844005346298,.620640993118286],[.49992299079895,.351523995399475],[.288718998432159,.819945991039276],[.335278987884521,.852819979190826],[.440512001514435,.902418971061707],[.128294005990028,.791940987110138],[.408771991729736,.373893976211548],[.455606997013092,.451801002025604],[.499877005815506,.908990025520325],[.375436991453171,.924192011356354],[.11421000212431,.615022003650665],[.448662012815475,.695277988910675],[.4480200111866,.704632043838501],[.447111994028091,.715808033943176],[.444831997156143,.730794012546539],[.430011987686157,.766808986663818],[.406787008047104,.685672998428345],[.400738000869751,.681069016456604],[.392399996519089,.677703022956848],[.367855995893478,.663918972015381],[.247923001646996,.601333022117615],[.452769994735718,.420849978923798],[.43639200925827,.359887003898621],[.416164010763168,.368713974952698],[.413385987281799,.692366003990173],[.228018000721931,.683571994304657],[.468268007040024,.352671027183533],[.411361992359161,.804327011108398],[.499989002943039,.469825029373169],[.479153990745544,.442654013633728],[.499974012374878,.439637005329132],[.432112008333206,.493588984012604],[.499886006116867,.866917014122009],[.49991300702095,.821729004383087],[.456548988819122,.819200992584229],[.344549000263214,.745438992977142],[.37890899181366,.574010014533997],[.374292999505997,.780184984207153],[.319687992334366,.570737957954407],[.357154995203018,.604269981384277],[.295284003019333,.621580958366394],[.447750002145767,.862477004528046],[.410986006259918,.508723020553589],[.31395098567009,.775308012962341],[.354128003120422,.812552988529205],[.324548006057739,.703992962837219],[.189096003770828,.646299958229065],[.279776990413666,.71465802192688],[.1338230073452,.682700991630554],[.336768001317978,.644733011722565],[.429883986711502,.466521978378296],[.455527991056442,.548622965812683],[.437114000320435,.558896005153656],[.467287987470627,.529924988746643],[.414712011814117,.335219979286194],[.37704598903656,.322777986526489],[.344107985496521,.320150971412659],[.312875986099243,.32233202457428],[.283526003360748,.333190023899078],[.241245999932289,.382785975933075],[.102986000478268,.468762993812561],[.267612010240555,.424560010433197],[.297879010438919,.433175981044769],[.333433985710144,.433878004550934],[.366427004337311,.426115989685059],[.396012008190155,.416696012020111],[.420121014118195,.41022801399231],[.007561000064015,.480777025222778],[.432949006557465,.569517970085144],[.458638995885849,.479089021682739],[.473466008901596,.545744001865387],[.476087987422943,.563830018043518],[.468472003936768,.555056989192963],[.433990985155106,.582361996173859],[.483518004417419,.562983989715576],[.482482999563217,.57784903049469],[.42645001411438,.389798998832703],[.438998997211456,.39649498462677],[.450067013502121,.400434017181396],[.289712011814117,.368252992630005],[.276670008897781,.363372981548309],[.517862021923065,.471948027610779],[.710287988185883,.380764007568359],[.526226997375488,.573909997940063],[.895093023777008,.254140973091125],[.634069979190826,.409575998783112],[.661242008209229,.41302502155304],[.688880026340485,.409460008144379],[.725341975688934,.389131009578705],[.606630027294159,.40370500087738],[.654766023159027,.344011008739471],[.629905998706818,.346076011657715],[.680678009986877,.347265005111694],[.702096998691559,.353591024875641],[.75221198797226,.410804986953735],[.602918028831482,.842862963676453],[.719901978969574,.375599980354309],[.893692970275879,.399959981441498],[.790081977844238,.391354024410248],[.643998026847839,.534487962722778],[.528249025344849,.65040397644043],[.525849997997284,.680191040039062],[.560214996337891,.657229006290436],[.585384011268616,.66654098033905],[.549625992774963,.680860996246338],[.57122802734375,.682691991329193],[.624852001667023,.72809898853302],[.513050019741058,.547281980514526],[.51509702205658,.527251958847046],[.742246985435486,.314507007598877],[.598631024360657,.454979002475739],[.570338010787964,.548575043678284],[.578631997108459,.533622980117798],[.723087012767792,.532054007053375],[.516445994377136,.499638974666595],[.662801027297974,.282917976379395],[.70362401008606,.293271005153656],[.830704987049103,.193813979625702],[.552385985851288,.302568018436432],[.607609987258911,.353887975215912],[.645429015159607,.696707010269165],[.932694971561432,.730105042457581],[.557260990142822,.572826027870178],[.542901992797852,.584792017936707],[.6180260181427,.694710969924927],[.607590973377228,.694203019142151],[.722943007946014,.271963000297546],[.577413976192474,.563166975975037],[.614082992076874,.281386971473694],[.616907000541687,.255886018276215],[.668509006500244,.119913995265961],[.770092010498047,.232020974159241],[.635536015033722,.189248979091644],[.77039098739624,.299556016921997],[.826722025871277,.278755009174347],[.527121007442474,.666198015213013],[.553171992301941,.668527007102966],[.577238023281097,.673889994621277],[.554691970348358,.580065965652466],[.611896991729736,.693961024284363],[.59696102142334,.706539988517761],[.596370995044708,.693953037261963],[.539958000183105,.557139039039612],[.568841993808746,.692366003990173],[.547818005084991,.692366003990173],[.52461302280426,.692366003990173],[.534089982509613,.779141008853912],[.527670979499817,.736225962638855],[.526912987232208,.717857003211975],[.526877999305725,.704625964164734],[.526966989040375,.695277988910675],[.572058022022247,.695277988910675],[.573521018028259,.703539967536926],[.57683801651001,.711845993995667],[.581691026687622,.720062971115112],[.609944999217987,.639909982681274],[.986046016216278,.560034036636353],[.5867999792099,.69539999961853],[.590372025966644,.701822996139526],[.531915009021759,.601536989212036],[.577268004417419,.585934996604919],[.536915004253387,.593786001205444],[.627542972564697,.473352015018463],[.665585994720459,.495950996875763],[.588353991508484,.546862006187439],[.757824003696442,.14767599105835],[.709249973297119,.201507985591888],[.672684013843536,.256581008434296],[.600408971309662,.74900496006012],[.55826598405838,.261672019958496],[.570303976535797,.187870979309082],[.588165998458862,.109044015407562],[.711045026779175,.398952007293701],[.781069993972778,.435405015945435],[.587247014045715,.398931980133057],[.742869973182678,.355445981025696],[.572156012058258,.437651991844177],[.55186802148819,.536570012569427],[.821442008018494,.457556009292603],[.752701997756958,.457181990146637],[.71375697851181,.467626988887787],[.66711300611496,.460672974586487],[.631101012229919,.447153985500336],[.6008620262146,.432473003864288],[.523481011390686,.405627012252808],[.810747981071472,.523926019668579],[.771045982837677,.348959028720856],[.509127020835876,.562718033790588],[.595292985439301,.485023975372314],[.980530977249146,.401564002037048],[.573499977588654,.420000016689301],[.602994978427887,.548687994480133],[.733529984951019,.376977026462555],[.560611009597778,.519016981124878],[.967685997486115,.644356966018677],[.580985009670258,.387160003185272],[.537728011608124,.505385041236877],[.760966002941132,.779752969741821],[.801778972148895,.831938028335571],[.892440974712372,.54076099395752],[.816350996494293,.740260004997253],[.865594983100891,.333687007427216],[.614073991775513,.883246004581451],[.508952975273132,.579437971115112],[.617941975593567,.508316040039062],[.825608015060425,.397674977779388],[.681214988231659,.39623498916626],[.656635999679565,.400596976280212],[.603900015354156,.710216999053955],[.81208598613739,.588539004325867],[.56801301240921,.944564998149872],[.681007981300354,.898285031318665],[.733752012252808,.869701027870178],[.633830010890961,.398822009563446],[.606792986392975,.39553701877594],[.589659988880157,.391062021255493],[.805015981197357,.342108011245728],[.611334979534149,.362284004688263],[.634037971496582,.355970978736877],[.656635999679565,.355356991291046],[.681214988231659,.35834002494812],[.698584973812103,.363156020641327],[.941866993904114,.319076001644135],[.698584973812103,.387449026107788],[.584177017211914,.624107003211975],[.554318010807037,.566076993942261],[.534153997898102,.62064003944397],[.711217999458313,.819975018501282],[.664629995822906,.852871000766754],[.559099972248077,.902631998062134],[.871706008911133,.791940987110138],[.591234028339386,.373893976211548],[.544341027736664,.451583981513977],[.624562978744507,.924192011356354],[.88577002286911,.615028977394104],[.551338016986847,.695277988910675],[.551980018615723,.704632043838501],[.552887976169586,.715808033943176],[.555167973041534,.730794012546539],[.569944024085999,.767035007476807],[.593203008174896,.685675978660583],[.599261999130249,.681069016456604],[.607599973678589,.677703022956848],[.631937980651855,.663500010967255],[.752032995223999,.601315021514893],[.547226011753082,.420395016670227],[.563543975353241,.359827995300293],[.583841025829315,.368713974952698],[.586614012718201,.692366003990173],[.771915018558502,.683578014373779],[.531597018241882,.352482974529266],[.588370978832245,.804440975189209],[.52079701423645,.442565023899078],[.567984998226166,.493479013442993],[.543282985687256,.819254994392395],[.655317008495331,.745514988899231],[.621008992195129,.574018001556396],[.625559985637665,.78031200170517],[.680198013782501,.570719003677368],[.64276397228241,.604337990283966],[.704662978649139,.621529996395111],[.552012026309967,.862591981887817],[.589071989059448,.508637011051178],[.685944974422455,.775357007980347],[.645735025405884,.812640011310577],[.675342977046967,.703978002071381],[.810858011245728,.646304965019226],[.72012197971344,.714666962623596],[.866151988506317,.682704985141754],[.663187026977539,.644596993923187],[.570082008838654,.466325998306274],[.544561982154846,.548375964164734],[.562758982181549,.558784961700439],[.531987011432648,.530140042304993],[.585271000862122,.335177004337311],[.622952997684479,.32277899980545],[.655896008014679,.320163011550903],[.687132000923157,.322345972061157],[.716481983661652,.333200991153717],[.758756995201111,.382786989212036],[.897013008594513,.468769013881683],[.732392013072968,.424547016620636],[.70211398601532,.433162987232208],[.66652500629425,.433866024017334],[.633504986763,.426087975502014],[.603875994682312,.416586995124817],[.579657971858978,.409945011138916],[.992439985275269,.480777025222778],[.567192018032074,.569419980049133],[.54136598110199,.478899002075195],[.526564002037048,.546118021011353],[.523913025856018,.563830018043518],[.531529009342194,.555056989192963],[.566035985946655,.582329034805298],[.51631098985672,.563053965568542],[.5174720287323,.577877044677734],[.573594987392426,.389806985855103],[.560697972774506,.395331978797913],[.549755990505219,.399751007556915],[.710287988185883,.368252992630005],[.723330020904541,.363372981548309]];function k(t,e,n){return r(this,void 0,void 0,(function(){return i(this,(function(o){return[2,l({maxFaces:t,iouThreshold:e,scoreThreshold:n})]}))}))}function O(){return r(this,void 0,void 0,(function(){return i(this,(function(t){return[2,n.loadGraphModel("https://tfhub.dev/mediapipe/tfjs-model/facemesh/1/default/1",{fromTFHub:!0})]}))}))}function B(t,n){if(t.mesh instanceof e.Tensor){var o=e.tidy((function(){var o=e.tensor1d([n-1,0,0]),r=e.tensor1d([1,-1,1]);return e.tidy((function(){return[e.concat([e.sub(n-1,t.boundingBox.topLeft.slice(0,1)),t.boundingBox.topLeft.slice(1,1)]),e.concat([e.sub(n-1,t.boundingBox.bottomRight.slice(0,1)),t.boundingBox.bottomRight.slice(1,1)]),e.sub(o,t.mesh).mul(r),e.sub(o,t.scaledMesh).mul(r)]}))})),r=o[0],i=o[1],s=o[2],a=o[3];return Object.assign({},t,{boundingBox:{topLeft:r,bottomRight:i},mesh:s,scaledMesh:a})}return Object.assign({},t,{boundingBox:{topLeft:[n-1-t.boundingBox.topLeft[0],t.boundingBox.topLeft[1]],bottomRight:[n-1-t.boundingBox.bottomRight[0],t.boundingBox.bottomRight[1]]},mesh:t.mesh.map((function(t){var e=t.slice(0);return e[0]=n-1-t[0],e})),scaledMesh:t.scaledMesh.map((function(t){var e=t.slice(0);return e[0]=n-1-t[0],e}))})}var I=function(){function t(t,e,n,o,r){this.pipeline=new E(t,e,192,192,n,r),this.detectionConfidence=o}return t.getAnnotations=function(){return d},t.getUVCoords=function(){return L},t.prototype.estimateFaces=function(t,n,o){return void 0===n&&(n=!1),void 0===o&&(o=!1),r(this,void 0,void 0,(function(){var s,a,c,u,h,l=this;return i(this,(function(f){switch(f.label){case 0:return s=function(t){return t instanceof e.Tensor?[t.shape[0],t.shape[1]]:[t.height,t.width]}(t),a=s[1],c=e.tidy((function(){return t instanceof e.Tensor||(t=e.browser.fromPixels(t)),t.toFloat().expandDims(0)})),"webgl"!==e.getBackend()?[3,2]:(h=e.env().get("WEBGL_PACK_DEPTHWISECONV"),e.env().set("WEBGL_PACK_DEPTHWISECONV",!0),[4,this.pipeline.predict(c)]);case 1:return u=f.sent(),e.env().set("WEBGL_PACK_DEPTHWISECONV",h),[3,4];case 2:return[4,this.pipeline.predict(c)];case 3:u=f.sent(),f.label=4;case 4:return c.dispose(),null!=u&&u.length>0?[2,Promise.all(u.map((function(t,s){return r(l,void 0,void 0,(function(){var c,u,h,l,f,p,m,b,g,y,P,v,w,x,M=this;return i(this,(function(E){switch(E.label){case 0:return c=t.coords,u=t.scaledCoords,h=t.box,l=t.flag,f=[l],n||(f=f.concat([c,u])),[4,Promise.all(f.map((function(t){return r(M,void 0,void 0,(function(){return i(this,(function(e){return[2,t.array()]}))}))})))];case 1:if(p=E.sent(),m=p[0],l.dispose(),m<this.detectionConfidence&&this.pipeline.clearRegionOfInterest(s),n)return b={faceInViewConfidence:m,mesh:c,scaledMesh:u,boundingBox:{topLeft:e.tensor1d(h.startPoint),bottomRight:e.tensor1d(h.endPoint)}},o?[2,B(b,a)]:[2,b];for(x in g=p.slice(1),y=g[0],P=g[1],u.dispose(),c.dispose(),v={faceInViewConfidence:m,boundingBox:{topLeft:h.startPoint,bottomRight:h.endPoint},mesh:y,scaledMesh:P},o&&(v=B(v,a)),w={},d)w[x]=d[x].map((function(t){return v.scaledMesh[t]}));return v.annotations=w,[2,v]}}))}))})))]:[2,[]]}}))}))},t}();t.FaceMesh=I,t.load=function(t){var e=void 0===t?{}:t,n=e.maxContinuousChecks,o=void 0===n?5:n,s=e.detectionConfidence,a=void 0===s?.9:s,c=e.maxFaces,u=void 0===c?10:c,h=e.iouThreshold,l=void 0===h?.3:h,d=e.scoreThreshold,f=void 0===d?.75:d;return r(this,void 0,void 0,(function(){var t,e,n;return i(this,(function(r){switch(r.label){case 0:return[4,Promise.all([k(u,l,f),O()])];case 1:return t=r.sent(),e=t[0],n=t[1],[2,new I(e,n,o,a,u)]}}))}))},Object.defineProperty(t,"__esModule",{value:!0})})); |
"use strict"; | ||
/** | ||
* @license | ||
* Copyright 2020 Google LLC. All Rights Reserved. | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
* ============================================================================= | ||
*/ | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const blazeface = require("@tensorflow-models/blazeface"); | ||
const tfconv = require("@tensorflow/tfjs-converter"); | ||
const tf = require("@tensorflow/tfjs-core"); | ||
const keypoints_1 = require("./keypoints"); | ||
const pipeline_1 = require("./pipeline"); | ||
const uv_coords_1 = require("./uv_coords"); | ||
const FACEMESH_GRAPHMODEL_PATH = 'https://tfhub.dev/mediapipe/tfjs-model/facemesh/1/default/1'; | ||
const MESH_MODEL_INPUT_WIDTH = 192; | ||
const MESH_MODEL_INPUT_HEIGHT = 192; | ||
async function load({ maxContinuousChecks = 5, detectionConfidence = 0.9, maxFaces = 10, iouThreshold = 0.3, scoreThreshold = 0.75 } = {}) { | ||
const [blazeFace, blazeMeshModel] = await Promise.all([ | ||
loadDetectorModel(maxFaces, iouThreshold, scoreThreshold), loadMeshModel() | ||
]); | ||
const faceMesh = new FaceMesh(blazeFace, blazeMeshModel, maxContinuousChecks, detectionConfidence, maxFaces); | ||
return faceMesh; | ||
var blazeface = require("@tensorflow-models/blazeface"); | ||
var tfconv = require("@tensorflow/tfjs-converter"); | ||
var tf = require("@tensorflow/tfjs-core"); | ||
var keypoints_1 = require("./keypoints"); | ||
var pipeline_1 = require("./pipeline"); | ||
var uv_coords_1 = require("./uv_coords"); | ||
var FACEMESH_GRAPHMODEL_PATH = 'https://tfhub.dev/mediapipe/tfjs-model/facemesh/1/default/1'; | ||
var MESH_MODEL_INPUT_WIDTH = 192; | ||
var MESH_MODEL_INPUT_HEIGHT = 192; | ||
/** | ||
* Load the model. | ||
* | ||
* @param options - a configuration object with the following properties: | ||
* - `maxContinuousChecks` How many frames to go without running the bounding | ||
* box detector. Only relevant if maxFaces > 1. Defaults to 5. | ||
* - `detectionConfidence` Threshold for discarding a prediction. Defaults to | ||
* 0.9. | ||
* - `maxFaces` The maximum number of faces detected in the input. Should be | ||
* set to the minimum number for performance. Defaults to 10. | ||
* - `iouThreshold` A float representing the threshold for deciding whether | ||
* boxes overlap too much in non-maximum suppression. Must be between [0, 1]. | ||
* Defaults to 0.3. | ||
* - `scoreThreshold` A threshold for deciding when to remove boxes based | ||
* on score in non-maximum suppression. Defaults to 0.75. | ||
*/ | ||
function load(_a) { | ||
var _b = _a === void 0 ? {} : _a, _c = _b.maxContinuousChecks, maxContinuousChecks = _c === void 0 ? 5 : _c, _d = _b.detectionConfidence, detectionConfidence = _d === void 0 ? 0.9 : _d, _e = _b.maxFaces, maxFaces = _e === void 0 ? 10 : _e, _f = _b.iouThreshold, iouThreshold = _f === void 0 ? 0.3 : _f, _g = _b.scoreThreshold, scoreThreshold = _g === void 0 ? 0.75 : _g; | ||
return __awaiter(this, void 0, void 0, function () { | ||
var _h, blazeFace, blazeMeshModel, faceMesh; | ||
return __generator(this, function (_j) { | ||
switch (_j.label) { | ||
case 0: return [4 /*yield*/, Promise.all([ | ||
loadDetectorModel(maxFaces, iouThreshold, scoreThreshold), loadMeshModel() | ||
])]; | ||
case 1: | ||
_h = _j.sent(), blazeFace = _h[0], blazeMeshModel = _h[1]; | ||
faceMesh = new FaceMesh(blazeFace, blazeMeshModel, maxContinuousChecks, detectionConfidence, maxFaces); | ||
return [2 /*return*/, faceMesh]; | ||
} | ||
}); | ||
}); | ||
} | ||
exports.load = load; | ||
async function loadDetectorModel(maxFaces, iouThreshold, scoreThreshold) { | ||
return blazeface.load({ maxFaces, iouThreshold, scoreThreshold }); | ||
function loadDetectorModel(maxFaces, iouThreshold, scoreThreshold) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, blazeface.load({ maxFaces: maxFaces, iouThreshold: iouThreshold, scoreThreshold: scoreThreshold })]; | ||
}); | ||
}); | ||
} | ||
async function loadMeshModel() { | ||
return tfconv.loadGraphModel(FACEMESH_GRAPHMODEL_PATH, { fromTFHub: true }); | ||
function loadMeshModel() { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/, tfconv.loadGraphModel(FACEMESH_GRAPHMODEL_PATH, { fromTFHub: true })]; | ||
}); | ||
}); | ||
} | ||
@@ -32,6 +117,6 @@ function getInputTensorDimensions(input) { | ||
if (face.mesh instanceof tf.Tensor) { | ||
const [topLeft, bottomRight, mesh, scaledMesh] = tf.tidy(() => { | ||
const subtractBasis = tf.tensor1d([imageWidth - 1, 0, 0]); | ||
const multiplyBasis = tf.tensor1d([1, -1, 1]); | ||
return tf.tidy(() => { | ||
var _a = tf.tidy(function () { | ||
var subtractBasis = tf.tensor1d([imageWidth - 1, 0, 0]); | ||
var multiplyBasis = tf.tensor1d([1, -1, 1]); | ||
return tf.tidy(function () { | ||
return [ | ||
@@ -50,4 +135,4 @@ tf.concat([ | ||
}); | ||
}); | ||
return Object.assign({}, face, { boundingBox: { topLeft, bottomRight }, mesh, scaledMesh }); | ||
}), topLeft = _a[0], bottomRight = _a[1], mesh = _a[2], scaledMesh = _a[3]; | ||
return Object.assign({}, face, { boundingBox: { topLeft: topLeft, bottomRight: bottomRight }, mesh: mesh, scaledMesh: scaledMesh }); | ||
} | ||
@@ -65,9 +150,9 @@ return Object.assign({}, face, { | ||
}, | ||
mesh: (face.mesh).map(coord => { | ||
const flippedCoord = coord.slice(0); | ||
mesh: (face.mesh).map(function (coord) { | ||
var flippedCoord = coord.slice(0); | ||
flippedCoord[0] = imageWidth - 1 - coord[0]; | ||
return flippedCoord; | ||
}), | ||
scaledMesh: face.scaledMesh.map(coord => { | ||
const flippedCoord = coord.slice(0); | ||
scaledMesh: face.scaledMesh.map(function (coord) { | ||
var flippedCoord = coord.slice(0); | ||
flippedCoord[0] = imageWidth - 1 - coord[0]; | ||
@@ -78,79 +163,128 @@ return flippedCoord; | ||
} | ||
class FaceMesh { | ||
constructor(blazeFace, blazeMeshModel, maxContinuousChecks, detectionConfidence, maxFaces) { | ||
var FaceMesh = /** @class */ (function () { | ||
function FaceMesh(blazeFace, blazeMeshModel, maxContinuousChecks, detectionConfidence, maxFaces) { | ||
this.pipeline = new pipeline_1.Pipeline(blazeFace, blazeMeshModel, MESH_MODEL_INPUT_WIDTH, MESH_MODEL_INPUT_HEIGHT, maxContinuousChecks, maxFaces); | ||
this.detectionConfidence = detectionConfidence; | ||
} | ||
static getAnnotations() { | ||
FaceMesh.getAnnotations = function () { | ||
return keypoints_1.MESH_ANNOTATIONS; | ||
} | ||
static getUVCoords() { | ||
}; | ||
/** | ||
* Returns an array of UV coordinates for the 468 facial keypoint vertices in | ||
* mesh_map.jpg. Can be used to map textures to the facial mesh. | ||
*/ | ||
FaceMesh.getUVCoords = function () { | ||
return uv_coords_1.UV_COORDS; | ||
} | ||
async estimateFaces(input, returnTensors = false, flipHorizontal = false) { | ||
const [, width] = getInputTensorDimensions(input); | ||
const image = tf.tidy(() => { | ||
if (!(input instanceof tf.Tensor)) { | ||
input = tf.browser.fromPixels(input); | ||
} | ||
return input.toFloat().expandDims(0); | ||
}); | ||
const savedWebglPackDepthwiseConvFlag = tf.env().get('WEBGL_PACK_DEPTHWISECONV'); | ||
tf.env().set('WEBGL_PACK_DEPTHWISECONV', true); | ||
const predictions = await this.pipeline.predict(image); | ||
tf.env().set('WEBGL_PACK_DEPTHWISECONV', savedWebglPackDepthwiseConvFlag); | ||
image.dispose(); | ||
if (predictions != null && predictions.length > 0) { | ||
return Promise.all(predictions.map(async (prediction, i) => { | ||
const { coords, scaledCoords, box, flag } = prediction; | ||
let tensorsToRead = [flag]; | ||
if (!returnTensors) { | ||
tensorsToRead = tensorsToRead.concat([coords, scaledCoords, box.startPoint, box.endPoint]); | ||
} | ||
const tensorValues = await Promise.all(tensorsToRead.map(async (d) => d.array())); | ||
const flagValue = tensorValues[0]; | ||
flag.dispose(); | ||
if (flagValue < this.detectionConfidence) { | ||
this.pipeline.clearRegionOfInterest(i); | ||
} | ||
if (returnTensors) { | ||
const annotatedPrediction = { | ||
faceInViewConfidence: flagValue, | ||
mesh: coords, | ||
scaledMesh: scaledCoords, | ||
boundingBox: { | ||
topLeft: box.startPoint.squeeze(), | ||
bottomRight: box.endPoint.squeeze() | ||
}; | ||
/** | ||
* Returns an array of faces in an image. | ||
* | ||
* @param input The image to classify. Can be a tensor, DOM element image, | ||
* video, or canvas. | ||
* @param returnTensors (defaults to `false`) Whether to return tensors as | ||
* opposed to values. | ||
* @param flipHorizontal Whether to flip/mirror the facial keypoints | ||
* horizontally. Should be true for videos that are flipped by default (e.g. | ||
* webcams). | ||
* | ||
* @return An array of AnnotatedPrediction objects. | ||
*/ | ||
FaceMesh.prototype.estimateFaces = function (input, returnTensors, flipHorizontal) { | ||
if (returnTensors === void 0) { returnTensors = false; } | ||
if (flipHorizontal === void 0) { flipHorizontal = false; } | ||
return __awaiter(this, void 0, void 0, function () { | ||
var _a, width, image, predictions, savedWebglPackDepthwiseConvFlag; | ||
var _this = this; | ||
return __generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: | ||
_a = getInputTensorDimensions(input), width = _a[1]; | ||
image = tf.tidy(function () { | ||
if (!(input instanceof tf.Tensor)) { | ||
input = tf.browser.fromPixels(input); | ||
} | ||
return input.toFloat().expandDims(0); | ||
}); | ||
if (!(tf.getBackend() === 'webgl')) return [3 /*break*/, 2]; | ||
savedWebglPackDepthwiseConvFlag = tf.env().get('WEBGL_PACK_DEPTHWISECONV'); | ||
tf.env().set('WEBGL_PACK_DEPTHWISECONV', true); | ||
return [4 /*yield*/, this.pipeline.predict(image)]; | ||
case 1: | ||
predictions = _b.sent(); | ||
tf.env().set('WEBGL_PACK_DEPTHWISECONV', savedWebglPackDepthwiseConvFlag); | ||
return [3 /*break*/, 4]; | ||
case 2: return [4 /*yield*/, this.pipeline.predict(image)]; | ||
case 3: | ||
predictions = _b.sent(); | ||
_b.label = 4; | ||
case 4: | ||
image.dispose(); | ||
if (predictions != null && predictions.length > 0) { | ||
return [2 /*return*/, Promise.all(predictions.map(function (prediction, i) { return __awaiter(_this, void 0, void 0, function () { | ||
var coords, scaledCoords, box, flag, tensorsToRead, tensorValues, flagValue, annotatedPrediction_1, _a, coordsArr, coordsArrScaled, annotatedPrediction, annotations, key; | ||
var _this = this; | ||
return __generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: | ||
coords = prediction.coords, scaledCoords = prediction.scaledCoords, box = prediction.box, flag = prediction.flag; | ||
tensorsToRead = [flag]; | ||
if (!returnTensors) { | ||
tensorsToRead = tensorsToRead.concat([coords, scaledCoords]); | ||
} | ||
return [4 /*yield*/, Promise.all(tensorsToRead.map(function (d) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { | ||
return [2 /*return*/, d.array()]; | ||
}); }); }))]; | ||
case 1: | ||
tensorValues = _b.sent(); | ||
flagValue = tensorValues[0]; | ||
flag.dispose(); | ||
if (flagValue < this.detectionConfidence) { | ||
this.pipeline.clearRegionOfInterest(i); | ||
} | ||
if (returnTensors) { | ||
annotatedPrediction_1 = { | ||
faceInViewConfidence: flagValue, | ||
mesh: coords, | ||
scaledMesh: scaledCoords, | ||
boundingBox: { | ||
topLeft: tf.tensor1d(box.startPoint), | ||
bottomRight: tf.tensor1d(box.endPoint) | ||
} | ||
}; | ||
if (flipHorizontal) { | ||
return [2 /*return*/, flipFaceHorizontal(annotatedPrediction_1, width)]; | ||
} | ||
return [2 /*return*/, annotatedPrediction_1]; | ||
} | ||
_a = tensorValues.slice(1), coordsArr = _a[0], coordsArrScaled = _a[1]; | ||
scaledCoords.dispose(); | ||
coords.dispose(); | ||
annotatedPrediction = { | ||
faceInViewConfidence: flagValue, | ||
boundingBox: { topLeft: box.startPoint, bottomRight: box.endPoint }, | ||
mesh: coordsArr, | ||
scaledMesh: coordsArrScaled | ||
}; | ||
if (flipHorizontal) { | ||
annotatedPrediction = | ||
flipFaceHorizontal(annotatedPrediction, width); | ||
} | ||
annotations = {}; | ||
for (key in keypoints_1.MESH_ANNOTATIONS) { | ||
annotations[key] = keypoints_1.MESH_ANNOTATIONS[key].map(function (index) { return annotatedPrediction.scaledMesh[index]; }); | ||
} | ||
annotatedPrediction['annotations'] = annotations; | ||
return [2 /*return*/, annotatedPrediction]; | ||
} | ||
}); | ||
}); }))]; | ||
} | ||
}; | ||
if (flipHorizontal) { | ||
return flipFaceHorizontal(annotatedPrediction, width); | ||
} | ||
return annotatedPrediction; | ||
return [2 /*return*/, []]; | ||
} | ||
const [coordsArr, coordsArrScaled, topLeft, bottomRight] = tensorValues.slice(1); | ||
scaledCoords.dispose(); | ||
coords.dispose(); | ||
let annotatedPrediction = { | ||
faceInViewConfidence: flagValue, | ||
boundingBox: { topLeft, bottomRight }, | ||
mesh: coordsArr, | ||
scaledMesh: coordsArrScaled | ||
}; | ||
if (flipHorizontal) { | ||
annotatedPrediction = | ||
flipFaceHorizontal(annotatedPrediction, width); | ||
} | ||
const annotations = {}; | ||
for (const key in keypoints_1.MESH_ANNOTATIONS) { | ||
annotations[key] = keypoints_1.MESH_ANNOTATIONS[key].map(index => annotatedPrediction.scaledMesh[index]); | ||
} | ||
annotatedPrediction['annotations'] = annotations; | ||
return annotatedPrediction; | ||
})); | ||
} | ||
return []; | ||
} | ||
} | ||
}); | ||
}); | ||
}; | ||
return FaceMesh; | ||
}()); | ||
exports.FaceMesh = FaceMesh; | ||
//# sourceMappingURL=index.js.map |
"use strict"; | ||
/** | ||
* @license | ||
* Copyright 2020 Google LLC. All Rights Reserved. | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
* ============================================================================= | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -3,0 +19,0 @@ exports.MESH_ANNOTATIONS = { |
"use strict"; | ||
/** | ||
* @license | ||
* Copyright 2020 Google LLC. All Rights Reserved. | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
* ============================================================================= | ||
*/ | ||
var __assign = (this && this.__assign) || function () { | ||
__assign = Object.assign || function(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) | ||
t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const tf = require("@tensorflow/tfjs-core"); | ||
const box_1 = require("./box"); | ||
const LANDMARKS_COUNT = 468; | ||
const UPDATE_REGION_OF_INTEREST_IOU_THRESHOLD = 0.25; | ||
class Pipeline { | ||
constructor(boundingBoxDetector, meshDetector, meshWidth, meshHeight, maxContinuousChecks, maxFaces) { | ||
var tf = require("@tensorflow/tfjs-core"); | ||
var box_1 = require("./box"); | ||
var util_1 = require("./util"); | ||
var UPDATE_REGION_OF_INTEREST_IOU_THRESHOLD = 0.25; | ||
var LANDMARKS_COUNT = 468; | ||
var MESH_MODEL_KEYPOINTS_LINE_OF_SYMMETRY_INDICES = [1, 168]; | ||
var BLAZEFACE_KEYPOINTS_LINE_OF_SYMMETRY_INDICES = [3, 2]; | ||
// The Pipeline coordinates between the bounding box and skeleton models. | ||
var Pipeline = /** @class */ (function () { | ||
function Pipeline(boundingBoxDetector, meshDetector, meshWidth, meshHeight, maxContinuousChecks, maxFaces) { | ||
// An array of facial bounding boxes. | ||
this.regionsOfInterest = []; | ||
@@ -18,93 +85,155 @@ this.runsWithoutFaceDetector = 0; | ||
} | ||
async predict(input) { | ||
if (this.shouldUpdateRegionsOfInterest()) { | ||
const returnTensors = true; | ||
const annotateFace = false; | ||
const { boxes, scaleFactor } = await this.boundingBoxDetector.getBoundingBoxes(input, returnTensors, annotateFace); | ||
if (boxes.length === 0) { | ||
scaleFactor.dispose(); | ||
this.clearAllRegionsOfInterest(); | ||
return null; | ||
} | ||
const scaledBoxes = boxes.map((prediction) => box_1.enlargeBox(box_1.scaleBoxCoordinates(prediction, scaleFactor))); | ||
boxes.forEach(box_1.disposeBox); | ||
this.updateRegionsOfInterest(scaledBoxes); | ||
this.runsWithoutFaceDetector = 0; | ||
} | ||
else { | ||
this.runsWithoutFaceDetector++; | ||
} | ||
return tf.tidy(() => { | ||
return this.regionsOfInterest.map((box, i) => { | ||
const face = box_1.cutBoxFromImageAndResize(box, input, [ | ||
this.meshHeight, this.meshWidth | ||
]).div(255); | ||
const [, flag, coords] = this.meshDetector.predict(face); | ||
const coordsReshaped = tf.reshape(coords, [-1, 3]); | ||
const normalizedBox = tf.div(box_1.getBoxSize(box), [this.meshWidth, this.meshHeight]); | ||
const scaledCoords = tf.mul(coordsReshaped, normalizedBox.concat(tf.tensor2d([1], [1, 1]), 1)) | ||
.add(box.startPoint.concat(tf.tensor2d([0], [1, 1]), 1)); | ||
const landmarksBox = this.calculateLandmarksBoundingBox(scaledCoords); | ||
const previousBox = this.regionsOfInterest[i]; | ||
box_1.disposeBox(previousBox); | ||
this.regionsOfInterest[i] = landmarksBox; | ||
const prediction = { | ||
coords: coordsReshaped, | ||
scaledCoords, | ||
box: landmarksBox, | ||
flag: flag.squeeze() | ||
}; | ||
return prediction; | ||
Pipeline.prototype.transformRawCoords = function (rawCoords, box, angle, rotationMatrix) { | ||
var _this = this; | ||
var boxSize = box_1.getBoxSize({ startPoint: box.startPoint, endPoint: box.endPoint }); | ||
var scaleFactor = [boxSize[0] / this.meshWidth, boxSize[1] / this.meshHeight]; | ||
var coordsScaled = rawCoords.map(function (coord) { | ||
return [ | ||
scaleFactor[0] * (coord[0] - _this.meshWidth / 2), | ||
scaleFactor[1] * (coord[1] - _this.meshHeight / 2), coord[2] | ||
]; | ||
}); | ||
var coordsRotationMatrix = util_1.buildRotationMatrix(angle, [0, 0]); | ||
var coordsRotated = coordsScaled.map(function (coord) { | ||
var rotated = util_1.rotatePoint(coord, coordsRotationMatrix); | ||
return rotated.concat([coord[2]]); | ||
}); | ||
var inverseRotationMatrix = util_1.invertTransformMatrix(rotationMatrix); | ||
var boxCenter = box_1.getBoxCenter({ startPoint: box.startPoint, endPoint: box.endPoint }).concat([ | ||
1 | ||
]); | ||
var originalBoxCenter = [ | ||
util_1.dot(boxCenter, inverseRotationMatrix[0]), | ||
util_1.dot(boxCenter, inverseRotationMatrix[1]) | ||
]; | ||
return coordsRotated.map(function (coord) { return ([ | ||
coord[0] + originalBoxCenter[0], | ||
coord[1] + originalBoxCenter[1], coord[2] | ||
]); }); | ||
}; | ||
/** | ||
* Returns an array of predictions for each face in the input. | ||
* | ||
* @param input - tensor of shape [1, H, W, 3]. | ||
*/ | ||
Pipeline.prototype.predict = function (input) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var returnTensors, annotateFace, _a, boxes, scaleFactor_1, scaledBoxes; | ||
var _this = this; | ||
return __generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: | ||
if (!this.shouldUpdateRegionsOfInterest()) return [3 /*break*/, 2]; | ||
returnTensors = false; | ||
annotateFace = true; | ||
return [4 /*yield*/, this.boundingBoxDetector.getBoundingBoxes(input, returnTensors, annotateFace)]; | ||
case 1: | ||
_a = _b.sent(), boxes = _a.boxes, scaleFactor_1 = _a.scaleFactor; | ||
if (boxes.length === 0) { | ||
this.regionsOfInterest = []; | ||
return [2 /*return*/, null]; | ||
} | ||
scaledBoxes = boxes.map(function (prediction) { | ||
var predictionBoxCPU = { | ||
startPoint: prediction.box.startPoint.squeeze().arraySync(), | ||
endPoint: prediction.box.endPoint.squeeze().arraySync() | ||
}; | ||
var scaledBox = box_1.scaleBoxCoordinates(predictionBoxCPU, scaleFactor_1); | ||
var enlargedBox = box_1.enlargeBox(scaledBox); | ||
return __assign({}, enlargedBox, { landmarks: prediction.landmarks.arraySync() }); | ||
}); | ||
boxes.forEach(function (box) { | ||
if (box != null && box.startPoint != null) { | ||
box.startEndTensor.dispose(); | ||
box.startPoint.dispose(); | ||
box.endPoint.dispose(); | ||
} | ||
}); | ||
this.updateRegionsOfInterest(scaledBoxes); | ||
this.runsWithoutFaceDetector = 0; | ||
return [3 /*break*/, 3]; | ||
case 2: | ||
this.runsWithoutFaceDetector++; | ||
_b.label = 3; | ||
case 3: return [2 /*return*/, tf.tidy(function () { | ||
return _this.regionsOfInterest.map(function (box, i) { | ||
var angle; | ||
// The facial bounding box landmarks could come either from blazeface | ||
// (if we are using a fresh box), or from the mesh model (if we are | ||
// reusing an old box). | ||
var boxLandmarksFromMeshModel = box.landmarks.length === LANDMARKS_COUNT; | ||
if (boxLandmarksFromMeshModel) { | ||
var indexOfNose = MESH_MODEL_KEYPOINTS_LINE_OF_SYMMETRY_INDICES[0], indexOfForehead = MESH_MODEL_KEYPOINTS_LINE_OF_SYMMETRY_INDICES[1]; | ||
angle = util_1.computeRotation(box.landmarks[indexOfNose], box.landmarks[indexOfForehead]); | ||
} | ||
else { | ||
var indexOfNose = BLAZEFACE_KEYPOINTS_LINE_OF_SYMMETRY_INDICES[0], indexOfForehead = BLAZEFACE_KEYPOINTS_LINE_OF_SYMMETRY_INDICES[1]; | ||
angle = util_1.computeRotation(box.landmarks[indexOfNose], box.landmarks[indexOfForehead]); | ||
} | ||
var faceCenter = box_1.getBoxCenter({ startPoint: box.startPoint, endPoint: box.endPoint }); | ||
var faceCenterNormalized = [faceCenter[0] / input.shape[2], faceCenter[1] / input.shape[1]]; | ||
var rotatedImage = tf.image.rotateWithOffset(input, angle, 0, faceCenterNormalized); | ||
var rotationMatrix = util_1.buildRotationMatrix(-angle, faceCenter); | ||
var boxCPU = { startPoint: box.startPoint, endPoint: box.endPoint }; | ||
var face = box_1.cutBoxFromImageAndResize(boxCPU, rotatedImage, [ | ||
_this.meshHeight, _this.meshWidth | ||
]).div(255); | ||
// The first returned tensor represents facial contours, which are | ||
// included in the coordinates. | ||
var _a = _this.meshDetector.predict(face), flag = _a[1], coords = _a[2]; | ||
var coordsReshaped = tf.reshape(coords, [-1, 3]); | ||
var rawCoords = coordsReshaped.arraySync(); | ||
var transformedCoordsData = _this.transformRawCoords(rawCoords, box, angle, rotationMatrix); | ||
var transformedCoords = tf.tensor2d(transformedCoordsData); | ||
var landmarksBox = _this.calculateLandmarksBoundingBox(transformedCoordsData); | ||
_this.regionsOfInterest[i] = __assign({}, landmarksBox, { landmarks: transformedCoords.arraySync() }); | ||
var prediction = { | ||
coords: coordsReshaped, | ||
scaledCoords: transformedCoords, | ||
box: landmarksBox, | ||
flag: flag.squeeze() | ||
}; | ||
return prediction; | ||
}); | ||
})]; | ||
} | ||
}); | ||
}); | ||
} | ||
updateRegionsOfInterest(boxes) { | ||
for (let i = 0; i < boxes.length; i++) { | ||
const box = boxes[i]; | ||
const previousBox = this.regionsOfInterest[i]; | ||
let iou = 0; | ||
}; | ||
// Updates regions of interest if the intersection over union between | ||
// the incoming and previous regions falls below a threshold. | ||
Pipeline.prototype.updateRegionsOfInterest = function (boxes) { | ||
for (var i = 0; i < boxes.length; i++) { | ||
var box = boxes[i]; | ||
var previousBox = this.regionsOfInterest[i]; | ||
var iou = 0; | ||
if (previousBox && previousBox.startPoint) { | ||
const [boxStartX, boxStartY, boxEndX, boxEndY] = box.startEndTensor.arraySync()[0]; | ||
const [previousBoxStartX, previousBoxStartY, previousBoxEndX, previousBoxEndY] = previousBox.startEndTensor.arraySync()[0]; | ||
const xStartMax = Math.max(boxStartX, previousBoxStartX); | ||
const yStartMax = Math.max(boxStartY, previousBoxStartY); | ||
const xEndMin = Math.min(boxEndX, previousBoxEndX); | ||
const yEndMin = Math.min(boxEndY, previousBoxEndY); | ||
const intersection = (xEndMin - xStartMax) * (yEndMin - yStartMax); | ||
const boxArea = (boxEndX - boxStartX) * (boxEndY - boxStartY); | ||
const previousBoxArea = (previousBoxEndX - previousBoxStartX) * | ||
var _a = box.startPoint, boxStartX = _a[0], boxStartY = _a[1]; | ||
var _b = box.endPoint, boxEndX = _b[0], boxEndY = _b[1]; | ||
var _c = previousBox.startPoint, previousBoxStartX = _c[0], previousBoxStartY = _c[1]; | ||
var _d = previousBox.endPoint, previousBoxEndX = _d[0], previousBoxEndY = _d[1]; | ||
var xStartMax = Math.max(boxStartX, previousBoxStartX); | ||
var yStartMax = Math.max(boxStartY, previousBoxStartY); | ||
var xEndMin = Math.min(boxEndX, previousBoxEndX); | ||
var yEndMin = Math.min(boxEndY, previousBoxEndY); | ||
var intersection = (xEndMin - xStartMax) * (yEndMin - yStartMax); | ||
var boxArea = (boxEndX - boxStartX) * (boxEndY - boxStartY); | ||
var previousBoxArea = (previousBoxEndX - previousBoxStartX) * | ||
(previousBoxEndY - boxStartY); | ||
iou = intersection / (boxArea + previousBoxArea - intersection); | ||
} | ||
if (iou > UPDATE_REGION_OF_INTEREST_IOU_THRESHOLD) { | ||
box_1.disposeBox(box); | ||
} | ||
else { | ||
if (iou < UPDATE_REGION_OF_INTEREST_IOU_THRESHOLD) { | ||
this.regionsOfInterest[i] = box; | ||
box_1.disposeBox(previousBox); | ||
} | ||
} | ||
for (let i = boxes.length; i < this.regionsOfInterest.length; i++) { | ||
box_1.disposeBox(this.regionsOfInterest[i]); | ||
} | ||
this.regionsOfInterest = this.regionsOfInterest.slice(0, boxes.length); | ||
} | ||
clearRegionOfInterest(index) { | ||
}; | ||
Pipeline.prototype.clearRegionOfInterest = function (index) { | ||
if (this.regionsOfInterest[index] != null) { | ||
box_1.disposeBox(this.regionsOfInterest[index]); | ||
this.regionsOfInterest = [ | ||
...this.regionsOfInterest.slice(0, index), | ||
...this.regionsOfInterest.slice(index + 1) | ||
]; | ||
this.regionsOfInterest = this.regionsOfInterest.slice(0, index).concat(this.regionsOfInterest.slice(index + 1)); | ||
} | ||
} | ||
clearAllRegionsOfInterest() { | ||
for (let i = 0; i < this.regionsOfInterest.length; i++) { | ||
box_1.disposeBox(this.regionsOfInterest[i]); | ||
} | ||
this.regionsOfInterest = []; | ||
} | ||
shouldUpdateRegionsOfInterest() { | ||
const roisCount = this.regionsOfInterest.length; | ||
const noROIs = roisCount === 0; | ||
}; | ||
Pipeline.prototype.shouldUpdateRegionsOfInterest = function () { | ||
var roisCount = this.regionsOfInterest.length; | ||
var noROIs = roisCount === 0; | ||
if (this.maxFaces === 1 || noROIs) { | ||
@@ -115,12 +244,14 @@ return noROIs; | ||
this.runsWithoutFaceDetector >= this.maxContinuousChecks; | ||
} | ||
calculateLandmarksBoundingBox(landmarks) { | ||
const xs = landmarks.slice([0, 0], [LANDMARKS_COUNT, 1]); | ||
const ys = landmarks.slice([0, 1], [LANDMARKS_COUNT, 1]); | ||
const boxMinMax = tf.stack([xs.min(), ys.min(), xs.max(), ys.max()]); | ||
const box = box_1.createBox(boxMinMax.expandDims(0)); | ||
return box_1.enlargeBox(box); | ||
} | ||
} | ||
}; | ||
Pipeline.prototype.calculateLandmarksBoundingBox = function (landmarks) { | ||
var xs = landmarks.map(function (d) { return d[0]; }); | ||
var ys = landmarks.map(function (d) { return d[1]; }); | ||
var startPoint = [Math.min.apply(Math, xs), Math.min.apply(Math, ys)]; | ||
var endPoint = [Math.max.apply(Math, xs), Math.max.apply(Math, ys)]; | ||
var box = { startPoint: startPoint, endPoint: endPoint }; | ||
return box_1.enlargeBox({ startPoint: box.startPoint, endPoint: box.endPoint }); | ||
}; | ||
return Pipeline; | ||
}()); | ||
exports.Pipeline = Pipeline; | ||
//# sourceMappingURL=pipeline.js.map |
"use strict"; | ||
/** | ||
* @license | ||
* Copyright 2020 Google LLC. All Rights Reserved. | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
* ============================================================================= | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -3,0 +19,0 @@ exports.UV_COORDS = [ |
"use strict"; | ||
/** @license See the LICENSE file. */ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const version = '0.0.3'; | ||
// This code is auto-generated, do not modify this file! | ||
var version = '0.0.4'; | ||
exports.version = version; | ||
//# sourceMappingURL=version.js.map |
{ | ||
"name": "@tensorflow-models/facemesh", | ||
"version": "0.0.3", | ||
"version": "0.0.4", | ||
"description": "Pretrained facemesh model", | ||
@@ -16,23 +16,27 @@ "main": "dist/index.js", | ||
"peerDependencies": { | ||
"@tensorflow/tfjs-converter": "^1.6.1", | ||
"@tensorflow/tfjs-core": "^1.6.1" | ||
"@tensorflow/tfjs-converter": "^2.1.0", | ||
"@tensorflow/tfjs-core": "^2.1.0" | ||
}, | ||
"dependencies": { | ||
"@tensorflow-models/blazeface": "0.0.5" | ||
"@tensorflow-models/blazeface": "0.0.5", | ||
"rimraf": "^3.0.2" | ||
}, | ||
"devDependencies": { | ||
"@tensorflow/tfjs-converter": "^1.6.1", | ||
"@tensorflow/tfjs-core": "^1.6.1", | ||
"@types/jasmine": "~2.5.53", | ||
"jasmine": "~3.2.0", | ||
"jasmine-core": "~3.1.0", | ||
"rimraf": "~2.6.2", | ||
"rollup": "~0.58.2", | ||
"rollup-plugin-node-resolve": "~3.3.0", | ||
"rollup-plugin-typescript2": "~0.13.0", | ||
"rollup-plugin-uglify": "~3.0.0", | ||
"ts-node": "~5.0.0", | ||
"tslint": "~5.8.0", | ||
"typescript": "3.3.3333", | ||
"yalc": "^1.0.0-pre.27" | ||
"@rollup/plugin-commonjs": "^11.0.2", | ||
"@rollup/plugin-node-resolve": "^7.1.1", | ||
"@rollup/plugin-typescript": "^3.0.0", | ||
"@tensorflow/tfjs-converter": "^2.1.0", | ||
"@tensorflow/tfjs-core": "^2.1.0", | ||
"@tensorflow/tfjs-backend-cpu": "^2.1.0", | ||
"@types/jasmine": "~2.8.8", | ||
"babel-core": "~6.26.0", | ||
"babel-plugin-transform-runtime": "~6.23.0", | ||
"jasmine-core": "~3.5.0", | ||
"rollup": "~2.3.2", | ||
"rollup-plugin-terser": "~5.3.0", | ||
"rollup-plugin-visualizer": "~3.3.2", | ||
"ts-node": "~8.8.2", | ||
"tslint": "~5.18.0", | ||
"typescript": "~3.5.3", | ||
"yalc": "~1.0.0-pre.21" | ||
}, | ||
@@ -42,3 +46,3 @@ "scripts": { | ||
"publish-local": "yarn build && rollup -c && yalc publish", | ||
"test": "ts-node run_tests.ts", | ||
"test": "yarn build && ts-node --skip-ignore run_tests.ts", | ||
"build-npm": "yarn build && rollup -c", | ||
@@ -45,0 +49,0 @@ "lint": "tslint -p . -t verbose", |
@@ -18,2 +18,16 @@ # MediaPipe Facemesh | ||
Via script tags: | ||
```html | ||
<!-- Require the peer dependencies of facemesh. --> | ||
<script src="https://unpkg.com/@tensorflow/tfjs-core@2.1.0/dist/tf-core.js"></script> | ||
<script src="https://unpkg.com/@tensorflow/tfjs-converter@2.1.0/dist/tf-converter.js"></script> | ||
<!-- You must explicitly require a TF.js backend if you're not using the tfs union bundle. --> | ||
<script src="https://unpkg.com/@tensorflow/tfjs-backend-wasm@2.1.0/dist/tf-backend-wasm.js"></script> | ||
<!-- Alternatively you can use the WebGL backend: <script src="https://unpkg.com/@tensorflow/tfjs-backend-webgl@2.1.0/dist/tf-backend-webgl.js"></script> --> | ||
``` | ||
Via npm: | ||
Using `yarn`: | ||
@@ -23,22 +37,17 @@ | ||
Using `npm`: | ||
$ yarn add @tensorflow/tfjs-core, @tensorflow/tfjs-converter | ||
$ yarn add @tensorflow/tfjs-backend-wasm # or @tensorflow/tfjs-backend-webgl | ||
$ npm install @tensorflow-models/facemesh | ||
Note that this package specifies `@tensorflow/tfjs-core` and `@tensorflow/tfjs-converter` as peer dependencies, so they will also need to be installed. | ||
## Usage | ||
To import in npm: | ||
If you are using via npm, first add: | ||
```js | ||
const facemesh = require('@tensorflow-models/facemesh'); | ||
``` | ||
or as a standalone script tag: | ||
// If you are using the WASM backend: | ||
require('@tensorflow/tfjs-backend-wasm'); // You need to require the backend explicitly because facemesh itself does not | ||
```html | ||
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-core"></script> | ||
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-converter"></script> | ||
<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/facemesh"></script> | ||
// If you are using the WebGL backend: | ||
// require('@tensorflow/tfjs-backend-webgl'); | ||
``` | ||
@@ -45,0 +54,0 @@ |
@@ -18,5 +18,5 @@ /** | ||
import node from 'rollup-plugin-node-resolve'; | ||
import typescript from 'rollup-plugin-typescript2'; | ||
import uglify from 'rollup-plugin-uglify'; | ||
import resolve from '@rollup/plugin-node-resolve'; | ||
import typescript from '@rollup/plugin-typescript'; | ||
import {terser} from 'rollup-plugin-terser'; | ||
@@ -40,12 +40,14 @@ const PREAMBLE = `/** | ||
function minify() { | ||
return uglify({output: {preamble: PREAMBLE}}); | ||
} | ||
function config({ plugins = [], output = {}, tsCompilerOptions = {} }) { | ||
const defaultTsOptions = { | ||
include: ['src/**/*.ts'], | ||
module: 'ES2015', | ||
}; | ||
const tsoptions = Object.assign({}, defaultTsOptions, tsCompilerOptions); | ||
function config({plugins = [], output = {}}) { | ||
return { | ||
input: 'src/index.ts', | ||
plugins: [ | ||
typescript({tsconfigOverride: {compilerOptions: {module: 'ES2015'}}}), | ||
node(), ...plugins | ||
typescript(tsoptions), | ||
resolve(), ...plugins | ||
], | ||
@@ -70,13 +72,9 @@ output: { | ||
config({ | ||
plugins: [ | ||
minify() | ||
], | ||
plugins: [terser({output: {preamble: PREAMBLE, comments: false}})], | ||
output: {format: 'umd', name: 'facemesh', file: 'dist/facemesh.min.js'} | ||
}), | ||
config({ | ||
plugins: [ | ||
minify() | ||
], | ||
plugins: [terser({output: {preamble: PREAMBLE, comments: false}})], | ||
output: {format: 'es', file: 'dist/facemesh.esm.js'} | ||
}) | ||
]; |
@@ -18,5 +18,24 @@ /** | ||
// Use the CPU backend for running tests. | ||
import '@tensorflow/tfjs-backend-cpu'; | ||
// tslint:disable-next-line:no-imports-from-dist | ||
import * as jasmine_util from '@tensorflow/tfjs-core/dist/jasmine_util'; | ||
import {runTests} from '../test_util'; | ||
runTests(jasmine_util); | ||
// tslint:disable-next-line:no-require-imports | ||
const jasmineCtor = require('jasmine'); | ||
// tslint:disable-next-line:no-require-imports | ||
Error.stackTraceLimit = Infinity; | ||
process.on('unhandledRejection', e => { | ||
throw e; | ||
}); | ||
jasmine_util.setTestEnvs( | ||
[{name: 'test-facemesh', backendName: 'cpu', flags: {}}]); | ||
const unitTests = 'src/**/*_test.ts'; | ||
const runner = new jasmineCtor(); | ||
runner.loadConfig({spec_files: [unitTests], random: false}); | ||
runner.execute(); |
{ | ||
"compilerOptions": { | ||
"module": "commonjs", | ||
"moduleResolution": "node", | ||
"noImplicitAny": true, | ||
"sourceMap": true, | ||
"removeComments": true, | ||
"preserveConstEnums": true, | ||
"declaration": true, | ||
"target": "es2017", | ||
"lib": [ | ||
"es2015", | ||
"dom" | ||
], | ||
"outDir": "./dist", | ||
"noUnusedLocals": true, | ||
"noImplicitReturns": true, | ||
"noImplicitThis": true, | ||
"alwaysStrict": true, | ||
"noUnusedParameters": false, | ||
"pretty": true, | ||
"noFallthroughCasesInSwitch": true, | ||
"allowUnreachableCode": false, | ||
"experimentalDecorators": true | ||
}, | ||
"extends": "../tsconfig", | ||
"include": [ | ||
@@ -30,5 +7,7 @@ "src/" | ||
"exclude": [ | ||
"node_modules/", | ||
"dist/" | ||
] | ||
"node_modules/" | ||
], | ||
"compilerOptions": { | ||
"outDir": "./dist" | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
10857528
2895
143
4
17
24
+ Addedrimraf@^3.0.2
+ Added@tensorflow/tfjs-converter@2.8.6(transitive)
+ Added@tensorflow/tfjs-core@2.8.6(transitive)
+ Addedbalanced-match@1.0.2(transitive)
+ Addedbrace-expansion@1.1.11(transitive)
+ Addedconcat-map@0.0.1(transitive)
+ Addedfs.realpath@1.0.0(transitive)
+ Addedglob@7.2.3(transitive)
+ Addedinflight@1.0.6(transitive)
+ Addedinherits@2.0.4(transitive)
+ Addedminimatch@3.1.2(transitive)
+ Addednode-fetch@2.6.13(transitive)
+ Addedonce@1.4.0(transitive)
+ Addedpath-is-absolute@1.0.1(transitive)
+ Addedrimraf@3.0.2(transitive)
+ Addedtr46@0.0.3(transitive)
+ Addedwebidl-conversions@3.0.1(transitive)
+ Addedwhatwg-url@5.0.0(transitive)
+ Addedwrappy@1.0.2(transitive)