簡體   English   中英

Android應用程序跟蹤點:Video.calcOpticalFlow(...)方法無法正常工作?

[英]Android App Tracking Points: Video.calcOpticalFlow(…) method not working properly?

我目前正在嘗試使用OpenCV創建一個Android應用,該應用允許用戶使用智能手機攝像頭跟蹤運動對象的點。 可以在以下鏈接中找到C ++中與我正在尋找的功能完全相同的類似代碼: OpticalFlow C ++示例代碼

我一直在谷歌搜索並在StackOverflow中四處查看,但是我仍然不知道為什么我的代碼無法正常工作。 每次按某個點時,我都可以在屏幕上放置點,但是即使將對象移動到攝像機前面,這些點也似乎一動不動。 計算視力流量的方法如下:

void org.opencv.video.Video.calcOpticalFlowPyrLK(Mat prevImg, Mat nextImg, MatOfPoint2f prevPts, MatOfPoint2f nextPts, MatOfByte status, MatOfFloat err)

我相信我傳遞了計算連續圖像光流所需的確切參數,但是由於某些原因,它不起作用。 下面是我的代碼:

package org.opencv.UActivity;

//INCLUDE FILES
...

public class U2Activity extends Activity implements OnTouchListener,CvCameraViewListener2{



  private static final String  TAG              = "OCVSample::Activity";

  private Mat                       nextGray,Rscale;  
  private Mat                       prevGray;
  private MatOfPoint2f              prev2D,next2D;
  private MatOfByte                 status; 
  private MatOfFloat                err; 
  private Scalar                    color;

  private CameraBridgeViewBase mOpenCvCameraView;
  private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
      @Override
      public void onManagerConnected(int status) {
          switch (status) {
              case LoaderCallbackInterface.SUCCESS:
              {
                  Log.i(TAG, "OpenCV loaded successfully");
                  mOpenCvCameraView.enableView();
                  mOpenCvCameraView.setOnTouchListener(U2Activity.this);
              } break;
              default:
              {
                  super.onManagerConnected(status);
              } break;
          }
      }
  };

  public U2Activity() {
      Log.i(TAG, "Instantiated new " + this.getClass());
  }

  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
      Log.i(TAG, "called onCreate");
      super.onCreate(savedInstanceState);
      requestWindowFeature(Window.FEATURE_NO_TITLE);
      getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

      setContentView(R.layout.u2_surface_view);

      mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.u2_activity_surface_view);
      mOpenCvCameraView.setCvCameraViewListener(this);

      color = new Scalar(0, 255, 0);

  }

  @Override
  public void onPause()
  {
      super.onPause();
      if (mOpenCvCameraView != null)
          mOpenCvCameraView.disableView();
  }

  @Override
  public void onResume()
  {
      super.onResume();
      OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback);
  }

  public void onDestroy() {
      super.onDestroy();
      if (mOpenCvCameraView != null)
          mOpenCvCameraView.disableView();
  }

  public void onCameraViewStarted(int width, int height) {
      nextGray = new Mat(height, width, CvType.CV_8UC1); //unsigned char
      Rscale = new Mat(height, width, CvType.CV_8UC1);
      prevGray = new Mat(height, width, CvType.CV_8UC1);

      prev2D = new MatOfPoint2f(new Point());
      next2D = new MatOfPoint2f(new Point());                           
      status = new MatOfByte();                             
      err = new MatOfFloat();   
  }

  public void onCameraViewStopped() {
      nextGray.release();
      Rscale.release();
  }

  public boolean onTouch(View v, MotionEvent event) {

      int cols = nextGray.cols();
      int rows = nextGray.rows();

      int xOffset = (mOpenCvCameraView.getWidth() - cols) / 2;
      int yOffset = (mOpenCvCameraView.getHeight() - rows) / 2;

      int x = (int)event.getX() - xOffset;
      int y = (int)event.getY() - yOffset;

      if ((x < 0) || (y < 0) || (x > cols) || (y > rows)) return false;

      prev2D.push_back(new MatOfPoint2f(new Point((double)x,(double)y)));
      next2D.push_back(new MatOfPoint2f(new Point()));

      return false; // don't need subsequent touch events
  }

  public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
      nextGray = inputFrame.gray(); //get current image
      Rscale = nextGray; //make a copy of current image
      if(prevGray.empty()) prevGray = nextGray; //on start there is no prevGray. Copy current.
      Video.calcOpticalFlowPyrLK(prevGray,nextGray,prev2D,next2D,status,err);  //Calc the Optical Flow
      prevGray = nextGray; //Overwrite old Image (prevGray)
      prev2D = next2D; //Overwrite old point coordinates
      for(int i=0;i<next2D.toArray().length;i++){ //Draw the points in the image
          Core.circle(Rscale, next2D.toArray()[i], 3, color);
      }
      return Rscale;   
  }
}

解決

我變了:

  prevGray = nextGray;
  prev2D = next2D;

至:

  nextGray.copyTo(prevGray);
  next2D.copyTo(prev2D);

我希望它可以幫助遇到類似問題的任何人。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM