2017-07-19 11 views
0

屋外のいくつかのオブジェクトの近距離写真を撮るためにアンドロイドカメラアプリ(カメラ2のAPIを使用しない)をビルドしています。写真はバーストモードで撮影する必要があります。つまり、一度起動すると、5枚の写真が連続して撮影され、すべての写真によく焦点を合わせる必要があります。写真を撮っている間にユーザがカメラを動かしている可能性があり、ユーザは焦点を手動で選択することができない。オブジェクトは色が濃く、カメラビューの明るいオブジェクトによってカメラが過剰露出していることがあります。
私はカメラパラメータとしてフォーカスエリアを設定する方法を知っていますが、フォーカスエリアの位置はカメラビューの暗い領域に常に焦点を合わせるように自動的に変更する必要があります。暗いオブジェクトの位置はカメラビューでは固定されていないため、フォーカスエリアを設定する前にすべてのフレームで暗いピクセルを探す必要があります。
onPreviewFrame()コールバックで暗い地域を調べることを検討していますが、これが正しい方法であるかどうかはわかりません。正しい方向に向けることができる人は誰ですか?たとえば、顔検出器を使って顔にアンドロイドカメラの焦点を合わせるプロジェクトがありますか?私はインターネットを見ようとしましたが、関連するプロジェクトは見つかりませんでした。アンドロイドカメラのダイナミックフォーカスエリア

答えて

0

タッチフォーカスを実装する必要があります。このようDomething:touchFocusはこのようになります

@Override 
public boolean onTouchEvent(MotionEvent event) { 

    if(event.getAction() == MotionEvent.ACTION_DOWN){ 
    float x = event.getX(); 
     float y = event.getY(); 
     float touchMajor = event.getTouchMajor(); 
     float touchMinor = event.getTouchMinor(); 

     Rect touchRect = new Rect(
     (int)(x - touchMajor/2), 
     (int)(y - touchMinor/2), 
     (int)(x + touchMajor/2), 
     (int)(y + touchMinor/2)); 
     if (mTouchEventListener != null) 
      mTouchEventListener.touchFocus(touchRect, false); 
    } 

:新しいAPIについて

@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) 
    public void touchFocus(Rect tfocusRect, boolean useInMid) { 

     if (mCamera == null) return; 

     try{ 
     mCamera.cancelAutoFocus(); 

     //Convert from View's width and height to +/- 1000 
     Rect targetFocusRect = (useInMid || sfv == null) ? new Rect() : 
      new Rect(tfocusRect.left * 2000/sfv.getWidth() - 1000, 
       tfocusRect.top * 2000/sfv.getHeight() - 1000, 
       tfocusRect.right * 2000/sfv.getWidth() - 1000, 
       tfocusRect.bottom * 2000/sfv.getHeight() - 1000); 

     final List<Camera.Area> focusList = new ArrayList<Camera.Area>(); 
     Camera.Area focusArea = new Camera.Area(targetFocusRect, 1000); 
     focusList.add(focusArea); 
     Parameters para = mCamera.getParameters(); 
     O.Log.d(TAG,para.getMaxNumFocusAreas() + ";" + para.getMaxNumMeteringAreas() + " >> " + tfocusRect.toString()); 
     para.setFocusAreas(focusList); 
     para.setMeteringAreas(focusList); 
      try{ 
      mCamera.setParameters(para); 
      }catch(RuntimeException e){ 
       O.Log.e(TAG, "setParameters failed", e); 
      } 
    mCamera.autoFocus(myAutoFocusCallback); 
// _.setCameraTorch(1); 
     }catch (Exception e){ 
      O.Log.e(TAG, "Touch Focus Camera Error", e); 
     } 
    } 
    private static AutoFocusCallback myAutoFocusCallback = new AutoFocusCallback() { 

      @Override 
      public void onAutoFocus(boolean success, Camera camera) { 
       // TODO Auto-generated method stub 

      } 
     }; 

http://www.morethantechnical.com/2017/02/28/android-camera2-touch-to-focus/

//Override in your touch-enabled view (this can be differen than the view you use for displaying the cam preview) 
    @Override 
    public boolean onTouch(View view, MotionEvent motionEvent) { 
     final int actionMasked = motionEvent.getActionMasked(); 
     if (actionMasked != MotionEvent.ACTION_DOWN) { 
      return false; 
     } 
     if (mManualFocusEngaged) { 
      Log.d(TAG, "Manual focus already engaged"); 
      return true; 
     } 

     final Rect sensorArraySize = mCameraInfo.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE); 

     //TODO: here I just flip x,y, but this needs to correspond with the sensor orientation (via SENSOR_ORIENTATION) 
     final int y = (int)((motionEvent.getX()/(float)view.getWidth()) * (float)sensorArraySize.height()); 
     final int x = (int)((motionEvent.getY()/(float)view.getHeight()) * (float)sensorArraySize.width()); 
     final int halfTouchWidth = 150; //(int)motionEvent.getTouchMajor(); //TODO: this doesn't represent actual touch size in pixel. Values range in [3, 10]... 
     final int halfTouchHeight = 150; //(int)motionEvent.getTouchMinor(); 
     MeteringRectangle focusAreaTouch = new MeteringRectangle(Math.max(x - halfTouchWidth, 0), 
                   Math.max(y - halfTouchHeight, 0), 
                   halfTouchWidth * 2, 
                   halfTouchHeight * 2, 
                   MeteringRectangle.METERING_WEIGHT_MAX - 1); 

     CameraCaptureSession.CaptureCallback captureCallbackHandler = new CameraCaptureSession.CaptureCallback() { 
      @Override 
      public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) { 
       super.onCaptureCompleted(session, request, result); 
       mManualFocusEngaged = false; 

       if (request.getTag() == "FOCUS_TAG") { 
        //the focus trigger is complete - 
        //resume repeating (preview surface will get frames), clear AF trigger 
        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, null); 
        mCameraOps.setRepeatingRequest(mPreviewRequestBuilder.build(), null, null); 
       } 
      } 

      @Override 
      public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request, CaptureFailure failure) { 
       super.onCaptureFailed(session, request, failure); 
       Log.e(TAG, "Manual AF failure: " + failure); 
       mManualFocusEngaged = false; 
      } 
     }; 

     //first stop the existing repeating request 
     mCameraOps.stopRepeating(); 

     //cancel any existing AF trigger (repeated touches, etc.) 
     mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL); 
     mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF); 
     mCameraOps.capture(mPreviewRequestBuilder.build(), captureCallbackHandler, mBackgroundHandler); 

     //Now add a new AF trigger with focus region 
     if (isMeteringAreaAFSupported()) { 
      mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_REGIONS, new MeteringRectangle[]{focusAreaTouch}); 
     } 
     mPreviewRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO); 
     mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO); 
     mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START); 
     mPreviewRequestBuilder.setTag("FOCUS_TAG"); //we'll capture this later for resuming the preview 

     //then we ask for a single request (not repeating!) 
     mCameraOps.capture(mPreviewRequestBuilder.build(), captureCallbackHandler, mBackgroundHandler); 
     mManualFocusEngaged = true; 

     return true; 
    } 

    private boolean isMeteringAreaAFSupported() { 
     return mCameraInfo.get(CameraCharacteristics.CONTROL_MAX_REGIONS_AF) >= 1; 
    } 
+0

が、私は問題のあいまいさがある参照この記事を読んで、私は持っていますそれを編集しました。返信いただきありがとうございますが、ユーザーが画面に触れるのではなく、自動的にフォーカスを設定する必要があります。カメラは暗い領域自体を検出し、焦点を変えなければなりません。 – abggcv

+0

自分でこのフォーカスエリアを変更することができます – Vyacheslav

+0

フォーカスエリアは重要ではなく、その位置です。私は自動的にフォーカスのポイントを選択するカメラアプリが必要です。 – abggcv

関連する問題