初次提交

This commit is contained in:
2025-03-17 10:19:27 +08:00
commit 6c29336660
22 changed files with 1461 additions and 0 deletions

19
src/cv/addon.ts Normal file
View File

@ -0,0 +1,19 @@
import { LINE_8, MARKER_CROSS } from "./consts";
export const config = {
ADDON_PATH: "../../build/cv.node",
DEFAULT_LINE_TYPE: LINE_8,
DEFAULT_THICKNESS: 1,
DEFAULT_MARKER: MARKER_CROSS,
};
export function getAddon() {
return require(config.ADDON_PATH);
}
export function getConfig<N extends keyof typeof config>(name: N): typeof config[N] { return config[name]; }
export function setConfig<N extends keyof typeof config>(name: N, value: typeof config[N]) { config[name] = value; }
export function CVMat() { return getAddon().Mat; }
export function CVUtil() { return getAddon().util; }

14
src/cv/common.ts Normal file
View File

@ -0,0 +1,14 @@
import { getAddon, getConfig } from "./addon";
import { Mat } from "./mat";
export type TypedArray = Uint8Array | Int8Array | Uint16Array | Int16Array | Uint32Array | Int32Array | BigUint64Array | BigInt64Array | Float32Array | Float64Array
export function FromCV(mat: any): Mat { return new (Mat as any)(mat); }
export function M(mat: Mat) { return (mat as any).__mat__; }
export function C(name: Parameters<typeof getConfig>[0]) { return getConfig(name); }
export function resolveArgs<R extends Array<any>>(args: any[], checker: boolean | (() => boolean)): R {
if (typeof checker === "function") checker = checker();
if (checker) return args as R;
return [args[0], new Mat(), ...args.slice(1)] as R;
}

166
src/cv/consts.ts Normal file
View File

@ -0,0 +1,166 @@
export const IMREAD_UNCHANGED = -1;
export const IMREAD_GRAYSCALE = 0;
export const IMREAD_COLOR_BGR = 1;
export const IMREAD_COLOR = 1;
export const IMREAD_ANYDEPTH = 2;
export const IMREAD_ANYCOLOR = 4;
export const IMREAD_LOAD_GDAL = 8;
export const IMREAD_REDUCED_GRAYSCALE_2 = 16;
export const IMREAD_REDUCED_COLOR_2 = 17;
export const IMREAD_REDUCED_GRAYSCALE_4 = 32;
export const IMREAD_REDUCED_COLOR_4 = 33;
export const IMREAD_REDUCED_GRAYSCALE_8 = 64;
export const IMREAD_REDUCED_COLOR_8 = 65;
export const IMREAD_IGNORE_ORIENTATION = 128;
export const IMREAD_COLOR_RGB = 256;
export const CV_8U = 0;
export const CV_8S = 1;
export const CV_16U = 2;
export const CV_16S = 3;
export const CV_32S = 4;
export const CV_32F = 5;
export const CV_64F = 6;
export const CV_16F = 7;
const CV_CN_MAX = 512
const CV_CN_SHIFT = 3
const CV_DEPTH_MAX = (1 << CV_CN_SHIFT)
const CV_MAT_DEPTH_MASK = (CV_DEPTH_MAX - 1)
const CV_MAT_DEPTH = (flags: number) => ((flags) & CV_MAT_DEPTH_MASK)
const CV_MAKETYPE = (depth: number, cn: number) => (CV_MAT_DEPTH(depth) + (((cn) - 1) << CV_CN_SHIFT))
export const CV_8UC1 = CV_MAKETYPE(CV_8U, 1);
export const CV_8UC2 = CV_MAKETYPE(CV_8U, 2);
export const CV_8UC3 = CV_MAKETYPE(CV_8U, 3);
export const CV_8UC4 = CV_MAKETYPE(CV_8U, 4);
export const CV_8UC = (n: number) => CV_MAKETYPE(CV_8U, (n));
export const CV_8SC1 = CV_MAKETYPE(CV_8S, 1);
export const CV_8SC2 = CV_MAKETYPE(CV_8S, 2);
export const CV_8SC3 = CV_MAKETYPE(CV_8S, 3);
export const CV_8SC4 = CV_MAKETYPE(CV_8S, 4);
export const CV_8SC = (n: number) => CV_MAKETYPE(CV_8S, (n));
export const CV_16UC1 = CV_MAKETYPE(CV_16U, 1);
export const CV_16UC2 = CV_MAKETYPE(CV_16U, 2);
export const CV_16UC3 = CV_MAKETYPE(CV_16U, 3);
export const CV_16UC4 = CV_MAKETYPE(CV_16U, 4);
export const CV_16UC = (n: number) => CV_MAKETYPE(CV_16U, (n));
export const CV_16SC1 = CV_MAKETYPE(CV_16S, 1);
export const CV_16SC2 = CV_MAKETYPE(CV_16S, 2);
export const CV_16SC3 = CV_MAKETYPE(CV_16S, 3);
export const CV_16SC4 = CV_MAKETYPE(CV_16S, 4);
export const CV_16SC = (n: number) => CV_MAKETYPE(CV_16S, (n));
export const CV_32SC1 = CV_MAKETYPE(CV_32S, 1);
export const CV_32SC2 = CV_MAKETYPE(CV_32S, 2);
export const CV_32SC3 = CV_MAKETYPE(CV_32S, 3);
export const CV_32SC4 = CV_MAKETYPE(CV_32S, 4);
export const CV_32SC = (n: number) => CV_MAKETYPE(CV_32S, (n));
export const CV_32FC1 = CV_MAKETYPE(CV_32F, 1);
export const CV_32FC2 = CV_MAKETYPE(CV_32F, 2);
export const CV_32FC3 = CV_MAKETYPE(CV_32F, 3);
export const CV_32FC4 = CV_MAKETYPE(CV_32F, 4);
export const CV_32FC = (n: number) => CV_MAKETYPE(CV_32F, (n));
export const CV_64FC1 = CV_MAKETYPE(CV_64F, 1);
export const CV_64FC2 = CV_MAKETYPE(CV_64F, 2);
export const CV_64FC3 = CV_MAKETYPE(CV_64F, 3);
export const CV_64FC4 = CV_MAKETYPE(CV_64F, 4);
export const CV_64FC = (n: number) => CV_MAKETYPE(CV_64F, (n));
export const CV_16FC1 = CV_MAKETYPE(CV_16F, 1);
export const CV_16FC2 = CV_MAKETYPE(CV_16F, 2);
export const CV_16FC3 = CV_MAKETYPE(CV_16F, 3);
export const CV_16FC4 = CV_MAKETYPE(CV_16F, 4);
export const CV_16FC = (n: number) => CV_MAKETYPE(CV_16F, (n));
export const INTER_NEAREST = 0;
export const INTER_LINEAR = 1;
export const INTER_CUBIC = 2;
export const INTER_AREA = 3;
export const INTER_LANCZOS4 = 4;
export const INTER_LINEAR_EXACT = 5;
export const INTER_NEAREST_EXACT = 6;
export const INTER_MAX = 7;
export const WARP_FILL_OUTLIERS = 8;
export const WARP_INVERSE_MAP = 16;
export const WARP_RELATIVE_MAP = 32;
export const BORDER_CONSTANT = 0;
export const BORDER_REPLICATE = 1;
export const BORDER_REFLECT = 2;
export const BORDER_WRAP = 3;
export const BORDER_REFLECT_101 = 4;
export const BORDER_TRANSPARENT = 5;
export const BORDER_REFLECT101 = BORDER_REFLECT_101;
export const BORDER_DEFAULT = BORDER_REFLECT_101;
export const BORDER_ISOLATED = 16;
export const IMWRITE_JPEG_QUALITY = 1;
export const IMWRITE_JPEG_PROGRESSIVE = 2;
export const IMWRITE_JPEG_OPTIMIZE = 3;
export const IMWRITE_JPEG_RST_INTERVAL = 4;
export const IMWRITE_JPEG_LUMA_QUALITY = 5;
export const IMWRITE_JPEG_CHROMA_QUALITY = 6;
export const IMWRITE_JPEG_SAMPLING_FACTOR = 7;
export const IMWRITE_PNG_COMPRESSION = 16;
export const IMWRITE_PNG_STRATEGY = 17;
export const IMWRITE_PNG_BILEVEL = 18;
export const IMWRITE_PXM_BINARY = 32;
export const IMWRITE_EXR_TYPE = (3 << 4) + 0;
export const IMWRITE_EXR_COMPRESSION = (3 << 4) + 1;
export const IMWRITE_EXR_DWA_COMPRESSION_LEVEL = (3 << 4) + 2;
export const IMWRITE_WEBP_QUALITY = 64;
export const IMWRITE_HDR_COMPRESSION = (5 << 4) + 0;
export const IMWRITE_PAM_TUPLETYPE = 128;
export const IMWRITE_TIFF_RESUNIT = 256;
export const IMWRITE_TIFF_XDPI = 257;
export const IMWRITE_TIFF_YDPI = 258;
export const IMWRITE_TIFF_COMPRESSION = 259;
export const IMWRITE_TIFF_ROWSPERSTRIP = 278;
export const IMWRITE_TIFF_PREDICTOR = 317;
export const IMWRITE_JPEG2000_COMPRESSION_X1000 = 272;
export const IMWRITE_AVIF_QUALITY = 512;
export const IMWRITE_AVIF_DEPTH = 513;
export const IMWRITE_AVIF_SPEED = 514;
export const IMWRITE_JPEGXL_QUALITY = 640;
export const IMWRITE_JPEGXL_EFFORT = 641;
export const IMWRITE_JPEGXL_DISTANCE = 642;
export const IMWRITE_JPEGXL_DECODING_SPEED = 643;
export const IMWRITE_GIF_LOOP = 1024;
export const IMWRITE_GIF_SPEED = 1025;
export const IMWRITE_GIF_QUALITY = 1026;
export const IMWRITE_GIF_DITHER = 1027;
export const IMWRITE_GIF_TRANSPARENCY = 1028;
export const IMWRITE_GIF_COLORTABLE = 1029;
export const FILLED = -1;
export const LINE_4 = 4;
export const LINE_8 = 8;
export const LINE_AA = 16;
export const FONT_HERSHEY_SIMPLEX = 0;
export const FONT_HERSHEY_PLAIN = 1;
export const FONT_HERSHEY_DUPLEX = 2;
export const FONT_HERSHEY_COMPLEX = 3;
export const FONT_HERSHEY_TRIPLEX = 4;
export const FONT_HERSHEY_COMPLEX_SMALL = 5;
export const FONT_HERSHEY_SCRIPT_SIMPLEX = 6;
export const FONT_HERSHEY_SCRIPT_COMPLEX = 7;
export const FONT_ITALIC = 16;
export const MARKER_CROSS = 0;
export const MARKER_TILTED_CROSS = 1;
export const MARKER_STAR = 2;
export const MARKER_DIAMOND = 3;
export const MARKER_SQUARE = 4;
export const MARKER_TRIANGLE_UP = 5;
export const MARKER_TRIANGLE_DOWN = 6;

104
src/cv/draw.ts Normal file
View File

@ -0,0 +1,104 @@
import { CVMat, CVUtil } from "./addon";
import { C, M } from "./common";
import { Mat } from "./mat";
type Color = [b: number, g: number, r: number] | { r: number, g: number, b: number };
type Point = [x: number, y: number] | { x: number, y: number };
type Size = [width: number, height: number] | { width: number, height: number };
type Rect = [x: number, y: number, width: number, height: number] | { x: number, y: number, width: number, height: number };
function __checkType(val: any, props: string[]) {
if (!val) return false;
if (val instanceof Array) return val.length === props.length && val.every(i => typeof i === "number");
return Object.keys(props).length === props.length && props.every(p => typeof val?.[p] === "number");
}
function __typeToArray<R = number[]>(val: any, props: string[]) {
if (val instanceof Array) return val as R;
return props.map(p => val[p]) as R;
}
function isColor(val: any): val is Color { return __checkType(val, ["r", "g", "b"]); }
function isPoint(val: any): val is Point { return __checkType(val, ["x", "y"]); }
function isSize(val: any): val is Size { return __checkType(val, ["width", "height"]); }
function isRect(val: any): val is Rect { return __checkType(val, ["x", "y", "width", "height"]); }
function getColor(color: Color) { return __typeToArray<[number, number, number]>(color, ["b", "g", "r"]); }
function getPoint(point: Point) { return __typeToArray<[number, number]>(point, ["x", "y"]); }
function getSize(point: Size) { return __typeToArray<[number, number]>(point, ["width", "height"]); }
function getRectPoints(rect: Rect): [number, number, number, number] {
const [x, y, width, height] = __typeToArray(rect, ["x", "y", "width", "height"]);
return [x, y, x + width, y + height];
}
export function rectangle(img: Mat, rect: Rect, color: Color, thickness?: number, lineType?: number, shift?: number): void
export function rectangle(img: Mat, pt1: Point, pt2: Point, color: Color, thickness?: number, lineType?: number, shift?: number): void
export function rectangle(img: Mat, x1: number, y1: number, x2: number, y2: number, b: number, g: number, r: number, thickness?: number, lineType?: number, shift?: number): void
export function rectangle(img: Mat, ...rest: any[]) {
if (isPoint(rest[0])) rectangle(img, ...getPoint(rest[0]), ...getPoint(rest[1]), ...getColor(rest[2]), ...rest.slice(3));
else if (isRect(rest[0])) rectangle(img, ...getRectPoints(rest[0]), ...getColor(rest[1]), ...rest.slice(2));
else CVMat().Rectangle(M(img), rest[0], rest[1], rest[2], rest[3], rest[4], rest[5], rest[6], rest[7] ?? C("DEFAULT_THICKNESS"), rest[8] ?? C("DEFAULT_LINE_TYPE"), rest[9] ?? 0);
}
export function circle(img: Mat, center: Point, radius: number, color: Color, thickness?: number, lineType?: number, shift?: number): void
export function circle(img: Mat, x: number, y: number, radius: number, b: number, g: number, r: number, thickness?: number, lineType?: number, shift?: number): void
export function circle(img: Mat, ...rest: any[]) {
if (isPoint(rest[0])) circle(img, ...getPoint(rest[0]), rest[1], ...getColor(rest[2]), ...rest.slice(3));
else CVMat().Circle(M(img), rest[0], rest[1], rest[2], rest[3], rest[4], rest[5], rest[6] ?? C("DEFAULT_THICKNESS"), rest[7] ?? C("DEFAULT_LINE_TYPE"), rest[8] ?? 0);
}
export function line(img: Mat, pt1: Point, pt2: Point, color: Color, thickness?: number, lineType?: number, shift?: number): void
export function line(img: Mat, x1: number, y1: number, x2: number, y2: number, b: number, g: number, r: number, thickness?: number, lineType?: number, shift?: number): void
export function line(img: Mat, ...rest: any[]) {
if (isPoint(rest[0])) line(img, ...getPoint(rest[0]), ...getPoint(rest[1]), ...getColor(rest[2]), ...rest.slice(3));
else CVMat().Line(M(img), rest[0], rest[1], rest[2], rest[3], rest[4], rest[5], rest[6], rest[7] ?? C("DEFAULT_THICKNESS"), rest[8] ?? C("DEFAULT_LINE_TYPE"), rest[9] ?? 0);
}
export function ellipse(img: Mat, center: Point, size: Size, angle: number, startAngle: number, endAngle: number, color: Color, thickness?: number, lineType?: number, shift?: number): void
export function ellipse(img: Mat, centerX: number, centerY: number, width: number, height: number, angle: number, startAngle: number, endAngle: number, b: number, g: number, r: number, thickness?: number, lineType?: number, shift?: number): void
export function ellipse(img: Mat, ...rest: any[]) {
if (isPoint(rest[0])) ellipse(img, ...getPoint(rest[0]), ...getSize(rest[1]), rest[2], rest[3], rest[4], ...getColor(rest[5]), ...rest.slice(6));
else CVMat().Ellipse(M(img), rest[0], rest[1], rest[2], rest[3], rest[4], rest[5], rest[6], rest[7], rest[8], rest[9], rest[10] ?? C("DEFAULT_THICKNESS"), rest[11] ?? C("DEFAULT_LINE_TYPE"), rest[12] ?? 0);
}
export function polylines(img: Mat, points: Point[], isClosed: boolean, color: Color, thickness?: number, lineType?: number, shift?: number): void;
export function polylines(img: Mat, points: Point[], isClosed: boolean, b: number, g: number, r: number, thickness?: number, lineType?: number, shift?: number): void;
export function polylines(img: Mat, points: Point[], isClosed: boolean, ...rest: any[]) {
if (isColor(rest[0])) polylines(img, points, isClosed, ...getColor(rest[0]), rest[1], rest[2], rest[3]);
else CVMat().Polylines(M(img), points.map(p => getPoint(p)), isClosed, rest[0], rest[1], rest[2], rest[3] ?? C("DEFAULT_THICKNESS"), rest[4] ?? C("DEFAULT_LINE_TYPE"), rest[5] ?? 0);
}
export function fillPoly(img: Mat, points: Point[], color: Color, lineType?: number, shift?: number): void;
export function fillPoly(img: Mat, points: Point[], b: number, g: number, r: number, lineType?: number, shift?: number): void;
export function fillPoly(img: Mat, points: Point[], ...rest: any[]) {
if (isColor(rest[0])) fillPoly(img, points, ...getColor(rest[0]), rest[1], rest[2]);
else CVMat().FillPoly(M(img), points.map(p => getPoint(p)), rest[0], rest[1], rest[2], rest[3] ?? C("DEFAULT_LINE_TYPE"), rest[4] ?? 0);
}
export function fillConvexPoly(img: Mat, points: Point[], color: Color, lineType?: number, shift?: number): void;
export function fillConvexPoly(img: Mat, points: Point[], b: number, g: number, r: number, lineType?: number, shift?: number): void;
export function fillConvexPoly(img: Mat, points: Point[], ...rest: any[]) {
if (isColor(rest[0])) fillConvexPoly(img, points, ...getColor(rest[0]), rest[1], rest[2]);
else CVMat().FillConvexPoly(M(img), points.map(p => getPoint(p)), rest[0], rest[1], rest[2], rest[3] ?? C("DEFAULT_LINE_TYPE"), rest[4] ?? 0);
}
export function drawMarker(img: Mat, pos: Point, color: Color, markerType?: number, markerSize?: number, lineType?: number, shift?: number): void;
export function drawMarker(img: Mat, x: number, y: number, b: number, g: number, r: number, markerType?: number, markerSize?: number, lineType?: number, shift?: number): void;
export function drawMarker(img: Mat, ...rest: any[]) {
if (isPoint(rest[0])) drawMarker(img, ...getPoint(rest[0]), ...getColor(rest[1]), rest[2], rest[3], rest[4], rest[5]);
else CVMat().DrawMarker(M(img), rest[0], rest[1], rest[2], rest[3], rest[4], rest[5] ?? C("DEFAULT_MARKER"), rest[6] ?? 20, rest[7] ?? 1, rest[8] ?? C("DEFAULT_LINE_TYPE"));
}
export function putText(img: Mat, text: string, org: Point, fontFace: number, fontScale: number, color: Color, thickness?: number, lineType?: number, bottomLeftOrigin?: boolean): void
export function putText(img: Mat, text: string, x: number, y: number, fontFace: number, fontScale: number, b: number, g: number, r: number, thickness?: number, lineType?: number, bottomLeftOrigin?: boolean): void
export function putText(img: Mat, text: string, ...rest: any[]) {
if (isPoint(rest[0])) putText(img, text, ...getPoint(rest[0]), rest[1], rest[2], ...getColor(rest[3]), rest[4], rest[5], rest[6]);
else CVMat().PutText(M(img), text, rest[0], rest[1], rest[2], rest[3], rest[4], rest[5], rest[6], rest[7] ?? C("DEFAULT_THICKNESS"), rest[8] ?? C("DEFAULT_LINE_TYPE"), rest[9] ?? false);
}
export function getTextSize(text: string, fontFace: number, fontScale: number, thickness?: number) {
return CVUtil().GetTextSize(text, fontFace, fontScale, thickness ?? C("DEFAULT_THICKNESS"));
}
export function getFontScaleFromHeight(fontFace: number, pixelHeight: number, thickness?: number) {
return CVUtil().GetFontScaleFromHeight(fontFace, pixelHeight, thickness ?? C("DEFAULT_THICKNESS"));
}

5
src/cv/index.ts Normal file
View File

@ -0,0 +1,5 @@
export { setConfig as config } from "./addon";
export * from "./mat";
export * from "./consts";
export * from "./proc";
export * from "./draw";

55
src/cv/mat.ts Normal file
View File

@ -0,0 +1,55 @@
import { CVMat } from "./addon";
import { FromCV, M, TypedArray } from "./common";
import { IMREAD_COLOR_BGR } from "./consts";
export class Mat {
#mat: any
public constructor();
public constructor(rows: number, cols: number, type: number, data?: TypedArray);
public constructor(sizes: number[], type: number, data?: TypedArray);
public constructor(va?: any, vb?: any, vc?: any, vd?: any) {
const _CVMat = CVMat();
if (va instanceof _CVMat) this.#mat = va;
if (typeof va === "number") this.#mat = new _CVMat([va, vb], vc, vd);
else if (typeof va === "undefined") this.#mat = new _CVMat();
else if (va instanceof Array) this.#mat = new _CVMat(va, vb, vc);
}
private get __mat__() { return this.#mat; }
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 type(): number { return this.#mat.GetType(); }
public get depth(): number { return this.#mat.GetDepth(); }
public get channels(): number { return this.#mat.GetChannels(); }
public get flags(): number { return this.#mat.GetFlags(); }
public get dims(): number { return this.#mat.GetDims(); }
public get isContinuous(): boolean { return this.#mat.GetIsContinuous(); }
public get isSubmatrix(): boolean { return this.#mat.GetIsSubmatrix(); }
public get elemSize(): number { return this.#mat.GetElemSize(); }
public get elemSize1(): number { return this.#mat.GetElemSize1(); }
public total(startDim?: number, endDim?: number): number {
if (startDim === null || startDim === undefined) return this.#mat.GetTotal();
else return this.#mat.GetTotalWithDim(startDim, endDim ?? 2147483647);
}
public get size(): number[] { return this.#mat.GetSize(); }
public clone() { return FromCV(this.#mat.Clone()); }
public row(y: number) { return FromCV(this.#mat.Row(y)); }
public col(x: number) { return FromCV(this.#mat.Col(x)); }
public rowRange(start: number, end: number) { return FromCV(this.#mat.RowRange(start, end)); }
public colRange(start: number, end: number) { return FromCV(this.#mat.ColRange(start, end)); }
public diag(d: number) { return FromCV(this.#mat.Diag(d)); }
};
export function imread(filename: string, flag?: number) { return FromCV(CVMat().ImRead(filename, flag ?? IMREAD_COLOR_BGR)); }
export function imdecode(data: Uint8Array, flag?: number) { return FromCV(CVMat().ImDecode(data, flag ?? IMREAD_COLOR_BGR)); }
export function imwrite(filename: string, mat: Mat, params?: number[]): boolean { return CVMat().ImWrite(M(mat), filename, params); }
export function imencode(ext: string, mat: Mat, params?: number[]): Uint8Array | null {
const res = CVMat().ImEncode(M(mat), ext, params);
if (!res) return null;
return new Uint8Array(res);
}

53
src/cv/proc.ts Normal file
View File

@ -0,0 +1,53 @@
import { Mat } from "./mat";
import { FromCV, M, resolveArgs } from "./common";
import { BORDER_CONSTANT, BORDER_DEFAULT, INTER_LINEAR } from "./consts";
import { CVMat } from "./addon";
type CropRange = { x: number, y: number, width: number, height: number } | Array<{ start: number, end: number }>;
export function crop(src: Mat, range: CropRange): Mat;
export function crop(src: Mat, dst: Mat, range: CropRange): Mat;
export function crop(...args: any[]) {
let [src, dst, range] = resolveArgs<[src: Mat, dst: Mat, range: CropRange]>(args, args[1] instanceof Mat);
if (!(range instanceof Array)) range = [{ start: range.y, end: range.y + range.height }, { start: range.x, end: range.x + range.width }];
return FromCV(CVMat().Crop(M(src), M(dst), range));
}
export function resize(src: Mat, width: number, height: number, fx?: number, fy?: number, interpolation?: number): Mat;
export function resize(src: Mat, dst: Mat, width: number, height: number, fx?: number, fy?: number, interpolation?: number): Mat;
export function resize(...args: any[]) {
const [src, dst, width, height, fx, fy, interpolation] = resolveArgs<[src: Mat, dst: Mat, width: number, height: number, fx?: number, fy?: number, interpolation?: number]>(args, args[1] instanceof Mat);
return FromCV(CVMat().Resize(M(src), M(dst), width, height, fx ?? 0, fy ?? 0, interpolation ?? INTER_LINEAR));
}
export function blur(src: Mat, kernelWidth: number, kernelHeight: number, anchorX?: number, anchorY?: number, borderType?: number): Mat
export function blur(src: Mat, dst: Mat, kernelWidth: number, kernelHeight: number, anchorX?: number, anchorY?: number, borderType?: number): Mat
export function blur(...args: any[]) {
let [src, dst, kernelWidth, kernelHeight, anchorX = -1, anchorY = -1, borderType = BORDER_DEFAULT] = resolveArgs<[src: Mat, dst: Mat, kernelWidth: number, kernelHeight: number, anchorX?: number, anchorY?: number, borderType?: number]>(args, args[1] instanceof Mat);
if (anchorX == -1 || anchorY == -1) anchorX = anchorY = -1;
return FromCV(CVMat().Blur(M(src), M(dst), kernelWidth, kernelHeight, anchorX, anchorY, borderType));
}
export function copyMakeBorder(src: Mat, top: number, bottom: number, left: number, right: number, borderType: number): Mat
export function copyMakeBorder(src: Mat, dst: Mat, top: number, bottom: number, left: number, right: number, borderType: number): Mat
export function copyMakeBorder(...args: any[]) {
const [src, dst, top, bottom, left, right, borderType] = resolveArgs<[src: Mat, dst: Mat, top: number, bottom: number, left: number, right: number, borderType: number]>(args, args[1] instanceof Mat);
return FromCV(CVMat().CopyMakeBorder(M(src), M(dst), top, bottom, left, right, borderType));
}
type FlipCode = 0 | 1 | -1 | "x" | "y" | "both";
export function flip(src: Mat, flipCode: FlipCode): Mat
export function flip(src: Mat, dst: Mat, flipCode: FlipCode): Mat
export function flip(...args: any[]) {
let [src, dst, flipCode] = resolveArgs<[src: Mat, dst: Mat, flipCode: FlipCode]>(args, args[1] instanceof Mat);
if (typeof flipCode == "string") flipCode = ({ x: 0, y: 1, both: -1 } as Record<"x" | "y" | "both", 0 | 1 | -1>)[flipCode];
return FromCV(CVMat().Flip(M(src), M(dst), flipCode));
}
export function warpAffine(src: Mat, transfromMat: Mat, dwidth: number, dheight: number, flags?: number, borderMode?: number): Mat;
export function warpAffine(src: Mat, dst: Mat, transfromMat: Mat, dwidth: number, dheight: number, flags?: number, borderMode?: number): Mat;
export function warpAffine(...args: any[]) {
const [src, dst, transfromMat, dwidth, dheight, flags, borderMode] = resolveArgs<[src: Mat, dst: Mat, transfromMat: Mat, dwidth: number, dheight: number, flags?: number, borderMode?: number]>(args, () => args[2] instanceof Mat);
return FromCV(CVMat().WarpAffine(M(src), M(dst), M(transfromMat), dwidth, dheight, flags ?? INTER_LINEAR, borderMode ?? BORDER_CONSTANT));
}
export function getRotationMatrix2D(centerX: number, centerY: number, angle: number, scale: number) { return FromCV(CVMat().GetRotationMatrix2D(centerX, centerY, angle, scale)); }

3
src/index.ts Normal file
View File

@ -0,0 +1,3 @@
import * as cv from "./cv";
export default cv;
export { cv };

34
src/test.ts Normal file
View File

@ -0,0 +1,34 @@
import cv from ".";
async function test() {
const fs = await import("fs");
// const buffer = fs.readFileSync("data/im1.jpeg")
const res = await cv.imread("test_data/im1.jpeg");
// const res = await cv.imdecode(buffer);
const cropIm = cv.crop(res, { x: 10, y: 10, width: 300, height: 200 });
console.log(cv.imwrite("test_data/cropIm.jpg", cropIm));
fs.writeFileSync("test_data/base.jpg", cv.imencode(".jpg", res)!);
const rotated = cv.warpAffine(res, cv.getRotationMatrix2D(100, 100, 50, 1), res.cols, res.rows);
cv.imwrite("test_data/rotated.jpg", rotated);
cv.imwrite("test_data/blur.jpg", cv.blur(res, 20, 20));
cv.imwrite("test_data/copyMakeBorder.jpg", cv.copyMakeBorder(res, 100, 30, 50, 40, cv.BORDER_CONSTANT));
cv.imwrite("test_data/flip.jpg", cv.flip(res, "both"));
cv.rectangle(res, [10, 10, 200, 200], [0, 0, 255], 3);
cv.circle(res, [200, 200], 200, [255, 0, 0], 4);
cv.line(res, [100, 100], [300, 500], [0, 0, 255], 3);
cv.ellipse(res, [300, 500], [200, 100], 45, 0, 360, [0, 255, 0], 3);
cv.polylines(res, [[50, 50], [150, 150], [50, 150]], true, [255, 0, 255], 3);
cv.fillConvexPoly(res, [[50, 50], [150, 150], [150, 50]], [255, 0, 255]);
cv.drawMarker(res, [300, 200], [255, 255, 0]);
cv.imwrite("test_data/draw.jpg", res);
}
test();