-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b596fc3
commit 4ce007d
Showing
10 changed files
with
353 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -111,3 +111,4 @@ venv.bak/ | |
# js | ||
node_modules/ | ||
package-lock.json | ||
test_tipc/web/models/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# Web 端基础预测功能测试 | ||
|
||
Web 端主要基于 Jest-Puppeteer 完成 e2e 测试,其中 Puppeteer 操作 Chrome 完成推理流程,Jest 完成测试流程。 | ||
>Puppeteer 是一个 Node 库,它提供了一个高级 API 来通过 DevTools 协议控制 Chromium 或 Chrome | ||
>Jest 是一个 JavaScript 测试框架,旨在确保任何 JavaScript 代码的正确性。 | ||
#### 环境准备 | ||
|
||
* 安装 Node(包含 npm ) (https://nodejs.org/zh-cn/download/) | ||
* 确认是否安装成功,在命令行执行 | ||
```sh | ||
# 显示所安 node 版本号,即表示成功安装 | ||
node -v | ||
``` | ||
* 确认 npm 是否安装成成 | ||
```sh | ||
# npm 随着 node 一起安装,一般无需额外安装 | ||
# 显示所安 npm 版本号,即表示成功安装 | ||
npm -v | ||
``` | ||
|
||
#### 使用 | ||
```sh | ||
# web 测试环境准备 | ||
bash test_tipc/prepare_js.sh 'js_infer' | ||
|
||
# web 推理测试 | ||
bash test_tipc/test_infer_js.sh | ||
``` | ||
|
||
|
||
#### 流程设计 | ||
|
||
###### paddlejs prepare | ||
1. 判断 node, npm 是否安装 | ||
2. 下载测试模型,当前为 ppseg_lite_portrait_398x224 ,如果需要替换,把对应模型连接和模型包名字修改即可 | ||
- 当前模型:https://paddleseg.bj.bcebos.com/dygraph/ppseg/ppseg_lite_portrait_398x224.tar.gz | ||
- 模型配置:configs/pp_humanseg_lite/pp_humanseg_lite_export_398x224.yml | ||
3. 导出模型为静态图模型(保存地址:test_tipc/web/models/pphumanseg_lite) | ||
4. 转换模型, model.pdmodel model.pdiparams 转换为 model.json chunk.dat | ||
5. 安装最新版本 humanseg sdk @paddlejs-models/humanseg@latest | ||
6. 安装测试环境依赖 puppeteer、jest、jest-puppeteer,如果检查到已经安装,则不会进行二次安装 | ||
|
||
|
||
###### paddlejs infer test | ||
1. Jest 执行 server command:`python3 -m http.server 9811` 开启本地服务 | ||
2. 启动 Jest 测试服务,通过 jest-puppeteer 插件完成 chrome 操作,加载 @paddlejs-models/humanseg 脚本完成推理流程 | ||
3. 测试用例为分割后的图片与预期图片(expect img)效果进行**逐像素对比**,精度误差不超过 **2%**,则视为测试通过,通过为如下显示: | ||
<img width="594" alt="infoflow 2021-12-02 16-34-05" src="https://user-images.githubusercontent.com/ | ||
10822846/144386307-b4e10b07-f105-499f-b953-4dc2707c6242.png"> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
#!/bin/bash | ||
|
||
set -o errexit | ||
set -o nounset | ||
shopt -s extglob | ||
|
||
# paddlejs prepare 主要流程 | ||
# 1. 判断 node, npm 是否安装 | ||
# 2. 下载测试模型,当前为 ppseg_lite_portrait_398x224 ,如果需要替换,把对应模型连接和模型包名字修改即可 | ||
# - 当前模型:https://paddleseg.bj.bcebos.com/dygraph/ppseg/ppseg_lite_portrait_398x224.tar.gz | ||
# - 模型配置:configs/pp_humanseg_lite/pp_humanseg_lite_export_398x224.yml | ||
# 3. 导出模型为静态图模型 | ||
# 4. 转换模型, model.pdmodel model.pdiparams 转换为 model.json chunk.dat | ||
# 5. 安装最新版本 humanseg sdk @paddlejs-models/humanseg@latest | ||
# 6. 安装测试环境依赖 puppeteer、jest、jest-puppeteer | ||
|
||
# 判断是否安装了node | ||
if ! type node >/dev/null 2>&1; then | ||
echo -e "\033[31m node 未安装 \033[0m" | ||
exit | ||
fi | ||
|
||
# 判断是否安装了npm | ||
if ! type npm >/dev/null 2>&1; then | ||
echo -e "\033[31m npm 未安装 \033[0m" | ||
exit | ||
fi | ||
|
||
# MODE be 'js_infer' | ||
MODE=$1 | ||
# js_infer MODE , load model file and convert model to js_infer | ||
if [ ${MODE} != "js_infer" ];then | ||
echo "Please change mode to 'js_infer'" | ||
exit | ||
fi | ||
|
||
|
||
# saved_model_name | ||
saved_model_name=pphumanseg_lite | ||
# model_path | ||
model_path=test_tipc/web/models/ | ||
|
||
rm -rf $model_path | ||
echo ${model_path}${saved_model_name} | ||
|
||
# download inference model | ||
wget -nc -P $model_path https://paddleseg.bj.bcebos.com/dygraph/ppseg/ppseg_lite_portrait_398x224.tar.gz | ||
cd $model_path && tar xf ppseg_lite_portrait_398x224.tar.gz && cd ../../../ | ||
|
||
# export to static shape model | ||
python3 export.py \ | ||
--config configs/pp_humanseg_lite/pp_humanseg_lite_export_398x224.yml \ | ||
--model_path test_tipc/web/models/ppseg_lite_portrait_398x224/model.pdparams \ | ||
--save_dir $model_path$saved_model_name/ \ | ||
--input_shape 1 3 224 398 \ | ||
--without_argmax --with_softmax | ||
|
||
|
||
pip3 install paddlejsconverter | ||
# convert inference model to web model: model.json、chunk_1.dat | ||
paddlejsconverter \ | ||
--modelPath=$model_path$saved_model_name/model.pdmodel \ | ||
--paramPath=$model_path$saved_model_name/model.pdiparams \ | ||
--outputDir=$model_path$saved_model_name/ \ | ||
|
||
|
||
|
||
|
||
# always install latest humanseg sdk | ||
cd test_tipc/web | ||
echo -e "\033[33m Installing the latest humanseg sdk... \033[0m" | ||
npm install @paddlejs-models/humanseg@latest | ||
echo -e "\033[32m The latest humanseg sdk installed completely.!~ \033[0m" | ||
|
||
# install dependencies | ||
if [ `npm list --dept 0 | grep puppeteer | wc -l` -ne 0 ] && [ `npm list --dept 0 | grep jest | wc -l` -ne 0 ];then | ||
echo -e "\033[32m Dependencies have installed \033[0m" | ||
else | ||
echo -e "\033[33m Installing dependencies ... \033[0m" | ||
npm install jest jest-puppeteer puppeteer | ||
echo -e "\033[32m Dependencies installed completely.!~ \033[0m" | ||
fi | ||
|
||
# del package-lock.json | ||
rm package-lock.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#!/bin/bash | ||
|
||
set -o errexit | ||
set -o nounset | ||
|
||
cd test_tipc/web | ||
# run humanseg test in chrome | ||
./node_modules/.bin/jest --config ./jest.config.js |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<meta http-equiv="X-UA-Compatible" content="ie=edge"> | ||
<title>pphumanseg_lite test</title> | ||
<style> | ||
body img { | ||
width: 300px; | ||
border: 2px black solid; | ||
} | ||
canvas { | ||
border: 2px black solid; | ||
} | ||
.test { | ||
display: flex; | ||
} | ||
.test div.item { | ||
display: flex; | ||
flex-direction: column; | ||
justify-content: center; | ||
align-items: center; | ||
} | ||
</style> | ||
</head> | ||
<body > | ||
<div class="test"> | ||
<div class="item"> | ||
<img id="human" src="./imgs/human.jpg"/> | ||
<div> origin img </div> | ||
</div> | ||
<div class="item"> | ||
<img id="seg" src="./imgs/seg.png"/> | ||
<div> expect img </div> | ||
</div> | ||
</div> | ||
<canvas id="back_canvas"></canvas> | ||
</body> | ||
<script src="./node_modules/@paddlejs-models/humanseg/lib/index.js"></script> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
describe('e2e test humanseg model', () => { | ||
beforeAll(async () => { | ||
await page.goto(PATH); | ||
}); | ||
|
||
it('humanseg infer and diff test', async () => { | ||
page.on('console', msg => console.log('PAGE LOG:', msg.text())); | ||
const mAP = await page.evaluate(async () => { | ||
const human = document.querySelector('#human'); | ||
const seg = document.querySelector('#seg'); | ||
const back_canvas = document.getElementById('back_canvas'); | ||
const back_ctx = back_canvas.getContext('2d'); | ||
|
||
const seg_canvas = document.createElement('canvas'); | ||
const seg_ctx = seg_canvas.getContext('2d'); | ||
seg_canvas.width = back_canvas.width = seg.naturalWidth; | ||
seg_canvas.height = back_canvas.height = seg.naturalHeight; | ||
seg_ctx.drawImage(seg, 0, 0, seg_canvas.width, seg_canvas.height); | ||
|
||
const humanseg = paddlejs['humanseg']; | ||
|
||
await humanseg.load(true, false, './models/pphumanseg_lite/model.json'); | ||
const { | ||
data | ||
} = await humanseg.getGrayValue(human); | ||
humanseg.drawHumanSeg(data, back_canvas); | ||
|
||
const backImageData = back_ctx.getImageData(0, 0, back_canvas.width, back_canvas.height).data; | ||
const segImageData = seg_ctx.getImageData(0, 0, seg_canvas.width, seg_canvas.height).data; | ||
|
||
let diffPixelsNum = 0; | ||
for (let index = 0; index < backImageData.length; index++) { | ||
if (backImageData[index] !== segImageData[index]) { | ||
diffPixelsNum++; | ||
} | ||
} | ||
return diffPixelsNum / backImageData.length; | ||
}); | ||
|
||
const expectedMAP = 0.02; | ||
await expect(mAP).toBeLessThanOrEqual(expectedMAP); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// jest-puppeteer.config.js | ||
module.exports = { | ||
launch: { | ||
headless: false, | ||
product: 'chrome' | ||
}, | ||
browserContext: 'default', | ||
server: { | ||
command: 'python3 -m http.server 9811', | ||
port: 9811, | ||
launchTimeout: 10000, | ||
debug: true | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
// For a detailed explanation regarding each configuration property and type check, visit: | ||
// https://jestjs.io/docs/en/configuration.html | ||
|
||
module.exports = { | ||
preset: 'jest-puppeteer', | ||
// All imported modules in your tests should be mocked automatically | ||
// automock: false, | ||
|
||
// Automatically clear mock calls and instances between every test | ||
clearMocks: true, | ||
|
||
// An object that configures minimum threshold enforcement for coverage results | ||
// coverageThreshold: undefined, | ||
|
||
// A set of global variables that need to be available in all test environments | ||
globals: { | ||
PATH: 'http://localhost:9811' | ||
}, | ||
|
||
// The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers. | ||
// maxWorkers: "50%", | ||
|
||
// An array of directory names to be searched recursively up from the requiring module's location | ||
// moduleDirectories: [ | ||
// "node_modules" | ||
// ], | ||
|
||
// An array of file extensions your modules use | ||
moduleFileExtensions: [ | ||
'js', | ||
'json', | ||
'jsx', | ||
'ts', | ||
'tsx', | ||
'node' | ||
], | ||
|
||
|
||
// The root directory that Jest should scan for tests and modules within | ||
// rootDir: undefined, | ||
|
||
// A list of paths to directories that Jest should use to search for files in | ||
roots: [ | ||
'<rootDir>' | ||
], | ||
|
||
// Allows you to use a custom runner instead of Jest's default test runner | ||
// runner: "jest-runner", | ||
|
||
// The paths to modules that run some code to configure or set up the testing environment before each test | ||
// setupFiles: [], | ||
|
||
// A list of paths to modules that run some code to configure or set up the testing framework before each test | ||
// setupFilesAfterEnv: [], | ||
|
||
// The number of seconds after which a test is considered as slow and reported as such in the results. | ||
// slowTestThreshold: 5, | ||
|
||
// A list of paths to snapshot serializer modules Jest should use for snapshot testing | ||
// snapshotSerializers: [], | ||
|
||
// The test environment that will be used for testing | ||
// testEnvironment: 'jsdom', | ||
|
||
// Options that will be passed to the testEnvironment | ||
// testEnvironmentOptions: {}, | ||
|
||
// An array of regexp pattern strings that are matched against all test paths, matched tests are skipped | ||
testPathIgnorePatterns: [ | ||
'/node_modules/' | ||
], | ||
|
||
// The regexp pattern or array of patterns that Jest uses to detect test files | ||
testRegex: '.(.+)\\.test\\.(js|ts)$', | ||
|
||
// This option allows the use of a custom results processor | ||
// testResultsProcessor: undefined, | ||
|
||
// This option allows use of a custom test runner | ||
// testRunner: "jest-circus/runner", | ||
|
||
// This option sets the URL for the jsdom environment. It is reflected in properties such as location.href | ||
testURL: 'http://localhost:9898/', | ||
|
||
// Setting this value to "fake" allows the use of fake timers for functions such as "setTimeout" | ||
// timers: "real", | ||
|
||
// A map from regular expressions to paths to transformers | ||
transform: { | ||
'^.+\\.js$': 'babel-jest' | ||
}, | ||
|
||
// An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation | ||
transformIgnorePatterns: [ | ||
'/node_modules/', | ||
'\\.pnp\\.[^\\/]+$' | ||
], | ||
|
||
// An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them | ||
// unmockedModulePathPatterns: undefined, | ||
|
||
// Indicates whether each individual test should be reported during the run | ||
verbose: true, | ||
|
||
// An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode | ||
// watchPathIgnorePatterns: [], | ||
|
||
// Whether to use watchman for file crawling | ||
// watchman: true, | ||
testTimeout: 50000 | ||
}; |