RedApparat / FaceDetector

Face detection for your Android app
Apache License 2.0
1.17k stars 197 forks source link

Incompatibility with Fotoapparat 2.1.2 #17

Open victor5171 opened 6 years ago

victor5171 commented 6 years ago

Hi!

I'm trying to couple FaceDetector to Fotoapparat but it looks like the newest version of it is incompatible with FaceDetector.

The following code is used to startup the camera and the detector:

val faceDetectorProcessor = FaceDetectorProcessor.with(this).listener { rectanglesView.setRectangles(it) }.build()

fotoApparat = Fotoapparat.with(this) .into(cameraView) .frameProcessor { faceDetectorProcessor.processFrame(it) } .build()

As you can see, the FrameProcessor property is now a lambda, so i've adapted the call.

But i'm receiving the following error (the application is crashing) if i run this code:

E/AndroidRuntime: FATAL EXCEPTION: pool-10-thread-1 Process: br.com.esapiens.ysos, PID: 17567 java.lang.IllegalAccessError: Field 'io.fotoapparat.preview.Frame.image' is inaccessible to class 'io.fotoapparat.facedetector.processor.FaceDetectorProcessor' (declaration of 'io.fotoapparat.facedetector.processor.FaceDetectorProcessor' appears in /data/app/br.com.esapiens.ysos-1/split_lib_dependencies_apk.apk) at io.fotoapparat.facedetector.processor.FaceDetectorProcessor.processFrame(FaceDetectorProcessor.java:37) at br.com.esapiens.ysos.camera.CameraActivity$onCreate$1.invoke(CameraActivity.kt:27) at br.com.esapiens.ysos.camera.CameraActivity$onCreate$1.invoke(CameraActivity.kt:11) at io.fotoapparat.preview.PreviewStream.dispatchFrame(PreviewStream.kt:92) at io.fotoapparat.preview.PreviewStream.access$dispatchFrame(PreviewStream.kt:14) at io.fotoapparat.preview.PreviewStream$dispatchFrameOnBackgroundThread$1.run(PreviewStream.kt:77) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) at java.lang.Thread.run(Thread.java:818)

Diolor commented 6 years ago

Thanks @victor5171. Let's think if @dmitry-zaitsev if we want the 2 libraries version independent or coupled.

ghost commented 6 years ago

any solution for this problem?

Diolor commented 6 years ago

Can you please try FA 2.2.0? Curious why image field is not accessible.

predasorinionut commented 6 years ago

Hi!

I'm having the same problem as @victor5171 with FA 2.2.0 and FD 1.0.0. Any idea about a solution @Diolor ?

ghost commented 6 years ago

This is the exception I get : FATAL EXCEPTION: pool-4-thread-1 java.lang.AbstractMethodError: abstract method "void io.fotoapparat.preview.FrameProcessor.process(io.fotoapparat.preview.Frame)" at io.fotoapparat.FotoapparatBuilder$frameProcessor$$inlined$apply$lambda$1.invoke(FotoapparatBuilder.kt:125) at io.fotoapparat.FotoapparatBuilder$frameProcessor$$inlined$apply$lambda$1.invoke(FotoapparatBuilder.kt:19) at io.fotoapparat.preview.PreviewStream.dispatchFrame(PreviewStream.kt:107) at io.fotoapparat.preview.PreviewStream.access$dispatchFrame(PreviewStream.kt:16) at io.fotoapparat.preview.PreviewStream$dispatchFrameOnBackgroundThread$1.run(PreviewStream.kt:92) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) at java.lang.Thread.run(Thread.java:762)f

RationalRank commented 6 years ago

Hey @kim24 . I do get the same exception. Any heads up on it?

joelhaasnoot commented 6 years ago

I have a solution in the mean time, write your frame processor like this

frameProcessor = { val faces = faceDetector.detectFaces(it.image, it.size.width, it.size.height, it.rotation)
                                runOnUiThread {
                                    rectangles?.setRectangles(faces)
                                }
                            })

where faceDetector is

val faceDetector = FaceDetector.create(this)

In this way you essentially recreate FaceDetectorProcessor as a lambda function.

scognito commented 5 years ago

Following @joelhaasnoot advice, here it is the Java version:

private class CustomFrameProcessor implements FrameProcessor {
    @Override
    public void process(@NotNull Frame frame) {

        List<Rectangle> faces = faceDetector.detectFaces(frame.getImage(), frame.getSize().width, frame.getSize().height, frame.getRotation());
        runOnUiThread(() -> rectanglesView.setRectangles(faces));
    }
}

FaceDetector faceDetector = FaceDetector.create(this);
CustomFrameProcessor processor = new CustomFrameProcessor();

fotoapparat = Fotoapparat.with(this)
            .frameProcessor(processor)
            ...