没有调用CvCameraViewListener接口的OnCameraFrame方法

时间:2015-03-20 09:44:15

标签: android opencv

我是opencv的新手并尝试创建一个简单的应用程序,它将打开相机并捕获照片。为此,我已经实现了CvCameraViewListener接口。我的代码如下:

MainActivity.java

public class MainActivity extends Activity implements CvCameraViewListener2{

    public String TAG = "MainActivity";
    private int mCameraIndex;
    private Mat mBgr;
    private Boolean mIsPhotoPending;
    private CameraBridgeViewBase mCameraView;
    private static final String STATE_CAMERA_INDEX = "cameraIndex";
    private Boolean mIsMenuLocked;
    private CameraBridgeViewBase.CvCameraViewFrame inputFrame;


    int screen_w, screen_h;
    private Mat gray, frame, lowRes;

    static {
        if (!OpenCVLoader.initDebug()) {
            Log.v("MainActivity","Loading of OpenCv Failed");
        }
    }



    private BaseLoaderCallback mLoaderCallBack = new BaseLoaderCallback(this) {
        @Override
        public void onManagerConnected(int status) {
            switch(status) {
                case LoaderCallbackInterface.SUCCESS:
                {
                    String TAG = "";
                    Log.i(TAG, "Open CV successfully loaded");
                    mCameraView.enableView();
                    mBgr = new Mat();
                    }break;
                default:
                {
                    super.onManagerConnected(status);
                }break;
            }
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);


        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        if(savedInstanceState != null)
        {
            mCameraIndex = savedInstanceState.getInt(STATE_CAMERA_INDEX, 0);
        }
        else
        {
            mCameraIndex = 0;
        }

        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD)
        {
            Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
            Camera.getCameraInfo(mCameraIndex, cameraInfo);

        }

        mCameraView = new NativeCameraView(this, mCameraIndex);
        //mCameraView.setCvCameraViewListener(this);

        findViewById(R.id.HelloOpenCvView);

        //mOpenCvCameraView = new JavaCameraView(this,-1);
        setContentView(mCameraView);





    }


    @Override
    public void onResume() {
        super.onResume();
        mLoaderCallBack.onManagerConnected(LoaderCallbackInterface.SUCCESS);
       // OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_11, this, mLoaderCallBack);
        mIsMenuLocked = false;
    }

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

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

    @Override
    public void onCameraViewStarted(int width, int height) {

    }

    @Override
    public void onCameraViewStopped() {

    }

    @Override
    public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
        Mat rgba = inputFrame.rgba();

        if(mIsPhotoPending)
        {
            takePhoto(rgba);
        }

        return rgba;
    }


    private void takePhoto(Mat rgba)
    {



        //get the path of the photo
        final long currentTimeMillis = System.currentTimeMillis();
        final String appName = getString(R.string.app_name);
        final String galleryPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString();
        final String albumPath = galleryPath + "/" + appName;
        final String photoPath = albumPath + "/" + currentTimeMillis + ".png";

        final ContentValues  values = new ContentValues();
        values.put(MediaStore.MediaColumns.DATA, photoPath);
        values.put(MediaStore.Images.Media.MIME_TYPE, showActivity.PHOTO_MIME_TYPE);
        values.put(MediaStore.Images.Media.TITLE, appName);
        values.put(MediaStore.Images.Media.DESCRIPTION, appName);
        values.put(MediaStore.Images.Media.DATE_TAKEN, currentTimeMillis);

        //check if the album directory exists
        File album = new File(albumPath);
        if(!album.isDirectory() && !album.mkdirs())
        {
            Log.e(TAG,"Failed to create album directory at" + albumPath);
            return;
        }

        //try to create the photo
        Imgproc.cvtColor(rgba, mBgr, Imgproc.COLOR_RGBA2BGR, 3);
        if(!Highgui.imwrite(photoPath, mBgr))
        {
            Log.d(TAG,"Photo saved successfully");
            onTakePhotoFailed();
        }

        Log.d(TAG, "Photo saved successfully");

        //insert photo in mediastore
        Uri uri;
        final Intent intent = new Intent();
        try
        {
           uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
            intent.putExtra(showActivity.EXTRA_PHOTO_URI, uri);
        }catch(final Exception e)
        {
            Log.e(TAG, "Failed to insert photo into media store");
            e.printStackTrace();
        }

        //delete the photo because insertion failed
        File photo = new File(photoPath);
        if(!photo.delete())
        {
            Log.e(TAG, "Failed to delete non-inserted photo");
        }
        onTakePhotoFailed();



        intent.putExtra(showActivity.EXTRA_PHOTO_DATA_PATH, photoPath);
        startActivity(intent);

        return;

    }




    private void onTakePhotoFailed()
    {
        mIsMenuLocked = false;

        //display error message
        final String errorMessage = getString(R.string.photo_error_message);
        runOnUiThread(new Runnable()
        {
            @Override
            public void run()
            {
                Toast.makeText(MainActivity.this, errorMessage, Toast.LENGTH_SHORT).show();
            }
        });
    }

我的问题是永远不会调用onCameraFrame()方法,而这种方法又不会调用takePhoto()方法而我无法捕获照片。我在onCamerFrame()方法中调用了takePhoto()方法,因为该方法将采用Mat详细信息。请告诉我哪里出错了。

任何帮助都将受到高度赞赏。

1 个答案:

答案 0 :(得分:0)

您可能需要实现您的活动的PictureCallBack界面。请参阅教程3 - 摄像机控制应用程序。