如何计算来自相机(OpenCV)的两个输入帧之间的差异?

4

我想通过计算从相机传入的两个帧之间的差异来检测移动,并在手机屏幕上显示这个差异。我需要重写 OnCameraFrame() 方法,所以我这样做了:

  @Override
    public Mat onCameraFrame(Mat inputFrame) {
        inputFrame.copyTo(current);
        Core.absdiff(current, previous, difference);
        current.copyTo(previous);
        return difference;
    }

很不幸,应用程序崩溃了,并出现以下信息:
06-13 18:17:30.000: E/cv::error()(13097): OpenCV Error: Sizes of input arguments do not match (The operation is neither 'array op array' (where arrays have the same size and the same number of channels), nor 'array op scalar', nor 'scalar op array') in void cv::arithm_op(cv::InputArray, cv::InputArray, cv::OutputArray, cv::InputArray, int, void (**)(const uchar*, size_t, const uchar*, size_t, uchar*, size_t, cv::Size, void*), bool, void*), file /home/reports/ci/slave/50-SDK/opencv/modules/core/src/arithm.cpp, line 1277
06-13 18:17:30.005: W/dalvikvm(13097): threadid=11: thread exiting with uncaught exception (group=0x411df2a0)
06-13 18:17:30.005: E/AndroidRuntime(13097): FATAL EXCEPTION: Thread-983
06-13 18:17:30.005: E/AndroidRuntime(13097): CvException [org.opencv.core.CvException: /home/reports/ci/slave/50-SDK/opencv/modules/core/src/arithm.cpp:1277: error: (-209) The operation is neither 'array op array' (where arrays have the same size and the same number of channels), nor 'array op scalar', nor 'scalar op array' in function void cv::arithm_op(cv::InputArray, cv::InputArray, cv::OutputArray, cv::InputArray, int, void (**)(const uchar*, size_t, const uchar*, size_t, uchar*, size_t, cv::Size, void*), bool, void*)

完整的类代码如下:
   package com.example.szpieg2;

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Range;
import org.opencv.core.Size;

import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.Window;
import android.view.WindowManager;

public class TrackActivity extends Activity implements CvCameraViewListener {
    private Mat current;
    private CameraBridgeViewBase cameraView;
    private Mat previous;
    private Mat difference;//difference between previous and current
    private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
        @Override
        public void onManagerConnected(int status) {
            switch (status) {
            case LoaderCallbackInterface.SUCCESS: {
                Log.i("Co sie dzieje?", "OpenCV loaded successfully");
                cameraView.enableView();
                // cameraView.setOnTouchListener(ColorBlobDetectionActivity.this);
            }
                break;
            default: {
                super.onManagerConnected(status);
            }
                break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        setContentView(R.layout.activity_track);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        cameraView = (CameraBridgeViewBase) findViewById(R.id.surface_view);
        cameraView.setCvCameraViewListener(this);
    }

    // --------Activity Actions---------
    @Override
    public void onPause() {
        if (cameraView != null)
            cameraView.disableView();
        super.onPause();
    }

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

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

    // --------/Activity Actions/---------

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_track, menu);
        return true;
    }

    // --------listener method implementation-------------
    @Override
    public void onCameraViewStarted(int width, int height) {
        previous = new Mat(width, height, CvType.CV_64FC4);
        current = new Mat(width, height, CvType.CV_64FC4);
        difference = new Mat(width, height, CvType.CV_64FC4);
    }

    @Override
    public void onCameraViewStopped() {
        current.release();

    }

    @Override
    public Mat onCameraFrame(Mat inputFrame) {
        inputFrame.copyTo(current);
        Core.absdiff(current, previous, difference);
        current.copyTo(previous);
        return difference;
    }

}

我已经在设备上使用OpenCV管理器安装了OpenCV。所有添加到OpenCV的教程都在该设备上运行。该设备是三星Galaxy Note 2。该库项目正在使用的是 OpenCV 2.4.3,必须保持不变。
1个回答

4
问题未初始化Mat previous。所以:
@Override
public Mat onCameraFrame(Mat inputFrame) {
    inputFrame.copyTo(current);
    if(first){//first is true at the first time
        inputFrame.copyTo(previous);
        first = false;
        Log.i("First processing", "Pierwszy przebieg");
    }

    Core.absdiff(current, previous, difference);
//  current.copyTo(previous);
    inputFrame.copyTo(previous);

    return difference;
} 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接