shubham0204 / FaceRecognition_With_FaceNet_Android

Face Recognition using the FaceNet model and MLKit on Android.
https://towardsdatascience.com/using-facenet-for-on-device-face-recognition-with-android-f84e36e19761
Apache License 2.0
252 stars 88 forks source link

Error in FrameAnalyser.kt : Cannot copy to a TensorFlowLite tensor (input_1) with 307200 bytes from a Java Buffer with 150528 bytes #15

Closed gowthami77 closed 3 years ago

gowthami77 commented 3 years ago

Hi everyone,

I got the error i.e.,

E/Model: Exception in FrameAnalyser ......... : Cannot copy to a TensorFlowLite tensor (input_1) with 307200 bytes from a Java Buffer with 150528 bytes.

if face is there in the frame then only i got this error. Please help anyone to resolve this issue

shubham0204 commented 3 years ago

@gowthami77, have you modified any variables in FaceNetModel.kt? Like imgSize or embeddingDim?

gowthami77 commented 3 years ago

No, I was not changed anything

This is my file

// Utility class for FaceNet model class FaceNetModel( context : Context ) {

// TFLiteInterpreter used for running the FaceNet model.
private var interpreter : Interpreter

// Input image size for FaceNet model.
private val imgSize = 112

// Output embedding size
private val embeddingDim = 192

// Image Processor for preprocessing input images.
private val imageTensorProcessor = ImageProcessor.Builder()
        .add( ResizeOp( imgSize , imgSize , ResizeOp.ResizeMethod.BILINEAR ) )
        .add( NormalizeOp( 127.5f , 127.5f ) )
        .build()

init {
    // Initialize TFLiteInterpreter
    val interpreterOptions = Interpreter.Options().apply {
        setNumThreads( 4 )
    }
    interpreter = Interpreter(FileUtil.loadMappedFile(context, "facenet_int8.tflite") , interpreterOptions )
}

// Gets an face embedding using FaceNet, use the `crop` rect.
fun getFaceEmbedding( image : Bitmap , crop : Rect , preRotate: Boolean ) : FloatArray {

     return runFaceNet(
         convertBitmapToBuffer(
             cropRectFromBitmap( image , crop , preRotate )
         )
     )[0]
}

// Gets an face embedding using the FaceNet model, given the cropped images.
fun getFaceEmbeddingWithoutBBox( image : Bitmap ) : FloatArray {
    return runFaceNet( convertBitmapToBuffer( image ) )[0]
}

// Run the FaceNet model.
private fun runFaceNet(inputs: Any): Array<FloatArray> {
    val t1 = System.currentTimeMillis()
    val outputs = Array(1) { FloatArray(embeddingDim ) }
    interpreter.run(inputs, outputs)
    Log.i( "Performance" , "FaceNet Inference Speed in ms : ${System.currentTimeMillis() - t1}")
    return outputs
}

// Resize the given bitmap and convert it to a ByteBuffer
private fun convertBitmapToBuffer( image : Bitmap) : ByteBuffer {
    val imageTensor = imageTensorProcessor.process( TensorImage.fromBitmap( image ) )
    Log.e("bitmap after",imageTensor.toString());

    return imageTensor.buffer
}

// Crop the given bitmap with the given rect.
private fun cropRectFromBitmap(source: Bitmap, rect: Rect , preRotate : Boolean ): Bitmap {
    var width = rect.width()
    var height = rect.height()
    if ( (rect.left + width) > source.width ){
        width = source.width - rect.left
    }
    if ( (rect.top + height ) > source.height ){
        height = source.height - rect.top
    }
    val croppedBitmap = Bitmap.createBitmap(
            if ( preRotate ) rotateBitmap( source )!! else source,
            rect.left,
            rect.top,
            width,
            height )
    Log.e("cropped bitmap","");

// saveBitmap( croppedBitmap , "image111") return croppedBitmap }

private fun saveBitmap(image: Bitmap, name: String) {
    val fileOutputStream =
            FileOutputStream(File( Environment.getExternalStorageDirectory()!!.absolutePath + "/$name.png"))
    image.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream)
}

private fun rotateBitmap(source: Bitmap): Bitmap? {
    val matrix = Matrix()
    matrix.postRotate( -90f )
    return Bitmap.createBitmap(source, 0, 0, source.width, source.height, matrix , false )
}

}

can you please help me to resolve this issue. It was very important to me.

shubham0204 commented 3 years ago

@gowthami77, you need to change the model's file path, as well as imgSize and embeddingDim like,


// Utility class for FaceNet model
class FaceNetModel( context : Context ) {

    // TFLiteInterpreter used for running the FaceNet model.
    private var interpreter : Interpreter

    // Input image size for FaceNet model.
    private val imgSize = 160

    // Output embedding size
    private val embeddingDim = 128

    // Image Processor for preprocessing input images.
    private val imageTensorProcessor = ImageProcessor.Builder()
            .add( ResizeOp( imgSize , imgSize , ResizeOp.ResizeMethod.BILINEAR ) )
            .add( NormalizeOp( 127.5f , 127.5f ) )
            .build()

    init {
        // Initialize TFLiteInterpreter
        val interpreterOptions = Interpreter.Options().apply {
            setNumThreads( 4 )
        }
        interpreter = Interpreter(FileUtil.loadMappedFile(context, "facenet_int8.tflite") , interpreterOptions )
    }

This seems to be a bug, but I'll fix it in 2/3 days, as I have to make some other modifications as well. These changes will come in the next commit. Also, please verify if these changes are helpful.

vishmanihub commented 3 years ago

it works. Thanks for the fix.