主要的步骤其他人已经写过,请参考这篇: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倍!