rn-opencv-doc-perspective-correction 1.0.4 → 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,20 +41,29 @@ 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);
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;
56
64
  const approx = react_native_fast_opencv_1.OpenCV.createObject(react_native_fast_opencv_1.ObjectType.PointVector);
57
- react_native_fast_opencv_1.OpenCV.invoke('approxPolyDP', contour, approx, 0.02 * peri, true);
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);
58
67
  const approxJS = react_native_fast_opencv_1.OpenCV.toJSValue(approx);
59
68
  if (approxJS && approxJS.array && approxJS.array.length === 4) {
60
69
  maxArea = area;
@@ -62,6 +71,10 @@ class DocumentScanner {
62
71
  }
63
72
  }
64
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);
65
78
  if (largestPoly && largestPoly.length === 4) {
66
79
  return this.sortCorners(largestPoly);
67
80
  }
@@ -69,7 +82,9 @@ class DocumentScanner {
69
82
  }
70
83
  catch (e) {
71
84
  console.error('Lỗi khi dò tìm góc tài liệu (OpenCV):', e);
72
- return undefined;
85
+ if (onLog)
86
+ onLog(`[OpenCV Corner Detection Error]: ${e.message}`);
87
+ throw new Error(`[OpenCV Corner Detection Error]: ${e.message}`);
73
88
  }
74
89
  finally {
75
90
  react_native_fast_opencv_1.OpenCV.clearBuffers();
@@ -78,7 +93,7 @@ class DocumentScanner {
78
93
  /**
79
94
  * Bước 2: Perspective Correction
80
95
  */
81
- static applyPerspectiveCorrection(imageBase64, corners) {
96
+ static applyPerspectiveCorrection(imageBase64, corners, onLog) {
82
97
  let src = null;
83
98
  let dst = null;
84
99
  try {
@@ -108,13 +123,16 @@ class DocumentScanner {
108
123
  react_native_fast_opencv_1.OpenCV.createObject(react_native_fast_opencv_1.ObjectType.Point2f, maxWidth - 1, maxHeight - 1),
109
124
  react_native_fast_opencv_1.OpenCV.createObject(react_native_fast_opencv_1.ObjectType.Point2f, 0, maxHeight - 1)
110
125
  ]);
111
- 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);
112
127
  const size = react_native_fast_opencv_1.OpenCV.createObject(react_native_fast_opencv_1.ObjectType.Size, maxWidth, maxHeight);
113
- 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);
114
130
  return react_native_fast_opencv_1.OpenCV.invoke('toBase64', dst);
115
131
  }
116
132
  catch (e) {
117
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}`);
118
136
  return undefined;
119
137
  }
120
138
  finally {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rn-opencv-doc-perspective-correction",
3
- "version": "1.0.4",
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,25 +51,36 @@ 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);
78
+ if (area > maxArea && area > 10000) {
79
+ const periObj = OpenCV.invoke('arcLength', contour, true);
80
+ const peri = periObj ? periObj.value : 0;
71
81
  const approx = OpenCV.createObject(ObjectType.PointVector);
72
- OpenCV.invoke('approxPolyDP', contour, approx, 0.02 * peri, true);
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
85
  const approxJS = OpenCV.toJSValue(approx);
75
86
  if (approxJS && approxJS.array && approxJS.array.length === 4) {
@@ -78,14 +89,18 @@ export class DocumentScanner {
78
89
  }
79
90
  }
80
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);
81
95
 
82
96
  if (largestPoly && largestPoly.length === 4) {
83
97
  return this.sortCorners(largestPoly);
84
98
  }
85
99
  return undefined;
86
- } catch (e) {
100
+ } catch (e: any) {
87
101
  console.error('Lỗi khi dò tìm góc tài liệu (OpenCV):', e);
88
- return undefined;
102
+ if (onLog) onLog(`[OpenCV Corner Detection Error]: ${e.message}`);
103
+ throw new Error(`[OpenCV Corner Detection Error]: ${e.message}`);
89
104
  } finally {
90
105
  OpenCV.clearBuffers();
91
106
  }
@@ -94,7 +109,7 @@ export class DocumentScanner {
94
109
  /**
95
110
  * Bước 2: Perspective Correction
96
111
  */
97
- public static applyPerspectiveCorrection(imageBase64: string, corners: Point[]): string | undefined {
112
+ public static applyPerspectiveCorrection(imageBase64: string, corners: Point[], onLog?: (msg: string) => void): string | undefined {
98
113
  let src: OpenCVMat | null = null;
99
114
  let dst: OpenCVMat | null = null;
100
115
 
@@ -134,14 +149,17 @@ export class DocumentScanner {
134
149
  ]
135
150
  );
136
151
 
137
- const perspectiveMatrix = OpenCV.invoke('getPerspectiveTransform', srcPoints, dstPoints);
152
+ const perspectiveMatrix = OpenCV.invoke('getPerspectiveTransform', srcPoints, dstPoints, 0);
138
153
 
139
154
  const size = OpenCV.createObject(ObjectType.Size, maxWidth, maxHeight);
140
- 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);
141
158
 
142
159
  return OpenCV.invoke('toBase64', dst);
143
160
  } catch (e) {
144
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}`);
145
163
  return undefined;
146
164
  } finally {
147
165
  OpenCV.clearBuffers();