react-native-vision-camera-spoof-detector 1.1.16 → 1.1.17
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.
|
@@ -198,8 +198,10 @@ class FaceAntiSpoofingAdvanced(private val assetManager: AssetManager) {
|
|
|
198
198
|
}
|
|
199
199
|
|
|
200
200
|
return try {
|
|
201
|
-
val
|
|
202
|
-
val
|
|
201
|
+
val sampled = sampleRgbaToModelAndGray(rgba, width, height)
|
|
202
|
+
val nnResult = neuralNetworkAntiSpoofingSampled(sampled.rgbBuffer)
|
|
203
|
+
val nnScore = nnResult.getOrNull() ?: throw IllegalStateException(nnResult.exceptionOrNull()?.message ?: "NN inference failed")
|
|
204
|
+
val laplacianScore = calculateLaplacianFromGray(sampled.grayBuffer)
|
|
203
205
|
val isLive = nnScore < BASE_THRESHOLD && laplacianScore > LAPLACIAN_THRESHOLD
|
|
204
206
|
val combinedScore = calculateCombinedScore(nnScore, laplacianScore)
|
|
205
207
|
val confidence = calculateConfidence(nnScore, laplacianScore)
|
|
@@ -282,6 +284,23 @@ class FaceAntiSpoofingAdvanced(private val assetManager: AssetManager) {
|
|
|
282
284
|
}
|
|
283
285
|
}
|
|
284
286
|
|
|
287
|
+
private fun neuralNetworkAntiSpoofingSampled(rgbBuffer: Array<Array<FloatArray>>): Result<Float> {
|
|
288
|
+
return try {
|
|
289
|
+
val input = arrayOf(rgbBuffer)
|
|
290
|
+
clssPred[0].fill(0f)
|
|
291
|
+
leafNodeMask[0].fill(0f)
|
|
292
|
+
outputs[outputIndex0] = clssPred
|
|
293
|
+
outputs[outputIndex1] = leafNodeMask
|
|
294
|
+
interpreter!!.runForMultipleInputsOutputs(arrayOf(input), outputs)
|
|
295
|
+
Log.i(TAG, "clss_pred: [${clssPred[0].joinToString()}]")
|
|
296
|
+
Log.i(TAG, "leaf_node_mask: [${leafNodeMask[0].joinToString()}]")
|
|
297
|
+
Result.success(leafScore1(clssPred, leafNodeMask))
|
|
298
|
+
} catch (e: Exception) {
|
|
299
|
+
Log.e(TAG, "Error in neuralNetworkAntiSpoofingSampled", e)
|
|
300
|
+
Result.failure(e)
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
285
304
|
// FROM WORKING VERSION: leafScore1
|
|
286
305
|
private fun leafScore1(clssPred: Array<FloatArray>, leafNodeMask: Array<FloatArray>): Float {
|
|
287
306
|
var score = 0f
|
|
@@ -340,6 +359,40 @@ class FaceAntiSpoofingAdvanced(private val assetManager: AssetManager) {
|
|
|
340
359
|
return floatValues
|
|
341
360
|
}
|
|
342
361
|
|
|
362
|
+
private data class SampledFrame(
|
|
363
|
+
val rgbBuffer: Array<Array<FloatArray>>,
|
|
364
|
+
val grayBuffer: Array<IntArray>
|
|
365
|
+
)
|
|
366
|
+
|
|
367
|
+
private fun sampleRgbaToModelAndGray(
|
|
368
|
+
rgba: ByteArray,
|
|
369
|
+
srcWidth: Int,
|
|
370
|
+
srcHeight: Int
|
|
371
|
+
): SampledFrame {
|
|
372
|
+
val targetWidth = INPUT_IMAGE_SIZE
|
|
373
|
+
val targetHeight = INPUT_IMAGE_SIZE
|
|
374
|
+
val rgbBuffer = Array(targetHeight) { Array(targetWidth) { FloatArray(3) } }
|
|
375
|
+
val grayBuffer = Array(targetHeight) { IntArray(targetWidth) }
|
|
376
|
+
val scaleX = srcWidth.toFloat() / targetWidth
|
|
377
|
+
val scaleY = srcHeight.toFloat() / targetHeight
|
|
378
|
+
|
|
379
|
+
for (targetY in 0 until targetHeight) {
|
|
380
|
+
val srcY = (targetY * scaleY).toInt().coerceIn(0, srcHeight - 1)
|
|
381
|
+
for (targetX in 0 until targetWidth) {
|
|
382
|
+
val srcX = (targetX * scaleX).toInt().coerceIn(0, srcWidth - 1)
|
|
383
|
+
val srcIndex = (srcY * srcWidth + srcX) * 4
|
|
384
|
+
|
|
385
|
+
val r = (rgba[srcIndex].toInt() and 0xFF) / 255f
|
|
386
|
+
val g = (rgba[srcIndex + 1].toInt() and 0xFF) / 255f
|
|
387
|
+
val b = (rgba[srcIndex + 2].toInt() and 0xFF) / 255f
|
|
388
|
+
rgbBuffer[targetY][targetX] = floatArrayOf(r, g, b)
|
|
389
|
+
grayBuffer[targetY][targetX] = (0.299f * rgba[srcIndex].toInt() + 0.587f * rgba[srcIndex + 1].toInt() + 0.114f * rgba[srcIndex + 2].toInt()).toInt()
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
return SampledFrame(rgbBuffer, grayBuffer)
|
|
394
|
+
}
|
|
395
|
+
|
|
343
396
|
// FROM WORKING VERSION: laplacian with Bitmap
|
|
344
397
|
private fun laplacian(bitmap: Bitmap): Result<Int> {
|
|
345
398
|
return try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-vision-camera-spoof-detector",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.17",
|
|
4
4
|
"description": "High-performance face anti-spoofing and liveness detection module for React Native Vision Camera. Uses TensorFlow Lite with GPU acceleration and optimized YUV processing.",
|
|
5
5
|
"homepage": "https://github.com/dpraful/react-native-vision-camera-spoof-detector",
|
|
6
6
|
"repository": {
|