Skip to content

Commit 0541c8c

Browse files
committed
update
1 parent f4eebf6 commit 0541c8c

File tree

8 files changed

+1114
-1067
lines changed

8 files changed

+1114
-1067
lines changed

001_bodypix-worker-js/package-lock.json

Lines changed: 979 additions & 879 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

001_bodypix-worker-js/package.json

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@dannadori/bodypix-worker-js",
3-
"version": "1.0.42",
3+
"version": "1.0.43",
44
"description": "",
55
"main": "dist/bodypix-worker.js",
66
"scripts": {
@@ -25,24 +25,25 @@
2525
},
2626
"homepage": "https://github.com/w-okada/image-analyze-workers",
2727
"devDependencies": {
28-
"@babel/preset-env": "^7.15.8",
29-
"@types/node": "^16.11.6",
30-
"before-build-webpack": "^0.2.11",
28+
"@babel/core": "^7.17.8",
29+
"@babel/preset-env": "^7.16.11",
30+
"@types/node": "^17.0.23",
31+
"before-build-webpack": "^0.2.12",
3132
"npm-run-all": "^4.1.5",
3233
"rimraf": "^3.0.2",
33-
"ts-loader": "^9.2.6",
34-
"tsconfig-paths": "^3.11.0",
35-
"typescript": "^4.4.4",
36-
"webpack": "^5.60.0",
37-
"webpack-cli": "^4.9.1",
34+
"ts-loader": "^9.2.8",
35+
"tsconfig-paths": "^3.14.1",
36+
"typescript": "^4.6.3",
37+
"webpack": "^5.71.0",
38+
"webpack-cli": "^4.9.2",
3839
"worker-loader": "^3.0.8"
3940
},
4041
"dependencies": {
4142
"@tensorflow-models/body-pix": "^2.2.0",
42-
"@tensorflow/tfjs": "^3.10.0",
43-
"@tensorflow/tfjs-backend-wasm": "^3.10.0",
44-
"@tensorflow/tfjs-converter": "^3.10.0",
45-
"@tensorflow/tfjs-core": "^3.10.0",
46-
"await-semaphore": "^0.1.3"
43+
"@tensorflow/tfjs": "^3.15.0",
44+
"@tensorflow/tfjs-backend-wasm": "^3.15.0",
45+
"@tensorflow/tfjs-converter": "^3.15.0",
46+
"@tensorflow/tfjs-core": "^3.15.0",
47+
"worker-base": "file:../000_WorkerBase"
4748
}
4849
}

001_bodypix-worker-js/src/BrowserUtil.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,19 @@ export enum BrowserType {
1414

1515
export const getBrowserType = () => {
1616
var userAgent = window.navigator.userAgent.toLowerCase();
17-
if (userAgent.indexOf("msie") !== -1 || userAgent.indexOf("trident") !== -1) {
18-
return BrowserType.MSIE;
19-
} else if (userAgent.indexOf("edge") !== -1) {
20-
return BrowserType.EDGE;
21-
} else if (userAgent.indexOf("chrome") !== -1) {
22-
return BrowserType.CHROME;
23-
} else if (userAgent.indexOf("safari") !== -1) {
24-
return BrowserType.SAFARI;
25-
} else if (userAgent.indexOf("firefox") !== -1) {
26-
return BrowserType.FIREFOX;
27-
} else if (userAgent.indexOf("opera") !== -1) {
28-
return BrowserType.OPERA;
17+
if (userAgent.indexOf('msie') !== -1 || userAgent.indexOf('trident') !== -1) {
18+
return BrowserType.MSIE
19+
} else if (userAgent.indexOf('edge') !== -1) {
20+
return BrowserType.EDGE
21+
} else if (userAgent.indexOf('chrome') !== -1) {
22+
return BrowserType.CHROME
23+
} else if (userAgent.indexOf('safari') !== -1) {
24+
return BrowserType.SAFARI
25+
} else if (userAgent.indexOf('firefox') !== -1) {
26+
return BrowserType.FIREFOX
27+
} else if (userAgent.indexOf('opera') !== -1) {
28+
return BrowserType.OPERA
2929
} else {
30-
return BrowserType.OTHER;
30+
return BrowserType.OTHER
3131
}
32-
};
32+
}

001_bodypix-worker-js/src/bodypix-worker-worker.ts

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
import { WorkerCommand, WorkerResponse, BodypixFunctionType, BodyPixConfig, BodyPixOperatipnParams } from "./const";
1+
import { WorkerCommand, WorkerResponse, BodyPixConfig, BodyPixOperatipnParams, BodypixFunctionTypes } from "./const";
22
import * as bodyPix from "@tensorflow-models/body-pix";
33
import * as tf from "@tensorflow/tfjs";
4-
import { BrowserType } from "./BrowserUtil";
4+
import { BrowserTypes } from "worker-base";
55

66
const ctx: Worker = self as any; // eslint-disable-line no-restricted-globals
77

88
let model: bodyPix.BodyPix | null;
99

1010
const load_module = async (config: BodyPixConfig) => {
11-
if (config.useTFWasmBackend || config.browserType === BrowserType.SAFARI) {
11+
if (config.useTFWasmBackend || config.browserType === BrowserTypes.SAFARI) {
1212
console.log("use wasm backend");
1313
require("@tensorflow/tfjs-backend-wasm");
1414
await tf.setBackend("wasm");
@@ -55,7 +55,6 @@ const generateImage = (image: ImageBitmap, prediction: bodyPix.SemanticPersonSeg
5555
};
5656

5757
const predict = async (image: ImageBitmap, config: BodyPixConfig, params: BodyPixOperatipnParams) => {
58-
console.log("PREDICT_CHECK");
5958
// ImageData作成
6059
const processWidth = params.processWidth <= 0 || params.processHeight <= 0 ? image.width : params.processWidth;
6160
const processHeight = params.processWidth <= 0 || params.processHeight <= 0 ? image.height : params.processHeight;
@@ -67,13 +66,13 @@ const predict = async (image: ImageBitmap, config: BodyPixConfig, params: BodyPi
6766
const newImg = ctx.getImageData(0, 0, processWidth, processHeight);
6867

6968
let prediction;
70-
if (params.type === BodypixFunctionType.SegmentPerson) {
69+
if (params.type === BodypixFunctionTypes.SegmentPerson) {
7170
prediction = await model!.segmentPerson(newImg, params.segmentPersonParams);
72-
} else if (params.type === BodypixFunctionType.SegmentPersonParts) {
71+
} else if (params.type === BodypixFunctionTypes.SegmentPersonParts) {
7372
prediction = await model!.segmentPersonParts(newImg, params.segmentPersonPartsParams);
74-
} else if (params.type === BodypixFunctionType.SegmentMultiPerson) {
73+
} else if (params.type === BodypixFunctionTypes.SegmentMultiPerson) {
7574
prediction = await model!.segmentMultiPerson(newImg, params.segmentMultiPersonParams);
76-
} else if (params.type === BodypixFunctionType.SegmentMultiPersonParts) {
75+
} else if (params.type === BodypixFunctionTypes.SegmentMultiPersonParts) {
7776
prediction = await model!.segmentMultiPersonParts(newImg, params.segmentMultiPersonPartsParams);
7877
} else {
7978
// segmentPersonに倒す
@@ -93,14 +92,12 @@ onmessage = async (event) => {
9392
});
9493
} else if (event.data.message === WorkerCommand.PREDICT) {
9594
const config: BodyPixConfig = event.data.config;
96-
const image: ImageBitmap = event.data.image;
97-
const uid: number = event.data.uid;
9895
const params: BodyPixOperatipnParams = event.data.params;
96+
const image: ImageBitmap = event.data.data;
9997

10098
const prediction = await predict(image, config, params);
10199
ctx.postMessage({
102100
message: WorkerResponse.PREDICTED,
103-
uid: uid,
104101
prediction: prediction,
105102
});
106103
}

001_bodypix-worker-js/src/bodypix-worker.ts

Lines changed: 50 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
import { WorkerResponse, WorkerCommand, BodypixFunctionType, BodyPixConfig, ModelConfigMobileNetV1_05, BodyPixOperatipnParams } from "./const";
1+
import { BodyPixConfig, BodyPixOperatipnParams, BodypixFunctionTypes, ModelConfigs } from "./const";
22
import * as bodyPix from "@tensorflow-models/body-pix";
3-
import { BrowserType, getBrowserType } from "./BrowserUtil";
43
import { SemanticPersonSegmentation } from "@tensorflow-models/body-pix";
4+
import { WorkerManagerBase, LocalWorker, getBrowserType } from "worker-base";
55

6-
export { ModelConfigResNet, ModelConfigMobileNetV1, ModelConfigMobileNetV1_05, BodypixFunctionType, BodyPixConfig, BodyPixOperatipnParams } from "./const";
7-
export { BrowserType, getBrowserType } from "./BrowserUtil";
6+
export { BodypixFunctionTypes, BodyPixConfig, BodyPixOperatipnParams } from "./const";
87
export { SemanticPersonSegmentation, SemanticPartSegmentation, PersonSegmentation, PartSegmentation } from "@tensorflow-models/body-pix";
9-
export { BodyPixInternalResolution } from "@tensorflow-models/body-pix/dist/types";
8+
export { BodyPixInternalResolution, BodyPixArchitecture, BodyPixMultiplier, BodyPixOutputStride, BodyPixQuantBytes } from "@tensorflow-models/body-pix/dist/types";
109

1110
import * as tf from "@tensorflow/tfjs";
1211

@@ -28,7 +27,7 @@ const load_module = async (config: BodyPixConfig) => {
2827
export const generateBodyPixDefaultConfig = (): BodyPixConfig => {
2928
const defaultConf: BodyPixConfig = {
3029
browserType: getBrowserType(),
31-
model: ModelConfigMobileNetV1_05,
30+
model: ModelConfigs.ModelConfigMobileNetV1_05,
3231
processOnLocal: false,
3332
useTFWasmBackend: false,
3433
};
@@ -37,7 +36,7 @@ export const generateBodyPixDefaultConfig = (): BodyPixConfig => {
3736

3837
export const generateDefaultBodyPixParams = () => {
3938
const defaultParams: BodyPixOperatipnParams = {
40-
type: BodypixFunctionType.SegmentPerson,
39+
type: BodypixFunctionTypes.SegmentPerson,
4140
segmentPersonParams: {
4241
flipHorizontal: false,
4342
internalResolution: "medium",
@@ -80,7 +79,7 @@ export const generateDefaultBodyPixParams = () => {
8079
return defaultParams;
8180
};
8281

83-
class LocalBP {
82+
class LocalBP extends LocalWorker {
8483
model: bodyPix.BodyPix | null = null;
8584
canvas: HTMLCanvasElement = (() => {
8685
const newCanvas = document.createElement("canvas");
@@ -93,36 +92,29 @@ class LocalBP {
9392
this.model = await bodyPix.load(config.model);
9493
};
9594

96-
perf = Array.from(new Array(50), () => 0);
97-
predict = async (targetCanvas: HTMLCanvasElement, config: BodyPixConfig, params: BodyPixOperatipnParams) => {
98-
// ImageData作成
99-
const processWidth = params.processWidth <= 0 || params.processHeight <= 0 ? targetCanvas.width : params.processWidth;
100-
const processHeight = params.processWidth <= 0 || params.processHeight <= 0 ? targetCanvas.height : params.processHeight;
95+
predict = async (config: BodyPixConfig, params: BodyPixOperatipnParams, targetCanvas: HTMLCanvasElement) => {
96+
// // ImageData作成
97+
// const processWidth = params.processWidth <= 0 || params.processHeight <= 0 ? targetCanvas.width : params.processWidth;
98+
// const processHeight = params.processWidth <= 0 || params.processHeight <= 0 ? targetCanvas.height : params.processHeight;
10199

102-
//console.log("process image size:", processWidth, processHeight)
103-
this.canvas.width = processWidth;
104-
this.canvas.height = processHeight;
105-
const ctx = this.canvas.getContext("2d")!;
106-
ctx.drawImage(targetCanvas, 0, 0, processWidth, processHeight);
107-
const newImg = ctx.getImageData(0, 0, processWidth, processHeight);
100+
// //console.log("process image size:", processWidth, processHeight)
101+
// this.canvas.width = processWidth;
102+
// this.canvas.height = processHeight;
103+
// const ctx = this.canvas.getContext("2d")!;
104+
// ctx.drawImage(targetCanvas, 0, 0, processWidth, processHeight);
105+
// const newImg = ctx.getImageData(0, 0, processWidth, processHeight);
106+
107+
const ctx = targetCanvas.getContext("2d")!;
108+
const newImg = ctx.getImageData(0, 0, targetCanvas.width, targetCanvas.height);
108109

109110
let prediction;
110-
if (params.type === BodypixFunctionType.SegmentPerson) {
111-
const start = performance.now();
111+
if (params.type === BodypixFunctionTypes.SegmentPerson) {
112112
prediction = await this.model!.segmentPerson(newImg, params.segmentPersonParams);
113-
const end = performance.now();
114-
this.perf.shift();
115-
this.perf.push(end - start);
116-
const average =
117-
this.perf.reduce((p, c) => {
118-
return p + c;
119-
}) / this.perf.length;
120-
// console.log("inference average:", average, this.perf.length)
121-
} else if (params.type === BodypixFunctionType.SegmentPersonParts) {
113+
} else if (params.type === BodypixFunctionTypes.SegmentPersonParts) {
122114
prediction = await this.model!.segmentPersonParts(newImg, params.segmentPersonPartsParams);
123-
} else if (params.type === BodypixFunctionType.SegmentMultiPerson) {
115+
} else if (params.type === BodypixFunctionTypes.SegmentMultiPerson) {
124116
prediction = await this.model!.segmentMultiPerson(newImg, params.segmentMultiPersonParams);
125-
} else if (params.type === BodypixFunctionType.SegmentMultiPersonParts) {
117+
} else if (params.type === BodypixFunctionTypes.SegmentMultiPersonParts) {
126118
prediction = await this.model!.segmentMultiPersonParts(newImg, params.segmentMultiPersonPartsParams);
127119
} else {
128120
// segmentPersonに倒す
@@ -132,92 +124,42 @@ class LocalBP {
132124
};
133125
}
134126

135-
export class BodypixWorkerManager {
136-
private workerBP: Worker | null = null;
137-
127+
export class BodypixWorkerManager extends WorkerManagerBase {
138128
config: BodyPixConfig = generateBodyPixDefaultConfig();
139-
private localBP = new LocalBP();
140-
129+
localWorker = new LocalBP();
141130
init = async (config: BodyPixConfig | null = null) => {
142-
if (config != null) {
143-
this.config = config;
144-
}
145-
if (this.workerBP) {
146-
this.workerBP.terminate();
147-
}
148-
this.workerBP = null;
149-
150-
if (this.config.browserType === BrowserType.SAFARI || this.config.processOnLocal == true) {
151-
// safariはwebworkerでWebGLが使えないのでworkerは使わない。
152-
return new Promise<void>((onResolve, onFail) => {
153-
this.localBP.init(this.config!).then(() => {
154-
onResolve();
155-
});
156-
});
157-
}
158-
159-
const workerBP: Worker = new workerJs();
160-
161-
workerBP!.postMessage({
162-
message: WorkerCommand.INITIALIZE,
163-
config: this.config,
164-
});
165-
const p = new Promise<void>((onResolve, onFail) => {
166-
workerBP!.onmessage = (event) => {
167-
if (event.data.message === WorkerResponse.INITIALIZED) {
168-
console.log("WORKERSS INITIALIZED");
169-
this.workerBP = workerBP;
170-
onResolve();
171-
} else {
172-
console.log("Bodypix Initialization something wrong..");
173-
onFail(event);
174-
}
175-
};
176-
});
177-
await p;
131+
this.config = config || generateBodyPixDefaultConfig();
132+
await this.initCommon(
133+
{
134+
useWorkerForSafari: false,
135+
processOnLocal: this.config.processOnLocal,
136+
localWorker: () => {
137+
return new workerJs!();
138+
},
139+
workerJs: () => {
140+
return new workerJs();
141+
},
142+
},
143+
config
144+
);
178145
return;
179146
};
180147

181-
predict = async (targetCanvas: HTMLCanvasElement, params: BodyPixOperatipnParams) => {
182-
if (this.config.browserType === BrowserType.SAFARI || this.config.processOnLocal == true) {
183-
const prediction = await this.localBP.predict(targetCanvas, this.config, params);
148+
predict = async (params: BodyPixOperatipnParams, targetCanvas: HTMLCanvasElement) => {
149+
if (!this.worker) {
150+
const resizedCanvas = this.generateTargetCanvas(targetCanvas, params.processWidth, params.processHeight);
151+
const prediction = await this.localWorker.predict(this.config, params, resizedCanvas);
184152
return prediction;
185-
} else {
186-
if (!this.workerBP) {
187-
return Array.from(new Array(params.processWidth), () => new Array(params.processHeight).fill(1));
188-
}
189-
const offscreen = new OffscreenCanvas(targetCanvas.width, targetCanvas.height);
190-
const offctx = offscreen.getContext("2d")!;
191-
offctx.drawImage(targetCanvas, 0, 0, targetCanvas.width, targetCanvas.height);
192-
const imageBitmap = offscreen.transferToImageBitmap();
193-
const uid = performance.now();
194-
const p = new Promise((onResolve, onFail) => {
195-
this.workerBP!.postMessage(
196-
{
197-
message: WorkerCommand.PREDICT,
198-
uid: uid,
199-
params: params,
200-
image: imageBitmap,
201-
config: this.config,
202-
},
203-
[imageBitmap]
204-
);
205-
206-
this.workerBP!.onmessage = (event) => {
207-
if (event.data.message === WorkerResponse.PREDICTED && event.data.uid === uid) {
208-
onResolve(event.data.prediction);
209-
} else {
210-
console.log("Bodypix Prediction something wrong..", event.data.message, WorkerResponse.PREDICTED, event.data.uid, uid);
211-
// onFail(event)
212-
}
213-
};
214-
});
215-
return p;
216153
}
154+
const imageBitmap = this.generateImageBitmap(targetCanvas, params.processWidth, params.processHeight);
155+
const prediction = (await this.sendToWorker(this.config, params, imageBitmap)) as bodyPix.SemanticPersonSegmentation | bodyPix.SemanticPartSegmentation | bodyPix.PersonSegmentation[] | bodyPix.PartSegmentation[];
156+
return prediction;
217157
};
218158
}
219159

220-
//// Utility for Demo
160+
/////////////////////////
161+
//// Utility for Demo ///
162+
/////////////////////////
221163
export const createForegroundImage = (srcCanvas: HTMLCanvasElement, prediction: SemanticPersonSegmentation) => {
222164
const tmpCanvas = document.createElement("canvas");
223165
tmpCanvas.width = prediction.width;

0 commit comments

Comments
 (0)