GVKun编程网logo

linux 下编译支持 opencl 的 opencv for android(linux编译opencv源码)

2

本文将分享linux下编译支持opencl的opencvforandroid的详细内容,并且还将对linux编译opencv源码进行详尽解释,此外,我们还将为大家带来关于36篇博文带你学完opencv

本文将分享linux 下编译支持 opencl 的 opencv for android的详细内容,并且还将对linux编译opencv源码进行详尽解释,此外,我们还将为大家带来关于36 篇博文带你学完 opencv :python+opencv 进阶版学习笔记目录、Android 7.0 及以上使用 OpenCL、Android AARCH64 平台的 OpenCL 配置、Android OpenCV(零):OpenCV Android SDK的相关知识,希望对你有所帮助。

本文目录一览:

linux 下编译支持 opencl 的 opencv for android(linux编译opencv源码)

linux 下编译支持 opencl 的 opencv for android(linux编译opencv源码)

主要的步骤其他人已经写过,请参考这篇:https://www.cnblogs.com/hrlnw/p/4720977.html

操作的细节请参考附件的 pdf:  https://files.cnblogs.com/files/ahfuzhang/opencvwithopencl4androidndk-141129030940-conversion-gate02.pdf.zip

用于测试的代码如下:

//jpg2gary.cpp
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <opencv2/core.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/core/ocl.hpp>
#include <fstream>

#ifndef P
#define P(format, ...)                                                    \
    do {                                                                  \
        printf("%s %s %d " format "\n", __FILE__, __FUNCTION__, __LINE__, \
               ##__VA_ARGS__);                                            \
        fflush(stdout);                                                   \
    } while (0);
#endif

void cpu(const char* img, int times) {
    cv::Mat image = cv::imread(img, cv::IMREAD_UNCHANGED);
    cv::Mat out;
    struct timeval start, end;
    gettimeofday(&start, NULL);
    for (int i = 0; i < times; i++) {
        cv::cvtColor(image, out, cv::COLOR_BGR2GRAY);
    }
    gettimeofday(&end, NULL);
    P("run times:%d, spend:%d ms", times, (end.tv_sec - start.tv_sec) * 1000 +
                                       (end.tv_usec - start.tv_usec) / 1000);
}

void opencl(const char* img, int times) {
    cv::Mat image = cv::imread(img, cv::IMREAD_UNCHANGED);
    //cv::UMat u_img = image.getUMat(cv::ACCESS_READ);
    cv::UMat u_img;
    image.copyTo(u_img);
    cv::UMat out;
    struct timeval start, end;
    gettimeofday(&start, NULL);
    for (int i = 0; i < times; i++) {
        cv::cvtColor(u_img, out, cv::COLOR_BGR2GRAY);
    }
    gettimeofday(&end, NULL);
    P("run times:%d, spend:%d ms", times, (end.tv_sec - start.tv_sec) * 1000 +
                                       (end.tv_usec - start.tv_usec) / 1000);
}

int init_col(){
    cv::ocl::setUseOpenCL(true);
  if (!cv::ocl::haveOpenCL()) {
    P("OpenCL is not available...");
    return -1;
  }
  cv::ocl::Context context;
  if (!context.create(cv::ocl::Device::TYPE_GPU)) {
    P("Failed creating the context...");
    return -1;
  }
  std::vector<cv::ocl::PlatformInfo> platform_info;
  cv::ocl::getPlatfomsInfo(platform_info);
  for (int i = 0; i < platform_info.size(); i++) {
    cv::ocl::PlatformInfo sdk = platform_info.at(i);
    for (int j = 0; j < sdk.deviceNumber(); j++) {
      cv::ocl::Device device;
      sdk.getDevice(device, j);

      std::cout << "\n\n*********************\n Device " << i + 1 << std::endl;
      std::cout << "Vendor ID: " << device.vendorID() << std::endl;
      std::cout << "Vendor name: " << device.vendorName() << std::endl;
      std::cout << "Name: " << device.name() << std::endl;
      std::cout << "Driver version: " << device.driverVersion() << std::endl;
      std::cout << "available: " << device.available() << std::endl;

      if (device.isAMD()) std::cout << "Is an AMD device" << std::endl;
      if (device.isIntel()) std::cout << "Is a Intel device" << std::endl;

      std::cout << "Global Memory size: " << device.globalMemSize()
                << std::endl;
      std::cout << "Memory cache size: " << device.globalMemCacheSize()
                << std::endl;
      std::cout << "Memory cache type: " << device.globalMemCacheType()
                << std::endl;
      std::cout << "Local Memory size: " << device.localMemSize() << std::endl;
      std::cout << "Local Memory type: " << device.localMemType() << std::endl;
      std::cout << "Max Clock frequency: " << device.maxClockFrequency()
                << std::endl;
    }
  }
  if (!cv::ocl::haveOpenCL()) {
    P("OpenCL is not available, again...");
    return -1;
  }  
  cv::ocl::Device(context.device(0));   
  return 0; 
}

int main(int argc, char* argv[]) {
    if (argc < 3) {
        printf("usage:%s <from> <cpu/opencl> [times=1]\n", argv[0]);
        return 0;
    }
    int times = 1;
    if (argc >= 4) {
        times = atoi(argv[3]);
    }
    if (strcmp(argv[2], "cpu") == 0) {
        cpu(argv[1], times);
    } else if (strcmp(argv[2], "opencl") == 0) {
        if (0!=init_col()){
            return 1;
        }
        opencl(argv[1], times);
    } else {
        P("unknow cpu/opencl");
        return 0;
    }

    return 1;
}

  

使用 xiaomi mix 2s, 高通骁龙 845, GPU Adreno 630, 对一张 1080*1443 尺寸的图片使用 cvtColor 转换 RGB 到灰度。
连续执行 1000 次:
   CPU  595ms
   OpenCL  96ms

加速 6.2 倍!

 



 

36 篇博文带你学完 opencv :python+opencv 进阶版学习笔记目录

36 篇博文带你学完 opencv :python+opencv 进阶版学习笔记目录

基础版学习笔记传送门
36 篇博文带你学完 opencv :python3+opencv 学习笔记汇总目录(基础版)

进阶版笔记

项目
opencv 进阶学习笔记 1: 调用摄像头用法大全(打开摄像头,打开摄像头并实时不断截屏,读取视频并截图)
opencv 进阶学习笔记 2:numpy 操作图像,色彩空间,查找指定颜色范围,通道分离与合并
opencv 进阶学习笔记 3:像素运算和图像亮度对比度调节
opencv 进阶学习笔记 4:ROI 和泛洪扩充
opencv 进阶学习笔记 5:图像模糊操作,图像锐化,边缘保留滤波 EPF(图像滤镜)
opencv 进阶学习笔记 6:使用鼠标在图像上绘制矩形框或者多边形框
opencv 进阶学习笔记 7:直方图,直方图均衡化,直方图比较,直方图反向投影
opencv 进阶学习笔记 8:模板匹配
opencv 进阶学习 9:图像阈值大全,图像二值化,超大图像二值化
opencv 进阶学习笔记 10:图像金字塔和图像梯度
opencv 进阶学习笔记 11:cannny 边缘检测,直线检测,圆检测
opencv 进阶学习笔记 12:轮廓发现和对象测量
opencv 进阶学习笔记 13:图像形态学操作大全(膨胀,腐蚀,开闭,黑帽,顶帽,梯度)python 版
opencv 进阶学习笔记 14:分水岭算法 实现图像分割

OpenCV 告一段落,接下来,该实战啦。
计算机视觉三大任务,分类,监测,分割。
意见其他一些任务…
图像生成,OCR…


电气专业的计算机萌新,写博文不容易,如果你觉得本文对你有用,请点个赞支持下,谢谢。

Android 7.0 及以上使用 OpenCL

Android 7.0 及以上使用 OpenCL

由于从 Android 7.0, API 24, 开始,系统将阻止应用链接至非公开 NDK 库 , 所以,使用 libOpenCL.so 时与面向低版本的 Android 平台有所不同,需要把依赖的非公开 NDK 库打包到 APK 中

确定依赖的库

首先应该确定你所使用的 libOpenC.so 所依赖的库,使用命令 objdump -x libOpenCL.so | grep NEEDED, iI4jVH.png 这是在我的手机上面测试的情况,那么我们需要做的是从手机上面,把这些库全部 pull 出来,然后打包到 APK 中. (在本例中,libc.so 和 libm.so 是公开 NDK 库,可以不用打包,所以下面中没有打包)

打包依赖库

先是从手机 /system/lib/ 目录下面把这些库 pull 出来,然后把他们全部放到 AndroidStudio 工程的 jniLibs 目录下面,
iI4Oqe.png
然后在 CMakeLists.txt 中添加这些库

add_library(libOpenCL SHARED IMPORTED )
set_target_properties(libOpenCL PROPERTIES IMPORTED_LOCATION "${CMAKE_SOURCE_DIR}/src/main/jniLibs/armeabi-v7a/libOpenCL.so")
add_library(libcutils SHARED IMPORTED )
set_target_properties(libcutils PROPERTIES IMPORTED_LOCATION "${CMAKE_SOURCE_DIR}/src/main/jniLibs/armeabi-v7a/libcutils.so")
add_library(libvndksupport SHARED IMPORTED )
set_target_properties(libcutils PROPERTIES IMPORTED_LOCATION "${CMAKE_SOURCE_DIR}/src/main/jniLibs/armeabi-v7a/libvndksupport.so")
add_library(libc++ SHARED IMPORTED )
set_target_properties(libcutils PROPERTIES IMPORTED_LOCATION "${CMAKE_SOURCE_DIR}/src/main/jniLibs/armeabi-v7a/libc++.so")

这样应该就没问题了,如果执行时还有找不到库的报错,按照同样的方法添加对相应库的依赖即可.

Android AARCH64 平台的 OpenCL 配置

Android AARCH64 平台的 OpenCL 配置

原文地址:Android AARCH64 平台的 OpenCL 配置

Android AARCH64 平台的 OpenCL 配置

开发环境

IDE: Android Studio 3.4.1

Android: 7.1

minSdkVersion: 25

targetSdkVersion: 26

JNI CMake: 3.4.1

ABI: arm64-v8a

OpenCL: 1.2

配置 OpenCL 使用项目中的 so 库

这里以编译 openclTest.cpp 为 libopenclTest.so 并导入 OpenCL 的动态库为例

注 1: 下列 so 库需要从开发板上 pull 到项目中,其中 libGLES_mali.so 用于驱动 OpenCL,其他库为依赖库

注 2: 不同平台的驱动库位于不同位置,可以下载 OpenCL-Z 查看

注 3: set_target_properties 中第一项参数设置了生成库的名称,例如设置为 openclTest,则生成 libopenclTest.so 库,这里使用了 lib_* 作为前缀,则生成 liblib_*.so 库,实际开发中要避免这种情况

查看依赖库

objdump -x libGLES_mali.so | grep NEEDED

目录结构

opencltest
├─ app
│  ├─ build
│  ├─ libs
│  └─ src
│      ├─ androidTest
│      ├─ main
│      │  ├─ java
│      │  │  └─ com
│      │  │      └─ example
│      │  │          └─ opencltest
│      │  │                  MainActivity.java
│      │  ├─ jni    #C/C++ 源码目录
│      │  │  └─ openclTest.cpp
│      │  ├─ jniLibs    #JNI 需要调用的运行库
│      │  │  └─ arm64-v8a   #对应 ABI 版本建立文件夹
│      │  │      ├─ libbinder.so
│      │  │      ├─ libc++.so
│      │  │      ├─ libc.so
│      │  │      ├─ libcrypto.so
│      │  │      ├─ libcutils.so
│      │  │      ├─ libdl.so
│      │  │      ├─ libGLES_mali.so
│      │  │      ├─ libhardware.so
│      │  │      ├─ liblog.so
│      │  │      ├─ libm.so
│      │  │      ├─ libui.so
│      │  │      ├─ libutils.so
│      │  │      └─ libz.so
│      │  └─ res
│      └─ test
└─ gradle

CMakeLists.txt 增加配置

add_library(openclTest
        SHARED
        src/main/jni/openclTest.cpp )

add_library(lib_opencl SHARED IMPORTED)

set_target_properties(lib_opencl
        PROPERTIES
        IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libGLES_mali.so )

add_library(lib_z SHARED IMPORTED)
set_target_properties(lib_z
        PROPERTIES
        IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libz.so )

add_library(lib_log SHARED IMPORTED)
set_target_properties(lib_log
        PROPERTIES
        IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/liblog.so )

add_library(lib_utils SHARED IMPORTED)
set_target_properties(lib_utils
        PROPERTIES
        IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libutils.so )

add_library(lib_ui SHARED IMPORTED)
set_target_properties(lib_ui
        PROPERTIES
        IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libui.so )

add_library(lib_cutils SHARED IMPORTED)
set_target_properties(lib_cutils
        PROPERTIES
        IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libcutils.so )

add_library(lib_binder SHARED IMPORTED)
set_target_properties(lib_binder
        PROPERTIES
        IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libbinder.so )

add_library(lib_crypto SHARED IMPORTED)
set_target_properties(lib_crypto
        PROPERTIES
        IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libcrypto.so )

add_library(lib_dl SHARED IMPORTED)
set_target_properties(lib_dl
        PROPERTIES
        IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libdl.so )

add_library(lib_hardware SHARED IMPORTED)
set_target_properties(lib_hardware
        PROPERTIES
        IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libhardware.so )

add_library(lib_c++ SHARED IMPORTED)
set_target_properties(lib_c++
        PROPERTIES
        IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libc++.so )

add_library(lib_c SHARED IMPORTED)
set_target_properties(lib_c
        PROPERTIES
        IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libc.so )

add_library(lib_m SHARED IMPORTED)
set_target_properties(lib_m
        PROPERTIES
        IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libm.so )

target_link_libraries(openclTest
        ${log-lib}
        lib_opencl )

配置 OpenCL 使用 dlopen 打开开发板上的运行库

这种配置方法需要从 Github - KhronosGroup/OpenCL-Headers 仓库下载 OpenCL 的头文件,并且需要自行实现 OpenCL 的函数

注:需要在源码中定义 CL_TARGET_OPENCL_VERSION 120,否则会报找不到版本号的错误

目录结构

opencltest
├─ app
│  ├─ build
│  ├─ libs
│  └─ src
│      ├─ androidTest
│      ├─ main
│      │  ├─ java
│      │  │  └─ com
│      │  │      └─ example
│      │  │          └─ opencltest
│      │  │                  MainActivity.java
│      │  ├─ jni    #C/C++ 源码目录
│      │  │  ├─ dlopencl.cpp    #dlopen 打开运行库,实现 OpenCL 中的函数
│      │  │  ├─ openclTest.cpp  
│      │  │  └─ include     #JNI 调用的头文件
│      │  │      ├─ dlopencl.h  #定义 OpenCL 中的函数
│      │  │      └─ CL      #OpenCL 需要使用的头文件
│      │  │          ├─ cl.h
│      │  │          ├─ cl_ext.h
│      │  │          ├─ cl_gl.h
│      │  │          ├─ cl_gl_ext.h
│      │  │          ├─ cl_platform.h
│      │  │          ├─ cl_version.h
│      │  │          └─ opencl.h
│      │  └─ res
│      └─ test
└─ gradle

CMakeLists.txt 增加配置

include_directories(${PROJECT_SOURCE_DIR}/src/main/jni/include)

add_library(openclTest
        SHARED
        src/main/jni/openclTest.cpp )

add_library(lib_dlopencl
        SHARED
        src/main/jni/dlopencl.cpp )

target_link_libraries(openclTest
        ${log-lib}
        lib_dlopencl )

需要导入的 dlopencl.h 和 dlopencl.cpp 写在文末

OpenCL 使用

以下均以使用 dlopen 导入运行库的方式为例

  1. 定义 OpenCL 版本
#define CL_TARGET_OPENCL_VERSION 120
  1. 包含头文件
#include <CL/cl.h>
#include "dlopencl.h"
  1. 使用 Logcat 打印日志

由于 C 语言工作在 JNI 层,无法获取控制台,导致了 printf () 函数失效,这里使用 __android_log_print 方法打印日志到 Logcat

#include <android/log.h>

#define DEBUG

#ifdef DEBUG
#define LOG    "LOG-TAG"
#define LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG, LOG, __VA_ARGS__)
#define LOGI(...)  __android_log_print(ANDROID_LOG_INFO, LOG, __VA_ARGS__)
#define LOGW(...)  __android_log_print(ANDROID_LOG_WARN, LOG, __VA_ARGS__)
#define LOGE(...)  __android_log_print(ANDROID_LOG_ERROR, LOG, __VA_ARGS__)
#define LOGF(...)  __android_log_print(ANDROID_LOG_FATAL, LOG, __VA_ARGS__)
#else
#define LOG
#define LOGD(...)
#define LOGI(...)
#define LOGW(...)
#define LOGE(...)
#define LOGF(...)
#endif

使用方法同 printf (),例:

LOGI("Device ID: %d", device_id);
  1. 创建用于初始化 OpenCL 的 JNI 接口

建议在同一个文件中编写多个操作 OpenCL 的函数,这里的初始化实际上是将操作 OpenCL 的变量建立为全局变量,通过 JNI 一次调用后其他函数再使用这些被初始化过的变量

定义变量

cl_uint num_device;
cl_uint num_platform;
cl_platform_id *platform;
cl_device_id *devices;
cl_int err;
cl_context context;
extern "C"
JNIEXPORT jint JNICALL
Java_com_example_opencltest_MainActivity_initOpencl(JNIEnv *env, jobject instance) {
    initFns();
    LOGI("getPlatformNum");
    // 获取可用平台数量
    err = clGetPlatformIDs(0, 0, &num_platform);
    platform = (cl_platform_id*)malloc(sizeof(cl_platform_id)*num_platform);
    LOGI("getPlatformIDs");
    // 获取平台 ID
    err = clGetPlatformIDs(num_platform, platform, nullptr);
    if(err < 0) {
        LOGE("clGetPlatformIDs failed");
        return -1;
    }

    LOGI("getDeviceNum");
    // 获取可用设备数量
    err = clGetDeviceIDs(platform[0], CL_DEVICE_TYPE_GPU, 0, nullptr, &num_device);
    devices = (cl_device_id*)malloc(sizeof(cl_device_id)*num_device);
    LOGI("getDeviceIDs");
    // 获取设备 ID
    err = clGetDeviceIDs(platform[0], CL_DEVICE_TYPE_GPU, num_device, devices, nullptr);
    if (err < 0) {
        LOGE("clGetDeviceIDs failed");
        return -1;
    }

    return 0;
}

使用 OpenCL 执行 Kernel 函数

通常编写 OpenCL 中的 Kernel 函数要求单独写在 *.cl 文件中,调用时使用 fopen 打开,将里面的代码作为字符串读入之后再进行 runtime 编译,比较麻烦,这里直接将整个 Kernel 函数写成字符串

本例中因为测试原因没有释放掉创建的资源

可以使用允许正则替换的编辑器例如 VSCode,先写好 Kernel 函数,然后使用正则表达式 (.*) 选择所有行并将每一行作为一个参数 ($1),替换为 "$1\\n",例如替换前: int a = 0;,替换后: "int a = 0;\n"

注 1: 经测试发现 OpenCL 在 PC 端允许每次调用任意数量的矢量数据,而在开发板上只允许一次调用 1.2.3.4.8.16 个

PC 端允许的矢量调用:

Integralgraph.s0
Integralgraph.s01
Integralgraph.s012
Integralgraph.s0123
Integralgraph.s01234
Integralgraph.s0123456
Integralgraph.s01234567
Integralgraph.s012345678
Integralgraph.s0123456789
Integralgraph.s0123456789a
Integralgraph.s0123456789ab
Integralgraph.s0123456789abc
Integralgraph.s0123456789abcd
Integralgraph.s0123456789abcde
Integralgraph.s0123456789abcdef

开发板允许的矢量调用:

Integralgraph.s0
Integralgraph.s01
Integralgraph.s012
Integralgraph.s0123
Integralgraph.s01234567
Integralgraph.s0123456789abcdef

所以在编写运行于 AARCH64 架构的 OpenCL Kernel 函数时需要将被调用的矢量数组分组相加

例如在 PC 端为

TableInteg1 = (int16)(Integralgraph[index1].sf*flagx0, Integralgraph[index4].s0123456789abcde);

在开发板中需要改为

TableInteg1 = (int16)(Integralgraph[index1].sf*flagx0, Integralgraph[index4].s01234567, Integralgraph[index4].s89ab, Integralgraph[index4].scde);

注 2: 测试中发现 PC 端的 OpenCL 遇到数组越界问题会直接跳过不予处理,但在 AARCH64 中会导致执行失败

注 3: AARCH64 平台上 OpenCL 能申请到的可调用内存远小于 PC 端,如果出现输入或输出的数据超出 OpenCL 申请到的内存可能会导致数据输出不完整,读取数据时错误代码返回 -14 等问题

先在 Activity 中调用 initOpencl (),初始化 OpenCL 及其平台和设备

// 定义积分图宽度
#define CLL_IMAGE_W (400)
// 定义积分图高度
#define CLL_IMAGE_H (80)

// 构建 Kernel 函数字符串
const char *clkernel[] = {
        "__kernel void kernel_Integralgraph_45int(__global int16 * grayImage,\n"
        "    __global int16 * Integralgraph,\n"
        "    __global unsigned * const p_height) {\n"
        "    int x = get_global_id(0);\n"
        "    int height = *p_height;\n"
        "    int width = get_global_size(0);\n"
        "    __local int index, index1, index2, index3, index4, index5;\n"
        "    __local bool flagx0, flagxw, flagy1, flagy2;\n"
        "    __local int16 TableInteg1, TableInteg2, TableInteg3;\n"
        "    flagx0 = min(0, -x);\n"
        "    flagxw = min(0, x - width + 1);\n"
        "    for (int j = 0; j < height; j++) {\n"
        "        flagy1 = min(0, -j);\n"
        "        flagy2 = min(0, 1 - j);\n"
        "        index = j * width + x;\n"
        "        if(j==0) {\n"
        "            Integralgraph[index] = (int16)grayImage[index];\n"
        "        } else if(j==1) {\n"
        "            index1 = (j - 1)*width + x - 1;\n"
        "            index3 = (j - 1)*width + x + 1;\n"
        "            index4 = (j - 1)*width + x;\n"
        "            TableInteg1 = (int16)(Integralgraph[index1].sf*flagx0, Integralgraph[index4].s01234567, Integralgraph[index4].s89ab, Integralgraph[index4].scde);\n"
        "            TableInteg3 = (int16)(Integralgraph[index4].s12345678, Integralgraph[index4].s9abc, Integralgraph[index4].sdef, Integralgraph[index3].s0*flagxw);\n"
        "            Integralgraph[index] = (int16)((int16)TableInteg1*flagy1 + (int16)TableInteg3*flagy1 + (int16)grayImage[index4] * flagy1 + (int16)grayImage[index]);\n"
        "        } else {\n"
        "            index1 = (j - 1)*width + x - 1;\n"
        "            index2 = (j - 2)*width + x;\n"
        "            index3 = (j - 1)*width + x + 1;\n"
        "            index4 = (j - 1)*width + x;\n"
        "            TableInteg1 = (int16)(Integralgraph[index1].sf*flagx0, Integralgraph[index4].s01234567, Integralgraph[index4].s89ab, Integralgraph[index4].scde);\n"
        "            TableInteg2 = (int16)(Integralgraph[index2].s0*flagx0, Integralgraph[index2].s12345678, Integralgraph[index2].s9ab, Integralgraph[index2].scde, Integralgraph[index2].sf*flagxw);\n"
        "            TableInteg3 = (int16)(Integralgraph[index4].s12345678, Integralgraph[index4].s9abc, Integralgraph[index4].sdef, Integralgraph[index3].s0*flagxw);\n"
        "            Integralgraph[index] = (int16)((int16)TableInteg1*flagy1 + (int16)TableInteg3*flagy1 - (int16)TableInteg2 * flagy2 + (int16)grayImage[index4] * flagy1 + (int16)grayImage[index]);\n"
        "        }\n"
        "    }\n"
        "}\n"
};

// 创建 Context
context = clCreateContext(nullptr, 1, devices, nullptr, nullptr, &err);
if(err < 0) {
    LOGE("Create context failed, error code: [%d]", err);
    return -1;
}

int inputData[CLL_IMAGE_W * CLL_IMAGE_H];
int outputData[CLL_IMAGE_W * CLL_IMAGE_H];
int width = CLL_IMAGE_W;
int height = CLL_IMAGE_H;
// 初始化输入输出数据
for (int i = 0; i < height; i++) {
    for (int j = 0; j < width; j++) {
        inputData[i * width + j] = 1;
        outputData[i * width + j] = 0;
    }
}

clock_t time_start;
clock_t time_finish;
double total_time;

char *program_log;
cl_command_queue queue;
cl_kernel kernel;
size_t log_size;
cl_program program;

// 创建命令队列
queue = clCreateCommandQueue(context, devices[0], 0, &err);
if (err < 0) {
    LOGE("Create command queue failed, error code: [%d]", err);
}

// 创建程序
program = clCreateProgramWithSource(context, sizeof(clkernel) / sizeof(clkernel[0]), clkernel, nullptr, nullptr);

// 构建/编译程序
err = clBuildProgram(program, 0, nullptr, nullptr, nullptr, nullptr);
if (err < 0) {
    clGetProgramBuildInfo(program, devices[0], CL_PROGRAM_BUILD_LOG, 0, nullptr, &log_size);
    program_log = (char*)malloc(sizeof(log_size));
    // 查询构建/编译过程中的 log
    clGetProgramBuildInfo(program, devices[0], CL_PROGRAM_BUILD_LOG, log_size, program_log, nullptr);
    LOGE("program_build_info: \n[%s]\n", program_log);
    free(program_log);
}

// 创建 Kernel
kernel = clCreateKernel(program, "kernel_Integralgraph_45int", &err);
if (err < 0) {
    LOGE("Create kernel failed, error code: [%d]", err);
}

// 创建用于输入参数、输出数据的内存空间
cl_mem meminput_buffer = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(int) * height * width, inputData, &err);
cl_mem memoutput_buffer = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(int) * height * width, nullptr, &err);
cl_mem memHeight_buffer = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(int), &height, &err);
// 向 Kernel 传递参数
err = clSetKernelArg(kernel, 0, sizeof(cl_mem), &meminput_buffer);
err = clSetKernelArg(kernel, 1, sizeof(cl_mem), &memoutput_buffer);
err = clSetKernelArg(kernel, 2, sizeof(cl_mem), &memHeight_buffer);

size_t global_work_offset[2] = {0, 0};
size_t localThreads[2] = {1, 1};
size_t globalThreads[2] = {(size_t)(width / 16), 1};

// 获得程序开始执行的时间戳
time_start = clock();

// 排布工作组与工作项并执行
err = clEnqueueNDRangeKernel(queue, kernel, 2, global_work_offset, globalThreads, localThreads, 0, nullptr, nullptr);
if (err < 0) {
    LOGE("Run Kernel failed, error code: [%d]", err);
}

// 获得程序执行完成的时间戳
time_finish = clock();
// 计算运行时间
total_time = (double)(time_finish - time_start) / CLOCKS_PER_SEC;
LOGI("Total time: [%f]s", total_time);

// 从输出的内存空间中读取数据
err = clEnqueueReadBuffer(queue, memoutput_buffer, CL_TRUE, 0, sizeof(int) * height * width, outputData, 0, nullptr, nullptr);
if (err < 0) {
    LOGE("Read buffer failed, error code: [%d]", err);
}

// 输出数据,积分图中的每一行拼接为一条 LOG
char outputDataTemp[2048];
for (int i = 0; i < height ; i++) {
    // 清空字符串,拼接下一行
    memset(outputDataTemp, 0x00, 2048);
    for (int j = 0; j < width ; j++) {
        // 将一行数据拼接在一个字符串中
        sprintf(outputDataTemp, "%s %d", outputDataTemp, outputData[i * width + j]);
    }
    // LOG打印
    LOGI("line [%d]\n%s", i, outputDataTemp);
}

附加

dlopencl.h

#ifndef __AOPENCL_CL_H
#define __AOPENCL_CL_H

#ifdef __APPLE__
#include <OpenCL/cl_platform.h>
#else
#include <CL/cl_platform.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif

#define IAH()
//#define IAH() printf("File:%s, Line:%d\n",__FILE__, __LINE__);

void initFns();

/* Platform API */
#define clGetPlatformIDs aclGetPlatformIDs
cl_int
(*aclGetPlatformIDs)(cl_uint          /* num_entries */,
                     cl_platform_id * /* platforms */,
                     cl_uint *        /* num_platforms */);

#define clGetPlatformInfo aclGetPlatformInfo
cl_int
(*aclGetPlatformInfo)(cl_platform_id   /* platform */,
                      cl_platform_info /* param_name */,
                      size_t           /* param_value_size */,
                      void *           /* param_value */,
                      size_t *         /* param_value_size_ret */);

/* Device APIs */
#define clGetDeviceIDs aclGetDeviceIDs
cl_int
(*aclGetDeviceIDs)(cl_platform_id   /* platform */,
                   cl_device_type   /* device_type */,
                   cl_uint          /* num_entries */,
                   cl_device_id *   /* devices */,
                   cl_uint *        /* num_devices */);

#define clGetDeviceInfo aclGetDeviceInfo
cl_int
(*aclGetDeviceInfo)(cl_device_id    /* device */,
                    cl_device_info  /* param_name */,
                    size_t          /* param_value_size */,
                    void *          /* param_value */,
                    size_t *        /* param_value_size_ret */);




/* Context APIs  */
#define clCreateContext aclCreateContext
cl_context
(*aclCreateContext)(const cl_context_properties * /* properties */,
                    cl_uint                 /* num_devices */,
                    const cl_device_id *    /* devices */,
                    void (CL_CALLBACK * /* pfn_notify */)(const char *, const void *, size_t, void *),
                    void *                  /* user_data */,
                    cl_int *                /* errcode_ret */);

#define clCreateContextFromType aclCreateContextFromType
cl_context
(*aclCreateContextFromType)(const cl_context_properties * /* properties */,
                            cl_device_type          /* device_type */,
                            void (CL_CALLBACK *     /* pfn_notify*/ )(const char *, const void *, size_t, void *),
                            void *                  /* user_data */,
                            cl_int *                /* errcode_ret */);

#define clRetainContext aclRetainContext
cl_int
(*aclRetainContext)(cl_context /* context */);

#define clReleaseContext aclReleaseContext
cl_int
(*aclReleaseContext)(cl_context /* context */);

#define clGetContextInfo aclGetContextInfo
cl_int
(*aclGetContextInfo)(cl_context         /* context */,
                     cl_context_info    /* param_name */,
                     size_t             /* param_value_size */,
                     void *             /* param_value */,
                     size_t *           /* param_value_size_ret */);

/* Command Queue APIs */
#define clCreateCommandQueue aclCreateCommandQueue
cl_command_queue
(*aclCreateCommandQueue)(cl_context                     /* context */,
                         cl_device_id                   /* device */,
                         cl_command_queue_properties    /* properties */,
                         cl_int *                       /* errcode_ret */);

#define clRetainCommandQueue aclRetainCommandQueue
cl_int
(*aclRetainCommandQueue)(cl_command_queue /* command_queue */);

#define clReleaseCommandQueue aclReleaseCommandQueue
cl_int
(*aclReleaseCommandQueue)(cl_command_queue /* command_queue */);

#define clGetCommandQueueInfo aclGetCommandQueueInfo
cl_int
(*aclGetCommandQueueInfo)(cl_command_queue      /* command_queue */,
                          cl_command_queue_info /* param_name */,
                          size_t                /* param_value_size */,
                          void *                /* param_value */,
                          size_t *              /* param_value_size_ret */);

/* Memory Object APIs */
#define clCreateBuffer aclCreateBuffer
cl_mem
(*aclCreateBuffer)(cl_context   /* context */,
                   cl_mem_flags /* flags */,
                   size_t       /* size */,
                   void *       /* host_ptr */,
                   cl_int *     /* errcode_ret */);

#define clCreateSubBuffer aclCreateSubBuffer
cl_mem
(*aclCreateSubBuffer)(cl_mem                   /* buffer */,
                      cl_mem_flags             /* flags */,
                      cl_buffer_create_type    /* buffer_create_type */,
                      const void *             /* buffer_create_info */,
                      cl_int *                 /* errcode_ret */);


#define clRetainMemObject aclRetainMemObject
cl_int
(*aclRetainMemObject)(cl_mem /* memobj */);

#define clReleaseMemObject aclReleaseMemObject
cl_int
(*aclReleaseMemObject)(cl_mem /* memobj */);

#define clGetSupportedImageFormats aclGetSupportedImageFormats
cl_int
(*aclGetSupportedImageFormats)(cl_context           /* context */,
                               cl_mem_flags         /* flags */,
                               cl_mem_object_type   /* image_type */,
                               cl_uint              /* num_entries */,
                               cl_image_format *    /* image_formats */,
                               cl_uint *            /* num_image_formats */);

#define clGetMemObjectInfo aclGetMemObjectInfo
cl_int
(*aclGetMemObjectInfo)(cl_mem           /* memobj */,
                       cl_mem_info      /* param_name */,
                       size_t           /* param_value_size */,
                       void *           /* param_value */,
                       size_t *         /* param_value_size_ret */);

#define clGetImageInfo aclGetImageInfo
cl_int
(*aclGetImageInfo)(cl_mem           /* image */,
                   cl_image_info    /* param_name */,
                   size_t           /* param_value_size */,
                   void *           /* param_value */,
                   size_t *         /* param_value_size_ret */);

#define clSetMemObjectDestructorCallback aclSetMemObjectDestructorCallback
cl_int
(*aclSetMemObjectDestructorCallback)(  cl_mem /* memobj */,
                                       void (CL_CALLBACK * /*pfn_notify*/)( cl_mem /* memobj */, void* /*user_data*/),
                                       void * /*user_data */ );

/* Sampler APIs */
#define clCreateSampler aclCreateSampler
cl_sampler
(*aclCreateSampler)(cl_context          /* context */,
                    cl_bool             /* normalized_coords */,
                    cl_addressing_mode  /* addressing_mode */,
                    cl_filter_mode      /* filter_mode */,
                    cl_int *            /* errcode_ret */);

#define clRetainSampler aclRetainSampler
cl_int
(*aclRetainSampler)(cl_sampler /* sampler */);

#define clReleaseSampler aclReleaseSampler
cl_int
(*aclReleaseSampler)(cl_sampler /* sampler */);

#define clGetSamplerInfo aclGetSamplerInfo
cl_int
(*aclGetSamplerInfo)(cl_sampler         /* sampler */,
                     cl_sampler_info    /* param_name */,
                     size_t             /* param_value_size */,
                     void *             /* param_value */,
                     size_t *           /* param_value_size_ret */);

/* Program Object APIs  */
#define clCreateProgramWithSource aclCreateProgramWithSource
cl_program
(*aclCreateProgramWithSource)(cl_context        /* context */,
                              cl_uint           /* count */,
                              const char **     /* strings */,
                              const size_t *    /* lengths */,
                              cl_int *          /* errcode_ret */);

#define clCreateProgramWithBinary aclCreateProgramWithBinary
cl_program
(*aclCreateProgramWithBinary)(cl_context                     /* context */,
                              cl_uint                        /* num_devices */,
                              const cl_device_id *           /* device_list */,
                              const size_t *                 /* lengths */,
                              const unsigned char **         /* binaries */,
                              cl_int *                       /* binary_status */,
                              cl_int *                       /* errcode_ret */);


#define clRetainProgram aclRetainProgram
cl_int
(*aclRetainProgram)(cl_program /* program */);

#define clReleaseProgram aclReleaseProgram
cl_int
(*aclReleaseProgram)(cl_program /* program */);

#define clBuildProgram aclBuildProgram
cl_int
(*aclBuildProgram)(cl_program           /* program */,
                   cl_uint              /* num_devices */,
                   const cl_device_id * /* device_list */,
                   const char *         /* options */,
                   void (CL_CALLBACK *  /* pfn_notify */)(cl_program /* program */, void * /* user_data */),
                   void *               /* user_data */);





#define clGetProgramInfo aclGetProgramInfo
cl_int
(*aclGetProgramInfo)(cl_program         /* program */,
                     cl_program_info    /* param_name */,
                     size_t             /* param_value_size */,
                     void *             /* param_value */,
                     size_t *           /* param_value_size_ret */);

#define clGetProgramBuildInfo aclGetProgramBuildInfo
cl_int
(*aclGetProgramBuildInfo)(cl_program            /* program */,
                          cl_device_id          /* device */,
                          cl_program_build_info /* param_name */,
                          size_t                /* param_value_size */,
                          void *                /* param_value */,
                          size_t *              /* param_value_size_ret */);

/* Kernel Object APIs */
#define clCreateKernel aclCreateKernel
cl_kernel
(*aclCreateKernel)(cl_program      /* program */,
                   const char *    /* kernel_name */,
                   cl_int *        /* errcode_ret */);

#define clCreateKernelsInProgram aclCreateKernelsInProgram
cl_int
(*aclCreateKernelsInProgram)(cl_program     /* program */,
                             cl_uint        /* num_kernels */,
                             cl_kernel *    /* kernels */,
                             cl_uint *      /* num_kernels_ret */);

#define clRetainKernel aclRetainKernel
cl_int
(*aclRetainKernel)(cl_kernel    /* kernel */);

#define clReleaseKernel aclReleaseKernel
cl_int
(*aclReleaseKernel)(cl_kernel   /* kernel */);

#define clSetKernelArg aclSetKernelArg
cl_int
(*aclSetKernelArg)(cl_kernel    /* kernel */,
                   cl_uint      /* arg_index */,
                   size_t       /* arg_size */,
                   const void * /* arg_value */);

#define clGetKernelInfo aclGetKernelInfo
cl_int
(*aclGetKernelInfo)(cl_kernel       /* kernel */,
                    cl_kernel_info  /* param_name */,
                    size_t          /* param_value_size */,
                    void *          /* param_value */,
                    size_t *        /* param_value_size_ret */);


#define clGetKernelWorkGroupInfo aclGetKernelWorkGroupInfo
cl_int
(*aclGetKernelWorkGroupInfo)(cl_kernel                  /* kernel */,
                             cl_device_id               /* device */,
                             cl_kernel_work_group_info  /* param_name */,
                             size_t                     /* param_value_size */,
                             void *                     /* param_value */,
                             size_t *                   /* param_value_size_ret */);

/* Event Object APIs */
#define clWaitForEvents aclWaitForEvents
cl_int
(*aclWaitForEvents)(cl_uint             /* num_events */,
                    const cl_event *    /* event_list */);

#define clGetEventInfo aclGetEventInfo
cl_int
(*aclGetEventInfo)(cl_event         /* event */,
                   cl_event_info    /* param_name */,
                   size_t           /* param_value_size */,
                   void *           /* param_value */,
                   size_t *         /* param_value_size_ret */);

#define clCreateUserEvent aclCreateUserEvent
cl_event
(*aclCreateUserEvent)(cl_context    /* context */,
                      cl_int *      /* errcode_ret */);

#define clRetainEvent aclRetainEvent
cl_int
(*aclRetainEvent)(cl_event /* event */);

#define clReleaseEvent aclReleaseEvent
cl_int
(*aclReleaseEvent)(cl_event /* event */);

#define clSetUserEventStatus aclSetUserEventStatus
cl_int
(*aclSetUserEventStatus)(cl_event   /* event */,
                         cl_int     /* execution_status */);

#define clSetEventCallback aclSetEventCallback
cl_int
(*aclSetEventCallback)( cl_event    /* event */,
                        cl_int      /* command_exec_callback_type */,
                        void (CL_CALLBACK * /* pfn_notify */)(cl_event, cl_int, void *),
                        void *      /* user_data */);

/* Profiling APIs */
#define clGetEventProfilingInfo aclGetEventProfilingInfo
cl_int
(*aclGetEventProfilingInfo)(cl_event            /* event */,
                            cl_profiling_info   /* param_name */,
                            size_t              /* param_value_size */,
                            void *              /* param_value */,
                            size_t *            /* param_value_size_ret */);

/* Flush and Finish APIs */
#define clFlush aclFlush
cl_int
(*aclFlush)(cl_command_queue /* command_queue */);

#define clFinish aclFinish
cl_int
(*aclFinish)(cl_command_queue /* command_queue */);

/* Enqueued Commands APIs */
#define clEnqueueReadBuffer aclEnqueueReadBuffer
cl_int
(*aclEnqueueReadBuffer)(cl_command_queue    /* command_queue */,
                        cl_mem              /* buffer */,
                        cl_bool             /* blocking_read */,
                        size_t              /* offset */,
                        size_t              /* size */,
                        void *              /* ptr */,
                        cl_uint             /* num_events_in_wait_list */,
                        const cl_event *    /* event_wait_list */,
                        cl_event *          /* event */);

#define clEnqueueReadBufferRect aclEnqueueReadBufferRect
cl_int
(*aclEnqueueReadBufferRect)(cl_command_queue    /* command_queue */,
                            cl_mem              /* buffer */,
                            cl_bool             /* blocking_read */,
                            const size_t *      /* buffer_offset */,
                            const size_t *      /* host_offset */,
                            const size_t *      /* region */,
                            size_t              /* buffer_row_pitch */,
                            size_t              /* buffer_slice_pitch */,
                            size_t              /* host_row_pitch */,
                            size_t              /* host_slice_pitch */,
                            void *              /* ptr */,
                            cl_uint             /* num_events_in_wait_list */,
                            const cl_event *    /* event_wait_list */,
                            cl_event *          /* event */);

#define clEnqueueWriteBuffer aclEnqueueWriteBuffer
cl_int
(*aclEnqueueWriteBuffer)(cl_command_queue   /* command_queue */,
                         cl_mem             /* buffer */,
                         cl_bool            /* blocking_write */,
                         size_t             /* offset */,
                         size_t             /* size */,
                         const void *       /* ptr */,
                         cl_uint            /* num_events_in_wait_list */,
                         const cl_event *   /* event_wait_list */,
                         cl_event *         /* event */);

#define clEnqueueWriteBufferRect aclEnqueueWriteBufferRect
cl_int
(*aclEnqueueWriteBufferRect)(cl_command_queue    /* command_queue */,
                             cl_mem              /* buffer */,
                             cl_bool             /* blocking_write */,
                             const size_t *      /* buffer_offset */,
                             const size_t *      /* host_offset */,
                             const size_t *      /* region */,
                             size_t              /* buffer_row_pitch */,
                             size_t              /* buffer_slice_pitch */,
                             size_t              /* host_row_pitch */,
                             size_t              /* host_slice_pitch */,
                             const void *        /* ptr */,
                             cl_uint             /* num_events_in_wait_list */,
                             const cl_event *    /* event_wait_list */,
                             cl_event *          /* event */);


#define clEnqueueCopyBuffer aclEnqueueCopyBuffer
cl_int
(*aclEnqueueCopyBuffer)(cl_command_queue    /* command_queue */,
                        cl_mem              /* src_buffer */,
                        cl_mem              /* dst_buffer */,
                        size_t              /* src_offset */,
                        size_t              /* dst_offset */,
                        size_t              /* size */,
                        cl_uint             /* num_events_in_wait_list */,
                        const cl_event *    /* event_wait_list */,
                        cl_event *          /* event */);

#define clEnqueueCopyBufferRect aclEnqueueCopyBufferRect
cl_int
(*aclEnqueueCopyBufferRect)(cl_command_queue    /* command_queue */,
                            cl_mem              /* src_buffer */,
                            cl_mem              /* dst_buffer */,
                            const size_t *      /* src_origin */,
                            const size_t *      /* dst_origin */,
                            const size_t *      /* region */,
                            size_t              /* src_row_pitch */,
                            size_t              /* src_slice_pitch */,
                            size_t              /* dst_row_pitch */,
                            size_t              /* dst_slice_pitch */,
                            cl_uint             /* num_events_in_wait_list */,
                            const cl_event *    /* event_wait_list */,
                            cl_event *          /* event */);

#define clEnqueueReadImage aclEnqueueReadImage
cl_int
(*aclEnqueueReadImage)(cl_command_queue     /* command_queue */,
                       cl_mem               /* image */,
                       cl_bool              /* blocking_read */,
                       const size_t *       /* origin[3] */,
                       const size_t *       /* region[3] */,
                       size_t               /* row_pitch */,
                       size_t               /* slice_pitch */,
                       void *               /* ptr */,
                       cl_uint              /* num_events_in_wait_list */,
                       const cl_event *     /* event_wait_list */,
                       cl_event *           /* event */);

#define clEnqueueWriteImage aclEnqueueWriteImage
cl_int
(*aclEnqueueWriteImage)(cl_command_queue    /* command_queue */,
                        cl_mem              /* image */,
                        cl_bool             /* blocking_write */,
                        const size_t *      /* origin[3] */,
                        const size_t *      /* region[3] */,
                        size_t              /* input_row_pitch */,
                        size_t              /* input_slice_pitch */,
                        const void *        /* ptr */,
                        cl_uint             /* num_events_in_wait_list */,
                        const cl_event *    /* event_wait_list */,
                        cl_event *          /* event */);


#define clEnqueueCopyImage aclEnqueueCopyImage
cl_int
(*aclEnqueueCopyImage)(cl_command_queue     /* command_queue */,
                       cl_mem               /* src_image */,
                       cl_mem               /* dst_image */,
                       const size_t *       /* src_origin[3] */,
                       const size_t *       /* dst_origin[3] */,
                       const size_t *       /* region[3] */,
                       cl_uint              /* num_events_in_wait_list */,
                       const cl_event *     /* event_wait_list */,
                       cl_event *           /* event */);

#define clEnqueueCopyImageToBuffer aclEnqueueCopyImageToBuffer
cl_int
(*aclEnqueueCopyImageToBuffer)(cl_command_queue /* command_queue */,
                               cl_mem           /* src_image */,
                               cl_mem           /* dst_buffer */,
                               const size_t *   /* src_origin[3] */,
                               const size_t *   /* region[3] */,
                               size_t           /* dst_offset */,
                               cl_uint          /* num_events_in_wait_list */,
                               const cl_event * /* event_wait_list */,
                               cl_event *       /* event */);

#define clEnqueueCopyBufferToImage aclEnqueueCopyBufferToImage
cl_int
(*aclEnqueueCopyBufferToImage)(cl_command_queue /* command_queue */,
                               cl_mem           /* src_buffer */,
                               cl_mem           /* dst_image */,
                               size_t           /* src_offset */,
                               const size_t *   /* dst_origin[3] */,
                               const size_t *   /* region[3] */,
                               cl_uint          /* num_events_in_wait_list */,
                               const cl_event * /* event_wait_list */,
                               cl_event *       /* event */);

void *
(*aclEnqueueMapBuffer)(cl_command_queue /* command_queue */,
                       cl_mem           /* buffer */,
                       cl_bool          /* blocking_map */,
                       cl_map_flags     /* map_flags */,
                       size_t           /* offset */,
                       size_t           /* size */,
                       cl_uint          /* num_events_in_wait_list */,
                       const cl_event * /* event_wait_list */,
                       cl_event *       /* event */,
                       cl_int *         /* errcode_ret */);

void *
(*aclEnqueueMapImage)(cl_command_queue  /* command_queue */,
                      cl_mem            /* image */,
                      cl_bool           /* blocking_map */,
                      cl_map_flags      /* map_flags */,
                      const size_t *    /* origin[3] */,
                      const size_t *    /* region[3] */,
                      size_t *          /* image_row_pitch */,
                      size_t *          /* image_slice_pitch */,
                      cl_uint           /* num_events_in_wait_list */,
                      const cl_event *  /* event_wait_list */,
                      cl_event *        /* event */,
                      cl_int *          /* errcode_ret */);

#define clEnqueueUnmapMemObject aclEnqueueUnmapMemObject
cl_int
(*aclEnqueueUnmapMemObject)(cl_command_queue /* command_queue */,
                            cl_mem           /* memobj */,
                            void *           /* mapped_ptr */,
                            cl_uint          /* num_events_in_wait_list */,
                            const cl_event *  /* event_wait_list */,
                            cl_event *        /* event */);

#define clEnqueueNDRangeKernel aclEnqueueNDRangeKernel
cl_int
(*aclEnqueueNDRangeKernel)(cl_command_queue /* command_queue */,
                           cl_kernel        /* kernel */,
                           cl_uint          /* work_dim */,
                           const size_t *   /* global_work_offset */,
                           const size_t *   /* global_work_size */,
                           const size_t *   /* local_work_size */,
                           cl_uint          /* num_events_in_wait_list */,
                           const cl_event * /* event_wait_list */,
                           cl_event *       /* event */);

#define clEnqueueTask aclEnqueueTask
cl_int
(*aclEnqueueTask)(cl_command_queue  /* command_queue */,
                  cl_kernel         /* kernel */,
                  cl_uint           /* num_events_in_wait_list */,
                  const cl_event *  /* event_wait_list */,
                  cl_event *        /* event */);

#define clEnqueueNativeKernel aclEnqueueNativeKernel
cl_int
(*aclEnqueueNativeKernel)(cl_command_queue  /* command_queue */,
                          void (CL_CALLBACK * /*user_func*/)(void *),
                          void *            /* args */,
                          size_t            /* cb_args */,
                          cl_uint           /* num_mem_objects */,
                          const cl_mem *    /* mem_list */,
                          const void **     /* args_mem_loc */,
                          cl_uint           /* num_events_in_wait_list */,
                          const cl_event *  /* event_wait_list */,
                          cl_event *        /* event */);





#ifdef CL_USE_DEPRECATED_OPENCL_1_0_APIS
//#warning CL_USE_DEPRECATED_OPENCL_1_0_APIS is defined. These APIs are unsupported and untested in OpenCL 1.1!
    /*
     *  WARNING:
     *     This API introduces mutable state into the OpenCL implementation. It has been REMOVED
     *  to better facilitate thread safety.  The 1.0 API is not thread safe. It is not tested by the
     *  OpenCL 1.1 conformance test, and consequently may not work or may not work dependably.
     *  It is likely to be non-performant. Use of this API is not advised. Use at your own risk.
     *
     *  Software developers previously relying on this API are instructed to set the command queue
     *  properties when creating the queue, instead.
     */
#define clSetCommandQueueProperty aclSetCommandQueueProperty
 cl_int
(*aclSetCommandQueueProperty)(cl_command_queue              /* command_queue */,
                              cl_command_queue_properties   /* properties */,
                              cl_bool                        /* enable */,
                              cl_command_queue_properties * /* old_properties */);
#endif /* CL_USE_DEPRECATED_OPENCL_1_0_APIS */


#ifdef CL_USE_DEPRECATED_OPENCL_1_1_APIS
#define clCreateImage2D aclCreateImage2D
 cl_mem
(*aclCreateImage2D)(cl_context              /* context */,
                    cl_mem_flags            /* flags */,
                    const cl_image_format * /* image_format */,
                    size_t                  /* image_width */,
                    size_t                  /* image_height */,
                    size_t                  /* image_row_pitch */,
                    void *                  /* host_ptr */,
                    cl_int *                /* errcode_ret */);

#define clCreateImage3D aclCreateImage3D
 cl_mem
(*aclCreateImage3D)(cl_context              /* context */,
                    cl_mem_flags            /* flags */,
                    const cl_image_format * /* image_format */,
                    size_t                  /* image_width */,
                    size_t                  /* image_height */,
                    size_t                  /* image_depth */,
                    size_t                  /* image_row_pitch */,
                    size_t                  /* image_slice_pitch */,
                    void *                  /* host_ptr */,
                    cl_int *                /* errcode_ret */);

#define clEnqueueMarker aclEnqueueMarker
 cl_int
(*aclEnqueueMarker)(cl_command_queue    /* command_queue */,
                    cl_event *          /* event */);

#define clEnqueueWaitForEvents aclEnqueueWaitForEvents
 cl_int
(*aclEnqueueWaitForEvents)(cl_command_queue /* command_queue */,
                           cl_uint          /* num_events */,
                           const cl_event * /* event_list */);

#define clEnqueueBarrier aclEnqueueBarrier
 cl_int
(*aclEnqueueBarrier)(cl_command_queue /* command_queue */);

#define clUnloadCompiler aclUnloadCompiler
 cl_int
(*aclUnloadCompiler)(void);

void *
(*aclGetExtensionFunctionAddress)(const char * /* func_name */);
#endif

#ifdef __cplusplus
}
#endif

#endif  /* __AOPENCL_CL_H */

dlopencl.cpp

根据实际情况自行修改 so_path 的路径

#define CL_TARGET_OPENCL_VERSION 120
#include "CL/cl.h"
#include <dlfcn.h>
#include <cstdio>
#include <string.h>
#include "dlopencl.h"

int loadedCL;

void *getCLHandle() {
    LOGD("get_handle");
    void *res = nullptr;
    char *so_path = (char*)"/system/vendor/lib64/egl/libGLES_mali.so";
    res = dlopen(so_path, RTLD_LAZY);

    if (res == nullptr) {
        LOGD("Open library failed");
    } else {
        LOGD("Loaded library name: [%s]", so_path);
    }

    return res;
}

void initFns() {
    loadedCL = 0;
    void *handle = getCLHandle();
    if (handle == nullptr) return;

/* Platform API */
    IAH();
    aclGetPlatformIDs = (cl_int  (*)(cl_uint          /* num_entries */,
                                     cl_platform_id * /* platforms */,
                                     cl_uint *        /* num_platforms */)) dlsym(handle, "clGetPlatformIDs");

    IAH();
    aclGetPlatformInfo = (cl_int   (*)(cl_platform_id   /* platform */,
                                       cl_platform_info /* param_name */,
                                       size_t           /* param_value_size */,
                                       void *           /* param_value */,
                                       size_t *         /* param_value_size_ret */)) dlsym(handle, "clGetPlatformInfo");

/* Device APIs */
    IAH();
    aclGetDeviceIDs = (cl_int  (*)(cl_platform_id   /* platform */,
                                   cl_device_type   /* device_type */,
                                   cl_uint          /* num_entries */,
                                   cl_device_id *   /* devices */,
                                   cl_uint *        /* num_devices */)) dlsym(handle, "clGetDeviceIDs");

    IAH();
    aclGetDeviceInfo = (cl_int  (*)(cl_device_id    /* device */,
                                    cl_device_info  /* param_name */,
                                    size_t          /* param_value_size */,
                                    void *          /* param_value */,
                                    size_t *        /* param_value_size_ret */)) dlsym(handle, "clGetDeviceInfo");

/* Context APIs  */
    IAH();
    aclCreateContext = (cl_context  (*)(const cl_context_properties * /* properties */,
    cl_uint                 /* num_devices */,
    const cl_device_id *    /* devices */,
    void (CL_CALLBACK *     /* pfn_notify */)(const char *, const void *, size_t, void *),
    void *                  /* user_data */,
    cl_int *                /* errcode_ret */)) dlsym(handle, "clCreateContext");

    IAH();
    aclCreateContextFromType = (cl_context  (*)(const cl_context_properties * /* properties */,
    cl_device_type          /* device_type */,
    void (CL_CALLBACK *     /* pfn_notify*/ )(const char *, const void *, size_t, void *),
    void *                  /* user_data */,
    cl_int *                /* errcode_ret */)) dlsym(handle, "clCreateContextFromType");

    IAH();
    aclRetainContext = (cl_int  (*)(cl_context /* context */)) dlsym(handle, "clRetainContext");

    IAH();
    aclReleaseContext = (cl_int  (*)(cl_context /* context */)) dlsym(handle, "clReleaseContext");

    IAH();
    aclGetContextInfo = (cl_int  (*)(cl_context         /* context */,
                                     cl_context_info    /* param_name */,
                                     size_t             /* param_value_size */,
                                     void *             /* param_value */,
                                     size_t *           /* param_value_size_ret */)) dlsym(handle, "clGetContextInfo");

/* Command Queue APIs */
    IAH();
    aclCreateCommandQueue = (cl_command_queue  (*)(cl_context                     /* context */,
                                                   cl_device_id                   /* device */,
                                                   cl_command_queue_properties    /* properties */,
                                                   cl_int *                       /* errcode_ret */)) dlsym(handle, "clCreateCommandQueue");

    IAH();
    aclRetainCommandQueue = (cl_int  (*)(cl_command_queue /* command_queue */)) dlsym(handle, "clRetainCommandQueue");

    IAH();
    aclReleaseCommandQueue = (cl_int  (*)(cl_command_queue /* command_queue */)) dlsym(handle, "clReleaseCommandQueue");

    IAH();
    aclGetCommandQueueInfo = (cl_int  (*)(cl_command_queue      /* command_queue */,
                                          cl_command_queue_info /* param_name */,
                                          size_t                /* param_value_size */,
                                          void *                /* param_value */,
                                          size_t *              /* param_value_size_ret */)) dlsym(handle, "clGetCommandQueueInfo");

/* Memory Object APIs */
    IAH();
    aclCreateBuffer = (cl_mem  (*)(cl_context   /* context */,
                                   cl_mem_flags /* flags */,
                                   size_t       /* size */,
                                   void *       /* host_ptr */,
                                   cl_int *     /* errcode_ret */)) dlsym(handle, "clCreateBuffer");

    IAH();
    aclCreateSubBuffer = (cl_mem  (*)(cl_mem                   /* buffer */,
                                      cl_mem_flags             /* flags */,
                                      cl_buffer_create_type    /* buffer_create_type */,
                                      const void *             /* buffer_create_info */,
                                      cl_int *                 /* errcode_ret */)) dlsym(handle, "clCreateSubBuffer");

    IAH();
    aclRetainMemObject = (cl_int  (*)(cl_mem /* memobj */)) dlsym(handle, "clRetainMemObject");

    IAH();
    aclReleaseMemObject = (cl_int  (*)(cl_mem /* memobj */)) dlsym(handle, "clReleaseMemObject");

    IAH();
    aclGetSupportedImageFormats = (cl_int  (*)(cl_context           /* context */,
                                               cl_mem_flags         /* flags */,
                                               cl_mem_object_type   /* image_type */,
                                               cl_uint              /* num_entries */,
                                               cl_image_format *    /* image_formats */,
                                               cl_uint *            /* num_image_formats */)) dlsym(handle, "clGetSupportedImageFormats");

    IAH();
    aclGetMemObjectInfo = (cl_int  (*)(cl_mem           /* memobj */,
                                       cl_mem_info      /* param_name */,
                                       size_t           /* param_value_size */,
                                       void *           /* param_value */,
                                       size_t *         /* param_value_size_ret */)) dlsym(handle, "clGetMemObjectInfo");

    IAH();
    aclGetImageInfo = (cl_int  (*)(cl_mem           /* image */,
                                   cl_image_info    /* param_name */,
                                   size_t           /* param_value_size */,
                                   void *           /* param_value */,
                                   size_t *         /* param_value_size_ret */)) dlsym(handle, "clGetImageInfo");

    IAH();
    aclSetMemObjectDestructorCallback = (cl_int  (*)(  cl_mem /* memobj */,
                                                       void (CL_CALLBACK * /*pfn_notify*/)( cl_mem /* memobj */, void* /*user_data*/),
            void * /*user_data */ )) dlsym(handle, "clSetMemObjectDestructorCallback");

/* Sampler APIs */
    IAH();
    aclCreateSampler = (cl_sampler  (*)(cl_context          /* context */,
                                        cl_bool             /* normalized_coords */,
                                        cl_addressing_mode  /* addressing_mode */,
                                        cl_filter_mode      /* filter_mode */,
                                        cl_int *            /* errcode_ret */)) dlsym(handle, "clCreateSampler");

    IAH();
    aclRetainSampler = (cl_int  (*)(cl_sampler /* sampler */)) dlsym(handle, "clRetainSampler");

    IAH();
    aclReleaseSampler = (cl_int  (*)(cl_sampler /* sampler */)) dlsym(handle, "clReleaseSampler");

    IAH();
    aclGetSamplerInfo = (cl_int  (*)(cl_sampler         /* sampler */,
                                     cl_sampler_info    /* param_name */,
                                     size_t             /* param_value_size */,
                                     void *             /* param_value */,
                                     size_t *           /* param_value_size_ret */)) dlsym(handle, "clGetSamplerInfo");

/* Program Object APIs  */
    IAH();
    aclCreateProgramWithSource = (cl_program  (*)(cl_context        /* context */,
                                                  cl_uint           /* count */,
                                                  const char **     /* strings */,
                                                  const size_t *    /* lengths */,
                                                  cl_int *          /* errcode_ret */)) dlsym(handle, "clCreateProgramWithSource");

    IAH();
    aclCreateProgramWithBinary = (cl_program  (*)(cl_context                /* context */,
                                                  cl_uint                   /* num_devices */,
                                                  const cl_device_id *      /* device_list */,
                                                  const size_t *            /* lengths */,
                                                  const unsigned char **    /* binaries */,
                                                  cl_int *                  /* binary_status */,
                                                  cl_int *                  /* errcode_ret */)) dlsym(handle, "clCreateProgramWithBinary");

    IAH();
    aclRetainProgram = (cl_int  (*)(cl_program /* program */)) dlsym(handle, "clRetainProgram");

    IAH();
    aclReleaseProgram = (cl_int  (*)(cl_program /* program */)) dlsym(handle, "clReleaseProgram");

    IAH();
    aclBuildProgram = (cl_int  (*)(cl_program           /* program */,
                                   cl_uint              /* num_devices */,
    const cl_device_id * /* device_list */,
    const char *         /* options */,
    void (CL_CALLBACK *  /* pfn_notify */)(cl_program /* program */, void * /* user_data */),
    void *               /* user_data */)) dlsym(handle, "clBuildProgram");

    IAH();
    aclGetProgramInfo = (cl_int  (*)(cl_program         /* program */,
                                     cl_program_info    /* param_name */,
                                     size_t             /* param_value_size */,
                                     void *             /* param_value */,
                                     size_t *           /* param_value_size_ret */)) dlsym(handle, "clGetProgramInfo");

    IAH();
    aclGetProgramBuildInfo = (cl_int  (*)(cl_program            /* program */,
                                          cl_device_id          /* device */,
                                          cl_program_build_info /* param_name */,
                                          size_t                /* param_value_size */,
                                          void *                /* param_value */,
                                          size_t *              /* param_value_size_ret */)) dlsym(handle, "clGetProgramBuildInfo");

/* Kernel Object APIs */
    IAH();
    aclCreateKernel = (cl_kernel  (*)(cl_program      /* program */,
                                      const char *    /* kernel_name */,
                                      cl_int *        /* errcode_ret */)) dlsym(handle, "clCreateKernel");

    IAH();
    aclCreateKernelsInProgram = (cl_int  (*)(cl_program     /* program */,
                                             cl_uint        /* num_kernels */,
                                             cl_kernel *    /* kernels */,
                                             cl_uint *      /* num_kernels_ret */)) dlsym(handle, "clCreateKernelsInProgram");

    IAH();
    aclRetainKernel = (cl_int  (*)(cl_kernel    /* kernel */)) dlsym(handle, "clRetainKernel");

    IAH();
    aclReleaseKernel = (cl_int  (*)(cl_kernel   /* kernel */)) dlsym(handle, "clReleaseKernel");

    IAH();
    aclSetKernelArg = (cl_int  (*)(cl_kernel    /* kernel */,
                                   cl_uint      /* arg_index */,
                                   size_t       /* arg_size */,
                                   const void * /* arg_value */)) dlsym(handle, "clSetKernelArg");

    IAH();
    aclGetKernelInfo = (cl_int  (*)(cl_kernel       /* kernel */,
                                    cl_kernel_info  /* param_name */,
                                    size_t          /* param_value_size */,
                                    void *          /* param_value */,
                                    size_t *        /* param_value_size_ret */)) dlsym(handle, "clGetKernelInfo");

    IAH();
    aclGetKernelWorkGroupInfo = (cl_int  (*)(cl_kernel                  /* kernel */,
                                             cl_device_id               /* device */,
                                             cl_kernel_work_group_info  /* param_name */,
                                             size_t                     /* param_value_size */,
                                             void *                     /* param_value */,
                                             size_t *                   /* param_value_size_ret */)) dlsym(handle, "clGetKernelWorkGroupInfo");

/* Event Object APIs */
    IAH();
    aclWaitForEvents = (cl_int  (*)(cl_uint             /* num_events */,
                                    const cl_event *    /* event_list */)) dlsym(handle, "clWaitForEvents");

    IAH();
    aclGetEventInfo = (cl_int  (*)(cl_event         /* event */,
                                   cl_event_info    /* param_name */,
                                   size_t           /* param_value_size */,
                                   void *           /* param_value */,
                                   size_t *         /* param_value_size_ret */)) dlsym(handle, "clGetEventInfo");

    IAH();
    aclCreateUserEvent = (cl_event  (*)(cl_context    /* context */,
                                        cl_int *      /* errcode_ret */)) dlsym(handle, "clCreateUserEvent");

    IAH();
    aclRetainEvent = (cl_int  (*)(cl_event /* event */)) dlsym(handle, "clRetainEvent");

    IAH();
    aclReleaseEvent = (cl_int  (*)(cl_event /* event */)) dlsym(handle, "clReleaseEvent");

    IAH();
    aclSetUserEventStatus = (cl_int  (*)(cl_event   /* event */,
                                         cl_int     /* execution_status */)) dlsym(handle, "clSetUserEventStatus");

    IAH();
    aclSetEventCallback = (cl_int  (*)( cl_event    /* event */,
                                        cl_int      /* command_exec_callback_type */,
                                        void (CL_CALLBACK * /* pfn_notify */)(cl_event, cl_int, void *),
            void *      /* user_data */)) dlsym(handle, "clSetEventCallback");

/* Profiling APIs */
    IAH();
    aclGetEventProfilingInfo = (cl_int  (*)(cl_event            /* event */,
                                            cl_profiling_info   /* param_name */,
                                            size_t              /* param_value_size */,
                                            void *              /* param_value */,
                                            size_t *            /* param_value_size_ret */)) dlsym(handle, "clGetEventProfilingInfo");

/* Flush and Finish APIs */
    IAH();
    aclFlush = (cl_int  (*)(cl_command_queue /* command_queue */)) dlsym(handle, "clFlush");

    IAH();
    aclFinish = (cl_int  (*)(cl_command_queue /* command_queue */)) dlsym(handle, "clFinish");

/* Enqueued Commands APIs */
    IAH();
    aclEnqueueReadBuffer = (cl_int  (*)(cl_command_queue    /* command_queue */,
                                        cl_mem              /* buffer */,
                                        cl_bool             /* blocking_read */,
                                        size_t              /* offset */,
                                        size_t              /* size */,
                                        void *              /* ptr */,
                                        cl_uint             /* num_events_in_wait_list */,
                                        const cl_event *    /* event_wait_list */,
                                        cl_event *          /* event */)) dlsym(handle, "clEnqueueReadBuffer");

    IAH();
    aclEnqueueReadBufferRect = (cl_int  (*)(cl_command_queue    /* command_queue */,
                                            cl_mem              /* buffer */,
                                            cl_bool             /* blocking_read */,
                                            const size_t *      /* buffer_offset */,
                                            const size_t *      /* host_offset */,
                                            const size_t *      /* region */,
                                            size_t              /* buffer_row_pitch */,
                                            size_t              /* buffer_slice_pitch */,
                                            size_t              /* host_row_pitch */,
                                            size_t              /* host_slice_pitch */,
                                            void *              /* ptr */,
                                            cl_uint             /* num_events_in_wait_list */,
                                            const cl_event *    /* event_wait_list */,
                                            cl_event *          /* event */)) dlsym(handle, "clEnqueueReadBufferRect");

    IAH();
    aclEnqueueWriteBuffer = (cl_int  (*)(cl_command_queue   /* command_queue */,
                                         cl_mem             /* buffer */,
                                         cl_bool            /* blocking_write */,
                                         size_t             /* offset */,
                                         size_t             /* size */,
                                         const void *       /* ptr */,
                                         cl_uint            /* num_events_in_wait_list */,
                                         const cl_event *   /* event_wait_list */,
                                         cl_event *         /* event */)) dlsym(handle, "clEnqueueWriteBuffer");

    IAH();
    aclEnqueueWriteBufferRect = (cl_int  (*)(cl_command_queue    /* command_queue */,
                                             cl_mem              /* buffer */,
                                             cl_bool             /* blocking_write */,
                                             const size_t *      /* buffer_offset */,
                                             const size_t *      /* host_offset */,
                                             const size_t *      /* region */,
                                             size_t              /* buffer_row_pitch */,
                                             size_t              /* buffer_slice_pitch */,
                                             size_t              /* host_row_pitch */,
                                             size_t              /* host_slice_pitch */,
                                             const void *        /* ptr */,
                                             cl_uint             /* num_events_in_wait_list */,
                                             const cl_event *    /* event_wait_list */,
                                             cl_event *          /* event */)) dlsym(handle, "clEnqueueWriteBufferRect");

    IAH();
    aclEnqueueCopyBuffer = (cl_int  (*)(cl_command_queue    /* command_queue */,
                                        cl_mem              /* src_buffer */,
                                        cl_mem              /* dst_buffer */,
                                        size_t              /* src_offset */,
                                        size_t              /* dst_offset */,
                                        size_t              /* size */,
                                        cl_uint             /* num_events_in_wait_list */,
                                        const cl_event *    /* event_wait_list */,
                                        cl_event *          /* event */)) dlsym(handle, "clEnqueueCopyBuffer");

    IAH();
    aclEnqueueCopyBufferRect = (cl_int  (*)(cl_command_queue    /* command_queue */,
                                            cl_mem              /* src_buffer */,
                                            cl_mem              /* dst_buffer */,
                                            const size_t *      /* src_origin */,
                                            const size_t *      /* dst_origin */,
                                            const size_t *      /* region */,
                                            size_t              /* src_row_pitch */,
                                            size_t              /* src_slice_pitch */,
                                            size_t              /* dst_row_pitch */,
                                            size_t              /* dst_slice_pitch */,
                                            cl_uint             /* num_events_in_wait_list */,
                                            const cl_event *    /* event_wait_list */,
                                            cl_event *          /* event */)) dlsym(handle, "clEnqueueCopyBufferRect");

    IAH();
    aclEnqueueReadImage = (cl_int  (*)(cl_command_queue     /* command_queue */,
                                       cl_mem               /* image */,
                                       cl_bool              /* blocking_read */,
                                       const size_t *       /* origin[3] */,
                                       const size_t *       /* region[3] */,
                                       size_t               /* row_pitch */,
                                       size_t               /* slice_pitch */,
                                       void *               /* ptr */,
                                       cl_uint              /* num_events_in_wait_list */,
                                       const cl_event *     /* event_wait_list */,
                                       cl_event *           /* event */)) dlsym(handle, "clEnqueueReadImage");

    IAH();
    aclEnqueueWriteImage = (cl_int  (*)(cl_command_queue    /* command_queue */,
                                        cl_mem              /* image */,
                                        cl_bool             /* blocking_write */,
                                        const size_t *      /* origin[3] */,
                                        const size_t *      /* region[3] */,
                                        size_t              /* input_row_pitch */,
                                        size_t              /* input_slice_pitch */,
                                        const void *        /* ptr */,
                                        cl_uint             /* num_events_in_wait_list */,
                                        const cl_event *    /* event_wait_list */,
                                        cl_event *          /* event */)) dlsym(handle, "clEnqueueWriteImage");

    IAH();
    aclEnqueueCopyImage = (cl_int  (*)(cl_command_queue     /* command_queue */,
                                       cl_mem               /* src_image */,
                                       cl_mem               /* dst_image */,
                                       const size_t *       /* src_origin[3] */,
                                       const size_t *       /* dst_origin[3] */,
                                       const size_t *       /* region[3] */,
                                       cl_uint              /* num_events_in_wait_list */,
                                       const cl_event *     /* event_wait_list */,
                                       cl_event *           /* event */)) dlsym(handle, "clEnqueueCopyImage");

    IAH();
    aclEnqueueCopyImageToBuffer = (cl_int  (*)(cl_command_queue /* command_queue */,
                                               cl_mem           /* src_image */,
                                               cl_mem           /* dst_buffer */,
                                               const size_t *   /* src_origin[3] */,
                                               const size_t *   /* region[3] */,
                                               size_t           /* dst_offset */,
                                               cl_uint          /* num_events_in_wait_list */,
                                               const cl_event * /* event_wait_list */,
                                               cl_event *       /* event */)) dlsym(handle, "clEnqueueCopyImageToBuffer");

    IAH();
    aclEnqueueCopyBufferToImage = (cl_int  (*)(cl_command_queue /* command_queue */,
                                               cl_mem           /* src_buffer */,
                                               cl_mem           /* dst_image */,
                                               size_t           /* src_offset */,
                                               const size_t *   /* dst_origin[3] */,
                                               const size_t *   /* region[3] */,
                                               cl_uint          /* num_events_in_wait_list */,
                                               const cl_event * /* event_wait_list */,
                                               cl_event *       /* event */)) dlsym(handle, "clEnqueueCopyBufferToImage");

    #if 0
    void *
(*aclEnqueueMapBuffer)(cl_command_queue /* command_queue */,
                   cl_mem           /* buffer */,
                   cl_bool          /* blocking_map */,
                   cl_map_flags     /* map_flags */,
                   size_t           /* offset */,
                   size_t           /* size */,
                   cl_uint          /* num_events_in_wait_list */,
                   const cl_event * /* event_wait_list */,
                   cl_event *       /* event */,
                   cl_int *         /* errcode_ret */)) dlsym(handle,"");

void *
(*aclEnqueueMapImage)(cl_command_queue  /* command_queue */,
                  cl_mem            /* image */,
                  cl_bool           /* blocking_map */,
                  cl_map_flags      /* map_flags */,
                  const size_t *    /* origin[3] */,
                  const size_t *    /* region[3] */,
                  size_t *          /* image_row_pitch */,
                  size_t *          /* image_slice_pitch */,
                  cl_uint           /* num_events_in_wait_list */,
                  const cl_event *  /* event_wait_list */,
                  cl_event *        /* event */,
                  cl_int *          /* errcode_ret */)) dlsym(handle,"");
#endif

    IAH();
    aclEnqueueUnmapMemObject = (cl_int  (*)(cl_command_queue /* command_queue */,
                                            cl_mem           /* memobj */,
                                            void *           /* mapped_ptr */,
                                            cl_uint          /* num_events_in_wait_list */,
                                            const cl_event * /* event_wait_list */,
                                            cl_event *       /* event */)) dlsym(handle, "clEnqueueUnmapMemObject");

    IAH();
    aclEnqueueNDRangeKernel = (cl_int  (*)(cl_command_queue /* command_queue */,
                                           cl_kernel        /* kernel */,
                                           cl_uint          /* work_dim */,
                                           const size_t *   /* global_work_offset */,
                                           const size_t *   /* global_work_size */,
                                           const size_t *   /* local_work_size */,
                                           cl_uint          /* num_events_in_wait_list */,
                                           const cl_event * /* event_wait_list */,
                                           cl_event *       /* event */)) dlsym(handle, "clEnqueueNDRangeKernel");

    IAH();
    aclEnqueueTask = (cl_int  (*)(cl_command_queue  /* command_queue */,
                                  cl_kernel         /* kernel */,
                                  cl_uint           /* num_events_in_wait_list */,
                                  const cl_event *  /* event_wait_list */,
                                  cl_event *        /* event */)) dlsym(handle, "clEnqueueTask");

    IAH();
    aclEnqueueNativeKernel = (cl_int  (*)(cl_command_queue      /* command_queue */,
                                          void (CL_CALLBACK *   /*user_func*/)(void *),
            void *            /* args */,
            size_t            /* cb_args */,
            cl_uint           /* num_mem_objects */,
    const cl_mem *    /* mem_list */,
    const void **     /* args_mem_loc */,
    cl_uint           /* num_events_in_wait_list */,
    const cl_event *  /* event_wait_list */,
    cl_event *        /* event */)) dlsym(handle, "clEnqueueNativeKernel");

#ifdef CL_USE_DEPRECATED_OPENCL_1_0_APIS
    //#warning CL_USE_DEPRECATED_OPENCL_1_0_APIS is defined. These APIs are unsupported and untested in OpenCL 1.1!
    /*
     *  WARNING:
     *     This API introduces mutable state into the OpenCL implementation. It has been REMOVED
     *  to better facilitate thread safety.  The 1.0 API is not thread safe. It is not tested by the
     *  OpenCL 1.1 conformance test, and consequently may not work or may not work dependably.
     *  It is likely to be non-performant. Use of this API is not advised. Use at your own risk.
     *
     *  Software developers previously relying on this API are instructed to set the command queue
     *  properties when creating the queue, instead.
     */
 IAH();
 aclSetCommandQueueProperty = (cl_int  (*)(cl_command_queue              /* command_queue */,
                              cl_command_queue_properties   /* properties */,
                              cl_bool                        /* enable */,
                              cl_command_queue_properties * /* old_properties */)) dlsym(handle,"clSetCommandQueueProperty");
#endif /* CL_USE_DEPRECATED_OPENCL_1_0_APIS */

#ifdef CL_USE_DEPRECATED_OPENCL_1_1_APIS
    IAH();
 aclCreateImage2D = (cl_mem  (*)(cl_context              /* context */,
                    cl_mem_flags            /* flags */,
                    const cl_image_format * /* image_format */,
                    size_t                  /* image_width */,
                    size_t                  /* image_height */,
                    size_t                  /* image_row_pitch */,
                    void *                  /* host_ptr */,
                    cl_int *                /* errcode_ret */)) dlsym(handle,"clCreateImage2D");

 IAH();
 aclCreateImage3D = (cl_mem  (*)(cl_context              /* context */,
                    cl_mem_flags            /* flags */,
                    const cl_image_format * /* image_format */,
                    size_t                  /* image_width */,
                    size_t                  /* image_height */,
                    size_t                  /* image_depth */,
                    size_t                  /* image_row_pitch */,
                    size_t                  /* image_slice_pitch */,
                    void *                  /* host_ptr */,
                    cl_int *                /* errcode_ret */)) dlsym(handle,"clCreateImage3D");

 IAH();
 aclEnqueueMarker = (cl_int  (*)(cl_command_queue    /* command_queue */,
                    cl_event *          /* event */)) dlsym(handle,"clEnqueueMarker");

 IAH();
 aclEnqueueWaitForEvents = (cl_int  (*)(cl_command_queue /* command_queue */,
                           cl_uint          /* num_events */,
                           const cl_event * /* event_list */)) dlsym(handle,"clEnqueueWaitForEvents");

 IAH();
 aclEnqueueBarrier = (cl_int  (*)(cl_command_queue /* command_queue */)) dlsym(handle,"clEnqueueBarrier");

 IAH();
 aclUnloadCompiler = (cl_int  (*)(void)) dlsym(handle,"clUnloadCompiler");
#endif

#if 0
    void *
(*aclGetExtensionFunctionAddress)(const char * /* func_name */)) dlsym(handle,"");

#endif

    loadedCL = 1;
}

Android OpenCV(零):OpenCV Android SDK

Android OpenCV(零):OpenCV Android SDK

OpenCV

OpenCV,全称Open Source Computer VisionLibrary,是基于C/C++编写的,是BSD开源许可的计算机视觉开发框架,其开源协议允许在学术研究与商业应用开发中免费使用它。OpenCV支持Windows、Linux、Mac OS、iOS与Android操作系统上的应用开发。

OpenCV Android SDK

OpenCV Android SDK 是OpenCV针对Android平台提供的开发工具包。Android应用开发一般采用Java或者Kotlin语言进行,而OpenCV主要模块采用C、C++语言编制,因此,我们需要通过JNI技术,实现JAVA或者Kotlin调用OpenCV算法模块的目的。

下载

  • 官网下载地址(https://opencv.org/releases/)
  • 选择OpenCV版本下的Android

SDK概述

SDK目录结构如下:

OpenCV-android-sdk
|_ samples
|_ sdk
|    |_ etc
|    |_ java
|    |_ libcxx_helper
|    |_ native
|          |_ 3rdparty
|          |_ jni
|          |_ libs
|               |_ arm64-v8a
|               |_ armeabi-v7a
|               |_ x86
|               |_ x86_64
|          |_ staticlibs
|               |_ arm64-v8a
|               |_ armeabi-v7a
|               |_ x86
|               |_ x86_64
|
|_ LICENSE
|_ README.android
目录 文件
samples OpenCV运行案例
sdk OpenCV API以及依赖库
sdk/etc Haar和LBP级联分类器
sdk/java OpenCV Java API
sdk/libcxx_helper bring libc++_shared.so into packages
sdk/native OpenCV 静态库、动态库以及JNI文件

英文详细介绍(https://opencv.org/android/)。其实官方的这些介绍并不详细,很多资料随着版本的迭代已过时,意义不大,唯一阅读性高且具有指导意义的应该就是库内的代码与注释了。

开发环境

  • Android Studio 3.5.3 & Android SDK

  • Android NDK 20.1.5948944

  • CMake 3.10.2

  • OpenCV Android SDK 4.2.0

Hello OpenCV Android Sample

  • Open Project
  • 选择OpenCV-android-sdk目录下的samples目录
  • 待编译结束后运行face-detection

Face Detection运行结果

Hello OpenCV Android SDK

  • New Project
  • Import Module…
  • 选择OpenCV-android-sdk目录下的sdk目录,修改或者不修改module的名称
  • 添加app程序对sdk module的依赖
  • 期间可能会遇到一些问题,可能是NDK版本问题,可能是API LEVEL问题,也可能是build tools的问题,对应的稍作处理即可。

示例工程

https://github.com/onlyloveyd/LearningAndroidOpenCV

onlyloveyd 博客专家 发布了158 篇原创文章 · 获赞 263 · 访问量 32万+ 他的留言板 关注

今天的关于linux 下编译支持 opencl 的 opencv for androidlinux编译opencv源码的分享已经结束,谢谢您的关注,如果想了解更多关于36 篇博文带你学完 opencv :python+opencv 进阶版学习笔记目录、Android 7.0 及以上使用 OpenCL、Android AARCH64 平台的 OpenCL 配置、Android OpenCV(零):OpenCV Android SDK的相关知识,请在本站进行查询。

本文标签: