移除cv,请使用@yizhi/cv包
This commit is contained in:
@ -85,24 +85,6 @@ if(EXISTS ${MNN_CMAKE_FILE})
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# OpenCV
|
|
||||||
set(OpenCV_CMAKE_FILE ${CMAKE_SOURCE_DIR}/thirdpart/OpenCV/${CMAKE_BUILD_TYPE}/config.cmake)
|
|
||||||
if(EXISTS ${OpenCV_CMAKE_FILE})
|
|
||||||
include(${OpenCV_CMAKE_FILE})
|
|
||||||
message(STATUS "OpenCV_LIB_DIR: ${OpenCV_LIB_DIR}")
|
|
||||||
message(STATUS "OpenCV_INCLUDE_DIR: ${OpenCV_INCLUDE_DIR}")
|
|
||||||
message(STATUS "OpenCV_LIBS: ${OpenCV_LIBS}")
|
|
||||||
include_directories(${OpenCV_INCLUDE_DIRS})
|
|
||||||
link_directories(${OpenCV_LIB_DIR})
|
|
||||||
|
|
||||||
if(NODE_ADDON_FOUND)
|
|
||||||
add_node_targert(cv cxx/cv/node.cc)
|
|
||||||
target_link_libraries(cv ${OpenCV_LIBS})
|
|
||||||
target_compile_definitions(cv PUBLIC USE_OPENCV)
|
|
||||||
list(APPEND NODE_COMMON_SOURCES cxx/cv/node.cc)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# OnnxRuntime
|
# OnnxRuntime
|
||||||
set(ONNXRuntime_CMAKE_FILE ${CMAKE_SOURCE_DIR}/thirdpart/ONNXRuntime/config.cmake)
|
set(ONNXRuntime_CMAKE_FILE ${CMAKE_SOURCE_DIR}/thirdpart/ONNXRuntime/config.cmake)
|
||||||
if(EXISTS ${ONNXRuntime_CMAKE_FILE})
|
if(EXISTS ${ONNXRuntime_CMAKE_FILE})
|
||||||
@ -137,11 +119,6 @@ if(NODE_ADDON_FOUND)
|
|||||||
target_link_libraries(addon ${ONNXRuntime_LIBS})
|
target_link_libraries(addon ${ONNXRuntime_LIBS})
|
||||||
target_compile_definitions(addon PUBLIC USE_ONNXRUNTIME)
|
target_compile_definitions(addon PUBLIC USE_ONNXRUNTIME)
|
||||||
endif()
|
endif()
|
||||||
# OpenCV
|
|
||||||
if(EXISTS ${OpenCV_CMAKE_FILE})
|
|
||||||
target_link_libraries(addon ${OpenCV_LIBS})
|
|
||||||
target_compile_definitions(addon PUBLIC USE_OPENCV)
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(MSVC AND NODE_ADDON_FOUND)
|
if(MSVC AND NODE_ADDON_FOUND)
|
||||||
|
@ -29,14 +29,13 @@ const outputs = session.run(inputs);
|
|||||||
## 插件编译
|
## 插件编译
|
||||||
|
|
||||||
1. 依赖
|
1. 依赖
|
||||||
1. python3
|
|
||||||
1. cmake
|
1. cmake
|
||||||
1. ninja
|
1. ninja
|
||||||
1. c++编译器(gcc,clang,Visual Studio ...)
|
1. c++编译器(gcc,clang,Visual Studio ...)
|
||||||
|
|
||||||
1. 编译第三方库
|
1. 编译第三方库
|
||||||
```
|
```
|
||||||
node thirdpart/install.js --with-mnn --with-onnx --with-opencv
|
node thirdpart/install.js --with-mnn --with-onnx
|
||||||
```
|
```
|
||||||
1. 编译插件
|
1. 编译插件
|
||||||
```
|
```
|
||||||
|
145
cxx/cv/node.cc
145
cxx/cv/node.cc
@ -1,145 +0,0 @@
|
|||||||
#include <iostream>
|
|
||||||
#include <functional>
|
|
||||||
#include <opencv2/opencv.hpp>
|
|
||||||
#include "node.h"
|
|
||||||
|
|
||||||
using namespace Napi;
|
|
||||||
|
|
||||||
#define MAT_INSTANCE_METHOD(method) InstanceMethod<&CVMat::method>(#method, static_cast<napi_property_attributes>(napi_writable | napi_configurable))
|
|
||||||
|
|
||||||
static FunctionReference *constructor = nullptr;
|
|
||||||
|
|
||||||
class CVMat : public ObjectWrap<CVMat> {
|
|
||||||
public:
|
|
||||||
static Napi::Object Init(Napi::Env env, Napi::Object exports)
|
|
||||||
{
|
|
||||||
Function func = DefineClass(env, "Mat", {
|
|
||||||
MAT_INSTANCE_METHOD(IsEmpty),
|
|
||||||
MAT_INSTANCE_METHOD(GetCols),
|
|
||||||
MAT_INSTANCE_METHOD(GetRows),
|
|
||||||
MAT_INSTANCE_METHOD(GetChannels),
|
|
||||||
MAT_INSTANCE_METHOD(Resize),
|
|
||||||
MAT_INSTANCE_METHOD(Crop),
|
|
||||||
MAT_INSTANCE_METHOD(Rotate),
|
|
||||||
MAT_INSTANCE_METHOD(Clone),
|
|
||||||
|
|
||||||
MAT_INSTANCE_METHOD(DrawCircle),
|
|
||||||
|
|
||||||
MAT_INSTANCE_METHOD(Data),
|
|
||||||
MAT_INSTANCE_METHOD(Encode),
|
|
||||||
});
|
|
||||||
constructor = new FunctionReference();
|
|
||||||
*constructor = Napi::Persistent(func);
|
|
||||||
exports.Set("Mat", func);
|
|
||||||
env.SetInstanceData<FunctionReference>(constructor);
|
|
||||||
return exports;
|
|
||||||
}
|
|
||||||
|
|
||||||
CVMat(const CallbackInfo &info)
|
|
||||||
: ObjectWrap<CVMat>(info)
|
|
||||||
{
|
|
||||||
int mode = cv::IMREAD_COLOR_BGR;
|
|
||||||
if (info.Length() > 1 && info[1].IsObject()) {
|
|
||||||
Object options = info[1].As<Object>();
|
|
||||||
if (options.Has("mode") && options.Get("mode").IsNumber()) mode = options.Get("mode").As<Number>().Int32Value();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info[0].IsString()) im_ = cv::imread(info[0].As<String>().Utf8Value(), mode);
|
|
||||||
else if (info[0].IsTypedArray()) {
|
|
||||||
auto buffer = info[0].As<TypedArray>().ArrayBuffer();
|
|
||||||
uint8_t *bufferPtr = static_cast<uint8_t *>(buffer.Data());
|
|
||||||
std::vector<uint8_t> data(bufferPtr, bufferPtr + buffer.ByteLength());
|
|
||||||
im_ = cv::imdecode(data, mode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~CVMat() { im_.release(); }
|
|
||||||
|
|
||||||
Napi::Value IsEmpty(const Napi::CallbackInfo &info) { return Boolean::New(info.Env(), im_.empty()); }
|
|
||||||
Napi::Value GetCols(const Napi::CallbackInfo &info) { return Number::New(info.Env(), im_.cols); }
|
|
||||||
Napi::Value GetRows(const Napi::CallbackInfo &info) { return Number::New(info.Env(), im_.rows); }
|
|
||||||
Napi::Value GetChannels(const Napi::CallbackInfo &info) { return Number::New(info.Env(), im_.channels()); }
|
|
||||||
Napi::Value Resize(const Napi::CallbackInfo &info)
|
|
||||||
{
|
|
||||||
return CreateMat(info.Env(), [this, &info](auto &mat) { cv::resize(im_, mat.im_, cv::Size(info[0].As<Number>().Int32Value(), info[1].As<Number>().Int32Value())); });
|
|
||||||
}
|
|
||||||
Napi::Value Crop(const Napi::CallbackInfo &info)
|
|
||||||
{
|
|
||||||
return CreateMat(info.Env(), [this, &info](auto &mat) {
|
|
||||||
mat.im_ = im_(cv::Rect(
|
|
||||||
info[0].As<Number>().Int32Value(), info[1].As<Number>().Int32Value(),
|
|
||||||
info[2].As<Number>().Int32Value(), info[3].As<Number>().Int32Value()));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Napi::Value Rotate(const Napi::CallbackInfo &info)
|
|
||||||
{
|
|
||||||
return CreateMat(info.Env(), [this, &info](auto &mat) {
|
|
||||||
auto x = info[0].As<Number>().DoubleValue();
|
|
||||||
auto y = info[1].As<Number>().DoubleValue();
|
|
||||||
auto angle = info[2].As<Number>().DoubleValue();
|
|
||||||
cv::Mat rotation_matix = cv::getRotationMatrix2D(cv::Point2f(x, y), angle, 1.0);
|
|
||||||
cv::warpAffine(im_, mat.im_, rotation_matix, im_.size());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Napi::Value Clone(const Napi::CallbackInfo &info)
|
|
||||||
{
|
|
||||||
return CreateMat(info.Env(), [this, &info](auto &mat) { mat.im_ = im_.clone(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
Napi::Value DrawCircle(const Napi::CallbackInfo &info)
|
|
||||||
{
|
|
||||||
int x = info[0].As<Number>().Int32Value();
|
|
||||||
int y = info[1].As<Number>().Int32Value();
|
|
||||||
int radius = info[2].As<Number>().Int32Value();
|
|
||||||
int b = info[3].As<Number>().Int32Value();
|
|
||||||
int g = info[4].As<Number>().Int32Value();
|
|
||||||
int r = info[5].As<Number>().Int32Value();
|
|
||||||
int thickness = info[6].As<Number>().Int32Value();
|
|
||||||
int lineType = info[7].As<Number>().Int32Value();
|
|
||||||
int shift = info[8].As<Number>().Int32Value();
|
|
||||||
|
|
||||||
cv::circle(im_, cv::Point(x, y), radius, cv::Scalar(b, g, r), thickness, lineType, shift);
|
|
||||||
return info.Env().Undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
Napi::Value Data(const Napi::CallbackInfo &info) { return ArrayBuffer::New(info.Env(), im_.ptr(), im_.elemSize() * im_.total()); }
|
|
||||||
Napi::Value Encode(const Napi::CallbackInfo &info)
|
|
||||||
{
|
|
||||||
auto options = info[0].As<Object>();
|
|
||||||
auto extname = options.Get("extname").As<String>().Utf8Value();
|
|
||||||
cv::imencode(extname, im_, encoded_);
|
|
||||||
return ArrayBuffer::New(info.Env(), encoded_.data(), encoded_.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
inline Napi::Object EmptyMat(Napi::Env env) { return constructor->New({}).As<Object>(); }
|
|
||||||
inline CVMat &GetMat(Napi::Object obj) { return *ObjectWrap<CVMat>::Unwrap(obj); }
|
|
||||||
inline Napi::Object CreateMat(Napi::Env env, std::function<void(CVMat &mat)> callback)
|
|
||||||
{
|
|
||||||
auto obj = EmptyMat(env);
|
|
||||||
callback(GetMat(obj));
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
cv::Mat im_;
|
|
||||||
std::vector<uint8_t> encoded_;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void InstallOpenCVAPI(Env env, Object exports)
|
|
||||||
{
|
|
||||||
CVMat::Init(env, exports);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(USE_OPENCV) && !defined(BUILD_MAIN_WORD)
|
|
||||||
static Object Init(Env env, Object exports)
|
|
||||||
{
|
|
||||||
InstallOpenCVAPI(env, exports);
|
|
||||||
return exports;
|
|
||||||
}
|
|
||||||
NODE_API_MODULE(addon, Init)
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,8 +0,0 @@
|
|||||||
#ifndef __CV_NODE_H__
|
|
||||||
#define __CV_NODE_H__
|
|
||||||
|
|
||||||
#include "common/node.h"
|
|
||||||
|
|
||||||
void InstallOpenCVAPI(Napi::Env env, Napi::Object exports);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,5 +1,4 @@
|
|||||||
#include "common/node.h"
|
#include "common/node.h"
|
||||||
#include "cv/node.h"
|
|
||||||
#include "mnn/node.h"
|
#include "mnn/node.h"
|
||||||
#include "ort/node.h"
|
#include "ort/node.h"
|
||||||
|
|
||||||
@ -8,11 +7,6 @@ using namespace Napi;
|
|||||||
#if defined(BUILD_MAIN_WORD)
|
#if defined(BUILD_MAIN_WORD)
|
||||||
Object Init(Env env, Object exports)
|
Object Init(Env env, Object exports)
|
||||||
{
|
{
|
||||||
// OpenCV
|
|
||||||
#ifdef USE_OPENCV
|
|
||||||
printf("use opencv\n");
|
|
||||||
InstallOpenCVAPI(env, exports);
|
|
||||||
#endif
|
|
||||||
// OnnxRuntime
|
// OnnxRuntime
|
||||||
#ifdef USE_ONNXRUNTIME
|
#ifdef USE_ONNXRUNTIME
|
||||||
InstallOrtAPI(env, exports);
|
InstallOrtAPI(env, exports);
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "@yizhi/ai",
|
"name": "@yizhi/ai",
|
||||||
"version": "1.0.5",
|
"version": "1.0.6",
|
||||||
|
"releaseVersion": "1.0.6",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"types": "typing/index.d.ts",
|
"types": "typing/index.d.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc",
|
"build": "rm -rf dist typing && tsc",
|
||||||
"watch": "tsc -w --inlineSourceMap"
|
"watch": "tsc -w --inlineSourceMap"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
@ -17,5 +18,8 @@
|
|||||||
"compressing": "^1.10.1",
|
"compressing": "^1.10.1",
|
||||||
"node-addon-api": "^8.3.1",
|
"node-addon-api": "^8.3.1",
|
||||||
"unbzip2-stream": "^1.4.3"
|
"unbzip2-stream": "^1.4.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@yizhi/cv": "^1.0.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,7 +3,6 @@ import path from "path";
|
|||||||
const defaultAddonDir = path.join(__dirname, "../build")
|
const defaultAddonDir = path.join(__dirname, "../build")
|
||||||
|
|
||||||
const aiConfig = {
|
const aiConfig = {
|
||||||
"CV_ADDON_FILE": path.join(defaultAddonDir, "cv.node"),
|
|
||||||
"MNN_ADDON_FILE": path.join(defaultAddonDir, "mnn.node"),
|
"MNN_ADDON_FILE": path.join(defaultAddonDir, "mnn.node"),
|
||||||
"ORT_ADDON_FILE": path.join(defaultAddonDir, "ort.node"),
|
"ORT_ADDON_FILE": path.join(defaultAddonDir, "ort.node"),
|
||||||
};
|
};
|
||||||
|
@ -1 +0,0 @@
|
|||||||
export * as cv from "./main";
|
|
@ -1 +0,0 @@
|
|||||||
export { Mat, ImreadModes } from "./mat";
|
|
@ -1,80 +0,0 @@
|
|||||||
import { getConfig } from "../config";
|
|
||||||
|
|
||||||
export enum ImreadModes {
|
|
||||||
IMREAD_UNCHANGED = -1,
|
|
||||||
IMREAD_GRAYSCALE = 0,
|
|
||||||
IMREAD_COLOR_BGR = 1,
|
|
||||||
IMREAD_COLOR = 1,
|
|
||||||
IMREAD_ANYDEPTH = 2,
|
|
||||||
IMREAD_ANYCOLOR = 4,
|
|
||||||
IMREAD_LOAD_GDAL = 8,
|
|
||||||
IMREAD_REDUCED_GRAYSCALE_2 = 16,
|
|
||||||
IMREAD_REDUCED_COLOR_2 = 17,
|
|
||||||
IMREAD_REDUCED_GRAYSCALE_4 = 32,
|
|
||||||
IMREAD_REDUCED_COLOR_4 = 33,
|
|
||||||
IMREAD_REDUCED_GRAYSCALE_8 = 64,
|
|
||||||
IMREAD_REDUCED_COLOR_8 = 65,
|
|
||||||
IMREAD_IGNORE_ORIENTATION = 128,
|
|
||||||
IMREAD_COLOR_RGB = 256,
|
|
||||||
};
|
|
||||||
|
|
||||||
interface MatConstructorOption {
|
|
||||||
mode?: ImreadModes;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Mat {
|
|
||||||
#mat: any
|
|
||||||
|
|
||||||
public static async load(image: string, option?: MatConstructorOption) {
|
|
||||||
let buffer: Uint8Array
|
|
||||||
if (/^https?:\/\//.test(image)) buffer = await fetch(image).then(res => res.arrayBuffer()).then(res => new Uint8Array(res));
|
|
||||||
else buffer = await import("fs").then(fs => fs.promises.readFile(image));
|
|
||||||
return new Mat(buffer, option);
|
|
||||||
}
|
|
||||||
|
|
||||||
public constructor(imageData: Uint8Array, option?: MatConstructorOption) {
|
|
||||||
const addon = require(getConfig("CV_ADDON_FILE"));
|
|
||||||
if ((imageData as any) instanceof addon.Mat) this.#mat = imageData;
|
|
||||||
else this.#mat = new addon.Mat(imageData, option);
|
|
||||||
}
|
|
||||||
|
|
||||||
public get empty(): boolean { return this.#mat.IsEmpty() }
|
|
||||||
|
|
||||||
public get cols(): number { return this.#mat.GetCols(); }
|
|
||||||
|
|
||||||
public get rows(): number { return this.#mat.GetRows(); }
|
|
||||||
|
|
||||||
public get width() { return this.cols; }
|
|
||||||
|
|
||||||
public get height() { return this.rows; }
|
|
||||||
|
|
||||||
public get channels() { return this.#mat.GetChannels(); }
|
|
||||||
|
|
||||||
public resize(width: number, height: number) { return new Mat(this.#mat.Resize.bind(this.#mat)(width, height)); }
|
|
||||||
|
|
||||||
public crop(sx: number, sy: number, sw: number, sh: number) { return new Mat(this.#mat.Crop(sx, sy, sw, sh)); }
|
|
||||||
|
|
||||||
public rotate(sx: number, sy: number, angleDeg: number) { return new Mat(this.#mat.Rotate(sx, sy, angleDeg)); }
|
|
||||||
|
|
||||||
public get data() { return new Uint8Array(this.#mat.Data()); }
|
|
||||||
|
|
||||||
public encode(extname: string) { return new Uint8Array(this.#mat.Encode({ extname })); }
|
|
||||||
|
|
||||||
public clone() { return new Mat(this.#mat.Clone()); }
|
|
||||||
|
|
||||||
public circle(x: number, y: number, radius: number, options?: {
|
|
||||||
color?: { r: number, g: number, b: number },
|
|
||||||
thickness?: number
|
|
||||||
lineType?: number
|
|
||||||
}) {
|
|
||||||
this.#mat.DrawCircle(
|
|
||||||
x, y, radius,
|
|
||||||
options?.color?.b ?? 0,
|
|
||||||
options?.color?.g ?? 0,
|
|
||||||
options?.color?.r ?? 0,
|
|
||||||
options?.thickness ?? 1,
|
|
||||||
options?.lineType ?? 8,
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +1,5 @@
|
|||||||
|
import { cv } from "@yizhi/cv";
|
||||||
import { backend } from "../../backend";
|
import { backend } from "../../backend";
|
||||||
import { cv } from "../../cv";
|
|
||||||
|
|
||||||
export type ModelConstructor<T> = new (session: backend.CommonSession) => T;
|
export type ModelConstructor<T> = new (session: backend.CommonSession) => T;
|
||||||
|
|
||||||
@ -7,7 +7,7 @@ export type ImageSource = cv.Mat | Uint8Array | string;
|
|||||||
|
|
||||||
export interface ImageCropOption {
|
export interface ImageCropOption {
|
||||||
/** 图片裁剪区域 */
|
/** 图片裁剪区域 */
|
||||||
crop?: { sx: number, sy: number, sw: number, sh: number }
|
crop?: { x: number, y: number, width: number, height: number }
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ModelType = "onnx" | "mnn"
|
export type ModelType = "onnx" | "mnn"
|
||||||
@ -34,7 +34,7 @@ export abstract class Model {
|
|||||||
if (/^https?:\/\//.test(image)) image = await fetch(image).then(res => res.arrayBuffer()).then(buffer => new Uint8Array(buffer));
|
if (/^https?:\/\//.test(image)) image = await fetch(image).then(res => res.arrayBuffer()).then(buffer => new Uint8Array(buffer));
|
||||||
else image = await import("fs").then(fs => fs.promises.readFile(image as string));
|
else image = await import("fs").then(fs => fs.promises.readFile(image as string));
|
||||||
}
|
}
|
||||||
if (image instanceof Uint8Array) image = new cv.Mat(image, { mode: cv.ImreadModes.IMREAD_COLOR_BGR })
|
if (image instanceof Uint8Array) image = cv.imdecode(image, cv.IMREAD_COLOR_BGR);
|
||||||
if (image instanceof cv.Mat) return await resolver(image);
|
if (image instanceof cv.Mat) return await resolver(image);
|
||||||
else throw new Error("Invalid image");
|
else throw new Error("Invalid image");
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { writeFileSync } from "fs";
|
import cv from "@yizhi/cv";
|
||||||
import { cv } from "../../cv";
|
|
||||||
import { ImageCropOption, ImageSource, Model } from "../common/model";
|
import { ImageCropOption, ImageSource, Model } from "../common/model";
|
||||||
import { convertImage } from "../common/processors";
|
import { convertImage } from "../common/processors";
|
||||||
import { FaceAlignmentResult, FacePoint, indexFromTo } from "./common";
|
import { FaceAlignmentResult, FacePoint, indexFromTo } from "./common";
|
||||||
@ -38,10 +37,10 @@ export class FaceLandmark1000 extends Model {
|
|||||||
|
|
||||||
public async doPredict(image: cv.Mat, option?: FaceLandmark1000PredictOption) {
|
public async doPredict(image: cv.Mat, option?: FaceLandmark1000PredictOption) {
|
||||||
const input = this.input;
|
const input = this.input;
|
||||||
if (option?.crop) image = image.crop(option.crop.sx, option.crop.sy, option.crop.sw, option.crop.sh);
|
if (option?.crop) image = cv.crop(image, option?.crop);
|
||||||
const ratioWidth = image.width / input.shape[3];
|
const ratioWidth = image.cols / input.shape[3];
|
||||||
const ratioHeight = image.height / input.shape[2];
|
const ratioHeight = image.rows / input.shape[2];
|
||||||
image = image.resize(input.shape[3], input.shape[2]);
|
image = cv.resize(image, input.shape[3], input.shape[2]);
|
||||||
|
|
||||||
const nchwImageData = convertImage(image.data, { sourceImageFormat: "bgr", targetColorFormat: "gray", targetShapeFormat: "nchw", targetNormalize: { mean: [0], std: [1] } });
|
const nchwImageData = convertImage(image.data, { sourceImageFormat: "bgr", targetColorFormat: "gray", targetShapeFormat: "nchw", targetNormalize: { mean: [0], std: [1] } });
|
||||||
|
|
||||||
@ -55,8 +54,8 @@ export class FaceLandmark1000 extends Model {
|
|||||||
|
|
||||||
const points: FacePoint[] = [];
|
const points: FacePoint[] = [];
|
||||||
for (let i = 0; i < res.length; i += 2) {
|
for (let i = 0; i < res.length; i += 2) {
|
||||||
const x = res[i] * image.width * ratioWidth;
|
const x = res[i] * image.cols * ratioWidth;
|
||||||
const y = res[i + 1] * image.height * ratioHeight;
|
const y = res[i + 1] * image.rows * ratioHeight;
|
||||||
points.push({ x, y });
|
points.push({ x, y });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { writeFileSync } from "fs";
|
import cv from "@yizhi/cv";
|
||||||
import { cv } from "../../cv";
|
|
||||||
import { ImageCropOption, ImageSource, Model } from "../common/model";
|
import { ImageCropOption, ImageSource, Model } from "../common/model";
|
||||||
import { convertImage } from "../common/processors";
|
import { convertImage } from "../common/processors";
|
||||||
import { FaceAlignmentResult, FacePoint } from "./common";
|
import { FaceAlignmentResult, FacePoint } from "./common";
|
||||||
@ -39,10 +38,10 @@ export class PFLD extends Model {
|
|||||||
|
|
||||||
private async doPredict(image: cv.Mat, option?: PFLDPredictOption) {
|
private async doPredict(image: cv.Mat, option?: PFLDPredictOption) {
|
||||||
const input = this.input;
|
const input = this.input;
|
||||||
if (option?.crop) image = image.crop(option.crop.sx, option.crop.sy, option.crop.sw, option.crop.sh);
|
if (option?.crop) image = cv.crop(image, option.crop);
|
||||||
const ratioWidth = image.width / input.shape[3];
|
const ratioWidth = image.cols / input.shape[3];
|
||||||
const ratioHeight = image.height / input.shape[2];
|
const ratioHeight = image.rows / input.shape[2];
|
||||||
image = image.resize(input.shape[3], input.shape[2]);
|
image = cv.resize(image, input.shape[3], input.shape[2]);
|
||||||
|
|
||||||
const nchwImageData = convertImage(image.data, { sourceImageFormat: "bgr", targetColorFormat: "bgr", targetShapeFormat: "nchw", targetNormalize: { mean: [0], std: [255] } })
|
const nchwImageData = convertImage(image.data, { sourceImageFormat: "bgr", targetColorFormat: "bgr", targetShapeFormat: "nchw", targetNormalize: { mean: [0], std: [255] } })
|
||||||
|
|
||||||
@ -59,8 +58,8 @@ export class PFLD extends Model {
|
|||||||
|
|
||||||
const points: FacePoint[] = [];
|
const points: FacePoint[] = [];
|
||||||
for (let i = 0; i < pointsBuffer.length; i += 2) {
|
for (let i = 0; i < pointsBuffer.length; i += 2) {
|
||||||
const x = pointsBuffer[i] * image.width * ratioWidth;
|
const x = pointsBuffer[i] * image.cols * ratioWidth;
|
||||||
const y = pointsBuffer[i + 1] * image.height * ratioHeight;
|
const y = pointsBuffer[i + 1] * image.rows * ratioHeight;
|
||||||
points.push({ x, y });
|
points.push({ x, y });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { cv } from "../../cv";
|
import cv from "@yizhi/cv";
|
||||||
import { ImageCropOption, ImageSource, Model } from "../common/model";
|
import { ImageCropOption, ImageSource, Model } from "../common/model";
|
||||||
import { convertImage } from "../common/processors";
|
import { convertImage } from "../common/processors";
|
||||||
|
|
||||||
@ -25,8 +25,8 @@ export class GenderAge extends Model {
|
|||||||
private async doPredict(image: cv.Mat, option?: GenderAgePredictOption): Promise<GenderAgePredictResult> {
|
private async doPredict(image: cv.Mat, option?: GenderAgePredictOption): Promise<GenderAgePredictResult> {
|
||||||
const input = this.input;
|
const input = this.input;
|
||||||
const output = this.output;
|
const output = this.output;
|
||||||
if (option?.crop) image = image.crop(option.crop.sx, option.crop.sy, option.crop.sw, option.crop.sh);
|
if (option?.crop) image = cv.crop(image, option.crop);
|
||||||
image = image.resize(input.shape[3], input.shape[2]);
|
image = cv.resize(image, input.shape[3], input.shape[2]);
|
||||||
|
|
||||||
const nchwImage = convertImage(image.data, { sourceImageFormat: "bgr", targetColorFormat: "rgb", targetShapeFormat: "nchw", targetNormalize: { mean: [0], std: [1] } });
|
const nchwImage = convertImage(image.data, { sourceImageFormat: "bgr", targetColorFormat: "rgb", targetShapeFormat: "nchw", targetNormalize: { mean: [0], std: [1] } });
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { cv } from "../../cv"
|
import cv from "@yizhi/cv"
|
||||||
import { ImageSource, Model } from "../common/model"
|
import { ImageSource, Model } from "../common/model"
|
||||||
|
|
||||||
interface IFaceBoxConstructorOption {
|
interface IFaceBoxConstructorOption {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { cv } from "../../cv";
|
import cv from "@yizhi/cv";
|
||||||
import { convertImage } from "../common/processors";
|
import { convertImage } from "../common/processors";
|
||||||
import { FaceBox, FaceDetectOption, FaceDetector, nms } from "./common";
|
import { FaceBox, FaceDetectOption, FaceDetector, nms } from "./common";
|
||||||
|
|
||||||
@ -15,9 +15,9 @@ export class Yolov5Face extends FaceDetector {
|
|||||||
|
|
||||||
public async doPredict(image: cv.Mat, option?: FaceDetectOption): Promise<FaceBox[]> {
|
public async doPredict(image: cv.Mat, option?: FaceDetectOption): Promise<FaceBox[]> {
|
||||||
const input = this.input;
|
const input = this.input;
|
||||||
const resizedImage = image.resize(input.shape[2], input.shape[3]);
|
const resizedImage = cv.resize(image, input.shape[2], input.shape[3]);
|
||||||
const ratioWidth = image.width / resizedImage.width;
|
const ratioWidth = image.cols / resizedImage.cols;
|
||||||
const ratioHeight = image.height / resizedImage.height;
|
const ratioHeight = image.rows / resizedImage.rows;
|
||||||
const nchwImageData = convertImage(resizedImage.data, { sourceImageFormat: "bgr", targetColorFormat: "bgr", targetShapeFormat: "nchw", targetNormalize: { mean: [127.5], std: [127.5] } });
|
const nchwImageData = convertImage(resizedImage.data, { sourceImageFormat: "bgr", targetColorFormat: "bgr", targetShapeFormat: "nchw", targetNormalize: { mean: [127.5], std: [127.5] } });
|
||||||
|
|
||||||
const outputData = await this.session.run({ input: nchwImageData }).then(r => r.output);
|
const outputData = await this.session.run({ input: nchwImageData }).then(r => r.output);
|
||||||
@ -37,7 +37,7 @@ export class Yolov5Face extends FaceDetector {
|
|||||||
faces.push(new FaceBox({
|
faces.push(new FaceBox({
|
||||||
x1: x - w / 2, y1: y - h / 2,
|
x1: x - w / 2, y1: y - h / 2,
|
||||||
x2: x + w / 2, y2: y + h / 2,
|
x2: x + w / 2, y2: y + h / 2,
|
||||||
score, imw: image.width, imh: image.height,
|
score, imw: image.cols, imh: image.rows,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
return nms(faces, option?.mnsThreshold ?? 0.3).map(box => box.toInt());
|
return nms(faces, option?.mnsThreshold ?? 0.3).map(box => box.toInt());
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Mat } from "../../cv/mat";
|
import cv from "@yizhi/cv";
|
||||||
import { convertImage } from "../common/processors";
|
import { convertImage } from "../common/processors";
|
||||||
import { FaceRecognition, FaceRecognitionPredictOption } from "./common";
|
import { FaceRecognition, FaceRecognitionPredictOption } from "./common";
|
||||||
|
|
||||||
@ -13,12 +13,12 @@ export class AdaFace extends FaceRecognition {
|
|||||||
return this.cacheModel(MODEL_URL_CONFIG[type ?? "MOBILEFACENET_ADAFACE_ONNX"], { createModel: true }).then(r => r.model);
|
return this.cacheModel(MODEL_URL_CONFIG[type ?? "MOBILEFACENET_ADAFACE_ONNX"], { createModel: true }).then(r => r.model);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async doPredict(image: Mat, option?: FaceRecognitionPredictOption): Promise<number[]> {
|
public async doPredict(image: cv.Mat, option?: FaceRecognitionPredictOption): Promise<number[]> {
|
||||||
const input = this.input;
|
const input = this.input;
|
||||||
const output = this.output;
|
const output = this.output;
|
||||||
|
|
||||||
if (option?.crop) image = image.crop(option.crop.sx, option.crop.sy, option.crop.sw, option.crop.sh);
|
if (option?.crop) image = cv.crop(image, option.crop);
|
||||||
image = image.resize(input.shape[3], input.shape[2]);
|
image = cv.resize(image, input.shape[3], input.shape[2]);
|
||||||
|
|
||||||
const nchwImageData = convertImage(image.data, { sourceImageFormat: "bgr", targetColorFormat: "rgb", targetShapeFormat: "nchw", targetNormalize: { mean: [127.5], std: [127.5] } });
|
const nchwImageData = convertImage(image.data, { sourceImageFormat: "bgr", targetColorFormat: "rgb", targetShapeFormat: "nchw", targetNormalize: { mean: [127.5], std: [127.5] } });
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { cv } from "../../cv";
|
import cv from "@yizhi/cv";
|
||||||
import { ImageCropOption, ImageSource, Model } from "../common/model";
|
import { ImageCropOption, ImageSource, Model } from "../common/model";
|
||||||
|
|
||||||
export interface FaceRecognitionPredictOption extends ImageCropOption { }
|
export interface FaceRecognitionPredictOption extends ImageCropOption { }
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Mat } from "../../cv/mat";
|
import cv from "@yizhi/cv";
|
||||||
import { convertImage } from "../common/processors";
|
import { convertImage } from "../common/processors";
|
||||||
import { FaceRecognition, FaceRecognitionPredictOption } from "./common";
|
import { FaceRecognition, FaceRecognitionPredictOption } from "./common";
|
||||||
|
|
||||||
@ -29,11 +29,11 @@ const MODEL_URL_CONFIG_PARTIAL_FC = {
|
|||||||
|
|
||||||
export class Insightface extends FaceRecognition {
|
export class Insightface extends FaceRecognition {
|
||||||
|
|
||||||
public async doPredict(image: Mat, option?: FaceRecognitionPredictOption): Promise<number[]> {
|
public async doPredict(image: cv.Mat, option?: FaceRecognitionPredictOption): Promise<number[]> {
|
||||||
const input = this.input;
|
const input = this.input;
|
||||||
const output = this.output;
|
const output = this.output;
|
||||||
if (option?.crop) image = image.crop(option.crop.sx, option.crop.sy, option.crop.sw, option.crop.sh);
|
if (option?.crop) image = cv.crop(image, option.crop);
|
||||||
image = image.resize(input.shape[3], input.shape[2]);
|
image = cv.resize(image, input.shape[3], input.shape[2]);
|
||||||
const nchwImageData = convertImage(image.data, { sourceImageFormat: "bgr", targetColorFormat: "bgr", targetShapeFormat: "nchw", targetNormalize: { mean: [127.5], std: [127.5] } });
|
const nchwImageData = convertImage(image.data, { sourceImageFormat: "bgr", targetColorFormat: "bgr", targetShapeFormat: "nchw", targetNormalize: { mean: [127.5], std: [127.5] } });
|
||||||
|
|
||||||
const embedding = await this.session.run({
|
const embedding = await this.session.run({
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
export { deploy } from "./deploy";
|
export { deploy } from "./deploy";
|
||||||
export { cv } from "./cv";
|
|
||||||
export { backend } from "./backend";
|
export { backend } from "./backend";
|
||||||
export { setConfig as config } from "./config";
|
export { setConfig as config } from "./config";
|
||||||
|
49
src/test.ts
49
src/test.ts
@ -1,10 +1,20 @@
|
|||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
|
import cv from "@yizhi/cv";
|
||||||
import { deploy } from "./deploy";
|
import { deploy } from "./deploy";
|
||||||
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 ".";
|
|
||||||
|
cv.config("ADDON_PATH", path.join(__dirname, "../build/cv.node"));
|
||||||
|
|
||||||
|
function loadImage(url: string) {
|
||||||
|
if (/https?:\/\//.test(url)) return fetch(url).then(res => res.arrayBuffer()).then(data => cv.imdecode(new Uint8Array(data)));
|
||||||
|
else return import("fs").then(fs => fs.promises.readFile(url)).then(buffer => cv.imdecode(buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
function rotate(im: cv.Mat, x: number, y: number, angle: number) {
|
||||||
|
return cv.warpAffine(im, cv.getRotationMatrix2D(x, y, angle, 1), im.cols, im.rows);
|
||||||
|
}
|
||||||
|
|
||||||
async function cacheImage(group: string, url: string) {
|
async function cacheImage(group: string, url: string) {
|
||||||
const _url = new URL(url);
|
const _url = new URL(url);
|
||||||
@ -34,11 +44,11 @@ async function testGenderTest() {
|
|||||||
const facedet = await deploy.facedet.Yolov5Face.load("YOLOV5S_MNN");
|
const facedet = await deploy.facedet.Yolov5Face.load("YOLOV5S_MNN");
|
||||||
const detector = await deploy.faceattr.GenderAgeDetector.load("INSIGHT_GENDER_AGE_MNN");
|
const detector = await deploy.faceattr.GenderAgeDetector.load("INSIGHT_GENDER_AGE_MNN");
|
||||||
|
|
||||||
const image = await cv.Mat.load("https://b0.bdstatic.com/ugc/iHBWUj0XqytakT1ogBfBJwc7c305331d2cf904b9fb3d8dd3ed84f5.jpg");
|
const image = await loadImage("https://b0.bdstatic.com/ugc/iHBWUj0XqytakT1ogBfBJwc7c305331d2cf904b9fb3d8dd3ed84f5.jpg");
|
||||||
const boxes = await facedet.predict(image);
|
const boxes = await facedet.predict(image);
|
||||||
if (!boxes.length) return console.error("未检测到人脸");
|
if (!boxes.length) return console.error("未检测到人脸");
|
||||||
for (const [idx, box] of boxes.entries()) {
|
for (const [idx, box] of boxes.entries()) {
|
||||||
const res = await detector.predict(image, { crop: { sx: box.left, sy: box.top, sw: box.width, sh: box.height } });
|
const res = await detector.predict(image, { crop: { x: box.left, y: box.top, width: box.width, height: box.height } });
|
||||||
console.log(`[${idx + 1}]`, res);
|
console.log(`[${idx + 1}]`, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,10 +64,10 @@ async function testFaceID() {
|
|||||||
const { basic, tests } = faceidTestData.stars;
|
const { basic, tests } = faceidTestData.stars;
|
||||||
|
|
||||||
console.log("正在加载图片资源");
|
console.log("正在加载图片资源");
|
||||||
const basicImage = await cv.Mat.load(await cacheImage("faceid", basic.image));
|
const basicImage = await loadImage(await cacheImage("faceid", basic.image));
|
||||||
const testsImages: Record<string, cv.Mat[]> = {};
|
const testsImages: Record<string, cv.Mat[]> = {};
|
||||||
for (const [name, imgs] of Object.entries(tests)) {
|
for (const [name, imgs] of Object.entries(tests)) {
|
||||||
testsImages[name] = await Promise.all(imgs.map(img => cacheImage("faceid", img).then(img => cv.Mat.load(img))));
|
testsImages[name] = await Promise.all(imgs.map(img => cacheImage("faceid", img).then(img => loadImage(img))));
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("正在检测基本数据");
|
console.log("正在检测基本数据");
|
||||||
@ -69,9 +79,9 @@ async function testFaceID() {
|
|||||||
|
|
||||||
async function getEmbd(image: cv.Mat, box: deploy.facedet.FaceBox) {
|
async function getEmbd(image: cv.Mat, box: deploy.facedet.FaceBox) {
|
||||||
box = box.toSquare();
|
box = box.toSquare();
|
||||||
const alignResult = await facealign.predict(image, { crop: { sx: box.left, sy: box.top, sw: box.width, sh: box.height } });
|
const alignResult = await facealign.predict(image, { crop: { x: box.left, y: box.top, width: box.width, height: box.height } });
|
||||||
let faceImage = image.rotate(box.centerX, box.centerY, -alignResult.direction * 180 / Math.PI);
|
let faceImage = rotate(image, box.centerX, box.centerY, -alignResult.direction * 180 / Math.PI);
|
||||||
return faceid.predict(faceImage, { crop: { sx: box.left, sy: box.top, sw: box.width, sh: box.height } });
|
return faceid.predict(faceImage, { crop: { x: box.left, y: box.top, width: box.width, height: box.height } });
|
||||||
}
|
}
|
||||||
|
|
||||||
const basicEmbds: number[][] = [];
|
const basicEmbds: number[][] = [];
|
||||||
@ -116,33 +126,34 @@ async function testFaceAlign() {
|
|||||||
const fd = await deploy.facedet.Yolov5Face.load("YOLOV5S_ONNX");
|
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.PFLD.load("PFLD_106_LITE_MNN");
|
||||||
// const fa = await deploy.facealign.FaceLandmark1000.load("FACELANDMARK1000_ONNX");
|
// const fa = await deploy.facealign.FaceLandmark1000.load("FACELANDMARK1000_ONNX");
|
||||||
let image = await cv.Mat.load("https://i0.hdslb.com/bfs/archive/64e47ec9fdac9e24bc2b49b5aaad5560da1bfe3e.jpg");
|
let image = await loadImage("https://i0.hdslb.com/bfs/archive/64e47ec9fdac9e24bc2b49b5aaad5560da1bfe3e.jpg");
|
||||||
image = image.rotate(image.width / 2, image.height / 2, 0);
|
image = rotate(image, image.cols / 2, image.rows / 2, 0);
|
||||||
|
|
||||||
const face = await fd.predict(image).then(res => {
|
const face = await fd.predict(image).then(res => {
|
||||||
console.log(res);
|
console.log(res);
|
||||||
return res[0].toSquare()
|
return res[0].toSquare()
|
||||||
});
|
});
|
||||||
const points = await fa.predict(image, { crop: { sx: face.left, sy: face.top, sw: face.width, sh: face.height } });
|
const points = await fa.predict(image, { crop: { x: face.left, y: face.top, width: face.width, height: face.height } });
|
||||||
|
|
||||||
points.points.forEach((point, idx) => {
|
points.points.forEach((point, idx) => {
|
||||||
image.circle(face.left + point.x, face.top + point.y, 2);
|
cv.circle(image, face.left + point.x, face.top + point.y, 2, 0, 0, 0);
|
||||||
})
|
})
|
||||||
// const point = points.getPointsOf("rightEye")[1];
|
// const point = points.getPointsOf("rightEye")[1];
|
||||||
// image.circle(face.left + point.x, face.top + point.y, 2);
|
// image.circle(face.left + point.x, face.top + point.y, 2);
|
||||||
fs.writeFileSync("testdata/xx.jpg", image.encode(".jpg"));
|
// fs.writeFileSync("testdata/xx.jpg", image.encode(".jpg"));
|
||||||
|
cv.imwrite("testdata/xx.jpg", image);
|
||||||
|
|
||||||
let faceImage = image.rotate(face.centerX, face.centerY, -points.direction * 180 / Math.PI);
|
let faceImage = rotate(image, face.centerX, face.centerY, -points.direction * 180 / Math.PI);
|
||||||
faceImage = faceImage.crop(face.left, face.top, face.width, face.height);
|
faceImage = cv.crop(faceImage, { x: face.left, y: face.top, width: face.width, height: face.height });
|
||||||
fs.writeFileSync("testdata/face.jpg", faceImage.encode(".jpg"));
|
fs.writeFileSync("testdata/face.jpg", cv.imencode(".jpg", faceImage)!);
|
||||||
|
|
||||||
console.log(points);
|
console.log(points);
|
||||||
console.log(points.direction * 180 / Math.PI);
|
console.log(points.direction * 180 / Math.PI);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function test() {
|
async function test() {
|
||||||
// await testGenderTest();
|
await testGenderTest();
|
||||||
// await testFaceID();
|
await testFaceID();
|
||||||
await testFaceAlign();
|
await testFaceAlign();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,6 @@ function assert(cond, message) {
|
|||||||
|
|
||||||
const buildOptions = {
|
const buildOptions = {
|
||||||
withMNN: findArg("with-mnn", true) ?? false,
|
withMNN: findArg("with-mnn", true) ?? false,
|
||||||
withOpenCV: findArg("with-opencv", true) ?? false,
|
|
||||||
withONNX: findArg("with-onnx", true) ?? false,
|
withONNX: findArg("with-onnx", true) ?? false,
|
||||||
buildType: findArg("build-type", false) ?? "Release",
|
buildType: findArg("build-type", false) ?? "Release",
|
||||||
proxy: findArg("proxy"),
|
proxy: findArg("proxy"),
|
||||||
@ -107,9 +106,6 @@ async function downloadFromURL(name, url, resolver) {
|
|||||||
|
|
||||||
if (!checkFile(saveName)) {
|
if (!checkFile(saveName)) {
|
||||||
console.log(`开始下载${name}, 地址:${url}`);
|
console.log(`开始下载${name}, 地址:${url}`);
|
||||||
await fetch(url).then(res => {
|
|
||||||
console.log(res.status)
|
|
||||||
})
|
|
||||||
const result = spawnSync("curl", ["-o", saveName + ".cache", "-L", url, "-s", "-w", "%{http_code}"], { ...spawnOption, stdio: "pipe" });
|
const result = spawnSync("curl", ["-o", saveName + ".cache", "-L", url, "-s", "-w", "%{http_code}"], { ...spawnOption, stdio: "pipe" });
|
||||||
assert(result.status == 0 && result.stdout.toString() == "200", `下载${name}失败`);
|
assert(result.status == 0 && result.stdout.toString() == "200", `下载${name}失败`);
|
||||||
fs.renameSync(saveName + ".cache", saveName);
|
fs.renameSync(saveName + ".cache", saveName);
|
||||||
@ -163,31 +159,6 @@ async function main() {
|
|||||||
` set(MNN_LIBS \${MNN_LIB_DIR}/libMNN.a)`,
|
` set(MNN_LIBS \${MNN_LIB_DIR}/libMNN.a)`,
|
||||||
`endif()`,
|
`endif()`,
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
//OpenCV
|
|
||||||
if (buildOptions.withOpenCV) cmakeBuildFromSource("OpenCV", "https://github.com/opencv/opencv.git", "4.11.0", null, [
|
|
||||||
"-DBUILD_SHARED_LIBS=OFF",
|
|
||||||
"-DBUILD_opencv_apps=OFF",
|
|
||||||
"-DBUILD_opencv_js=OFF",
|
|
||||||
"-DBUILD_opencv_python2=OFF",
|
|
||||||
"-DBUILD_opencv_python3=OFF",
|
|
||||||
"-DBUILD_ANDROID_PROJECTS=OFF",
|
|
||||||
"-DBUILD_ANDROID_EXAMPLES=OFF",
|
|
||||||
"-DBUILD_TESTS=OFF",
|
|
||||||
"-DBUILD_FAT_JAVA_LIB=OFF",
|
|
||||||
"-DBUILD_ANDROID_SERVICE=OFF",
|
|
||||||
"-DBUILD_JAVA=OFF",
|
|
||||||
"-DBUILD_PERF_TESTS=OFF"
|
|
||||||
], (root) => [
|
|
||||||
`set(OpenCV_STATIC ON)`,
|
|
||||||
os.platform() == "win32" ?
|
|
||||||
`include(${JSON.stringify(P(path.join(root, "OpenCVConfig.cmake")))})` :
|
|
||||||
`include(${JSON.stringify(P(path.join(root, "lib/cmake/opencv4/OpenCVConfig.cmake")))})`,
|
|
||||||
`set(OpenCV_INCLUDE_DIR \${OpenCV_INCLUDE_DIRS})`,
|
|
||||||
os.platform() == "win32" ?
|
|
||||||
"set(OpenCV_LIB_DIR ${OpenCV_LIB_PATH})" :
|
|
||||||
`set(OpenCV_LIB_DIR ${JSON.stringify(P(path.join(root, "lib")))})`,
|
|
||||||
// `set(OpenCV_LIBS OpenCV_LIBS)`,
|
|
||||||
].join("\n"))
|
|
||||||
//ONNXRuntime
|
//ONNXRuntime
|
||||||
if (buildOptions.withONNX && !checkFile(THIRDPARTY_DIR, "ONNXRuntime/config.cmake")) {
|
if (buildOptions.withONNX && !checkFile(THIRDPARTY_DIR, "ONNXRuntime/config.cmake")) {
|
||||||
let url = "";
|
let url = "";
|
||||||
|
Reference in New Issue
Block a user