react-native-rectangle-doc-scanner 3.238.0 → 3.239.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.
@@ -106,6 +106,7 @@ class DocumentDetector {
106
106
  val blurredMat = Mat()
107
107
  val cannyMat = Mat()
108
108
  val morphMat = Mat()
109
+ val threshMat = Mat()
109
110
 
110
111
  try {
111
112
  // Convert to grayscale
@@ -124,57 +125,74 @@ class DocumentDetector {
124
125
  Imgproc.morphologyEx(cannyMat, morphMat, Imgproc.MORPH_CLOSE, kernel)
125
126
  kernel.release()
126
127
 
127
- // Find contours
128
- val contours = mutableListOf<MatOfPoint>()
129
- val hierarchy = Mat()
130
- Imgproc.findContours(
131
- morphMat,
132
- contours,
133
- hierarchy,
134
- Imgproc.RETR_EXTERNAL,
135
- Imgproc.CHAIN_APPROX_SIMPLE
136
- )
137
-
138
- // Find the largest contour that approximates to a quadrilateral
139
- var largestRectangle: Rectangle? = null
140
- var largestArea = 0.0
141
- val minArea = max(600.0, (srcMat.rows() * srcMat.cols()) * 0.001)
142
-
143
- for (contour in contours) {
144
- val contourArea = Imgproc.contourArea(contour)
145
-
146
- // Filter small contours
147
- if (contourArea < minArea) continue
148
-
149
- // Approximate contour to polygon
150
- val approx = MatOfPoint2f()
151
- val contour2f = MatOfPoint2f(*contour.toArray())
152
- val epsilon = 0.02 * Imgproc.arcLength(contour2f, true)
153
- Imgproc.approxPolyDP(contour2f, approx, epsilon, true)
154
-
155
- // Check if it's a quadrilateral
156
- if (approx.total() == 4L && Imgproc.isContourConvex(MatOfPoint(*approx.toArray()))) {
157
- val points = approx.toArray()
158
-
159
- if (contourArea > largestArea) {
160
- largestArea = contourArea
161
- largestRectangle = orderPoints(points)
128
+ fun findLargestRectangle(source: Mat): Rectangle? {
129
+ val contours = mutableListOf<MatOfPoint>()
130
+ val hierarchy = Mat()
131
+ Imgproc.findContours(
132
+ source,
133
+ contours,
134
+ hierarchy,
135
+ Imgproc.RETR_EXTERNAL,
136
+ Imgproc.CHAIN_APPROX_SIMPLE
137
+ )
138
+
139
+ var largestRectangle: Rectangle? = null
140
+ var largestArea = 0.0
141
+ val minArea = max(500.0, (srcMat.rows() * srcMat.cols()) * 0.0008)
142
+
143
+ for (contour in contours) {
144
+ val contourArea = Imgproc.contourArea(contour)
145
+ if (contourArea < minArea) continue
146
+
147
+ val approx = MatOfPoint2f()
148
+ val contour2f = MatOfPoint2f(*contour.toArray())
149
+ val epsilon = 0.018 * Imgproc.arcLength(contour2f, true)
150
+ Imgproc.approxPolyDP(contour2f, approx, epsilon, true)
151
+
152
+ if (approx.total() == 4L && Imgproc.isContourConvex(MatOfPoint(*approx.toArray()))) {
153
+ val points = approx.toArray()
154
+ if (contourArea > largestArea) {
155
+ largestArea = contourArea
156
+ largestRectangle = orderPoints(points)
157
+ }
162
158
  }
159
+
160
+ approx.release()
161
+ contour2f.release()
163
162
  }
164
163
 
165
- approx.release()
166
- contour2f.release()
164
+ hierarchy.release()
165
+ contours.forEach { it.release() }
166
+ return largestRectangle
167
167
  }
168
168
 
169
- hierarchy.release()
170
- contours.forEach { it.release() }
169
+ // First pass: Canny-based edges (good for strong edges).
170
+ var rectangle = findLargestRectangle(morphMat)
171
+
172
+ // Fallback: adaptive threshold (better for low-contrast cards).
173
+ if (rectangle == null) {
174
+ Imgproc.adaptiveThreshold(
175
+ blurredMat,
176
+ threshMat,
177
+ 255.0,
178
+ Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,
179
+ Imgproc.THRESH_BINARY,
180
+ 15,
181
+ 2.0
182
+ )
183
+ val kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, Size(3.0, 3.0))
184
+ Imgproc.morphologyEx(threshMat, morphMat, Imgproc.MORPH_CLOSE, kernel)
185
+ kernel.release()
186
+ rectangle = findLargestRectangle(morphMat)
187
+ }
171
188
 
172
- return largestRectangle
189
+ return rectangle
173
190
  } finally {
174
191
  grayMat.release()
175
192
  blurredMat.release()
176
193
  cannyMat.release()
177
194
  morphMat.release()
195
+ threshMat.release()
178
196
  }
179
197
  }
180
198
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-rectangle-doc-scanner",
3
- "version": "3.238.0",
3
+ "version": "3.239.0",
4
4
  "description": "Native-backed document scanner for React Native with customizable overlays.",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",