将Mat对象从androidjava传递到本机cpp部分

Passing Mat object from android java to native cpp part

本文关键字:本机 cpp 部分 Mat 对象 androidjava      更新时间:2023-10-16

我将Mat对象从android java代码传递到本机cpp部分,但得到了"OpenCV错误:不支持的格式或格式组合"。请帮忙。提前谢谢。

Java代码:

public class MainActivity extends ActionBarActivity {
static {
    if (!OpenCVLoader.initDebug())
        Log.d("ERROR", "Unable to load OpenCV");
    else
        Log.d("SUCCESS", "OpenCV loaded");
}
private static final String TAG = "OpenCV";
TextView tv;
ImageView img;
Button bt;
Bitmap bm;
int x = 0;
String s = "";
private Mat m;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}
public native String nativeCode(long mat);
private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) {
    @Override
    public void onManagerConnected(int status) {
        switch (status) {
        case LoaderCallbackInterface.SUCCESS: {
            Log.i(TAG, "OpenCV loaded successfully");
            setContentView(R.layout.activity_main);
            tv = (TextView) findViewById(R.id.tv);
            img = (ImageView) findViewById(R.id.iv);
            bt = (Button) findViewById(R.id.button1);
            img.setImageResource(R.drawable.c);
            bm = (Bitmap) ((BitmapDrawable) img.getDrawable()).getBitmap();
            bt.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                     Utils.bitmapToMat(bm, m);
                     nativeCode(m.getNativeObjAddr());
                }
            });
        }
            break;
        default: {
            super.onManagerConnected(status);
        }
            break;
        }
    }
};
@Override
public void onResume() {
    super.onResume();
    LoaderCallbackInterface mLoaderCallback = null;
    try {
        mOpenCVCallBack.onManagerConnected(LoaderCallbackInterface.SUCCESS);
        m = new Mat(bm.getHeight(), bm.getWidth(), CvType.CV_8U, new Scalar(1));            
        Log.i(TAG, "opencv successfull and object created");
    } catch (Exception e) {
        Log.e(TAG, "Cannot connect to OpenCV Manager");
    }
} 
static {
    System.loadLibrary("hellocpp");
    System.loadLibrary("opencv_java");
}
@Override
public void onStop() {
    super.onStop();
    if (m != null) m.release();
    m = null;
}
}

nativeCode:

class WatershedSegmenter{
private:
    Mat markers;
public:
    void setMarkers(Mat& markerImage){
        markerImage.convertTo(markers, CV_32S);
    }
    Mat process(Mat &image){
        watershed(image, markers);
        markers.convertTo(markers,CV_8U);
        return markers;
    }
};
JNIEXPORT jstring JNICALL
Java_com_example_color_MainActivity_stringFromJNI(JNIEnv *env, jobject thiz, jlong mat)
{ 
    Mat& input = *(Mat*)mat;
    Mat inputImage = input.clone();
    Mat blank(inputImage.size(),CV_8U,Scalar(0xFF));
    Mat dest; 
    Mat markers(inputImage.size(),CV_8U,Scalar(-1));
    markers(Rect(0,0,inputImage.cols, 5)) = Scalar::all(1);
    markers(Rect(0,inputImage.rows-5,inputImage.cols, 5)) = Scalar::all(1);
    markers(Rect(0,0,5,inputImage.rows)) = Scalar::all(1);
    markers(Rect(inputImage.cols-5,0,5,inputImage.rows)) = Scalar::all(1);
    int centreW = inputImage.cols/4;
    int centreH = inputImage.rows/4;
    markers(Rect((inputImage.cols/2)-(centreW/2),(inputImage.rows/2)-(centreH/2), centreW, centreH)) = Scalar::all(2);
    markers.convertTo(markers,CV_BGR2GRAY);
    WatershedSegmenter segmenter;
    segmenter.setMarkers(markers);
    Mat wshedMask = segmenter.process(inputImage);
    string result = "success";
    return env->NewStringUTF((const char* )result.c_str());
}

错误:

OpenCV Error: Unsupported format or combination of formats (Only 8-bit, 3-channel input images are supported) in void cvWatershed(const CvArr*, CvArr*), file /hdd2/buildbot/slaves/slave_ardbeg1/50-SDK/opencv/modules/imgproc/src/segmentation.cpp, line 147

您可以尝试更改此

m = new Mat(bm.getHeight(), bm.getWidth(), CvType.CV_8U, new Scalar(1));  

m = new Mat(bm.getHeight(), bm.getWidth(), CvType.CV_8U, new Scalar(3));