rn-opencv-doc-perspective-correction 1.0.13 → 1.0.14

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.
Files changed (3) hide show
  1. package/dist/index.js +34 -10
  2. package/package.json +1 -1
  3. package/src/index.ts +30 -10
package/dist/index.js CHANGED
@@ -35,15 +35,35 @@ class DocumentScanner {
35
35
  const ksize = react_native_fast_opencv_1.OpenCV.createObject(react_native_fast_opencv_1.ObjectType.Size, 5, 5);
36
36
  react_native_fast_opencv_1.OpenCV.invoke('GaussianBlur', gray, blurred, ksize, 0);
37
37
  // BƯỚC 3: Đo sáng môi trường để thiết lập Canny thông minh (Auto-Canny)
38
- // Lợi dụng Otsu Threshold để ra "Ngưỡng sáng sinh thái" của bức ảnh đó
39
- const dummyEdges = react_native_fast_opencv_1.OpenCV.createObject(react_native_fast_opencv_1.ObjectType.Mat, 0, 0, react_native_fast_opencv_1.DataTypes.CV_8U);
40
- const otsuResult = react_native_fast_opencv_1.OpenCV.invoke('threshold', blurred, dummyEdges, 0, 255, 8 /* THRESH_BINARY | THRESH_OTSU */);
41
- // Xử cẩn thận kiểu dữ liệu trả về từ Bridge (Primitive vs Object)
42
- let highThresh = 200;
43
- if (otsuResult !== undefined && otsuResult !== null) {
44
- highThresh = typeof otsuResult === 'number' ? otsuResult : (otsuResult.value || 200);
45
- }
46
- let lowThresh = highThresh * 0.5;
38
+ // invoke('threshold',...) bị lỗi C++ JSI Argument Index(3) out of bounds trên thư viện này,
39
+ // ta chuyển sang dùng meanStdDev để tính Median Pixel Value.
40
+ const meanMat = react_native_fast_opencv_1.OpenCV.createObject(react_native_fast_opencv_1.ObjectType.Mat, 0, 0, react_native_fast_opencv_1.DataTypes.CV_64F);
41
+ const stdMat = react_native_fast_opencv_1.OpenCV.createObject(react_native_fast_opencv_1.ObjectType.Mat, 0, 0, react_native_fast_opencv_1.DataTypes.CV_64F);
42
+ react_native_fast_opencv_1.OpenCV.invoke('meanStdDev', blurred, meanMat, stdMat);
43
+ const getFirstVal = (jsObj) => {
44
+ if (!jsObj)
45
+ return 128;
46
+ if (typeof jsObj === 'number')
47
+ return jsObj;
48
+ if (Array.isArray(jsObj))
49
+ return jsObj[0] || 128;
50
+ if (jsObj.array && Array.isArray(jsObj.array))
51
+ return jsObj.array[0] || 128;
52
+ if (jsObj.data && Array.isArray(jsObj.data))
53
+ return jsObj.data[0] || 128;
54
+ if (jsObj.value !== undefined) {
55
+ if (typeof jsObj.value === 'number')
56
+ return jsObj.value;
57
+ if (Array.isArray(jsObj.value))
58
+ return jsObj.value[0] || 128;
59
+ }
60
+ return 128;
61
+ };
62
+ const meanVal = getFirstVal(react_native_fast_opencv_1.OpenCV.toJSValue(meanMat));
63
+ // Công thức Zero-Parameter Canny Edge Detection (áp dụng Sigma = 0.33)
64
+ const sigma = 0.33;
65
+ let lowThresh = Math.max(0, (1.0 - sigma) * meanVal);
66
+ let highThresh = Math.min(255, (1.0 + sigma) * meanVal);
47
67
  // BƯỚC 4: Dò tìm cạnh viền Canny với cảm biến tự động
48
68
  react_native_fast_opencv_1.OpenCV.invoke('Canny', blurred, edges, lowThresh, highThresh);
49
69
  // BƯỚC 5: Liền sẹo nét viền (Morphology Dilate)
@@ -51,7 +71,11 @@ class DocumentScanner {
51
71
  const dilatedEdges = react_native_fast_opencv_1.OpenCV.createObject(react_native_fast_opencv_1.ObjectType.Mat, 0, 0, react_native_fast_opencv_1.DataTypes.CV_8U);
52
72
  try {
53
73
  const emptyKernel = react_native_fast_opencv_1.OpenCV.createObject(react_native_fast_opencv_1.ObjectType.Mat, 0, 0, react_native_fast_opencv_1.DataTypes.CV_8U);
54
- react_native_fast_opencv_1.OpenCV.invoke('dilate', edges, dilatedEdges, emptyKernel);
74
+ const anchor = react_native_fast_opencv_1.OpenCV.createObject(react_native_fast_opencv_1.ObjectType.Point, -1, -1);
75
+ // Tạo gía trị biên ảo (morphology filter defaults) để tránh lỗi Index out of bounds
76
+ const borderValue = react_native_fast_opencv_1.OpenCV.invoke('morphologyDefaultBorderValue');
77
+ // dilate yêu cầu đúng 8 tham số (gồm tên hàm): name, src, dst, kernel, anchor, iterations, borderType, borderValue
78
+ react_native_fast_opencv_1.OpenCV.invoke('dilate', edges, dilatedEdges, emptyKernel, anchor, 1, 0 /* BORDER_CONSTANT */, borderValue);
55
79
  }
56
80
  catch (dilateErr) {
57
81
  react_native_fast_opencv_1.OpenCV.invoke('copyTo', edges, dilatedEdges); // Fallback an toàn nếu dilate tàng hình fail
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rn-opencv-doc-perspective-correction",
3
- "version": "1.0.13",
3
+ "version": "1.0.14",
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
@@ -52,16 +52,31 @@ export class DocumentScanner {
52
52
  OpenCV.invoke('GaussianBlur', gray, blurred, ksize, 0);
53
53
 
54
54
  // BƯỚC 3: Đo sáng môi trường để thiết lập Canny thông minh (Auto-Canny)
55
- // Lợi dụng Otsu Threshold để ra "Ngưỡng sáng sinh thái" của bức ảnh đó
56
- const dummyEdges = OpenCV.createObject(ObjectType.Mat, 0, 0, DataTypes.CV_8U);
57
- const otsuResult = OpenCV.invoke('threshold', blurred, dummyEdges, 0, 255, 8 /* THRESH_BINARY | THRESH_OTSU */);
55
+ // invoke('threshold',...) bị lỗi C++ JSI Argument Index(3) out of bounds trên thư viện này,
56
+ // ta chuyển sang dùng meanStdDev để tính Median Pixel Value.
57
+ const meanMat = OpenCV.createObject(ObjectType.Mat, 0, 0, DataTypes.CV_64F);
58
+ const stdMat = OpenCV.createObject(ObjectType.Mat, 0, 0, DataTypes.CV_64F);
59
+ OpenCV.invoke('meanStdDev', blurred, meanMat, stdMat);
60
+
61
+ const getFirstVal = (jsObj: any): number => {
62
+ if (!jsObj) return 128;
63
+ if (typeof jsObj === 'number') return jsObj;
64
+ if (Array.isArray(jsObj)) return jsObj[0] || 128;
65
+ if (jsObj.array && Array.isArray(jsObj.array)) return jsObj.array[0] || 128;
66
+ if (jsObj.data && Array.isArray(jsObj.data)) return jsObj.data[0] || 128;
67
+ if (jsObj.value !== undefined) {
68
+ if (typeof jsObj.value === 'number') return jsObj.value;
69
+ if (Array.isArray(jsObj.value)) return jsObj.value[0] || 128;
70
+ }
71
+ return 128;
72
+ };
73
+
74
+ const meanVal = getFirstVal(OpenCV.toJSValue(meanMat));
58
75
 
59
- // Xử cẩn thận kiểu dữ liệu trả về từ Bridge (Primitive vs Object)
60
- let highThresh = 200;
61
- if (otsuResult !== undefined && otsuResult !== null) {
62
- highThresh = typeof otsuResult === 'number' ? otsuResult : (otsuResult.value || 200);
63
- }
64
- let lowThresh = highThresh * 0.5;
76
+ // Công thức Zero-Parameter Canny Edge Detection (áp dụng Sigma = 0.33)
77
+ const sigma = 0.33;
78
+ let lowThresh = Math.max(0, (1.0 - sigma) * meanVal);
79
+ let highThresh = Math.min(255, (1.0 + sigma) * meanVal);
65
80
 
66
81
  // BƯỚC 4: Dò tìm cạnh viền Canny với cảm biến tự động
67
82
  OpenCV.invoke('Canny', blurred, edges, lowThresh, highThresh);
@@ -71,7 +86,12 @@ export class DocumentScanner {
71
86
  const dilatedEdges = OpenCV.createObject(ObjectType.Mat, 0, 0, DataTypes.CV_8U);
72
87
  try {
73
88
  const emptyKernel = OpenCV.createObject(ObjectType.Mat, 0, 0, DataTypes.CV_8U);
74
- OpenCV.invoke('dilate', edges, dilatedEdges, emptyKernel);
89
+ const anchor = OpenCV.createObject(ObjectType.Point, -1, -1);
90
+ // Tạo gía trị biên ảo (morphology filter defaults) để tránh lỗi Index out of bounds
91
+ const borderValue = OpenCV.invoke('morphologyDefaultBorderValue');
92
+
93
+ // dilate yêu cầu đúng 8 tham số (gồm tên hàm): name, src, dst, kernel, anchor, iterations, borderType, borderValue
94
+ OpenCV.invoke('dilate', edges, dilatedEdges, emptyKernel, anchor, 1, 0 /* BORDER_CONSTANT */, borderValue);
75
95
  } catch (dilateErr) {
76
96
  OpenCV.invoke('copyTo', edges, dilatedEdges); // Fallback an toàn nếu dilate tàng hình fail
77
97
  }