Ask Your Question

Revision history [back]

Enable OpenCV-OpenCL on Android devices

I'm trying to figure out how to enable OpenCL on an Android device.

I've built opencv so that OpenCL is YES. I've tried some functions like cv::ocl::setUseOpenCV(true) and haveOpenCL() and they all seem to indicate that OpenCL kernels are now available to use through calls to OpenCV.

I'm trying to convert the following code so that it runs on the GPU with OpenCV. I'm just trying to convert an image from the camera on an android phone to one that is RGB. That's all. (Ignore the line numbering).

BEFORE:

JNIEXPORT void JNICALL Java_com_me_main_Activity_toRGB(
 JNIEnv *env, jobject obj, jbyteArray yuv, int width, int height,
 jintArray dst) {
     std::stringstream logd;

    jbyte *_yuv      = env->GetByteArrayElements(yuv, 0);
    jint *_dst      = env->GetIntArrayElements(dst, 0);

    cv::Mat myuv(height + height/2, width, CV_8UC1, (uchar *)_yuv);
    cv::Mat mdst(height, width, CV_8UC4, (uchar *)_dst);

    cv::Mat mrgb;

    cv::cvtColor(myuv, mrgb, CV_YUV420sp2RGB, 4);

    mdst.create(mrgb.size(), mrgb.type() );

    mrgb.copyTo(mdst);

   env->ReleaseByteArrayElements(yuv, _yuv, 0);
   env->ReleaseIntArrayElements(dst, _dst, 0);

   LOGD(TAG, logd);
 }

AFTER:

JNIEXPORT void JNICALL Java_com_me_main_Activity_toRGB(
JNIEnv *env, jobject obj, jbyteArray yuv, int width, int height,
jintArray dst)
{
  std::stringstream logd;

  jbyte *_yuv      = env->GetByteArrayElements(yuv, 0);
  jint *_dst      = env->GetIntArrayElements(dst, 0);

  cv::Mat myuv(height + height/2, width, CV_8UC1, (uchar *)_yuv);
  cv::Mat mdst(height, width, CV_8UC4, (uchar *)_dst);
  //UMats for OpenCL use
  cv::UMat umyuv = myuv.getUMat(cv::ACCESS_READ, cv::USAGE_ALLOCATE_DEVICE_MEMORY);
  cv::UMat umdst = mdst.getUMat(cv::ACCESS_WRITE, cv::USAGE_ALLOCATE_DEVICE_MEMORY);

  cv::Mat mrgb;
  //UMats for OpenCL use
  cv::UMat umrgb;

  cv::cvtColor(umyuv, umrgb, CV_YUV420sp2RGB, 4);

  umdst.create(umrgb.size(), umrgb.type() );

  umrgb.copyTo(umdst);
  umdst.copyTo(mdst); //Because this holds the pointer to where our destination data needs to go

  env->ReleaseByteArrayElements(yuv, _yuv, 0);
  env->ReleaseIntArrayElements(dst, _dst, 0);

  LOGD(TAG, logd);
}

I get a black screen. Any idea why?