2

I was trying to switch to the new OpenCV 3.0, as it implicitly calls OpenCL for faster operations on matrices. I followed a nice Tutorial provided by Sony and was able to integrate the required OpenCV files to make it compiling. I'm simply reading an image detect edges. The same thing is done on CPU and GPU side. But I think I'm missing something big, because the time, that it takes to process is the same in both cases. The Code snippets are the following:

clock_t startTimer1, stopTimer1;

cv::ocl::setUseOpenCL(true);

String path = "/storage/emulated/0/DCIM/100ANDRO/";
String filename = "DSC_0581.JPG";
String filename_result = "DSC_0581_processed.JPG";

ocl::setUseOpenCL(true);
Mat gpuFrame;
UMat gpuBW;
UMat gpuBlur;
UMat gpuEdges;

gpuFrame = imread(path+filename, IMREAD_COLOR);
gpuBW = gpuFrame.getUMat(cv::ACCESS_READ);

startTimer1=clock();
cvtColor(gpuBW, gpuBW, COLOR_BGR2GRAY);
GaussianBlur(gpuBW, gpuBlur, Size(1,1), 1.5, 1.5);
Canny(gpuBlur, gpuEdges, 0, 30, 3);
cv::ocl::finish();
stopTimer1 = clock();

imwrite(path+filename_result, gpuEdges);

double elapse = 1000.0* (double)(stopTimer1 - startTimer1)/(double)CLOCKS_PER_SEC;
info[2] = (int)elapse;
LOGI("OpenCL code on the GPU took %g ms\n\n", 1000.0* (double)(stopTimer1 - startTimer1)/(double)CLOCKS_PER_SEC) ;

and the "pure" native code:

ocl::setUseOpenCL(false);
Mat cpuFrame;
String path = "/storage/emulated/0/DCIM/100ANDRO/";
String filename = "DSC_0581.JPG";
String filename_result = "DSC_0581_cpu_processed.JPG";

Mat cpuBW;
Mat cpuBlur;
Mat cpuEdges;

cpuFrame = imread(path+filename);
startTimer=clock();
cvtColor(cpuFrame, cpuBW, COLOR_BGR2GRAY);
GaussianBlur(cpuBW, cpuBlur, Size(1, 1), 1.5, 1.5);
Canny(cpuBlur, cpuEdges, 0, 30, 3);
stopTimer = clock();
imwrite(path+filename_result, cpuEdges);

double elapse = 1000.0* (double)(stopTimer - startTimer)/(double)CLOCKS_PER_SEC;
info[2] = (int)elapse;

LOGI("C++ code on the CPU took %g ms\n\n", 1000.0* (double)(stopTimer - startTimer)/(double)CLOCKS_PER_SEC) ;

In the OpenCV/OpenCL/Android Tutorial here, it has been mentioned, that it is required to compile it with option

-DWITH_OPENCL=YES

Is that necessary? The application compiles and runs without any error, but I think doesn't run on GPU though. Any help much appreciated! Thanks a lot!

UPDATE

This is the Android.mk

LOCAL_PATH      := $(call my-dir)
LOCAL_PATH_EXT  := $(call my-dir)/../extra_libs/
include $(CLEAR_VARS)

#opencv
OPENCVROOT:= C:/Android/opencva3
OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on
OPENCV_LIB_TYPE:=SHARED
-DWITH_OPENCL=YES

include ${OPENCVROOT}/sdk/native/jni/OpenCV.mk

LOCAL_ARM_MODE  := arm

LOCAL_MODULE    := openclexample1

LOCAL_CFLAGS    += -DANDROID_CL -DWITH_OPENCL
LOCAL_CFLAGS    += -O3 -ffast-math

LOCAL_C_INCLUDES := $(LOCAL_PATH)/../include

LOCAL_SRC_FILES := sonyOpenCLexample1.cpp openCLNR.cpp refNR.cpp #ocdft.cpp

LOCAL_LDLIBS    +=  -ldl -llog -ljnigraphics
LOCAL_LDLIBS    += -lGLESv2 -lEGL
LOCAL_LDLIBS    += $(LOCAL_PATH_EXT)libOpenCL.so  

include $(BUILD_SHARED_LIBRARY)
beniroquai
  • 166
  • 2
  • 13
  • 1. Anything in the log to state that the T-API library is being used. 2. What device/OS version are you testing on. – Morrison Chang Nov 03 '15 at 21:26
  • The device is a Sony Xperia Z1 which has the opencllib.so available. I was able to run the example application from Sony and it worked fine and fast. The logcat gives only a lot of libEGL output. Nothing about T-API. Last three rows are:`11-03 22:52:53.415 21768-21794/com.sony.openclexample1 D/libEGL: glEndTilingQCOM(0x00000001); 11-03 22:52:53.418 21768-21794/com.sony.openclexample1 D/libEGL: glGetError(); 11-03 22:52:57.760 21768-21768/com.sony.openclexample1 I/JNIpart: OpenCL code on the GPU took 3034.24 ms` – beniroquai Nov 03 '15 at 21:56
  • So did you follow the instructions in your link regarding `-DWITH_OPENCL=YES` and `System.loadLibrary("opencv_java3")`? – Morrison Chang Nov 03 '15 at 21:59
  • Actually not. I'm not that familiar with "building" stuff. I've just downloaded OpenCV 3.0 Android from their side and put it into a Gradle module. Could you give a good website which shows the steps? I've updated the Android.mk above, that should work without the OpenCV Manager App, right? – beniroquai Nov 03 '15 at 22:05
  • Ah then you are using the regular OpenCV and the stuff with OpenCL isn't even setup. Without changing the code in the app to use a different library you'll use the Manager App. OpenCL has device/platform specific (i.e. NVidia OpenCL driver would be different than Samsung or Qualcomm) and not supported in regular Android. Sorry regarding steps - best is to learn about Android NDK as the code in the tutorial was C/C++ – Morrison Chang Nov 03 '15 at 22:25
  • Sorry, I don't want to extend this thread to infinity, but I'm sure everything is set up correclty. I've tried to use the App wihtout the manager installed and it works. The *.so files are included in the App. Maybe I just need to build the OpenCV for Android with the `-DWITH_OPENCL=YES flag`? When I try to compile the OpenCV Tutorial 4 (OpenCV with OpenCL) there is a compiling error: `error: 'attachContext' is not a member of 'cv::ocl'` could this be due to wrong build? Thank you very much!! – beniroquai Nov 03 '15 at 23:04

1 Answers1

2

Ok, I was able to make it work..Somehow. I recompiled OpenCV and inlcuded the OCL/OpenCL part into the build using this:

set PATH=%PATH%; PATH/TO/NINJA/ninja.exe
mkdir OpenCVCL3
cd OpenCVCL3
cmake -GNinja -DCMAKE_MAKE_PROGRAM="PATH/TO/NINJA//ninja.exe" -DCMAKE_TOOLCHAIN_FILE=PATH/TO/OPENCV3/platforms/android/android.toolchain.cmake -DANDROID_ABI="armeabi-v7a with NEON" -DCMAKE_BUILD_WITH_INSTALL_RPATH=ON -DWITH_OPENCL=YES PATH/TO/OPENCV3
path/to/ninja.exe install/strip

Computation Time hasn't decreased compared to CPU-Version of code.

Another more general question: The Xperia Z1 (Snapdragon Adreno 330) uses OpenCL 1.1 in KitKat originally. Does it cause major problems, when using Lollipop instead? The log says, that OCL-Version of OpenCV has been initialized succesfully. Program works ok, but is slow!

beniroquai
  • 166
  • 2
  • 13