ppu-ocv 1.0.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/canvas-toolkit.d.ts +18 -3
- package/canvas-toolkit.js +1 -1
- package/image-analysis.d.ts +4 -4
- package/image-analysis.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -77,7 +77,7 @@ import { CanvasToolkit, ImageProcessor, cv } from "ppu-ocv";
|
|
|
77
77
|
const file = Bun.file("./assets/receipt.jpg");
|
|
78
78
|
const image = await file.arrayBuffer();
|
|
79
79
|
|
|
80
|
-
const canvasToolkit =
|
|
80
|
+
const canvasToolkit = CanvasToolkit.getInstance();
|
|
81
81
|
const canvas = await ImageProcessor.prepareCanvas(image);
|
|
82
82
|
await ImageProcessor.initRuntime();
|
|
83
83
|
|
package/canvas-toolkit.d.ts
CHANGED
|
@@ -1,7 +1,22 @@
|
|
|
1
1
|
import type { BoundingBox, SKRSContext2D } from "./index";
|
|
2
2
|
import { Canvas, cv } from "./index";
|
|
3
|
+
/**
|
|
4
|
+
* Singleton class for canvas manipulation utilities
|
|
5
|
+
*/
|
|
3
6
|
export declare class CanvasToolkit {
|
|
7
|
+
private static instance;
|
|
4
8
|
private step;
|
|
9
|
+
/**
|
|
10
|
+
* Private constructor to prevent direct instantiation
|
|
11
|
+
*/
|
|
12
|
+
private constructor();
|
|
13
|
+
/**
|
|
14
|
+
* Get the singleton instance of CanvasToolkit
|
|
15
|
+
* @returns The singleton instance
|
|
16
|
+
* @example
|
|
17
|
+
* const canvasToolkit = CanvasToolkit.getInstance();
|
|
18
|
+
*/
|
|
19
|
+
static getInstance(): CanvasToolkit;
|
|
5
20
|
/**
|
|
6
21
|
* Crop a part of source canvas and return a new canvas of the cropped part
|
|
7
22
|
* @param options
|
|
@@ -9,7 +24,7 @@ export declare class CanvasToolkit {
|
|
|
9
24
|
* @param options.canvas Source canvas
|
|
10
25
|
* @returns A new canvas of the cropped part
|
|
11
26
|
* @example
|
|
12
|
-
* const croppedCanvas =
|
|
27
|
+
* const croppedCanvas = CanvasToolkit.getInstance().crop({
|
|
13
28
|
* bbox: { x0: 10, y0: 10, x1: 100, y1: 100 },
|
|
14
29
|
* canvas: sourceCanvas,
|
|
15
30
|
* });
|
|
@@ -26,7 +41,7 @@ export declare class CanvasToolkit {
|
|
|
26
41
|
* @param options.majorColorThreshold Major color threshold (default: 0.97)
|
|
27
42
|
* @returns true if the canvas is dirty, false otherwise
|
|
28
43
|
* @example
|
|
29
|
-
* const isDirty =
|
|
44
|
+
* const isDirty = CanvasToolkit.getInstance().isDirty({
|
|
30
45
|
* canvas: sourceCanvas,
|
|
31
46
|
* threshold: 127.5,
|
|
32
47
|
* majorColorThreshold: 0.97,
|
|
@@ -46,7 +61,7 @@ export declare class CanvasToolkit {
|
|
|
46
61
|
* @param options.path Path to save the image file (default: "out")
|
|
47
62
|
* @returns A promise that resolves when the image is saved
|
|
48
63
|
* @example
|
|
49
|
-
* await
|
|
64
|
+
* await CanvasToolkit.getInstance().saveImage({
|
|
50
65
|
* canvas: sourceCanvas,
|
|
51
66
|
* filename: "output.png",
|
|
52
67
|
* });
|
package/canvas-toolkit.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export class CanvasToolkit{step=0;crop(options){const{bbox,canvas}=options;let croppedCanvas=createCanvas(bbox.x1-bbox.x0,bbox.y1-bbox.y0);let croppedCtx=croppedCanvas.getContext("2d");croppedCtx.drawImage(canvas,bbox.x0,bbox.y0,bbox.x1-bbox.x0,bbox.y1-bbox.y0,0,0,croppedCanvas.width,croppedCanvas.height);return croppedCanvas}isDirty(options){const{canvas,threshold=127.5,majorColorThreshold=0.97}=options;let whiteCount=0;let blackCount=0;let borderlessCanvas=this.crop({bbox:{x0:canvas.width*0.1,y0:canvas.height*0.1,x1:canvas.width*0.9,y1:canvas.height*0.9},canvas});let ctx=borderlessCanvas.getContext("2d");let colorData=ctx.getImageData(0,0,borderlessCanvas.width,borderlessCanvas.height).data;for(let i=0;i<colorData.length;i+=4){let red=colorData[i];let green=colorData[i+1];let blue=colorData[i+2];if(red>=threshold&&green>=threshold&&blue>=threshold){whiteCount++}else{blackCount++}}let majorColorRatio=Math.max(whiteCount,blackCount)/(blackCount+whiteCount);return majorColorRatio<majorColorThreshold}saveImage(options){const{canvas,filename,path="out"}=options;let folderPath=join(process.cwd(),path);if(!existsSync(folderPath)){mkdirSync(folderPath,{recursive:true})}let filePath=join(folderPath,`${this.step++}. ${filename}.png`);let out=createWriteStream(filePath);let buffer=canvas.toBuffer("image/png");return new Promise((res,rej)=>{out.write(buffer,(err)=>{if(err){rej(err)}else{res()}})})}clearOutput(path="out"){let folderPath=join(process.cwd(),path);if(existsSync(folderPath)){let files=readdirSync(folderPath);for(let file of files){if(file===".gitignore")continue;let filePath=join(folderPath,file);unlinkSync(filePath)}}}drawLine(options){const{ctx,x,y,width,height,lineWidth=2,color="blue"}=options;ctx.beginPath();ctx.strokeStyle=color;ctx.lineWidth=lineWidth;ctx.strokeRect(x,y,width,height);ctx.closePath()}drawContour(options){const{ctx,contour,strokeStyle="red",lineWidth=2}=options;let pts=contour.data32S;if(pts.length<4)return;ctx.strokeStyle=strokeStyle;ctx.lineWidth=lineWidth;ctx.beginPath();ctx.moveTo(pts[0],pts[1]);for(let i=2;i<pts.length;i+=2){ctx.lineTo(pts[i],pts[i+1])}ctx.closePath();ctx.stroke()}}import{createCanvas}from"./index";import{createWriteStream,existsSync,mkdirSync,readdirSync,unlinkSync}from"fs";import{join}from"path";
|
|
1
|
+
export class CanvasToolkit{static instance=null;step=0;constructor(){}static getInstance(){if(!CanvasToolkit.instance){CanvasToolkit.instance=new CanvasToolkit}return CanvasToolkit.instance}crop(options){const{bbox,canvas}=options;let croppedCanvas=createCanvas(bbox.x1-bbox.x0,bbox.y1-bbox.y0);let croppedCtx=croppedCanvas.getContext("2d");croppedCtx.drawImage(canvas,bbox.x0,bbox.y0,bbox.x1-bbox.x0,bbox.y1-bbox.y0,0,0,croppedCanvas.width,croppedCanvas.height);return croppedCanvas}isDirty(options){const{canvas,threshold=127.5,majorColorThreshold=0.97}=options;let whiteCount=0;let blackCount=0;let borderlessCanvas=this.crop({bbox:{x0:canvas.width*0.1,y0:canvas.height*0.1,x1:canvas.width*0.9,y1:canvas.height*0.9},canvas});let ctx=borderlessCanvas.getContext("2d");let colorData=ctx.getImageData(0,0,borderlessCanvas.width,borderlessCanvas.height).data;for(let i=0;i<colorData.length;i+=4){let red=colorData[i];let green=colorData[i+1];let blue=colorData[i+2];if(red>=threshold&&green>=threshold&&blue>=threshold){whiteCount++}else{blackCount++}}let majorColorRatio=Math.max(whiteCount,blackCount)/(blackCount+whiteCount);return majorColorRatio<majorColorThreshold}saveImage(options){const{canvas,filename,path="out"}=options;let folderPath=join(process.cwd(),path);if(!existsSync(folderPath)){mkdirSync(folderPath,{recursive:true})}let filePath=join(folderPath,`${this.step++}. ${filename}.png`);let out=createWriteStream(filePath);let buffer=canvas.toBuffer("image/png");return new Promise((res,rej)=>{out.write(buffer,(err)=>{if(err){rej(err)}else{res()}})})}clearOutput(path="out"){let folderPath=join(process.cwd(),path);if(existsSync(folderPath)){let files=readdirSync(folderPath);for(let file of files){if(file===".gitignore")continue;let filePath=join(folderPath,file);unlinkSync(filePath)}}}drawLine(options){const{ctx,x,y,width,height,lineWidth=2,color="blue"}=options;ctx.beginPath();ctx.strokeStyle=color;ctx.lineWidth=lineWidth;ctx.strokeRect(x,y,width,height);ctx.closePath()}drawContour(options){const{ctx,contour,strokeStyle="red",lineWidth=2}=options;let pts=contour.data32S;if(pts.length<4)return;ctx.strokeStyle=strokeStyle;ctx.lineWidth=lineWidth;ctx.beginPath();ctx.moveTo(pts[0],pts[1]);for(let i=2;i<pts.length;i+=2){ctx.lineTo(pts[i],pts[i+1])}ctx.closePath();ctx.stroke()}}import{createCanvas}from"./index";import{createWriteStream,existsSync,mkdirSync,readdirSync,unlinkSync}from"fs";import{join}from"path";
|
package/image-analysis.d.ts
CHANGED
|
@@ -21,15 +21,15 @@ export interface CalculateMeanLightnessOptions {
|
|
|
21
21
|
* Lightness is normalized based on the image's own maximum lightness value before averaging.
|
|
22
22
|
*
|
|
23
23
|
* @param options - Configuration options.
|
|
24
|
-
* @returns
|
|
24
|
+
* @returns Mean normalized lightness (0-1).
|
|
25
25
|
* @throws Error if OpenCV operations fail.
|
|
26
26
|
*/
|
|
27
|
-
export declare function calculateMeanNormalizedLabLightness(options: CalculateMeanLightnessOptions):
|
|
27
|
+
export declare function calculateMeanNormalizedLabLightness(options: CalculateMeanLightnessOptions): number;
|
|
28
28
|
/**
|
|
29
29
|
* Calculates the mean pixel value of the image after converting it to grayscale.
|
|
30
30
|
*
|
|
31
31
|
* @param canvas - The source canvas to be processed.
|
|
32
|
-
* @returns
|
|
32
|
+
* @returns Mean grayscale value (typically 0-255).
|
|
33
33
|
* @throws Error if OpenCV operations fail.
|
|
34
34
|
*/
|
|
35
|
-
export declare function calculateMeanGrayscaleValue(canvas: Canvas):
|
|
35
|
+
export declare function calculateMeanGrayscaleValue(canvas: Canvas): number;
|
package/image-analysis.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ImageProcessor,cv}from"./index";export
|
|
1
|
+
import{ImageProcessor,cv}from"./index";export function calculateMeanNormalizedLabLightness(options){const{canvas,dimension}=options;let processor=null;let resized=null;let labImg=null;let channels=null;let L=null;let mask=null;let scalarMat=null;try{processor=new ImageProcessor(canvas);resized=processor.execute("resize",{width:dimension.width,height:dimension.height}).toMat();labImg=new cv.Mat;cv.cvtColor(resized,labImg,cv.COLOR_BGR2Lab);channels=new cv.MatVector;cv.split(labImg,channels);L=channels.get(0);mask=new cv.Mat;let maxLocResult=cv.minMaxLoc(L,mask);let maxPixelValue=maxLocResult.maxVal;if(maxPixelValue===0){return 0}scalarMat=new cv.Mat(L.rows,L.cols,L.type(),new cv.Scalar(maxPixelValue));cv.divide(L,scalarMat,L,1,-1);let meanL=cv.mean(L)[0];return meanL??0}finally{processor?.destroy();labImg?.delete();channels?.delete();L?.delete();mask?.delete();scalarMat?.delete()}}export function calculateMeanGrayscaleValue(canvas){let processor=null;let grayscaleImg=null;try{processor=new ImageProcessor(canvas);grayscaleImg=processor.blur().grayscale().toMat();let mean=cv.mean(grayscaleImg)[0];return mean??0}finally{processor?.destroy()}}
|
package/package.json
CHANGED