Skip to content

Commit ee0941d

Browse files
Merge pull request #282 from PaddlePaddle/master
merge master to v2.2.0 branch
2 parents f9f608b + 67eaf81 commit ee0941d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+26609
-14256
lines changed

e2e/server.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ const ocr = new ConfigInfo('ocr', ocrWebpackConfig, true);
4343
if (instance.isModelSdk) {
4444
config.resolve = Object.assign({}, config.resolve, {
4545
alias: {
46-
'@paddlejs/paddlejs-core': path.resolve(DIST_DIR, './core_bundle.js'),
47-
'@paddlejs/paddlejs-backend-webgl': path.resolve(DIST_DIR, './webgl_bundle.js')
46+
'@paddlejs/paddlejs-core': path.resolve(__dirname, '../packages/paddlejs-core/src/'),
47+
'@paddlejs/paddlejs-backend-webgl': path.resolve(__dirname, '../packages/paddlejs-backend-webgl/src/')
4848
}
4949
});
5050
}

packages/paddlejs-core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@paddlejs/paddlejs-core",
3-
"version": "2.1.7",
3+
"version": "2.1.9",
44
"description": "",
55
"main": "lib/index",
66
"scripts": {

packages/paddlejs-core/src/commons/interface.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,14 @@ export interface FeedShape {
5959
fw: number;
6060
fh: number;
6161
};
62+
63+
interface ModelObj {
64+
model: Model;
65+
params: Float32Array
66+
}
6267
export interface RunnerConfig {
63-
modelPath: string;
68+
modelPath?: string;
69+
modelObj?: ModelObj;
6470
modelName?: string;
6571
feedShape?: FeedShape;
6672
fill?: string; // 缩放后用什么颜色填充不足方形部分

packages/paddlejs-core/src/loader.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export default class ModelLoader {
7070
if (this.separateChunk) {
7171
if (this.dataType === 'binary') {
7272
await this.fetchChunks().then(allChunksData =>
73-
this.traverse(modelInfo.vars, allChunksData)
73+
ModelLoader.allocateParamsVar(modelInfo.vars, allChunksData)
7474
);
7575
}
7676
}
@@ -105,9 +105,7 @@ export default class ModelLoader {
105105
this.fetchOneChunk(this.urlConf.dir + this.getFileName(i))
106106
);
107107
}
108-
// console.time('加载时间');
109108
return Promise.all(chunkArray).then(chunks => {
110-
// console.timeEnd('加载时间');
111109
let chunksLength = 0;
112110
const f32Array: any[] = [];
113111
let float32Chunk;
@@ -128,7 +126,7 @@ export default class ModelLoader {
128126
});
129127
}
130128

131-
traverse(vars, allChunksData: Float32Array) {
129+
static allocateParamsVar(vars, allChunksData: Float32Array) {
132130
let marker = 0; // 读到哪个位置了
133131
let len; // 当前op长度
134132
traverseVars(vars, item => {

packages/paddlejs-core/src/runner.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,19 @@ export default class Runner {
7474
}
7575

7676
async load() {
77-
const { modelPath } = this.runnerConfig;
78-
const loader = new Loader(modelPath);
79-
this.model = await loader.load();
77+
const { modelPath, modelObj = null } = this.runnerConfig;
78+
if (modelPath) {
79+
const loader = new Loader(modelPath);
80+
this.model = await loader.load();
81+
}
82+
else if (modelObj?.model && modelObj?.params) {
83+
const {
84+
model,
85+
params
86+
} = modelObj;
87+
Loader.allocateParamsVar(model.vars, params);
88+
this.model = model;
89+
}
8090
}
8191

8292
genGraph() {
@@ -373,8 +383,8 @@ export default class Runner {
373383

374384
if (env.get('debug')
375385
&& op.opData?.outputTensors
376-
&& op.opData.outputTensors[0]
377-
&& op.opData.outputTensors[0].tensorId === this.modelName + '_'
386+
&& op.opData.outputTensors[op.opData.outputTensors.length - 1]
387+
&& op.opData.outputTensors[op.opData.outputTensors.length - 1].tensorId === this.modelName + '_'
378388
+ (env.get('ns').layerName || env.get('layerName'))) {
379389
console.info(op.opData.name + '_' + op.opData.iLayer, 'runner op');
380390
return;
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
[中文版](./README_cn.md)
2+
3+
# gesture
4+
5+
gesture is a gesture recognition module, including two models: gesture_detect and gesture_rec. gesture_detect model is used to identify the palm area of the person in the image. gesture_rec model is used to recognize human gesture. The interface provided by the module is simple, users only need to pass in gesture images to get the results.
6+
7+
# Setup
8+
```
9+
npm install
10+
```
11+
12+
### Compiles and hot-reloads for development
13+
```
14+
npm run dev
15+
```
16+
17+
### Compiles and minifies for production
18+
```
19+
npm run build
20+
```
21+
22+
# Usage
23+
24+
```js
25+
import * as gesture from '@paddlejs-models/gesture';
26+
27+
// Load gesture_detect model and gesture_rec model
28+
await gesture.load();
29+
30+
// Get the image recognition results. The results include: palm frame coordinates and recognition results
31+
const res = await gesture.classify(img);
32+
33+
```
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
[English](./README.md)
2+
3+
# gesture
4+
5+
gesture 为手势识别模块,包括两个模型:gesture_detect和gesture_rec。gesture_detect模型识别图片中人物手掌区域,gesture_rec模型识别人物手势。模块提供的接口简单,使用者只需传入手势图片即可获得结果。
6+
7+
# 安装
8+
```
9+
npm install
10+
```
11+
12+
### 编译
13+
```
14+
npm run dev
15+
```
16+
17+
### 构建
18+
```
19+
npm run build
20+
```
21+
22+
# 使用
23+
24+
```js
25+
import * as gesture from '@paddlejs-models/gesture';
26+
27+
// gesture_detect、gesture_rec模型加载
28+
await gesture.load();
29+
30+
// 获取图片识别结果。结果包括:手掌框选坐标和识别结果
31+
const res = await gesture.classify(img);
32+
33+
```
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<title>paddle ocr detection demo</title>
6+
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
7+
<style>
8+
.wrapper {
9+
position: relative;
10+
display: flex;
11+
text-align: left;
12+
padding: 2%;
13+
flex-wrap: wrap;
14+
min-height: 500px;
15+
}
16+
17+
.title {
18+
font-weight: 600;
19+
font-size: 20px;
20+
margin-bottom: 10px;
21+
}
22+
23+
.left {
24+
display: flex;
25+
flex-wrap: wrap;
26+
width: min-content;
27+
min-width: 55%;
28+
}
29+
30+
.box {
31+
min-width: 320px;
32+
border: 1px solid #ddd;
33+
border-radius: 5px;
34+
margin-bottom: 100px;
35+
padding: 10px;
36+
}
37+
38+
.tool {
39+
margin-right: 50px;
40+
flex-shrink: 0;
41+
}
42+
43+
.canvas {
44+
width: max-content;
45+
margin-right: 50px;
46+
}
47+
48+
#image {
49+
display: block;
50+
margin-top: 10px;
51+
}
52+
53+
#txt {
54+
line-height: 2;
55+
height: min-content;
56+
}
57+
58+
#isLoading {
59+
position: fixed;
60+
top: 0;
61+
left: 0;
62+
right: 0;
63+
bottom: 0;
64+
width: 100vw;
65+
height: 100vh;
66+
background-color: rgba(0, 0, 0, .5);
67+
}
68+
69+
#isLoading .loading-text {
70+
color: #fff;
71+
font-size: 24px;
72+
text-align: center;
73+
line-height: 100vh;
74+
}
75+
76+
</style>
77+
</head>
78+
<body>
79+
<div class="wrapper">
80+
<div class="left">
81+
<div class="tool box">
82+
<p class="title">上传手势图片:</p>
83+
<input type="file" id="uploadImg" />
84+
<img id="image" />
85+
</div>
86+
<div class="canvas box">
87+
<p class="title">手掌位置框选:</p>
88+
<canvas id="canvas"></canvas>
89+
</div>
90+
</div>
91+
<div class="box">
92+
<p class="title">手势识别结果:</p>
93+
<div id="txt"></div>
94+
</div>
95+
</div>
96+
97+
<div id="isLoading">
98+
<p class="loading-text center">loading中……</p>
99+
</div>
100+
101+
</body>
102+
</html>
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import * as gesture from '@paddlejs-models/gesture';
2+
3+
const $uploadImg = document.getElementById('uploadImg') as HTMLInputElement;
4+
const $img = document.getElementById('image') as HTMLImageElement;
5+
const $txt = document.getElementById('txt');
6+
7+
async function load() {
8+
await gesture.load();
9+
document.getElementById('isLoading').style.display = 'none';
10+
}
11+
12+
async function run(input: HTMLImageElement) {
13+
const res = await gesture.classify(input);
14+
let text = '未识别到手';
15+
if (res.box && res.box.length) {
16+
text = res.type;
17+
calculateBox(input, res.box);
18+
}
19+
$txt.innerText = text;
20+
}
21+
22+
function calculateBox(img, box) {
23+
let offsetX = 0;
24+
let offsetY = 0;
25+
26+
if (img.width < img.height) {
27+
offsetX = img.height - img.width;
28+
}
29+
30+
if (img.width > img.height) {
31+
offsetY = img.width - img.height;
32+
}
33+
34+
const $canvas = document.getElementById('canvas') as HTMLCanvasElement;
35+
const widthRatio = (img.width + offsetX) / 256;
36+
const heightRatio = (img.height + offsetY) / 256;
37+
const point = [];
38+
39+
box.forEach(item => {
40+
const tmpPonit = [];
41+
tmpPonit[0] = item[0] * widthRatio - offsetX / 2;
42+
tmpPonit[1] = item[1] * heightRatio - offsetY / 2;
43+
point.push(tmpPonit);
44+
});
45+
$canvas.width = img.width;
46+
$canvas.height = img.height;
47+
const ctx = $canvas.getContext('2d');
48+
// 开始一个新的绘制路径
49+
ctx.beginPath();
50+
ctx.drawImage(img, 0, 0, $canvas.width, $canvas.height);
51+
// 设置线条颜色为蓝色
52+
ctx.strokeStyle = 'blue';
53+
// 设置路径起点坐标
54+
ctx.moveTo(point[0][0], point[0][1]);
55+
ctx.lineTo(point[1][0], point[1][1]);
56+
ctx.lineTo(point[2][0], point[2][1]);
57+
ctx.lineTo(point[3][0], point[3][1]);
58+
ctx.closePath();
59+
ctx.stroke();
60+
}
61+
62+
load();
63+
64+
$uploadImg.onchange = (e: Event) => {
65+
const reader = new FileReader();
66+
reader.onload = () => {
67+
$img.src = URL.createObjectURL((e.target as HTMLInputElement).files[0]);
68+
$img.onload = () => {
69+
run($img);
70+
};
71+
};
72+
reader.readAsDataURL((e.target as HTMLInputElement).files[0]);
73+
};

0 commit comments

Comments
 (0)