I am facing an issue with mobile vision, the face detector is very slow, this is when I run the code in a function that is not the onCreate. The detect is done after 14 seconds. But when I first run the detect code in onCreate it loads within a second. I have tried this Google Mobile Vision: Poor FaceDetector performance without CameraSource . And I have watched this post mobile vision API takes too long to detect face but the answer is about the bitmap and this is not the problem. Below is given more information about the scenarios.
In scenario 1 I start the detect after I clicked on a button. But then the first time I run the detector, there is a delay of 14 or 15 seconds. The second time I run the detector it runs within 1 second. The memory and CPU seem normal. Here is the code:
private ImageButton mTakePictureButton;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTakePictureButton = (ImageButton) findViewById(R.id.take_picture_button);
mTakePictureButton.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.take_picture_button:
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.camera_example);
SparseArray<Face> faces = getFaceArrayFromBitmap(bmp);//<----
break;
}
}
private SparseArray<Face> getFaceArrayFromBitmap(Bitmap bmp){
FaceDetector detector = new FaceDetector.Builder(this)
.setTrackingEnabled(false)
.setMode(FaceDetector.FAST_MODE)
.setClassificationType(FaceDetector.NO_CLASSIFICATIONS)
.setLandmarkType(FaceDetector.NO_LANDMARKS)
.build();
// Create a frame from the bitmap and run face detection on the frame.
Frame frame = new Frame.Builder().setBitmap(bmp).build();
SparseArray<Face> faceArray = detector.detect(frame);// <--- First time takes 14/15 seconds
detector.release();
return faceArray;
}
In scenario 2, where I run the face detector in the onCreate for the first time, it only takes 1 second to run the detector code.
private ImageButton mTakePictureButton;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTakePictureButton = (ImageButton) findViewById(R.id.take_picture_button);
mTakePictureButton.setOnClickListener(this);
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.camera_example);
SparseArray<Face> faces = getFaceArrayFromBitmap(bmp);// <-----
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.take_picture_button:
break;
}
}
private SparseArray<Face> getFaceArrayFromBitmap(Bitmap bmp){
FaceDetector detector = new FaceDetector.Builder(this)
.setTrackingEnabled(false)
.setMode(FaceDetector.FAST_MODE)
.setClassificationType(FaceDetector.NO_CLASSIFICATIONS)
.setLandmarkType(FaceDetector.NO_LANDMARKS)
.build();
// Create a frame from the bitmap and run face detection on the frame.
Frame frame = new Frame.Builder().setBitmap(bmp).build();
SparseArray<Face> faceArray = detector.detect(frame);// <-- Now it takes only 1 second the first time
detector.release();
return faceArray;
}
I also saw the source code of mobile vision there is a bug, but this does not look like a problem for me because in the detect, it does not crash.
/** * This is a workaround for a bug in the face detector, in which either very small images (i.e., * most images with dimension < 147) and very thin images can cause a crash in the native face * detection code. This will add padding to such images before face detection in order to avoid * this issue.
* * This is not necessary for use with the camera, which doesn't ever create these types of * images.
* * This detector should wrap the underlying FaceDetector instance, like this: * * Detector safeDetector = new SafeFaceDetector(faceDetector); * * Replace all remaining occurrences of faceDetector with safeDetector. */