2017-01-20 7 views
3

Face Tracker приложение на основе Google Vision Face Tracker. По умолчанию Face Tracker использует заднюю/заднюю камеру, но я хочу обнаружить лица с передней камерой.Face Tracker CameraSource Android: Как улучшить качество передней камеры?

Это код CameraSourcePreview, что Google видение обеспечивает:

package com.google.android.gms.samples.vision.face.facetracker.ui.camera; 

import android.content.Context; 
import android.content.res.Configuration; 
import android.util.AttributeSet; 
import android.util.Log; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 
import android.view.ViewGroup; 

import com.google.android.gms.common.images.Size; 
import com.google.android.gms.vision.CameraSource; 

import java.io.IOException; 

public class CameraSourcePreview extends ViewGroup { 
    private static final String TAG = "CameraSourcePreview"; 

    private Context mContext; 
    private SurfaceView mSurfaceView; 
    private boolean mStartRequested; 
    private boolean mSurfaceAvailable; 
    private CameraSource mCameraSource; 

    private GraphicOverlay mOverlay; 

    public CameraSourcePreview(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     mContext = context; 
     mStartRequested = false; 
     mSurfaceAvailable = false; 

     mSurfaceView = new SurfaceView(context); 
     mSurfaceView.getHolder().addCallback(new SurfaceCallback()); 
     addView(mSurfaceView); 
    } 

    public void start(CameraSource cameraSource) throws IOException { 
     if (cameraSource == null) { 
      stop(); 
     } 

     mCameraSource = cameraSource; 

     if (mCameraSource != null) { 
      mStartRequested = true; 
      startIfReady(); 
     } 
    } 

    public void start(CameraSource cameraSource, GraphicOverlay overlay) throws IOException { 
     mOverlay = overlay; 
     start(cameraSource); 
    } 

    public void stop() { 
     if (mCameraSource != null) { 
      mCameraSource.stop(); 
     } 
    } 

    public void release() { 
     if (mCameraSource != null) { 
      mCameraSource.release(); 
      mCameraSource = null; 
     } 
    } 

    private void startIfReady() throws IOException { 
     if (mStartRequested && mSurfaceAvailable) { 
      mCameraSource.start(mSurfaceView.getHolder()); 
      if (mOverlay != null) { 
       Size size = mCameraSource.getPreviewSize(); 
       int min = Math.min(size.getWidth(), size.getHeight()); 
       int max = Math.max(size.getWidth(), size.getHeight()); 
       if (isPortraitMode()) { 
        // Swap width and height sizes when in portrait, since it will be rotated by 
        // 90 degrees 
        mOverlay.setCameraInfo(min, max, mCameraSource.getCameraFacing()); 
       } else { 
        mOverlay.setCameraInfo(max, min, mCameraSource.getCameraFacing()); 
       } 
       mOverlay.clear(); 
      } 
      mStartRequested = false; 
     } 
    } 

    private class SurfaceCallback implements SurfaceHolder.Callback { 
     @Override 
     public void surfaceCreated(SurfaceHolder surface) { 
      mSurfaceAvailable = true; 
      try { 
       startIfReady(); 
      } catch (IOException e) { 
       Log.e(TAG, "Could not start camera source.", e); 
      } 
     } 

     @Override 
     public void surfaceDestroyed(SurfaceHolder surface) { 
      mSurfaceAvailable = false; 
     } 

     @Override 
     public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
     } 
    } 

    @Override 
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 
     int width = 640; 
     int height = 480; 
     if (mCameraSource != null) { 
      Size size = mCameraSource.getPreviewSize(); 
      if (size != null) { 
       width = size.getWidth(); 
       height = size.getHeight(); 
      } 
     } 

     // Swap width and height sizes when in portrait, since it will be rotated 90 degrees 
     if (isPortraitMode()) { 
      int tmp = width; 
      width = height; 
      height = tmp; 
     } 

     final int layoutWidth = right - left; 
     final int layoutHeight = bottom - top; 

     // Computes height and width for potentially doing fit width. 
     int childWidth = layoutWidth; 
     int childHeight = (int)(((float) layoutWidth/(float) width) * height); 

     // If height is too tall using fit width, does fit height instead. 
     if (childHeight > layoutHeight) { 
      childHeight = layoutHeight; 
      childWidth = (int)(((float) layoutHeight/(float) height) * width); 
     } 

     for (int i = 0; i < getChildCount(); ++i) { 
      getChildAt(i).layout(0, 0, childWidth, childHeight); 
     } 

     try { 
      startIfReady(); 
     } catch (IOException e) { 
      Log.e(TAG, "Could not start camera source.", e); 
     } 
    } 

    private boolean isPortraitMode() { 
     int orientation = mContext.getResources().getConfiguration().orientation; 
     if (orientation == Configuration.ORIENTATION_LANDSCAPE) { 
      return false; 
     } 
     if (orientation == Configuration.ORIENTATION_PORTRAIT) { 
      return true; 
     } 

     Log.d(TAG, "isPortraitMode returning false by default"); 
     return false; 
    } 
} 

Я называю источник камеры с помощью этого метода:

private void startCameraSource() { 

     // check that the device has play services available. 
     int code = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(
       getApplicationContext()); 
     if (code != ConnectionResult.SUCCESS) { 
      Dialog dlg = 
        GoogleApiAvailability.getInstance().getErrorDialog(this, code, RC_HANDLE_GMS); 
      dlg.show(); 
     } 

     if (mCameraSource != null) { 
      try { 
       mPreview.start(mCameraSource, mGraphicOverlay); 
      } catch (IOException e) { 
       Log.e(TAG, "Unable to start camera source.", e); 
       mCameraSource.release(); 
       mCameraSource = null; 
      } 
     } 
    } 

Face Tracker передней камеры все еще слишком темно сравнить с умолчанию приложением телефона камерой ,

Как скрасить переднюю камеру в лицевом трекере google vision? Связано ли это с видом поверхности?

<com.google.android.gms.samples.vision.face.facetracker.ui.camera.CameraSourcePreview 
    android:id="@+id/preview" 
    android:layout_width="match_parent" 
    android:layout_height="0dp" 
    android:layout_weight="1.00" 
    android:weightSum="1"> 

<com.google.android.gms.samples.vision.face.facetracker.ui.camera.GraphicOverlay 
    android:id="@+id/faceOverlay" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:layout_weight="0.79" /> 

</com.google.android.gms.samples.vision.face.facetracker.ui.camera.CameraSourcePreview> 

ответ

0

Это вообще не связано с SurfaceView. Это неправильная настройка API-интерфейса камеры. Вам придется внести некоторые дополнительные изменения в файл CameraSource.java. Вы можете найти его на this GitHub repository

Во-первых, вы должны знать, что это проблема с экспозицией. Это относится к тому, что камера позволяет получать на объективе. Вы должны знать, поддерживает ли ваша камера компенсацию экспозиции. Вам нужно будет запросить getMinExposureCompensation() и getMaxExposureCompensation() с вашего экземпляра Camera.Parameters. Как объясняется в документации, если оба метода возвращают 0, компенсация экспозиции не поддерживается, и вы ничего не можете сделать.

К счастью, большую часть времени эта характеристика поддерживается всеми телефонами. Теперь вы можете проверить текущую экспозицию камеры, вызвав getExposureCompensation(), которая вернет значение по умолчанию (обычно 0, что означает, что экспозиция не регулируется). Теперь , чтобы предотвратить темные изображения, вам нужно установить только новую экспозицию между минимальными и максимальными значениями с помощью setExposureCompensation() и применить Camera.Parameters к своей камере.

Наконец, вы можете зафиксировать экспозицию, чтобы избежать потери конфигурации с помощью setAutoExposureLock(), getAutoExposureLock() и самое главное: перед установкой Блокировка экспозиции вы должны быть уверены, что isAutoExposureLockSupported() вернулся верно.

Удачи!