How to capture the photo or video of the person when their face is being detected.

asked 2020-06-20 17:04:43 -0600

updated 2020-06-21 03:23:49 -0600

So, I am trying to make a face recognition app using the OpenCV library. I am successfully able to detect the faces of the people using haarcascade. I am currently using the javaCameraView to show the live feed of the camera. I want to capture the person's picture or record a video when their face is being detected. I tried using onPictureTaken method but it has been deprecated as of android 5.0

Code :

CascadeClassifier faceDetector;

BaseLoaderCallback baseLoaderCallback = new BaseLoaderCallback(MainActivity.this) {


    @Override
    public void onManagerConnected(int status) throws IOException {
        switch (status) {
            case BaseLoaderCallback.SUCCESS: {


                InputStream is = getResources().openRawResource(R.raw.haarcascade_frontalface_alt2);
                File cascadeDir = getDir("cascade", Context.MODE_PRIVATE);
                cascFile = new File(cascadeDir, "haarcascade_frontalface_alt2.xml");

                FileOutputStream fos = new FileOutputStream(cascFile);
                byte[] buffer = new byte[4096];
                int bytesRead;

                while ((bytesRead = is.read(buffer)) != -1) {
                    fos.write(buffer, 0, bytesRead);
                }
                is.close();
                fos.close();

                faceDetector = new CascadeClassifier(cascFile.getAbsolutePath());
                if (faceDetector.empty()) {
                    faceDetector = null;
                } else {
                    cascadeDir.delete();
                }
                javaCameraView.enableView();

                break;


            }
            default: {
                super.onManagerConnected(status);
                break;
            }

        }


    }
};


static {

}


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    javaCameraView = findViewById(R.id.my_camera_view);
    javaCameraView.setVisibility(SurfaceView.VISIBLE);
    javaCameraView.setCvCameraViewListener(MainActivity.this);
    btnCapture = findViewById(R.id.btnCapture);

    btnCapture.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

//TALKING ABOUT THIS CODE

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
            String currentDateandTime = sdf.format(new Date());
            String fileName = Environment.getExternalStorageState() +
                    "/sample_picture_" + currentDateandTime + ".jpg";
            Toast.makeText(MainActivity.this,  fileName + " saved", Toast.LENGTH_SHORT).show();
            String filename = "/storage/emulated/0/DCIM/Camera/SampleImg.jpg";
            Imgcodecs.imwrite(filename,mRGBA);
        }
    });

}

@Override
public void onCameraViewStarted(int width, int height) {
    mRGBA = new Mat(height, width, CvType.CV_8UC4);
    mGray = new Mat();

}

@Override
public void onCameraViewStopped() {
    mRGBA.release();
    mGray.release();
}

@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) throws IOException {
    mRGBA = inputFrame.rgba();
    mGray = inputFrame.gray();
    //detect face

    MatOfRect faceDetections = new MatOfRect();
    faceDetector.detectMultiScale(mRGBA, faceDetections);

    for (Rect rect : faceDetections.toArray()) {
        Imgproc.rectangle(mRGBA, new Point(rect.x, rect.y),
                new Point(rect.x + rect.width, rect.y + rect.height),
                new Scalar(255, 0, 0));


    }



    return mRGBA;
}

@Override
public void onPointerCaptureChanged(boolean hasCapture) {

}

@Override
protected void onDestroy() {
    super.onDestroy();
    if (javaCameraView != null) {
        javaCameraView.disableView();
    }
}

@Override
protected void onPause() {
    super.onPause();
    if (javaCameraView != null) {
        javaCameraView.disableView();
    }
}

@Override
protected void onResume() {
    super.onResume();

    if (OpenCVLoader.initDebug()) {
        Log.d(TAG, "OpenCV connected successfully");
        try {
            baseLoaderCallback.onManagerConnected(BaseLoaderCallback.SUCCESS);
        } catch (IOException e) {
            e.printStackTrace();
        }
    } else {
        Log.d(TAG, "OpenCV not connected successfully");
        OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_4_0, this, baseLoaderCallback);
    }

}

I tried creating a button that could be used to capture the picture. I tried this code in onClick method from StackOverflow but it still doesn't save to my storage.

edit retag flag offensive close merge delete

Comments

1

please, show, what you have, so far.

if you're already using the javaCameraView, why not take images from there ?

berak gravatar imageberak ( 2020-06-21 02:46:58 -0600 )edit

You already have the frame on your hands when feeding it to "network". IN your case in the method public Mat onCameraFrame.
So just save the image. And you also need to save the coordinates of the detected face - maybe as json or plain text. But this would be basic software developer skills.

holger gravatar imageholger ( 2020-06-21 07:39:19 -0600 )edit

Which method to use to just save this image in onCameraFrame method?

manan05 gravatar imagemanan05 ( 2020-06-21 08:08:06 -0600 )edit

Hmm this is a very trivial question and it shows you most likely somehow just copied + pasted the code without any understanding of the opencv library.This is not a good approach.

Use the imwrite method. https://docs.opencv.org/master/javado...

holger gravatar imageholger ( 2020-06-21 12:56:43 -0600 )edit
1

@manan05 , you have to use Environment.getExternalStorageState(), /storage/emulated/0/ only exists in your ide / emulation, not on the actual device.

please also note, that imwrite() won't create any folders, you have to do that manually, using plain java means, else it will fail

berak gravatar imageberak ( 2020-06-21 13:21:07 -0600 )edit
1

@manan05, homework time ;)

for (Rect rect : faceDetections.toArray()) {
      // 1. crop the image to face region (hint: Mat.submat())
      // 2. imwrite() the cropped roi 
      //    (sidenote: a timestamp won't be enough to make a unique filename in case 
      //     of *several* faces detected)
      // 3. *then* draw a rectangle into the original image
}

you'll still have to solve the "which img belongs to whom" (id) problem, if you're serious about recognition ;)

but well, oh -- others have managed to do exactly this and hopefully so will you, it's a matter of coding skill. stop asking around, and up with your sleeves ;)

berak gravatar imageberak ( 2020-06-21 13:37:25 -0600 )edit