代码优化

This commit is contained in:
2025-03-10 18:12:32 +08:00
parent a966b82963
commit 524dcaecbd
10 changed files with 71 additions and 46 deletions

View File

@ -1,14 +1,47 @@
## AI工具箱 #AI工具箱
## 安装
### 代码编译
注意在Windows下编译时需要打开Visual Studio命令行
``` ```
# 编译第三方库 npm install @yizhi/ai
node thirdpart/install.js --with-onnx --with-mnn --with-opencv ```
# 编译主库
## 使用
```typescript
import ai from "@yizhi/ai";
// 配置相应的node插件插件需自行编译
ai.config("CV_ADDON_FILE", "/path/to/cv.node");
ai.config("MNN_ADDON_FILE", "/path/to/mnn.node");
ai.config("ORT_ADDON_FILE", "/path/to/onnxruntime.node");
//直接推理
const facedet = await ai.deploy.facedet.Yolov5Face.load("YOLOV5S_ONNX");
const boxes = await facedet.predict("/path/to/image");
//使用自己的模型
const session = new ai.backend.ort.Session(modelBuffer);
const outputs = session.run(inputs);
```
## 插件编译
1. 依赖
1. python3
1. cmake
1. ninja
1. c++编译器(gcc,clang,Visual Studio ...)
1. 编译第三方库
```
node thirdpart/install.js --with-mnn --with-onnx --with-opencv
```
1. 编译插件
```
cmake -B build -G Ninja . -DCMAKE_BUILD_TYPE=Release cmake -B build -G Ninja . -DCMAKE_BUILD_TYPE=Release
cmake --build build --config Release cmake --build build --config Release
``` ```
注意注意在Windows下编译时需要打开Visual Studio命令行

View File

@ -1,6 +1,6 @@
{ {
"name": "@yizhi/ai", "name": "@yizhi/ai",
"version": "1.0.0", "version": "1.0.1",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"watch": "tsc -w --inlineSourceMap" "watch": "tsc -w --inlineSourceMap"

View File

@ -1,3 +1,4 @@
import { getConfig } from "../../config";
import { CommonSession, dataTypeFrom, isTypedArray, SessionNodeData, SessionNodeInfo, SessionRunInputOption, SessionRunOutput } from "../common"; import { CommonSession, dataTypeFrom, isTypedArray, SessionNodeData, SessionNodeInfo, SessionRunInputOption, SessionRunOutput } from "../common";
export class MNNSession extends CommonSession { export class MNNSession extends CommonSession {
@ -7,7 +8,7 @@ export class MNNSession extends CommonSession {
public constructor(modelData: Uint8Array) { public constructor(modelData: Uint8Array) {
super(); super();
const addon = require("../../../build/mnn.node") const addon = require(getConfig("MNN_ADDON_FILE"));
this.#session = new addon.MNNSession(modelData); this.#session = new addon.MNNSession(modelData);
} }

View File

@ -1,3 +1,4 @@
import { getConfig } from "../../config";
import { CommonSession, dataTypeFrom, isTypedArray, SessionNodeData, SessionNodeInfo, SessionRunInputOption, SessionRunOutput } from "../common"; import { CommonSession, dataTypeFrom, isTypedArray, SessionNodeData, SessionNodeInfo, SessionRunInputOption, SessionRunOutput } from "../common";
export class OrtSession extends CommonSession { export class OrtSession extends CommonSession {
@ -7,7 +8,7 @@ export class OrtSession extends CommonSession {
public constructor(modelData: Uint8Array) { public constructor(modelData: Uint8Array) {
super(); super();
const addon = require("../../../build/ort.node") const addon = require(getConfig("ORT_ADDON_FILE"));
this.#session = new addon.OrtSession(modelData); this.#session = new addon.OrtSession(modelData);
} }

13
src/config.ts Normal file
View File

@ -0,0 +1,13 @@
import path from "path";
const defaultAddonDir = path.join(__dirname, "../build")
const aiConfig = {
"CV_ADDON_FILE": path.join(defaultAddonDir, "cv.node"),
"MNN_ADDON_FILE": path.join(defaultAddonDir, "mnn.node"),
"ORT_ADDON_FILE": path.join(defaultAddonDir, "ort.node"),
};
export function setConfig<K extends keyof typeof aiConfig>(key: K, value: typeof aiConfig[K]) { aiConfig[key] = value; }
export function getConfig<K extends keyof typeof aiConfig>(key: K): typeof aiConfig[K] { return aiConfig[key]; }

View File

@ -1,3 +1,4 @@
import { getConfig } from "../config";
export enum ImreadModes { export enum ImreadModes {
IMREAD_UNCHANGED = -1, IMREAD_UNCHANGED = -1,
@ -32,7 +33,7 @@ export class Mat {
} }
public constructor(imageData: Uint8Array, option?: MatConstructorOption) { public constructor(imageData: Uint8Array, option?: MatConstructorOption) {
const addon = require("../../build/cv.node"); const addon = require(getConfig("CV_ADDON_FILE"));
if ((imageData as any) instanceof addon.Mat) this.#mat = imageData; if ((imageData as any) instanceof addon.Mat) this.#mat = imageData;
else this.#mat = new addon.Mat(imageData, option); else this.#mat = new addon.Mat(imageData, option);
} }

View File

@ -0,0 +1,4 @@
import * as ai from "./main";
export default ai;
export { ai };

View File

@ -0,0 +1,4 @@
export { deploy } from "./deploy";
export { cv } from "./cv";
export { backend } from "./backend";
export { setConfig as config } from "./config";

View File

@ -4,6 +4,7 @@ import { cv } from "./cv";
import { faceidTestData } from "./test_data/faceid"; import { faceidTestData } from "./test_data/faceid";
import path from "path"; import path from "path";
import crypto from "crypto"; import crypto from "crypto";
import ai from ".";
async function cacheImage(group: string, url: string) { async function cacheImage(group: string, url: string) {
const _url = new URL(url); const _url = new URL(url);

View File

@ -1,33 +0,0 @@
export namespace utils {
export function rgba2rgb<T extends Uint8Array | Float32Array>(data: T): T {
const pixelCount = data.length / 4;
const result = new (data.constructor as any)(pixelCount * 3) as T;
for (let i = 0; i < pixelCount; i++) {
result[i * 3 + 0] = data[i * 4 + 0];
result[i * 3 + 1] = data[i * 4 + 1];
result[i * 3 + 2] = data[i * 4 + 2];
}
return result;
}
export function rgb2bgr<T extends Uint8Array | Float32Array>(data: T): T {
const pixelCount = data.length / 3;
const result = new (data.constructor as any)(pixelCount * 3) as T;
for (let i = 0; i < pixelCount; i++) {
result[i * 3 + 0] = data[i * 3 + 2];
result[i * 3 + 1] = data[i * 3 + 1];
result[i * 3 + 2] = data[i * 3 + 0];
}
return result;
}
export function normalize(data: Uint8Array | Float32Array, mean: number[], std: number[]): Float32Array {
const result = new Float32Array(data.length);
for (let i = 0; i < data.length; i++) {
result[i] = (data[i] - mean[i % mean.length]) / std[i % std.length];
}
return result;
}
}