Untitled

mail@pastecode.io avatar
unknown
plain_text
2 years ago
7.7 kB
1
Indexable
Never
package com.example.facedetection;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.content.res.AssetFileDescriptor;
import android.graphics.Canvas;
import android.media.Image;
import android.os.Build;
import android.os.Bundle;
import android.util.Size;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.Preview;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.view.PreviewView;
import androidx.core.content.ContextCompat;

import com.google.common.util.concurrent.ListenableFuture;
import com.google.mlkit.vision.common.InputImage;
import com.google.mlkit.vision.face.Face;
import com.google.mlkit.vision.face.FaceDetection;
import com.google.mlkit.vision.face.FaceDetector;
import com.google.mlkit.vision.face.FaceDetectorOptions;

import org.tensorflow.lite.Interpreter;

import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.concurrent.ExecutionException;


public class MainActivity extends AppCompatActivity {
    PreviewView previewView;
    ImageView imageView;
    Interpreter tfLite;
    Button camButton, switchCam;
    CameraSelector cameraSelector;
    GraphicOverlay graphicOverlay;
    boolean cameraOpen = false;
    int cam_face = CameraSelector.LENS_FACING_BACK; //Default Back Camera

    ProcessCameraProvider cameraProvider;

    String modelFile = "face_detection_sena.tflite";

    private ListenableFuture<ProcessCameraProvider> cameraProviderFuture;

    /////////////////////////////////////////////////////////////

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        previewView = findViewById(R.id.previewView);
        camButton = findViewById(R.id.button_cam);
        switchCam = findViewById(R.id.switch_cam); switchCam.setVisibility(View.INVISIBLE);
        imageView = findViewById(R.id.image_view); imageView.setVisibility(View.INVISIBLE);
        graphicOverlay = findViewById(R.id.draw_overlay);

        //Camera Permission
        if(checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED){
            requestPermissions(new String[]{Manifest.permission.CAMERA}, 100);
        }

        /////////////////////////////////////////////////////////

        camButton.setOnClickListener(v -> {
                if(!cameraOpen){
                    bindCamera();
                    switchCam.setVisibility(View.VISIBLE);
                    cameraOpen = true;
                }else{
                    cameraProvider.unbindAll();
                    switchCam.setVisibility(View.INVISIBLE);
                    cameraOpen = false;
            }
        });

        /////////////////////////////////////////////////////////

        switchCam.setOnClickListener(v -> {
            if(cam_face == CameraSelector.LENS_FACING_BACK){
                cam_face = CameraSelector.LENS_FACING_FRONT;
            }
            else{
                cam_face = CameraSelector.LENS_FACING_BACK;
            }
            cameraProvider.unbindAll();
            bindCamera();
        });

        /////////////////////////////////////////////////////////

        try {
            tfLite = new Interpreter(loadModelFile(this, modelFile));
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    /////////////////////////////////////////////////////////////

    private ByteBuffer loadModelFile(Activity activity, String MODEL_FILE)  throws IOException {
        AssetFileDescriptor fileDescriptor = activity.getAssets().openFd(MODEL_FILE);
        FileInputStream inputStream = new FileInputStream(fileDescriptor.getFileDescriptor());
        FileChannel fileChannel = inputStream.getChannel();
        long startOffset = fileDescriptor.getStartOffset();
        long declaredLength = fileDescriptor.getDeclaredLength();
        return fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength);
    }

    /////////////////////////////////////////////////////////////

    private void bindCamera() {
        cameraProviderFuture = ProcessCameraProvider.getInstance(this);
        cameraProviderFuture.addListener(() -> {
            try
            {
                cameraProvider = cameraProviderFuture.get();
                bindPreview(cameraProvider);
            }
            catch (ExecutionException | InterruptedException e)
            { // This should never be reached.
            }
        }, ContextCompat.getMainExecutor(this));
    }

    /////////////////////////////////////////////////////////////

    @SuppressLint("UnsafeOptInUsageError")
    void bindPreview(@NonNull ProcessCameraProvider cameraProvider) {

        Preview preview = new Preview.Builder().setTargetRotation(previewView.getDisplay().getRotation()).build();
        preview.setSurfaceProvider(previewView.getSurfaceProvider());
        cameraSelector = new CameraSelector.Builder().requireLensFacing(cam_face).build();

        ImageAnalysis imageAnalysis = new ImageAnalysis.Builder()
                .setTargetResolution(new Size(1280, 720))
                .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST) //Latest frame is shown
                .build();

        Canvas canvas = new Canvas();
        graphicOverlay.drawCenter(canvas);

        //Executor executor = Executors.newSingleThreadExecutor();
        imageAnalysis.setAnalyzer(ContextCompat.getMainExecutor(this), imageProxy -> {

            Image mediaImage = imageProxy.getImage();

            if (mediaImage != null) {
                InputImage image = InputImage.fromMediaImage(mediaImage, imageProxy.getImageInfo().getRotationDegrees());
                //Toast.makeText(this, "Rotation " + imageProxy.getImageInfo().getRotationDegrees(), Toast.LENGTH_SHORT).show();

                //Initialize Face Detector
                FaceDetectorOptions options = new FaceDetectorOptions.Builder()
                        .setPerformanceMode(FaceDetectorOptions.PERFORMANCE_MODE_ACCURATE)
                        .build();

                FaceDetector detector = FaceDetection.getClient(options);

                detector.process(image)
                        .addOnSuccessListener(faces -> {
                            Toast.makeText(this, "detect success", Toast.LENGTH_SHORT).show();
                            //drawOverlay.setAlpha(1f);
                            for (Face face : faces){
                                graphicOverlay.drawRect(face, canvas);
                            }
                        })
                        .addOnFailureListener(e -> {
                            Toast.makeText(this, "detect failure", Toast.LENGTH_SHORT).show();
                            //
                        });
            }
            imageProxy.close();
        });
        cameraProvider.bindToLifecycle(this, cameraSelector, imageAnalysis, preview);
    }

    /////////////////////////////////////////////////////////////
}