react-native-rectangle-doc-scanner 3.249.0 → 3.251.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.
|
@@ -70,7 +70,6 @@ class CameraController(
|
|
|
70
70
|
.enableMultipleObjects()
|
|
71
71
|
.build()
|
|
72
72
|
)
|
|
73
|
-
private var lastRefineTimestamp = 0L
|
|
74
73
|
private var lastRectangle: Rectangle? = null
|
|
75
74
|
private var lastRectangleTimestamp = 0L
|
|
76
75
|
|
|
@@ -78,7 +77,6 @@ class CameraController(
|
|
|
78
77
|
|
|
79
78
|
companion object {
|
|
80
79
|
private const val TAG = "CameraController"
|
|
81
|
-
private const val ANALYSIS_MAX_AREA = 1920 * 1080
|
|
82
80
|
private const val ANALYSIS_ASPECT_TOLERANCE = 0.15
|
|
83
81
|
}
|
|
84
82
|
|
|
@@ -220,7 +218,7 @@ class CameraController(
|
|
|
220
218
|
previewSize = chooseBestSize(previewSizes, viewAspect, null, preferClosestAspect = true)
|
|
221
219
|
|
|
222
220
|
val analysisSizes = streamConfigMap.getOutputSizes(ImageFormat.YUV_420_888)
|
|
223
|
-
analysisSize = chooseBestSize(analysisSizes, viewAspect,
|
|
221
|
+
analysisSize = chooseBestSize(analysisSizes, viewAspect, null, preferClosestAspect = true)
|
|
224
222
|
|
|
225
223
|
val captureSizes = streamConfigMap.getOutputSizes(ImageFormat.JPEG)
|
|
226
224
|
captureSize = captureSizes?.maxByOrNull { it.width * it.height }
|
|
@@ -412,13 +410,7 @@ class CameraController(
|
|
|
412
410
|
box.width() * box.height()
|
|
413
411
|
}
|
|
414
412
|
val mlBox = best?.boundingBox
|
|
415
|
-
val rectangle =
|
|
416
|
-
mlBox == null -> null
|
|
417
|
-
shouldRefineWithOpenCv() ->
|
|
418
|
-
refineWithOpenCv(nv21, imageWidth, imageHeight, rotationDegrees, mlBox)
|
|
419
|
-
?: boxToRectangle(mlBox)
|
|
420
|
-
else -> boxToRectangle(mlBox)
|
|
421
|
-
}
|
|
413
|
+
val rectangle = refineWithOpenCv(nv21, imageWidth, imageHeight, rotationDegrees, mlBox)
|
|
422
414
|
|
|
423
415
|
val frameWidth = if (rotationDegrees == 90 || rotationDegrees == 270) imageHeight else imageWidth
|
|
424
416
|
val frameHeight = if (rotationDegrees == 90 || rotationDegrees == 270) imageWidth else imageHeight
|
|
@@ -426,6 +418,15 @@ class CameraController(
|
|
|
426
418
|
}
|
|
427
419
|
.addOnFailureListener { e ->
|
|
428
420
|
Log.e(TAG, "[CAMERA2] ML Kit detection failed", e)
|
|
421
|
+
val rectangle = try {
|
|
422
|
+
DocumentDetector.detectRectangleInYUV(nv21, imageWidth, imageHeight, rotationDegrees)
|
|
423
|
+
} catch (detectError: Exception) {
|
|
424
|
+
Log.w(TAG, "[CAMERA2] OpenCV fallback failed", detectError)
|
|
425
|
+
null
|
|
426
|
+
}
|
|
427
|
+
val frameWidth = if (rotationDegrees == 90 || rotationDegrees == 270) imageHeight else imageWidth
|
|
428
|
+
val frameHeight = if (rotationDegrees == 90 || rotationDegrees == 270) imageWidth else imageHeight
|
|
429
|
+
onFrameAnalyzed?.invoke(smoothRectangle(rectangle), frameWidth, frameHeight)
|
|
429
430
|
}
|
|
430
431
|
.addOnCompleteListener {
|
|
431
432
|
analysisInFlight.set(false)
|
|
@@ -568,38 +569,32 @@ class CameraController(
|
|
|
568
569
|
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
|
|
569
570
|
}
|
|
570
571
|
|
|
571
|
-
private fun shouldRefineWithOpenCv(): Boolean {
|
|
572
|
-
val now = System.currentTimeMillis()
|
|
573
|
-
if (now - lastRefineTimestamp < 150) {
|
|
574
|
-
return false
|
|
575
|
-
}
|
|
576
|
-
lastRefineTimestamp = now
|
|
577
|
-
return true
|
|
578
|
-
}
|
|
579
|
-
|
|
580
572
|
private fun refineWithOpenCv(
|
|
581
573
|
nv21: ByteArray,
|
|
582
574
|
imageWidth: Int,
|
|
583
575
|
imageHeight: Int,
|
|
584
576
|
rotationDegrees: Int,
|
|
585
|
-
mlBox: Rect
|
|
577
|
+
mlBox: Rect?
|
|
586
578
|
): Rectangle? {
|
|
587
579
|
return try {
|
|
588
580
|
val uprightWidth = if (rotationDegrees == 90 || rotationDegrees == 270) imageHeight else imageWidth
|
|
589
581
|
val uprightHeight = if (rotationDegrees == 90 || rotationDegrees == 270) imageWidth else imageHeight
|
|
590
|
-
val
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
582
|
+
val openCvRect = if (mlBox != null) {
|
|
583
|
+
val expanded = expandRect(mlBox, uprightWidth, uprightHeight, 0.2f)
|
|
584
|
+
DocumentDetector.detectRectangleInYUVWithRoi(
|
|
585
|
+
nv21,
|
|
586
|
+
imageWidth,
|
|
587
|
+
imageHeight,
|
|
588
|
+
rotationDegrees,
|
|
589
|
+
expanded
|
|
590
|
+
)
|
|
591
|
+
} else {
|
|
592
|
+
DocumentDetector.detectRectangleInYUV(nv21, imageWidth, imageHeight, rotationDegrees)
|
|
593
|
+
}
|
|
598
594
|
if (openCvRect == null) {
|
|
599
|
-
|
|
595
|
+
mlBox?.let { boxToRectangle(it) }
|
|
600
596
|
} else {
|
|
601
|
-
|
|
602
|
-
if (computeIoU(openRectBounds, mlBox) >= 0.2f) openCvRect else null
|
|
597
|
+
openCvRect
|
|
603
598
|
}
|
|
604
599
|
} catch (e: Exception) {
|
|
605
600
|
Log.w(TAG, "[CAMERA2] OpenCV refine failed", e)
|
|
@@ -630,32 +625,16 @@ class CameraController(
|
|
|
630
625
|
val now = System.currentTimeMillis()
|
|
631
626
|
val last = lastRectangle
|
|
632
627
|
if (current == null) {
|
|
633
|
-
if (last != null && now - lastRectangleTimestamp <
|
|
628
|
+
if (last != null && now - lastRectangleTimestamp < 150) {
|
|
634
629
|
return last
|
|
635
630
|
}
|
|
636
631
|
lastRectangle = null
|
|
637
632
|
return null
|
|
638
633
|
}
|
|
639
634
|
|
|
640
|
-
|
|
641
|
-
val t = 0.35
|
|
642
|
-
Rectangle(
|
|
643
|
-
Point(lerp(last.topLeft.x, current.topLeft.x, t), lerp(last.topLeft.y, current.topLeft.y, t)),
|
|
644
|
-
Point(lerp(last.topRight.x, current.topRight.x, t), lerp(last.topRight.y, current.topRight.y, t)),
|
|
645
|
-
Point(lerp(last.bottomLeft.x, current.bottomLeft.x, t), lerp(last.bottomLeft.y, current.bottomLeft.y, t)),
|
|
646
|
-
Point(lerp(last.bottomRight.x, current.bottomRight.x, t), lerp(last.bottomRight.y, current.bottomRight.y, t))
|
|
647
|
-
)
|
|
648
|
-
} else {
|
|
649
|
-
current
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
lastRectangle = smoothed
|
|
635
|
+
lastRectangle = current
|
|
653
636
|
lastRectangleTimestamp = now
|
|
654
|
-
return
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
private fun lerp(start: Double, end: Double, t: Double): Double {
|
|
658
|
-
return start + (end - start) * t
|
|
637
|
+
return current
|
|
659
638
|
}
|
|
660
639
|
|
|
661
640
|
private fun rectangleBounds(rectangle: Rectangle): Rect {
|
|
@@ -666,17 +645,6 @@ class CameraController(
|
|
|
666
645
|
return Rect(left.toInt(), top.toInt(), right.toInt(), bottom.toInt())
|
|
667
646
|
}
|
|
668
647
|
|
|
669
|
-
private fun computeIoU(a: Rect, b: Rect): Float {
|
|
670
|
-
val left = max(a.left, b.left)
|
|
671
|
-
val top = max(a.top, b.top)
|
|
672
|
-
val right = minOf(a.right, b.right)
|
|
673
|
-
val bottom = minOf(a.bottom, b.bottom)
|
|
674
|
-
if (right <= left || bottom <= top) return 0f
|
|
675
|
-
val intersection = (right - left).toFloat() * (bottom - top).toFloat()
|
|
676
|
-
val union = (a.width() * a.height() + b.width() * b.height() - intersection).toFloat()
|
|
677
|
-
return if (union <= 0f) 0f else intersection / union
|
|
678
|
-
}
|
|
679
|
-
|
|
680
648
|
private fun imageToNv21(image: Image): ByteArray {
|
|
681
649
|
val width = image.width
|
|
682
650
|
val height = image.height
|
package/package.json
CHANGED