将mat对象从android java传递给native cpp part

时间:2015-02-27 05:23:50

标签: android c++ opencv android-ndk java-native-interface

我将Mat对象从android java代码传递给native cpp part,但得到" 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

1 个答案:

答案 0 :(得分:0)

您可以尝试更改此

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));