带有NDK grabCut的Android Studio中的OpenCV返回始终为黑色掩码

时间:2017-03-02 10:35:12

标签: android c++ opencv android-ndk

我使用此示例中的步骤创建了具有NDK支持和OpenCV本机库的Android Studio项目:

https://github.com/leadrien/opencv_native_androidstudio

这个例子运行正常,我正在尝试使用grabCut算法。我的应用程序应在主Activity中显示3个图像:原始图像,变换后的图像和使用的蒙版。但实际上显示的蒙版都是黑色的,为此,处理后的图像就像原始图像一样。

我的java代码:

    private void processImage(){
    Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pastis);

    Bitmap bmp32 = srcBitmap.copy(Bitmap.Config.ARGB_8888, true);

    Mat imgToProcess = new Mat();
    Mat mask = new Mat();

    //utils from opencv library
    Utils.bitmapToMat(bmp32, imgToProcess);

    //NDK function
    salt(imgToProcess.getNativeObjAddr(), mask.getNativeObjAddr(), 2000);

    Bitmap bmp = Bitmap.createBitmap(imgToProcess.cols(), imgToProcess.rows(), Bitmap.Config.ARGB_8888);

    //utils from opencv library
    Utils.matToBitmap(imgToProcess, bmp);

    Bitmap bmpMask = Bitmap.createBitmap(mask.cols(), mask.rows(), Bitmap.Config.ARGB_8888);

    //utils from opencv library
    Utils.matToBitmap(mask, bmpMask);

    ImageView imageContainer = (ImageView) findViewById(R.id.resultImage);
    imageContainer.setImageBitmap(bmp);

    ImageView maskContainer = (ImageView) findViewById(R.id.maskImage);
    maskContainer.setImageBitmap(bmpMask);
}

我的NDK代码是:

void JNICALL Java_com_ach_MainActivity_salt(JNIEnv *env, jobject instance, jlong matAddrGray, jlong mask, jint nbrElem) {
Mat &mGr = *(Mat *) matAddrGray;
Mat &maskR = *(Mat *) mask;

int r = mGr.rows;
int c = mGr.cols;

Mat bgdModel, fgdModel;

Rect rect = Rect(10, 10,c-10, r-10);

cvtColor(mGr , mGr , CV_RGBA2RGB);
maskR.create(mGr.size(), CV_8UC1);

grabCut(mGr, maskR, rect, bgdModel, fgdModel, 2, GC_INIT_WITH_RECT);

mGr.copyTo(mGr, maskR);
}

¿为什么我总是得到全黑面具?

此外,执行抓取,我的手机(三星Galaxy S5)需要大约50秒,图像分辨率为256 x 192,只有2步。 ¿这是正常的吗?¿我怎样才能改善这一点?

提前致谢:)

1 个答案:

答案 0 :(得分:0)

前段时间我发现了这个问题,但我忘记发布答案了。

似乎opencv + ndk中存在一些问题,我解决了我的问题,在 copyTo 函数中没有在源和目的地使用相同的位图:

mGr.copyTo(mGr, maskR); --> PROBLEMS

mGr.copyTo(mGrDest, maskR); --> WORKING

而且,以防万一,因为这个问题我对其他函数使用了像 cvtColor 这样的源 - 目标位图,但我认为该函数没有问题。

我希望我的解决方案适用于您的代码! :)