rn-opencv-doc-perspective-correction 1.0.3 → 1.0.5

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/dist/index.d.ts CHANGED
@@ -14,9 +14,9 @@ export declare class DocumentScanner {
14
14
  /**
15
15
  * Bước 1: Page Corner Detection (Auto-detect góc tài liệu)
16
16
  */
17
- static detectPageCorners(imageBase64: string): Point[] | undefined;
17
+ static detectPageCorners(imageBase64: string, onLog?: (msg: string) => void): Point[] | undefined;
18
18
  /**
19
19
  * Bước 2: Perspective Correction
20
20
  */
21
- static applyPerspectiveCorrection(imageBase64: string, corners: Point[]): string | undefined;
21
+ static applyPerspectiveCorrection(imageBase64: string, corners: Point[], onLog?: (msg: string) => void): string | undefined;
22
22
  }
package/dist/index.js CHANGED
@@ -26,7 +26,7 @@ class DocumentScanner {
26
26
  /**
27
27
  * Bước 1: Page Corner Detection (Auto-detect góc tài liệu)
28
28
  */
29
- static detectPageCorners(imageBase64) {
29
+ static detectPageCorners(imageBase64, onLog) {
30
30
  let src = null;
31
31
  let gray = null;
32
32
  let blurred = null;
@@ -41,37 +41,40 @@ class DocumentScanner {
41
41
  react_native_fast_opencv_1.OpenCV.invoke('cvtColor', src, gray, react_native_fast_opencv_1.ColorConversionCodes.COLOR_BGR2GRAY);
42
42
  const ksize = react_native_fast_opencv_1.OpenCV.createObject(react_native_fast_opencv_1.ObjectType.Size, 5, 5);
43
43
  react_native_fast_opencv_1.OpenCV.invoke('GaussianBlur', gray, blurred, ksize, 0);
44
- react_native_fast_opencv_1.OpenCV.invoke('Canny', blurred, edges, 75, 200, 3, false);
44
+ react_native_fast_opencv_1.OpenCV.invoke('Canny', blurred, edges, 50, 150);
45
45
  contoursObj = react_native_fast_opencv_1.OpenCV.createObject(react_native_fast_opencv_1.ObjectType.MatVector);
46
46
  hierarchyObj = react_native_fast_opencv_1.OpenCV.createObject(react_native_fast_opencv_1.ObjectType.Mat, 0, 0, react_native_fast_opencv_1.DataTypes.CV_8U);
47
- react_native_fast_opencv_1.OpenCV.invoke('findContours', edges, contoursObj, hierarchyObj, 1, 2);
48
- const contoursSize = react_native_fast_opencv_1.OpenCV.invoke('size', contoursObj) || 0;
47
+ react_native_fast_opencv_1.OpenCV.invoke('findContoursWithHierarchy', edges, contoursObj, hierarchyObj, 1 /* RETR_LIST */, 2 /* CHAIN_APPROX_SIMPLE */);
48
+ const contoursJS = react_native_fast_opencv_1.OpenCV.toJSValue(contoursObj);
49
+ const contoursArray = (contoursJS === null || contoursJS === void 0 ? void 0 : contoursJS.array) || [];
50
+ const contoursSize = contoursArray.length;
49
51
  let maxArea = 0;
50
52
  let largestPoly = undefined;
53
+ let foundContoursCount = 0;
51
54
  for (let i = 0; i < contoursSize; i++) {
52
- const contour = react_native_fast_opencv_1.OpenCV.invoke('get', contoursObj, i);
53
- const area = react_native_fast_opencv_1.OpenCV.invoke('contourArea', contour);
54
- if (area > maxArea) {
55
- const peri = react_native_fast_opencv_1.OpenCV.invoke('arcLength', contour, true);
56
- const approx = react_native_fast_opencv_1.OpenCV.createObject(react_native_fast_opencv_1.ObjectType.Mat, 0, 0, react_native_fast_opencv_1.DataTypes.CV_8U);
57
- react_native_fast_opencv_1.OpenCV.invoke('approxPolyDP', contour, approx, 0.02 * peri, true);
58
- const vertices = react_native_fast_opencv_1.OpenCV.invoke('rows', approx);
59
- if (vertices === 4) {
55
+ const contour = react_native_fast_opencv_1.OpenCV.copyObjectFromVector(contoursObj, i);
56
+ const areaObj = react_native_fast_opencv_1.OpenCV.invoke('contourArea', contour);
57
+ const area = areaObj ? areaObj.value : 0;
58
+ if (area > 10000) { // Lọc bỏ các contour quá nhỏ
59
+ foundContoursCount++;
60
+ }
61
+ if (area > maxArea && area > 10000) {
62
+ const periObj = react_native_fast_opencv_1.OpenCV.invoke('arcLength', contour, true);
63
+ const peri = periObj ? periObj.value : 0;
64
+ const approx = react_native_fast_opencv_1.OpenCV.createObject(react_native_fast_opencv_1.ObjectType.PointVector);
65
+ // Tăng eplison lên một chút để cho phép viền mấp mô hơn
66
+ react_native_fast_opencv_1.OpenCV.invoke('approxPolyDP', contour, approx, 0.04 * peri, true);
67
+ const approxJS = react_native_fast_opencv_1.OpenCV.toJSValue(approx);
68
+ if (approxJS && approxJS.array && approxJS.array.length === 4) {
60
69
  maxArea = area;
61
- const points = [];
62
- for (let v = 0; v < 4; v++) {
63
- try {
64
- const pt = react_native_fast_opencv_1.OpenCV.invoke('row', approx, v);
65
- if (pt && typeof pt === 'object' && 'x' in pt)
66
- points.push(pt);
67
- }
68
- catch (err) { }
69
- }
70
- if (points.length === 4)
71
- largestPoly = points;
70
+ largestPoly = approxJS.array;
72
71
  }
73
72
  }
74
73
  }
74
+ const logMsg = `[OpenCV] Đã tìm thấy ${contoursSize} contours. Số contour đủ lớn: ${foundContoursCount}`;
75
+ console.log(logMsg);
76
+ if (onLog)
77
+ onLog(logMsg);
75
78
  if (largestPoly && largestPoly.length === 4) {
76
79
  return this.sortCorners(largestPoly);
77
80
  }
@@ -79,7 +82,9 @@ class DocumentScanner {
79
82
  }
80
83
  catch (e) {
81
84
  console.error('Lỗi khi dò tìm góc tài liệu (OpenCV):', e);
82
- return undefined;
85
+ if (onLog)
86
+ onLog(`[OpenCV Corner Detection Error]: ${e.message}`);
87
+ throw new Error(`[OpenCV Corner Detection Error]: ${e.message}`);
83
88
  }
84
89
  finally {
85
90
  react_native_fast_opencv_1.OpenCV.clearBuffers();
@@ -88,7 +93,7 @@ class DocumentScanner {
88
93
  /**
89
94
  * Bước 2: Perspective Correction
90
95
  */
91
- static applyPerspectiveCorrection(imageBase64, corners) {
96
+ static applyPerspectiveCorrection(imageBase64, corners, onLog) {
92
97
  let src = null;
93
98
  let dst = null;
94
99
  try {
@@ -118,13 +123,16 @@ class DocumentScanner {
118
123
  react_native_fast_opencv_1.OpenCV.createObject(react_native_fast_opencv_1.ObjectType.Point2f, maxWidth - 1, maxHeight - 1),
119
124
  react_native_fast_opencv_1.OpenCV.createObject(react_native_fast_opencv_1.ObjectType.Point2f, 0, maxHeight - 1)
120
125
  ]);
121
- const perspectiveMatrix = react_native_fast_opencv_1.OpenCV.invoke('getPerspectiveTransform', srcPoints, dstPoints);
126
+ const perspectiveMatrix = react_native_fast_opencv_1.OpenCV.invoke('getPerspectiveTransform', srcPoints, dstPoints, 0);
122
127
  const size = react_native_fast_opencv_1.OpenCV.createObject(react_native_fast_opencv_1.ObjectType.Size, maxWidth, maxHeight);
123
- react_native_fast_opencv_1.OpenCV.invoke('warpPerspective', src, dst, perspectiveMatrix, size);
128
+ const borderValue = react_native_fast_opencv_1.OpenCV.createObject(react_native_fast_opencv_1.ObjectType.Scalar, 0);
129
+ react_native_fast_opencv_1.OpenCV.invoke('warpPerspective', src, dst, perspectiveMatrix, size, 1 /* INTER_LINEAR */, 0 /* BORDER_CONSTANT */, borderValue);
124
130
  return react_native_fast_opencv_1.OpenCV.invoke('toBase64', dst);
125
131
  }
126
132
  catch (e) {
127
133
  console.error('Lỗi khi bóp phối cảnh tài liệu (OpenCV):', e);
134
+ if (onLog)
135
+ onLog(`[OpenCV Perspective Correction Error]: ${e.message || e}`);
128
136
  return undefined;
129
137
  }
130
138
  finally {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rn-opencv-doc-perspective-correction",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "A React Native library for document corner detection and perspective correction using react-native-fast-opencv",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/index.ts CHANGED
@@ -32,7 +32,7 @@ export class DocumentScanner {
32
32
  /**
33
33
  * Bước 1: Page Corner Detection (Auto-detect góc tài liệu)
34
34
  */
35
- public static detectPageCorners(imageBase64: string): Point[] | undefined {
35
+ public static detectPageCorners(imageBase64: string, onLog?: (msg: string) => void): Point[] | undefined {
36
36
  let src: OpenCVMat | null = null;
37
37
  let gray: OpenCVMat | null = null;
38
38
  let blurred: OpenCVMat | null = null;
@@ -51,49 +51,56 @@ export class DocumentScanner {
51
51
  const ksize = OpenCV.createObject(ObjectType.Size, 5, 5);
52
52
  OpenCV.invoke('GaussianBlur', gray, blurred, ksize, 0);
53
53
 
54
- OpenCV.invoke('Canny', blurred, edges, 75, 200, 3, false);
54
+ OpenCV.invoke('Canny', blurred, edges, 50, 150);
55
55
 
56
56
  contoursObj = OpenCV.createObject(ObjectType.MatVector);
57
57
  hierarchyObj = OpenCV.createObject(ObjectType.Mat, 0, 0, DataTypes.CV_8U);
58
58
 
59
- OpenCV.invoke('findContours', edges, contoursObj, hierarchyObj, 1, 2);
59
+ OpenCV.invoke('findContoursWithHierarchy', edges, contoursObj, hierarchyObj, 1 /* RETR_LIST */, 2 /* CHAIN_APPROX_SIMPLE */);
60
+
61
+ const contoursJS = OpenCV.toJSValue(contoursObj);
62
+ const contoursArray = contoursJS?.array || [];
63
+ const contoursSize = contoursArray.length;
60
64
 
61
- const contoursSize = OpenCV.invoke('size', contoursObj) || 0;
62
65
  let maxArea = 0;
63
66
  let largestPoly: Point[] | undefined = undefined;
67
+ let foundContoursCount = 0;
64
68
 
65
69
  for (let i = 0; i < contoursSize; i++) {
66
- const contour = OpenCV.invoke('get', contoursObj, i);
67
- const area = OpenCV.invoke('contourArea', contour);
70
+ const contour = OpenCV.copyObjectFromVector(contoursObj, i);
71
+ const areaObj = OpenCV.invoke('contourArea', contour);
72
+ const area = areaObj ? areaObj.value : 0;
73
+
74
+ if (area > 10000) { // Lọc bỏ các contour quá nhỏ
75
+ foundContoursCount++;
76
+ }
68
77
 
69
- if (area > maxArea) {
70
- const peri = OpenCV.invoke('arcLength', contour, true);
71
- const approx = OpenCV.createObject(ObjectType.Mat, 0, 0, DataTypes.CV_8U);
72
- OpenCV.invoke('approxPolyDP', contour, approx, 0.02 * peri, true);
78
+ if (area > maxArea && area > 10000) {
79
+ const periObj = OpenCV.invoke('arcLength', contour, true);
80
+ const peri = periObj ? periObj.value : 0;
81
+ const approx = OpenCV.createObject(ObjectType.PointVector);
82
+ // Tăng eplison lên một chút để cho phép viền mấp mô hơn
83
+ OpenCV.invoke('approxPolyDP', contour, approx, 0.04 * peri, true);
73
84
 
74
- const vertices = OpenCV.invoke('rows', approx);
75
- if (vertices === 4) {
85
+ const approxJS = OpenCV.toJSValue(approx);
86
+ if (approxJS && approxJS.array && approxJS.array.length === 4) {
76
87
  maxArea = area;
77
-
78
- const points: Point[] = [];
79
- for (let v = 0; v < 4; v++) {
80
- try {
81
- const pt = OpenCV.invoke('row', approx, v);
82
- if (pt && typeof pt === 'object' && 'x' in pt) points.push(pt as Point);
83
- } catch (err) { }
84
- }
85
- if (points.length === 4) largestPoly = points;
88
+ largestPoly = approxJS.array as Point[];
86
89
  }
87
90
  }
88
91
  }
92
+ const logMsg = `[OpenCV] Đã tìm thấy ${contoursSize} contours. Số contour đủ lớn: ${foundContoursCount}`;
93
+ console.log(logMsg);
94
+ if (onLog) onLog(logMsg);
89
95
 
90
96
  if (largestPoly && largestPoly.length === 4) {
91
97
  return this.sortCorners(largestPoly);
92
98
  }
93
99
  return undefined;
94
- } catch (e) {
100
+ } catch (e: any) {
95
101
  console.error('Lỗi khi dò tìm góc tài liệu (OpenCV):', e);
96
- return undefined;
102
+ if (onLog) onLog(`[OpenCV Corner Detection Error]: ${e.message}`);
103
+ throw new Error(`[OpenCV Corner Detection Error]: ${e.message}`);
97
104
  } finally {
98
105
  OpenCV.clearBuffers();
99
106
  }
@@ -102,7 +109,7 @@ export class DocumentScanner {
102
109
  /**
103
110
  * Bước 2: Perspective Correction
104
111
  */
105
- public static applyPerspectiveCorrection(imageBase64: string, corners: Point[]): string | undefined {
112
+ public static applyPerspectiveCorrection(imageBase64: string, corners: Point[], onLog?: (msg: string) => void): string | undefined {
106
113
  let src: OpenCVMat | null = null;
107
114
  let dst: OpenCVMat | null = null;
108
115
 
@@ -127,29 +134,32 @@ export class DocumentScanner {
127
134
 
128
135
  const srcPoints = OpenCV.createObject(ObjectType.Point2fVector,
129
136
  [
130
- OpenCV.createObject(ObjectType.Point2f, tl.x, tl.y) as any,
131
- OpenCV.createObject(ObjectType.Point2f, tr.x, tr.y) as any,
132
- OpenCV.createObject(ObjectType.Point2f, br.x, br.y) as any,
133
- OpenCV.createObject(ObjectType.Point2f, bl.x, bl.y) as any
137
+ OpenCV.createObject(ObjectType.Point2f, tl.x, tl.y),
138
+ OpenCV.createObject(ObjectType.Point2f, tr.x, tr.y),
139
+ OpenCV.createObject(ObjectType.Point2f, br.x, br.y),
140
+ OpenCV.createObject(ObjectType.Point2f, bl.x, bl.y)
134
141
  ]
135
142
  );
136
143
  const dstPoints = OpenCV.createObject(ObjectType.Point2fVector,
137
144
  [
138
- OpenCV.createObject(ObjectType.Point2f, 0, 0) as any,
139
- OpenCV.createObject(ObjectType.Point2f, maxWidth - 1, 0) as any,
140
- OpenCV.createObject(ObjectType.Point2f, maxWidth - 1, maxHeight - 1) as any,
141
- OpenCV.createObject(ObjectType.Point2f, 0, maxHeight - 1) as any
145
+ OpenCV.createObject(ObjectType.Point2f, 0, 0),
146
+ OpenCV.createObject(ObjectType.Point2f, maxWidth - 1, 0),
147
+ OpenCV.createObject(ObjectType.Point2f, maxWidth - 1, maxHeight - 1),
148
+ OpenCV.createObject(ObjectType.Point2f, 0, maxHeight - 1)
142
149
  ]
143
150
  );
144
151
 
145
- const perspectiveMatrix = OpenCV.invoke('getPerspectiveTransform', srcPoints, dstPoints);
152
+ const perspectiveMatrix = OpenCV.invoke('getPerspectiveTransform', srcPoints, dstPoints, 0);
146
153
 
147
154
  const size = OpenCV.createObject(ObjectType.Size, maxWidth, maxHeight);
148
- OpenCV.invoke('warpPerspective', src, dst, perspectiveMatrix, size);
155
+ const borderValue = OpenCV.createObject(ObjectType.Scalar, 0);
156
+
157
+ OpenCV.invoke('warpPerspective', src, dst, perspectiveMatrix, size, 1 /* INTER_LINEAR */, 0 /* BORDER_CONSTANT */, borderValue);
149
158
 
150
159
  return OpenCV.invoke('toBase64', dst);
151
160
  } catch (e) {
152
161
  console.error('Lỗi khi bóp phối cảnh tài liệu (OpenCV):', e);
162
+ if (onLog) onLog(`[OpenCV Perspective Correction Error]: ${(e as Error).message || e}`);
153
163
  return undefined;
154
164
  } finally {
155
165
  OpenCV.clearBuffers();