From 232d480ca0e9eecb1ea6b6a21b32a3723db3b5b4 Mon Sep 17 00:00:00 2001 From: yizhi <946185759@qq.com> Date: Tue, 11 Mar 2025 11:34:05 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dtypescript=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E6=97=B6=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .npmignore | 12 ++++++ package.json | 8 ++-- src/deploy/facealign/common.ts | 62 +++++++++++++++------------- src/deploy/facealign/landmark1000.ts | 23 +++++++---- src/deploy/facealign/pfld.ts | 22 ++++++---- src/test.ts | 2 +- 6 files changed, 79 insertions(+), 50 deletions(-) create mode 100644 .npmignore diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..378158b --- /dev/null +++ b/.npmignore @@ -0,0 +1,12 @@ +/build +/cache +/cxx +/models +/node_modules +/src +/testdata +/thirdpart +/tool +/.clang-format +/CMakeLists.txt +/tsconfig.json \ No newline at end of file diff --git a/package.json b/package.json index 443aeb7..b7cce2c 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,10 @@ { "name": "@yizhi/ai", - "version": "1.0.1", - "main": "index.js", + "version": "1.0.3", + "main": "dist/index.js", + "types": "typing/index.d.ts", "scripts": { + "build": "tsc", "watch": "tsc -w --inlineSourceMap" }, "keywords": [], @@ -16,4 +18,4 @@ "node-addon-api": "^8.3.1", "unbzip2-stream": "^1.4.3" } -} +} \ No newline at end of file diff --git a/src/deploy/facealign/common.ts b/src/deploy/facealign/common.ts index c0b2631..53bf4ae 100644 --- a/src/deploy/facealign/common.ts +++ b/src/deploy/facealign/common.ts @@ -5,10 +5,41 @@ export interface FacePoint { type PointType = "leftEye" | "rightEye" | "leftEyebrow" | "rightEyebrow" | "nose" | "mouth" | "contour" +export function indexFromTo(from: number, to: number) { + const indexes: number[] = []; + for (let i = from; i <= to; i++) { + indexes.push(i); + } + return indexes; +} + +interface PointGroup { + /** 用于判断方向的两个点的索引(建议选取眼球中间的点) */ + directionPointIndex: [number, number]; + /** 左眼点的索引 */ + leftEyePointIndex: number[]; + /** 右眼点的索引 */ + rightEyePointIndex: number[]; + /** 左眉点的索引 */ + leftEyebrowPointIndex: number[]; + /** 右眉点的索引 */ + rightEyebrowPointIndex: number[]; + /** 嘴巴点的索引 */ + mouthPointIndex: number[]; + /** 鼻子的索引 */ + nosePointIndex: number[]; + /** 轮廓点的索引 */ + contourPointIndex: number[]; +} + export abstract class FaceAlignmentResult { #points: FacePoint[] + #group: PointGroup - public constructor(points: FacePoint[]) { this.#points = points; } + public constructor(points: FacePoint[], group: PointGroup) { + this.#points = points; + this.#group = group; + } /** 关键点 */ public get points() { return this.#points; } @@ -18,7 +49,7 @@ export abstract class FaceAlignmentResult { if (typeof type == "string") type = [type]; const result: FacePoint[] = []; for (const t of type) { - for (const idx of this[`${t}PointIndex` as const]()) { + for (const idx of this.#group[`${t}PointIndex` as const]) { result.push(this.points[idx]); } } @@ -27,32 +58,7 @@ export abstract class FaceAlignmentResult { /** 方向 */ public get direction() { - const [{ x: x1, y: y1 }, { x: x2, y: y2 }] = this.directionPointIndex().map(idx => this.points[idx]); + const [{ x: x1, y: y1 }, { x: x2, y: y2 }] = this.#group.directionPointIndex.map(idx => this.points[idx]); return Math.atan2(y1 - y2, x2 - x1) } - - /** 用于判断方向的两个点的索引(建议选取眼球中间的点) */ - protected abstract directionPointIndex(): [number, number]; - /** 左眼点的索引 */ - protected abstract leftEyePointIndex(): number[]; - /** 右眼点的索引 */ - protected abstract rightEyePointIndex(): number[]; - /** 左眉点的索引 */ - protected abstract leftEyebrowPointIndex(): number[]; - /** 右眉点的索引 */ - protected abstract rightEyebrowPointIndex(): number[]; - /** 嘴巴点的索引 */ - protected abstract mouthPointIndex(): number[]; - /** 鼻子的索引 */ - protected abstract nosePointIndex(): number[]; - /** 轮廓点的索引 */ - protected abstract contourPointIndex(): number[]; - - protected indexFromTo(from: number, to: number) { - const indexes: number[] = []; - for (let i = from; i <= to; i++) { - indexes.push(i); - } - return indexes; - } } diff --git a/src/deploy/facealign/landmark1000.ts b/src/deploy/facealign/landmark1000.ts index 4b093ee..9226653 100644 --- a/src/deploy/facealign/landmark1000.ts +++ b/src/deploy/facealign/landmark1000.ts @@ -2,19 +2,24 @@ import { writeFileSync } from "fs"; import { cv } from "../../cv"; import { ImageCropOption, ImageSource, Model } from "../common/model"; import { convertImage } from "../common/processors"; -import { FaceAlignmentResult, FacePoint } from "./common"; +import { FaceAlignmentResult, FacePoint, indexFromTo } from "./common"; interface FaceLandmark1000PredictOption extends ImageCropOption { } class FaceLandmark1000Result extends FaceAlignmentResult { - protected directionPointIndex(): [number, number] { return [401, 529]; } - protected leftEyePointIndex(): number[] { return this.indexFromTo(401, 528); } - protected rightEyePointIndex(): number[] { return this.indexFromTo(529, 656); } - protected leftEyebrowPointIndex(): number[] { return this.indexFromTo(273, 336); } - protected rightEyebrowPointIndex(): number[] { return this.indexFromTo(337, 400); } - protected mouthPointIndex(): number[] { return this.indexFromTo(845, 972); } - protected nosePointIndex(): number[] { return this.indexFromTo(657, 844); } - protected contourPointIndex(): number[] { return this.indexFromTo(0, 272); } + public constructor(points: FacePoint[]) { + super(points, { + directionPointIndex: [401, 529], + leftEyePointIndex: indexFromTo(401, 528), + rightEyePointIndex: indexFromTo(529, 656), + leftEyebrowPointIndex: indexFromTo(273, 336), + rightEyebrowPointIndex: indexFromTo(337, 400), + mouthPointIndex: indexFromTo(845, 972), + nosePointIndex: indexFromTo(657, 844), + contourPointIndex: indexFromTo(0, 272), + }); + } + } diff --git a/src/deploy/facealign/pfld.ts b/src/deploy/facealign/pfld.ts index fdb34c0..98f4641 100644 --- a/src/deploy/facealign/pfld.ts +++ b/src/deploy/facealign/pfld.ts @@ -7,14 +7,18 @@ import { FaceAlignmentResult, FacePoint } from "./common"; export interface PFLDPredictOption extends ImageCropOption { } class PFLDResult extends FaceAlignmentResult { - protected directionPointIndex(): [number, number] { return [36, 92]; } - protected leftEyePointIndex(): number[] { return [33, 34, 35, 36, 37, 38, 39, 40, 41, 42]; } - protected rightEyePointIndex(): number[] { return [87, 88, 89, 90, 91, 92, 93, 94, 95, 96]; } - protected leftEyebrowPointIndex(): number[] { return [43, 44, 45, 46, 47, 48, 49, 50, 51]; } - protected rightEyebrowPointIndex(): number[] { return [97, 98, 99, 100, 101, 102, 103, 104, 105]; } - protected mouthPointIndex(): number[] { return [52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71]; } - protected nosePointIndex(): number[] { return [72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86]; } - protected contourPointIndex(): number[] { return [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]; } + public constructor(points: FacePoint[]) { + super(points, { + directionPointIndex: [36, 92], + leftEyePointIndex: [33, 34, 35, 36, 37, 38, 39, 40, 41, 42], + rightEyePointIndex: [87, 88, 89, 90, 91, 92, 93, 94, 95, 96], + leftEyebrowPointIndex: [43, 44, 45, 46, 47, 48, 49, 50, 51], + rightEyebrowPointIndex: [97, 98, 99, 100, 101, 102, 103, 104, 105], + mouthPointIndex: [52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71], + nosePointIndex: [72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86], + contourPointIndex: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32], + }); + } } const MODEL_URL_CONFIG = { @@ -59,7 +63,7 @@ export class PFLD extends Model { const y = pointsBuffer[i + 1] * image.height * ratioHeight; points.push({ x, y }); } - +console.log(points) return new PFLDResult(points); } diff --git a/src/test.ts b/src/test.ts index 4f76338..9d3f3e9 100644 --- a/src/test.ts +++ b/src/test.ts @@ -113,7 +113,7 @@ async function testFaceID() { } async function testFaceAlign() { - const fd = await deploy.facedet.Yolov5Face.load("YOLOV5S_MNN"); + const fd = await deploy.facedet.Yolov5Face.load("YOLOV5S_ONNX"); const fa = await deploy.facealign.PFLD.load("PFLD_106_LITE_MNN"); // const fa = await deploy.facealign.FaceLandmark1000.load("FACELANDMARK1000_ONNX"); let image = await cv.Mat.load("https://i0.hdslb.com/bfs/archive/64e47ec9fdac9e24bc2b49b5aaad5560da1bfe3e.jpg");