2015-05-19 34 views
11

Non ci sono abbastanza informazioni sul meccanismo di riconoscimento facciale camera2. Ho usato l'esempio di Camera2 da Google: android-Camera2Basicriconoscimento fronte camera2 Android

Ho impostato la modalità di riconoscimento dei volti su FULL.

mPreviewRequestBuilder.set(CaptureRequest.STATISTICS_FACE_DETECT_MODE, 
            CameraMetadata.STATISTICS_FACE_DETECT_MODE_FULL); 

Inoltre ho controllato

STATISTICS_INFO_MAX_FACE_COUNT e STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES:

int max_count = characteristics.get(
CameraCharacteristics.STATISTICS_INFO_MAX_FACE_COUNT); 
int modes [] = characteristics.get(
CameraCharacteristics.STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES); 

uscita: MaxCount: 5, modalità: [0, 2]

mio CaptureCallback:

private CameraCaptureSession.CaptureCallback mCaptureCallback 
= new CameraCaptureSession.CaptureCallback() { 

    private void process(CaptureResult result) { 
       Integer mode = result.get(CaptureResult.STATISTICS_FACE_DETECT_MODE); 
       Face [] faces = result.get(CaptureResult.STATISTICS_FACES); 
       if(faces != null && mode != null) 
        Log.e("tag", "faces : " + faces.length + " , mode : " + mode); 
    } 

    @Override 
    public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request, 
            CaptureResult partialResult) { 
     process(partialResult); 
    } 

    @Override 
    public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, 
            TotalCaptureResult result) { 
     process(result); 
    } 

uscita: volti: 0, modalità: 2

public static final int STATISTICS_FACE_DETECT_MODE_FULL = 2; 

lunghezza Faces è costantemente 0. Sembra che non riconosce un volto correttamente o mi mancava qualcosa.

Conosco l'approccio con FaceDetector. Volevo solo verificare come funziona con la nuova camera2 Face.

+0

Scusa ho lo stesso problema ... Ma non risolve il tuo modo di aiutare ... Se maneggi questo problema, puoi dare un link su github o altro materiale? Grazie mille! –

+0

Ho lo stesso problema. Sto usando esclusivamente l'API Camera2. La cosa divertente è che ho un codice funzionante usando l'esempio qui: http://stackoverflow.com/questions/33748760/camera2-face-detection-call-back - ma un altro set di codice che ho costruito in un modo diverso non funziona ! E non riesco a capire la differenza! Come te, ottengo sempre 0 lunghezza dei visi. Sono sicuro che alla fine lo scoprirò, ma sicuramente non è ovvio. –

risposta

0

I miei tentativi riguardavano Android 5.0 (API 21). Dopo l'aggiornamento alla versione 5.1 (API 22) ha iniziato a funzionare senza modifiche al codice.

+0

lol non è un risultato molto stimolante per L api's è – Blundell

+0

Scusa ho lo stesso problema ... Ma non risolve il tuo modo di aiutare ... Se maneggi questo problema, puoi dare un link su github o altro discorso? Grazie mille! –

0

Credo che il telefono non funziona bene con il rilevamento del volto di Google. Sei sicuro che usi HAL3 e possa usare API2 ?.

Per esempio, nel mio codice che sto utilizzando il rilevamento del viso senza alcun problema in questo modo:

private CameraCaptureSession.CaptureCallback mPhotoCaptureCallback 
      = new CameraCaptureSession.CaptureCallback() { 
//more code... 
    private void process(CaptureResult result) { 
      switch (mState) { 
       case STATE_PREVIEW: { 
        checkFaces(result.get(CaptureResult.STATISTICS_FACES)); 
        //more code.... 
        break; 
       } 
//more code... 
} 

Ecco il metodo checkFaces:

private void checkFaces(Face[] faces) { 
    if (faces != null) { 
     CameraUtil.CustomFace[] mMappedCustomFaces; 
     mMappedCustomFaces = computeFacesFromCameraCoordinates(faces); 
     if (faces != null && faces.length > 0) { 
      mHandler.sendEmptyMessage(SHOW_FACES_MSG); 
      mLastTimeRenderingFaces = System.currentTimeMillis(); 
     } 
    } else { 
     if (System.currentTimeMillis() > (mLastTimeRenderingFaces + 100)) { 
      mHandler.sendEmptyMessage(HIDE_FACES_MSG); 
     } 
    } 
} 

mia classe viso personalizzato:

 // public static class CustomFace extends Camera.CustomFace{ 
public static class CustomFace { 
    private int score = 0; 
    private Rect rect = null; 

    public CustomFace(Rect rect, int score) { 
     this.score = score; 
     this.rect = rect; 
    } 

    public int getScore() { 
     return score; 
    } 

    public Rect getBounds() { 
     return rect; 
    } 
} 

finalmente con questo metodo è possibile disegnare correttamente le facce (è possibile utilizzare l'Android predefinito, b rettangoli ut non funziona così bene in 4: 3 o 16: 9 dimensioni o quando si ruota il telefono:

public static RectF rectToRectF(Rect r) { 
    return new RectF(r.left, r.top, r.right, r.bottom); 
} 

    private CameraFaceUtil.CustomFace[] computeFacesFromCameraCoordinates(Face[] faces) { 
     CameraFaceUtil.CustomFace[] mappedFacesList = new CameraFaceUtil.CustomFace[faces.length]; 

     mCameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE); 

     float toStandardAspectRatio = ((float) mPreviewRect.bottom/(float) mPreviewRect.right)/AutoFitTextureView.RATIO_STANDARD; 
// 
     for (int i = 0; i < faces.length; i++) { 

      RectF mappedRect = new RectF(); 
      Log.i(TAG, "[computeFacesFromCameraCoordinates] toStandardAspectRatio: " + toStandardAspectRatio); 
      Log.i(TAG, "[computeFacesFromCameraCoordinates] preview rect: " + mPreviewRect); 
      Log.i(TAG, "[computeFacesFromCameraCoordinates] raw rect: " + faces[i].getBounds()); 

      mCameraToPreviewMatrix.mapRect(mappedRect, CameraUtil.rectToRectF(faces[i].getBounds())); 

      Log.i(TAG, "[computeFacesFromCameraCoordinates] mapped rect: " + mappedRect); 

      Rect auxRect = new Rect(CameraUtil.rectFToRect(mappedRect)); 


      Log.i(TAG, "[computeFacesFromCameraCoordinates] aux rect: " + auxRect); 

      int cameraSensorOrientation = mCameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION); 
      Log.i(TAG, "[computeFacesFromCameraCoordinates] cameraSensorOrientation: " + cameraSensorOrientation); 
      switch (cameraSensorOrientation) { 
       case 90: 
        mappedRect.top = auxRect.left; 
        mappedRect.bottom = auxRect.right; 
        mappedRect.left = (mPreviewRect.right - auxRect.bottom); 
        mappedRect.right = (mPreviewRect.right - auxRect.top); 
        break; 

       case 180: 
        mappedRect.top = (mPreviewRect.bottom - auxRect.bottom) * toStandardAspectRatio; 
        mappedRect.bottom = (mPreviewRect.bottom - auxRect.top) * toStandardAspectRatio; 
        mappedRect.left = (mPreviewRect.right - auxRect.right) * toStandardAspectRatio; 
        mappedRect.right = (mPreviewRect.right - auxRect.left) * toStandardAspectRatio; 
        break; 

       case 270: 
        mappedRect.top = (mPreviewRect.bottom - auxRect.right) * toStandardAspectRatio; 
        mappedRect.bottom = (mPreviewRect.bottom - auxRect.left) * toStandardAspectRatio; 
        mappedRect.left = auxRect.top; 
        mappedRect.right = auxRect.bottom; 
        break; 
      } 

      Log.i(TAG, "[computeFacesFromCameraCoordinates] rotated by camera driver orientation rect without scale: " 
        + mappedRect + ", with score: " + faces[i].getScore()); 

      float topOffset = mappedRect.top; 
      float leftOffset = mappedRect.left; 

      mappedRect.top = mappedRect.top * toStandardAspectRatio; 
      mappedRect.bottom = mappedRect.bottom * toStandardAspectRatio; 
      mappedRect.left = mappedRect.left * toStandardAspectRatio; 
      mappedRect.right = mappedRect.right * toStandardAspectRatio; 


      Log.i(TAG, "[computeFacesFromCameraCoordinates] rotated by camera driver orientation rect with scale: " 
        + mappedRect + ", with score: " + faces[i].getScore()); 

      topOffset = mappedRect.top - topOffset; 
      leftOffset = mappedRect.left - leftOffset; 

      mappedRect.top -= topOffset /*- (mMirror ? mPreviewRect.height() : 0)*/; 
      mappedRect.bottom -= topOffset /* - (mMirror ? mPreviewRect.height() : 0)*/; 
      mappedRect.left -= leftOffset; 
      mappedRect.right -= leftOffset; 

      Log.i(TAG, "[computeFacesFromCameraCoordinates] rotated by camera driver orientation rect with offset: " 
        + mappedRect + " topOffset " + topOffset + " leftOffset " + leftOffset); 

      // set the new values to the mapping array to get rendered 
      mappedFacesList[i] = new CameraFaceUtil.CustomFace(CameraUtil.rectFToRect(mappedRect), faces[i].getScore()); 
     } 

     return mappedFacesList; 

    } 

Quello che sto facendo è disegnare i volti sulla base del rapporto tra schermo e le dimensioni. È un codice pazzo, ma spero che ti possa aiutare!

Buona giornata, sentiti libero di chiedere se hai bisogno di qualcos'altro su camera2API.

0

Ho trovato che solo nel caso STATE_PREVIEW, è possibile elaborare il risultato per mostrare i volti lenth.Change from

private CameraCaptureSession.CaptureCallback mCaptureCallback 
     = new CameraCaptureSession.CaptureCallback() { 

    private void process(CaptureResult result) { 
     Integer mode = result.get(CaptureResult.STATISTICS_FACE_DETECT_MODE); 
     Face[] faces = result.get(CaptureResult.STATISTICS_FACES); 
     if(faces != null && mode != null) { 
      Log.e("tag", "faces : " + faces.length + " , mode : " + mode); 
     } 

     switch (mState) { 
      case STATE_PREVIEW: { 
       // We have nothing to do when the camera preview is working normally. 
       break; 
      } 
... 

a

private CameraCaptureSession.CaptureCallback mCaptureCallback 
     = new CameraCaptureSession.CaptureCallback() { 

    private void process(CaptureResult result) { 


     switch (mState) { 
      case STATE_PREVIEW: { 
       Face[] faces = result.get(CaptureResult.STATISTICS_FACES); 
       if (faces != null && faces.length > 0) { 
        Log.e("tag", "faces : " + faces.length); 
       } 
       break; 
      } 

Si prega di provare questo per vedere se funziona.