Java 如何使用带有Android Studio的OpenCV从手机加载图像?

Java 如何使用带有Android Studio的OpenCV从手机加载图像?,java,opencv,android-studio,Java,Opencv,Android Studio,我正在android studio中使用opencv开发一个android应用程序,我按照《opencv android编程示例》一书中的说明编写了从手机加载图像的代码。但我无法在ImageView上显示它,尽管代码与书中的代码完全相同,但主要代码如下: @Override onCreate(...){...} .......... @Override public boolean onOptionsItemSelected(MenuItem item) { int i

我正在android studio中使用opencv开发一个android应用程序,我按照《opencv android编程示例》一书中的说明编写了从手机加载图像的代码。但我无法在ImageView上显示它,尽管代码与书中的代码完全相同,但主要代码如下:

 @Override
  onCreate(...){...}
..........

 @Override
public  boolean onOptionsItemSelected(MenuItem item)    {
    int id  =   item.getItemId();
    if  (id ==  R.id.read_img)  {
        Intent  intent=new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(Intent.createChooser(intent,"Select  Picture"),
                SELECT_PICTURE);
        return  true;
    }
    return  super.onOptionsItemSelected(item);
 }
  public void onActivityResult(int requeseCode,int resultCode,Intent data){
    if(resultCode==RESULT_OK){
        if(requeseCode==SELECT_PICTURE){
            Uri selectedImgUri=data.getData();
            selectedImagePath=getPath(selectedImgUri);

         loadImage(selectedImagePath);//the method to get the image
        displayImage(sampledImage);//to display the image on ImageView
        }
    }
}
............
getPath(String path){.....}//it works fine

  public void loadImage(String path){
    Mat originalImage=Imgcodecs.imread(path);
    Mat rgbImage=new    Mat();
    Imgproc.cvtColor(originalImage, rgbImage,   Imgproc.COLOR_BGR2RGB);

//to reshape the image.
    Display display =   getWindowManager().getDefaultDisplay();
    Point   size    =   new Point();
    display.getSize(size);
    int width=size.x;
    int height=size.y;
    sampledImage=new Mat();
    double  downSampleRatio=calculateSubSampleSize(rgbImage,width,height);
    Imgproc.resize(rgbImage,sampledImage,new Size(),downSampleRatio,downSampleRatio,Imgproc.INTER_AREA);

//to rotate the image,seems not a problem in this case.
    try {
        ExifInterface   exif    =   new ExifInterface(selectedImagePath);
        int orientation =   exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
    switch (orientation){
        case    ExifInterface.ORIENTATION_ROTATE_90:
            sampledImage=sampledImage.t();
            Core.flip(sampledImage, sampledImage,   1);
            break;
        case    ExifInterface.ORIENTATION_ROTATE_270:
            sampledImage=sampledImage.t();
            Core.flip(sampledImage, sampledImage,   0);
            break;}
    } catch (IOException e){
        e.printStackTrace();
    }
}


 public void displayImage(Mat image){
    Bitmap bitmap=Bitmap.createBitmap(image.cols(),image.rows(),Bitmap.Config.RGB_565);
    Utils.matToBitmap(image,bitmap);
    ImageView imageView2=(ImageView)findViewById(R.id.imageView2);
    imageView2.setImageBitmap(bitmap);
}
 private    static  double  calculateSubSampleSize(Mat  srcImage,   int reqWidth,   int reqHeight)  {
    //  Raw height  and width   of  image
    final   int height  =   srcImage.height();
    final   int width   =   srcImage.width();
    double  inSampleSize    =   1;

    if(height>reqHeight||   width   >   reqWidth)   {
        //  Calculate   ratios  of  requested   height  and width   to  the raw             height  and width
    final   double  heightRatio =   (double)    reqHeight   /   (double)    height;
    final   double  widthRatio  =   (double)    reqWidth    /   (double)    width;
        //  Choose  the smallest    ratio   as  inSampleSize    value,  this    will                    //guarantee final   image   with    both    dimensions  larger  than    or                  //equal to  the requested   height  and width.
    inSampleSize    =   heightRatio<widthRatio  ?   heightRatio :widthRatio;
}       return  inSampleSize;

显然这是loadImage()方法的问题,但我搜索了google和所有地方,没有找到好的答案,我试图解决它,但这是同一个问题。有人知道如何解决它吗?这让我发疯了。非常感谢

是否已检查清单上的应用程序权限?我在从外部存储器加载文件时遇到了同样的问题

我将
添加到我的
AndroidManifest.xml
。 由于Android 6,您需要在运行时请求权限

我处理了我的主要活动的那些权限,如下所示

package test;

import java.io.File;
import java.util.ArrayList;
import java.util.Map;

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.Intent;
import android.support.v4.app.ActivityCompat;
import android.util.Log;

public class MainActivity extends Activity implements OnClickListener, ActivityCompat.OnRequestPermissionsResultCallback {

    private String TAG = "MainActivity";

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

                default:
                {
                    Log.i(TAG, "OpenCV loaded FAILURE");
                    super.onManagerConnected(status);
                } break;
            }
        }
    };

    public void onResume()
    {
        super.onResume();
        OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_1_0, this, mLoaderCallback);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    public static boolean hasPermissions(Context context, String... permissions) {
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) {
            for (String permission : permissions) {
                if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
                    return false;
                }
            }
        }
        return true;
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        String[] PERMISSIONS = {
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.CAMERA
        };

        if(!hasPermissions(this, PERMISSIONS)){
            ActivityCompat.requestPermissions(this, PERMISSIONS, 1);
        }
        // Do work
    }
}

希望能有所帮助。

在执行opencv函数之前,您是否初始化或加载了opencv。例如,使用OpenCVLoader.initDebug()谢谢,它似乎不起作用,我已经在mainfest文件中添加了权限,我以后会解决它,无论如何,谢谢。
package test;

import java.io.File;
import java.util.ArrayList;
import java.util.Map;

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.Intent;
import android.support.v4.app.ActivityCompat;
import android.util.Log;

public class MainActivity extends Activity implements OnClickListener, ActivityCompat.OnRequestPermissionsResultCallback {

    private String TAG = "MainActivity";

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

                default:
                {
                    Log.i(TAG, "OpenCV loaded FAILURE");
                    super.onManagerConnected(status);
                } break;
            }
        }
    };

    public void onResume()
    {
        super.onResume();
        OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_1_0, this, mLoaderCallback);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    public static boolean hasPermissions(Context context, String... permissions) {
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) {
            for (String permission : permissions) {
                if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
                    return false;
                }
            }
        }
        return true;
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        String[] PERMISSIONS = {
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.CAMERA
        };

        if(!hasPermissions(this, PERMISSIONS)){
            ActivityCompat.requestPermissions(this, PERMISSIONS, 1);
        }
        // Do work
    }
}