如何将图像uri转换为cv :: Mat

时间:2018-04-18 23:41:58

标签: android opencv android-intent android-fileprovider

我正在尝试创建一个简单的Android应用:

  1. 启动主要活动以从相机拍摄照片,
  2. 打开一个新活动,对您刚拍摄的照片执行图像处理(通过opencv)。
  3. 主要活动的课程代码在这里:

    import android.content.Intent;
    import android.net.Uri;
    import android.os.Environment;
    import android.provider.MediaStore;
    import android.support.v4.content.FileProvider;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    
    import java.io.File;
    import java.io.IOException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    public class MainActivity extends AppCompatActivity {
        // Used for logging success or failure messages
        private static final String TAG = "MyApp::CaptureActivity";
        public static final String EXTRA_IMAGE_URI = "com.my.app.IMAGE_URI";
        private static final int REQUEST_IMAGE_CAPTURE = 1;
        private String mCurrentImageFilename;
        public Uri mImageUri;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            Log.i(TAG, "called onCreate");
            setContentView(R.layout.activity_main);
            dispatchTakePictureIntent();
        }
    
        private void dispatchTakePictureIntent() {
            Log.i(TAG, "Dispatching Intent to capture an image.");
            Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            // Ensure that there's a camera activity to handle the intent
            if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
                Log.i(TAG, "Found camera activity to handle intent.");
                // Create the File where the photo should go
                File photoFile = null;
                try {
                    photoFile = createImageFile();
                } catch (IOException ex) {
                    // Error occurred while creating the File
                    Log.i(TAG, "There was an error creating the file");
                }
                // Continue only if the File was successfully created
                if (photoFile != null) {
                    mImageUri = FileProvider.getUriForFile(this,
                            "com.my.app.fileprovider",
                            photoFile);
                    takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
                    startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
                }
            }
        }
    
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
                Log.i(TAG, "Image Capture Complete");
                Intent intent = new Intent(this, AnalyzeImageActivity.class);
                intent.putExtra(EXTRA_IMAGE_URI, mImageUri.toString());
                startActivity(intent);
            }
        }
    
        private File createImageFile() throws IOException {
            Log.i(TAG, "Creating Image File in directory...");
            // Create an image file name
            String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
            String imageFileName = "JPEG_" + timeStamp + "_";
            File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
            File image = File.createTempFile(
                    imageFileName,  /* prefix */
                    ".jpg",         /* suffix */
                    storageDir      /* directory */
            );
    
            // Save a file: path for use with ACTION_VIEW intents
            mCurrentImageFilename = imageFileName;
            return image;
        }
    
    }
    

    然后第二项活动是AnalyzeImageActivity

    import android.content.Intent;
    import android.database.Cursor;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.net.Uri;
    import android.provider.MediaStore;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.ImageView;
    
    import org.opencv.android.Utils;
    import org.opencv.core.CvType;
    import org.opencv.core.Mat;
    
    import java.io.File;
    import java.io.IOException;
    
    public class AnalyzeImageActivity extends AppCompatActivity {
    
        private static final String TAG = "MyApp::AnalyzeImageActivity";
        private Uri mImageUri;
        private ImageView mMainImage;
        Mat mImageMatrix;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            Log.i(TAG, "Creating AnalyzeImageActivity");
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_analyze_image);
    
            Log.i(TAG, "Parsing Intent to get asset URI");
            Intent intent = getIntent();
            mImageUri = Uri.parse(intent.getStringExtra(MainActivity.EXTRA_IMAGE_URI));
    
            Log.i(TAG, "Converting to OpenCV Assets");
            Bitmap bitmap = null;
            try {
                bitmap = Bitmap.createBitmap(MediaStore.Images.Media.getBitmap(getContentResolver(), mImageUri));
            } catch (IOException e) {
                e.printStackTrace();
            }
            mImageMatrix = new Mat (bitmap.getHeight(), bitmap.getWidth(), CvType.CV_8UC1);
            Utils.bitmapToMat(bitmap, mImageMatrix);
    
            Log.i(TAG, "Sending to ImageView");
            mMainImage = findViewById(R.id.cvImage);
            mMainImage.setImageURI(mImageUri);
            mMainImage.setRotation(90);
    
    
        }
    
        public void captureNewImage(View v) {
            Intent intent = new Intent(this, MainActivity.class);
            startActivity(intent);
        }
    }
    

    当我运行此代码时,启动相机并保存照片效果很好 - 但是当第二个屏幕打开时,Log.i(TAG, "Converting to OpenCV Assets");下面的代码会导致应用程序崩溃。该应用程序抛出一个通用"应用程序已停止"错误。

    ADB的调试是:

    04-18 19:39:35.162 1763-1763/com.my.app I/MyApp::AnalyzeImageActivity: Creating AnalyzeImageActivity
    04-18 19:39:35.178 1763-1763/com.my.app I/MyApp::AnalyzeImageActivity: Parsing Intent to get asset URI
        Converting to OpenCV Assets
    04-18 19:39:35.621 1763-1763/com.my.app E/art: No implementation found for long org.opencv.core.Mat.n_Mat(int, int, int) (tried Java_org_opencv_core_Mat_n_1Mat and Java_org_opencv_core_Mat_n_1Mat__III)
    04-18 19:39:35.622 1763-1763/com.my.app D/AndroidRuntime: Shutting down VM
    
    
        --------- beginning of crash
    04-18 19:39:35.622 1763-1763/com.my.app E/AndroidRuntime: FATAL EXCEPTION: main
        Process: com.my.app, PID: 1763
        java.lang.UnsatisfiedLinkError: No implementation found for long org.opencv.core.Mat.n_Mat(int, int, int) (tried Java_org_opencv_core_Mat_n_1Mat and Java_org_opencv_core_Mat_n_1Mat__III)
            at org.opencv.core.Mat.n_Mat(Native Method)
            at org.opencv.core.Mat.<init>(Mat.java:39)
            at com.my.app.AnalyzeImageActivity.onCreate(AnalyzeImageActivity.java:46)
            at android.app.Activity.performCreate(Activity.java:6687)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1140)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2631)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2743)
            at android.app.ActivityThread.-wrap12(ActivityThread.java)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1490)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:154)
            at android.app.ActivityThread.main(ActivityThread.java:6165)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:888)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:778)
    

    看起来这个cv::Mat构造函数没有实现,但这是直接来自OpenCV - 任何人都可以帮我弄清楚如何做到这一点吗?

    谢谢!

1 个答案:

答案 0 :(得分:0)

您应该在设备上安装OpenCV Manager并在代码中初始化它。

见相对answer