Skip to content

ObjectnessBING runs really slow #1962

@Noltibus

Description

@Noltibus
System information (version)
  • OpenCV => 3.3.1 with contrib modules
  • Operating System / Platform =>Android
  • Compiler => Cmake on Android
Detailed description

I evaluated the BING algorithm from cv::saliency::ObjectnessBING to get object proposals on images. I linked everything etc. and it gives me some results, but more important: it's slow! It takes around 2 seconds for an image of the size of 720 x 1280 pixels. So nowhere near the advertised 300 FPS of the original paper (I know, those numbers were on a PC, not a mobile device, but still). Is there any way to speed it up, or am I missing some implementation details?

Steps to reproduce

This is my current native code. The code on the Android side, just calls the init function once, and then the computeSaliency function with the Bitmap, which was converted to a Mat. The measured time is from multiple runs and only takes into account the time spent in the computeSaliency function.

#include "opencv2/opencv.hpp"
#include "opencv2/core/core.hpp"
#include <opencv2/core/utility.hpp>
#include <opencv2/saliency.hpp>
#include <opencv2/opencv_modules.hpp>
#include <opencv2/highgui.hpp>
#include "opencv2/saliency/saliencyBaseClasses.hpp"
#include <jni.h>
#include <android/log.h>
#include <android/bitmap.h>
#include "log.h"

using namespace std;

cv::Ptr<cv::saliency::Saliency> saliencyAlgorithm;


std::string jstring2string(JNIEnv *env, jstring jStr) {
  if (!jStr)
    return "";

  const jclass stringClass = env->GetObjectClass(jStr);
  const jmethodID getBytes = env->GetMethodID(stringClass, "getBytes", "(Ljava/lang/String;)[B");
  const jbyteArray stringJbytes = (jbyteArray) env->CallObjectMethod(jStr, getBytes, env->NewStringUTF("UTF-8"));

  size_t length = (size_t) env->GetArrayLength(stringJbytes);
  jbyte* pBytes = env->GetByteArrayElements(stringJbytes, NULL);

  std::string ret = std::string((char *)pBytes, length);
  env->ReleaseByteArrayElements(stringJbytes, pBytes, JNI_ABORT);

  env->DeleteLocalRef(stringJbytes);
  env->DeleteLocalRef(stringClass);
  return ret;
}


extern "C"
JNIEXPORT void JNICALL
Java_one_realnote_app_bing_BingTry_computeSaliency(JNIEnv *env,
                                              jclass type,
                                              jlong grayAddr,
                                              jint id,
                                              jfloatArray answerArray_,
                                              jstring trainingPath_) {

  try {
    jfloat *arr = env->GetFloatArrayElements(answerArray_, 0);

    cv::Mat &gray = *(cv::Mat *) grayAddr;

    //cv::Mat binaryMap;
    cv::Mat image = gray;

    vector<cv::Vec4i> saliencyMap;

    //saliencyAlgorithm.dynamicCast<ObjectnessBING>()->setBBResDir( "Results" );

    if( saliencyAlgorithm->computeSaliency( image, saliencyMap ) )
    {
      int ndet = int(saliencyMap.size());
      vector<float> objectnessScores;
      //objectnessScores = saliencyAlgorithm.dynamicCast<cv::saliency::ObjectnessBING>()->getobjectnessValues();
      //std::cout << "Objectness done " << ndet << std::endl;
      // The result are sorted by objectness. We only use the first maxd boxes here.
      int maxd = 7,  jitter=9; // jitter to seperate single rects
      for (int i = 0; i < std::min(maxd, ndet); i++) {
        cv::Vec4i bb = saliencyMap[i];
        //cv::Point off(cv::theRNG().uniform(-jitter,jitter), cv::theRNG().uniform(-jitter,jitter));
        arr[i*5+0] = bb[0];
        arr[i*5+1] = bb[1];
        arr[i*5+2] = bb[2];
        arr[i*5+3] = bb[3];
        arr[i*5+4] = 4;
      }

      env->ReleaseFloatArrayElements(answerArray_, arr, 0);
    }
    else
    {
      LOGDEBUG("No saliency found");
    }

  } catch (cv::Exception ex) {
    LOGERROR("Error in Process: %s", ex.msg.c_str());
  }
  return;
}

extern "C"
JNIEXPORT void JNICALL
Java_one_realnote_app_bing_BingTry_initBing(JNIEnv *env, jclass type, jstring trainingPath_) {
  const char *trainingPath = env->GetStringUTFChars(trainingPath_, 0);
  std::string training_path = jstring2string(env, trainingPath_);

  saliencyAlgorithm = cv::saliency::ObjectnessBING::create();
  saliencyAlgorithm.dynamicCast<cv::saliency::ObjectnessBING>()->setTrainingPath( training_path );

  env->ReleaseStringUTFChars(trainingPath_, trainingPath);
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions