react-native-rectangle-doc-scanner 0.6.0 → 0.7.0
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/DocScanner.js +22 -0
- package/package.json +1 -1
- package/src/DocScanner.tsx +23 -0
package/dist/DocScanner.js
CHANGED
|
@@ -87,6 +87,11 @@ const DocScanner = ({ onCapture, overlayColor = '#e7a649', autoCapture = true, m
|
|
|
87
87
|
const message = error instanceof Error ? error.message : `${error}`;
|
|
88
88
|
console.warn(`[DocScanner] frame error at ${step}: ${message}`);
|
|
89
89
|
}, []);
|
|
90
|
+
const reportStage = (0, react_native_worklets_core_1.useRunOnJS)((stage) => {
|
|
91
|
+
if (__DEV__) {
|
|
92
|
+
console.log('[DocScanner] stage', stage);
|
|
93
|
+
}
|
|
94
|
+
}, []);
|
|
90
95
|
const frameProcessor = (0, react_native_vision_camera_1.useFrameProcessor)((frame) => {
|
|
91
96
|
'worklet';
|
|
92
97
|
let step = 'start';
|
|
@@ -95,53 +100,68 @@ const DocScanner = ({ onCapture, overlayColor = '#e7a649', autoCapture = true, m
|
|
|
95
100
|
const width = Math.floor(frame.width * ratio);
|
|
96
101
|
const height = Math.floor(frame.height * ratio);
|
|
97
102
|
step = 'resize';
|
|
103
|
+
reportStage(step);
|
|
98
104
|
const resized = resize(frame, {
|
|
99
105
|
dataType: 'uint8',
|
|
100
106
|
pixelFormat: 'bgr',
|
|
101
107
|
scale: { width: width, height: height },
|
|
102
108
|
});
|
|
103
109
|
step = 'frameBufferToMat';
|
|
110
|
+
reportStage(step);
|
|
104
111
|
const mat = react_native_fast_opencv_1.OpenCV.frameBufferToMat(height, width, 3, resized);
|
|
105
112
|
step = 'cvtColor';
|
|
113
|
+
reportStage(step);
|
|
106
114
|
react_native_fast_opencv_1.OpenCV.invoke('cvtColor', mat, mat, react_native_fast_opencv_1.ColorConversionCodes.COLOR_BGR2GRAY);
|
|
107
115
|
const morphologyKernel = react_native_fast_opencv_1.OpenCV.createObject(react_native_fast_opencv_1.ObjectType.Size, 5, 5);
|
|
108
116
|
step = 'getStructuringElement';
|
|
117
|
+
reportStage(step);
|
|
109
118
|
const element = react_native_fast_opencv_1.OpenCV.invoke('getStructuringElement', react_native_fast_opencv_1.MorphShapes.MORPH_RECT, morphologyKernel);
|
|
110
119
|
step = 'morphologyEx';
|
|
120
|
+
reportStage(step);
|
|
111
121
|
react_native_fast_opencv_1.OpenCV.invoke('morphologyEx', mat, mat, react_native_fast_opencv_1.MorphTypes.MORPH_OPEN, element);
|
|
112
122
|
const gaussianKernel = react_native_fast_opencv_1.OpenCV.createObject(react_native_fast_opencv_1.ObjectType.Size, 5, 5);
|
|
113
123
|
step = 'GaussianBlur';
|
|
124
|
+
reportStage(step);
|
|
114
125
|
react_native_fast_opencv_1.OpenCV.invoke('GaussianBlur', mat, mat, gaussianKernel, 0);
|
|
115
126
|
step = 'Canny';
|
|
127
|
+
reportStage(step);
|
|
116
128
|
react_native_fast_opencv_1.OpenCV.invoke('Canny', mat, mat, 75, 100);
|
|
117
129
|
step = 'createContours';
|
|
130
|
+
reportStage(step);
|
|
118
131
|
const contours = react_native_fast_opencv_1.OpenCV.createObject(react_native_fast_opencv_1.ObjectType.PointVectorOfVectors);
|
|
119
132
|
react_native_fast_opencv_1.OpenCV.invoke('findContours', mat, contours, react_native_fast_opencv_1.RetrievalModes.RETR_LIST, react_native_fast_opencv_1.ContourApproximationModes.CHAIN_APPROX_SIMPLE);
|
|
120
133
|
let best = null;
|
|
121
134
|
let maxArea = 0;
|
|
122
135
|
step = 'toJSValue';
|
|
136
|
+
reportStage(step);
|
|
123
137
|
const contourVector = react_native_fast_opencv_1.OpenCV.toJSValue(contours);
|
|
124
138
|
const contourArray = Array.isArray(contourVector?.array) ? contourVector.array : [];
|
|
125
139
|
for (let i = 0; i < contourArray.length; i += 1) {
|
|
126
140
|
step = `contour_${i}_copy`;
|
|
141
|
+
reportStage(step);
|
|
127
142
|
const contour = react_native_fast_opencv_1.OpenCV.copyObjectFromVector(contours, i);
|
|
128
143
|
step = `contour_${i}_area`;
|
|
144
|
+
reportStage(step);
|
|
129
145
|
const { value: area } = react_native_fast_opencv_1.OpenCV.invoke('contourArea', contour, false);
|
|
130
146
|
if (area < width * height * 0.1) {
|
|
131
147
|
continue;
|
|
132
148
|
}
|
|
133
149
|
step = `contour_${i}_arcLength`;
|
|
150
|
+
reportStage(step);
|
|
134
151
|
const { value: perimeter } = react_native_fast_opencv_1.OpenCV.invoke('arcLength', contour, true);
|
|
135
152
|
const approx = react_native_fast_opencv_1.OpenCV.createObject(react_native_fast_opencv_1.ObjectType.PointVector);
|
|
136
153
|
step = `contour_${i}_approxPolyDP`;
|
|
154
|
+
reportStage(step);
|
|
137
155
|
react_native_fast_opencv_1.OpenCV.invoke('approxPolyDP', contour, approx, 0.02 * perimeter, true);
|
|
138
156
|
step = `contour_${i}_toJS`;
|
|
157
|
+
reportStage(step);
|
|
139
158
|
const approxValue = react_native_fast_opencv_1.OpenCV.toJSValue(approx);
|
|
140
159
|
const approxArray = Array.isArray(approxValue?.array) ? approxValue.array : [];
|
|
141
160
|
if (approxArray.length !== 4) {
|
|
142
161
|
continue;
|
|
143
162
|
}
|
|
144
163
|
step = `contour_${i}_convex`;
|
|
164
|
+
reportStage(step);
|
|
145
165
|
const points = approxArray.map((pt) => ({
|
|
146
166
|
x: pt.x / ratio,
|
|
147
167
|
y: pt.y / ratio,
|
|
@@ -155,8 +175,10 @@ const DocScanner = ({ onCapture, overlayColor = '#e7a649', autoCapture = true, m
|
|
|
155
175
|
}
|
|
156
176
|
}
|
|
157
177
|
step = 'clearBuffers';
|
|
178
|
+
reportStage(step);
|
|
158
179
|
react_native_fast_opencv_1.OpenCV.clearBuffers();
|
|
159
180
|
step = 'updateQuad';
|
|
181
|
+
reportStage(step);
|
|
160
182
|
updateQuad(best);
|
|
161
183
|
}
|
|
162
184
|
catch (error) {
|
package/package.json
CHANGED
package/src/DocScanner.tsx
CHANGED
|
@@ -94,6 +94,12 @@ export const DocScanner: React.FC<Props> = ({
|
|
|
94
94
|
console.warn(`[DocScanner] frame error at ${step}: ${message}`);
|
|
95
95
|
}, []);
|
|
96
96
|
|
|
97
|
+
const reportStage = useRunOnJS((stage: string) => {
|
|
98
|
+
if (__DEV__) {
|
|
99
|
+
console.log('[DocScanner] stage', stage);
|
|
100
|
+
}
|
|
101
|
+
}, []);
|
|
102
|
+
|
|
97
103
|
const frameProcessor = useFrameProcessor((frame) => {
|
|
98
104
|
'worklet';
|
|
99
105
|
|
|
@@ -104,6 +110,7 @@ export const DocScanner: React.FC<Props> = ({
|
|
|
104
110
|
const width = Math.floor(frame.width * ratio);
|
|
105
111
|
const height = Math.floor(frame.height * ratio);
|
|
106
112
|
step = 'resize';
|
|
113
|
+
reportStage(step);
|
|
107
114
|
const resized = resize(frame, {
|
|
108
115
|
dataType: 'uint8',
|
|
109
116
|
pixelFormat: 'bgr',
|
|
@@ -111,24 +118,31 @@ export const DocScanner: React.FC<Props> = ({
|
|
|
111
118
|
});
|
|
112
119
|
|
|
113
120
|
step = 'frameBufferToMat';
|
|
121
|
+
reportStage(step);
|
|
114
122
|
const mat = OpenCV.frameBufferToMat(height, width, 3, resized);
|
|
115
123
|
|
|
116
124
|
step = 'cvtColor';
|
|
125
|
+
reportStage(step);
|
|
117
126
|
OpenCV.invoke('cvtColor', mat, mat, ColorConversionCodes.COLOR_BGR2GRAY);
|
|
118
127
|
|
|
119
128
|
const morphologyKernel = OpenCV.createObject(ObjectType.Size, 5, 5);
|
|
120
129
|
step = 'getStructuringElement';
|
|
130
|
+
reportStage(step);
|
|
121
131
|
const element = OpenCV.invoke('getStructuringElement', MorphShapes.MORPH_RECT, morphologyKernel);
|
|
122
132
|
step = 'morphologyEx';
|
|
133
|
+
reportStage(step);
|
|
123
134
|
OpenCV.invoke('morphologyEx', mat, mat, MorphTypes.MORPH_OPEN, element);
|
|
124
135
|
|
|
125
136
|
const gaussianKernel = OpenCV.createObject(ObjectType.Size, 5, 5);
|
|
126
137
|
step = 'GaussianBlur';
|
|
138
|
+
reportStage(step);
|
|
127
139
|
OpenCV.invoke('GaussianBlur', mat, mat, gaussianKernel, 0);
|
|
128
140
|
step = 'Canny';
|
|
141
|
+
reportStage(step);
|
|
129
142
|
OpenCV.invoke('Canny', mat, mat, 75, 100);
|
|
130
143
|
|
|
131
144
|
step = 'createContours';
|
|
145
|
+
reportStage(step);
|
|
132
146
|
const contours = OpenCV.createObject(ObjectType.PointVectorOfVectors);
|
|
133
147
|
OpenCV.invoke('findContours', mat, contours, RetrievalModes.RETR_LIST, ContourApproximationModes.CHAIN_APPROX_SIMPLE);
|
|
134
148
|
|
|
@@ -136,14 +150,17 @@ export const DocScanner: React.FC<Props> = ({
|
|
|
136
150
|
let maxArea = 0;
|
|
137
151
|
|
|
138
152
|
step = 'toJSValue';
|
|
153
|
+
reportStage(step);
|
|
139
154
|
const contourVector = OpenCV.toJSValue(contours);
|
|
140
155
|
const contourArray = Array.isArray(contourVector?.array) ? contourVector.array : [];
|
|
141
156
|
|
|
142
157
|
for (let i = 0; i < contourArray.length; i += 1) {
|
|
143
158
|
step = `contour_${i}_copy`;
|
|
159
|
+
reportStage(step);
|
|
144
160
|
const contour = OpenCV.copyObjectFromVector(contours, i);
|
|
145
161
|
|
|
146
162
|
step = `contour_${i}_area`;
|
|
163
|
+
reportStage(step);
|
|
147
164
|
const { value: area } = OpenCV.invoke('contourArea', contour, false);
|
|
148
165
|
|
|
149
166
|
if (area < width * height * 0.1) {
|
|
@@ -151,13 +168,16 @@ export const DocScanner: React.FC<Props> = ({
|
|
|
151
168
|
}
|
|
152
169
|
|
|
153
170
|
step = `contour_${i}_arcLength`;
|
|
171
|
+
reportStage(step);
|
|
154
172
|
const { value: perimeter } = OpenCV.invoke('arcLength', contour, true);
|
|
155
173
|
const approx = OpenCV.createObject(ObjectType.PointVector);
|
|
156
174
|
|
|
157
175
|
step = `contour_${i}_approxPolyDP`;
|
|
176
|
+
reportStage(step);
|
|
158
177
|
OpenCV.invoke('approxPolyDP', contour, approx, 0.02 * perimeter, true);
|
|
159
178
|
|
|
160
179
|
step = `contour_${i}_toJS`;
|
|
180
|
+
reportStage(step);
|
|
161
181
|
const approxValue = OpenCV.toJSValue(approx);
|
|
162
182
|
const approxArray = Array.isArray(approxValue?.array) ? approxValue.array : [];
|
|
163
183
|
|
|
@@ -166,6 +186,7 @@ export const DocScanner: React.FC<Props> = ({
|
|
|
166
186
|
}
|
|
167
187
|
|
|
168
188
|
step = `contour_${i}_convex`;
|
|
189
|
+
reportStage(step);
|
|
169
190
|
const points: Point[] = approxArray.map((pt: { x: number; y: number }) => ({
|
|
170
191
|
x: pt.x / ratio,
|
|
171
192
|
y: pt.y / ratio,
|
|
@@ -182,8 +203,10 @@ export const DocScanner: React.FC<Props> = ({
|
|
|
182
203
|
}
|
|
183
204
|
|
|
184
205
|
step = 'clearBuffers';
|
|
206
|
+
reportStage(step);
|
|
185
207
|
OpenCV.clearBuffers();
|
|
186
208
|
step = 'updateQuad';
|
|
209
|
+
reportStage(step);
|
|
187
210
|
updateQuad(best);
|
|
188
211
|
} catch (error) {
|
|
189
212
|
reportError(step, error);
|