2014-01-30 85 views
1

我是第一次使用android程序員。 我正在處理的項目需要我做(簡單?)實時視頻處理。 該應用程序完成後需要執行此操作: 當我們單擊內置攝像頭應用程序時,它會打開。然後我繼續選擇視頻錄製選項。使用它我可以看到周圍的環境而不需要記錄。我試圖完成的是將顯示延遲幾百毫秒。我的一位同事可以通過使用筆記本電腦攝像頭和openCV(電腦)的延遲選項輕鬆完成此操作。我正在嘗試用android手機完成相同的操作。使用android openCV實時視頻處理

也許我做說明情況方面做得很差。請儘早回覆。 我現在正在編寫代碼,並且是第一次花費一些時間的程序員。 興奮地從Android編程開始!

+0

聽起來是可行的。只需將您的幀記錄到內存中的環形緩衝區,然後根據需要 – berak

+0

重播即可。但這並不簡單或不重要,我也不認爲有人能夠在StackOverflow上回復幾行。作爲第一次Android程序員,您將很難完成這項任務。 – Budius

+0

@Budius,爲什麼嚇到他?實際上這很容易。非常好的noob項目imho。 – berak

回答

3

不知道如果這個任務實際上需要 opencv(可能有點矯枉過正)但如果你選擇它,它相當容易。

看到所有我們在這裏做的是不斷地記錄幀,並實時/回放模式之間的一些事件(爲簡單起見,這裏onTouch)切換:

package com.berak.echo; 

import java.util.ArrayList; 
import java.util.List; 

import android.os.Bundle; 
import android.view.Menu; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.View.OnTouchListener; 
import android.app.Activity; 

import org.opencv.android.BaseLoaderCallback; 
import org.opencv.android.CameraBridgeViewBase; 
import org.opencv.android.LoaderCallbackInterface; 
import org.opencv.android.OpenCVLoader; 
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame; 
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2; 
import org.opencv.core.Core; 
import org.opencv.core.Mat; 
import org.opencv.core.Point; 
import org.opencv.core.Scalar; 

import com.berak.echo.R; 

public class EchoActivity extends Activity implements CvCameraViewListener2, OnTouchListener { 
    CameraBridgeViewBase mOpenCvCameraView; 
    List<Mat> ring = new ArrayList<Mat>(); // recording buffer 
    int delay = 100;      // delay == length of buffer 
    boolean delayed = false;    // state 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_echo); 
     mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.cam3_surface_view); 
     mOpenCvCameraView.setCvCameraViewListener(this); 
     mOpenCvCameraView.setOnTouchListener(this); // setup as touchlistener 
    } 

    // lots of boilerplate, ugly, but needed. 
    private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) { 
     @Override 
     public void onManagerConnected(int status) { 
      switch (status) { 
      case LoaderCallbackInterface.SUCCESS: 
       mOpenCvCameraView.enableView(); 
       break; 
      default: 
       super.onManagerConnected(status); 
       break; 
      } 
     } 
    }; 
    @Override 
    public void onResume() {; 
     super.onResume(); 
     OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_5,this, mLoaderCallback); 
    } 
    @Override 
    public void onPause() { 
     super.onPause(); 
     if (mOpenCvCameraView != null) 
      mOpenCvCameraView.disableView(); 
    } 
    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
    } 
    @Override 
    public void onCameraViewStarted(int width, int height) { } 
    @Override 
    public void onCameraViewStopped() { } 


    // here's the bread & butter stuff: 
    @Override 
    public Mat onCameraFrame(CvCameraViewFrame inputFrame) { 
     Mat mRgba = inputFrame.rgba(); 
     ring.add(mRgba.clone());   // add one at the end 
     if (ring.size() >= delay) {  // pop one from the front 
      ring.get(0).release(); 
      ring.remove(0); 
     } 

     Mat ret; 
     String txt; 
     if (delayed && ring.size()>0) { // depending on 'delayed' return either playback 
      ret = ring.get(0);    // return the 'oldest' 
      txt = "playback"; 
     } else { 
      ret = mRgba;     // or realtime frame 
      txt = "realtime"; 
     } 
     Core.putText(ret, txt, new Point(20,20), Core.FONT_HERSHEY_PLAIN, 1.2, new Scalar(200,0,0)); 
     return ret; 
    } 

    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     // just toggle between delayed an realtime view: 
     delayed = ! delayed; 
     return false; 
    }  
}