Path: blob/master/samples/tapi/opencl_custom_kernel.cpp
16337 views
// This file is part of OpenCV project.1// It is subject to the license terms in the LICENSE file found in the top-level directory2// of this distribution and at http://opencv.org/license.html34#include "opencv2/core.hpp"5#include "opencv2/core/ocl.hpp"6#include "opencv2/highgui.hpp"7#include "opencv2/imgcodecs.hpp"8#include "opencv2/imgproc.hpp"910#include <iostream>1112using namespace std;13using namespace cv;1415static const char* opencl_kernel_src =16"__kernel void magnutude_filter_8u(\n"17" __global const uchar* src, int src_step, int src_offset,\n"18" __global uchar* dst, int dst_step, int dst_offset, int dst_rows, int dst_cols,\n"19" float scale)\n"20"{\n"21" int x = get_global_id(0);\n"22" int y = get_global_id(1);\n"23" if (x < dst_cols && y < dst_rows)\n"24" {\n"25" int dst_idx = y * dst_step + x + dst_offset;\n"26" if (x > 0 && x < dst_cols - 1 && y > 0 && y < dst_rows - 2)\n"27" {\n"28" int src_idx = y * src_step + x + src_offset;\n"29" int dx = (int)src[src_idx]*2 - src[src_idx - 1] - src[src_idx + 1];\n"30" int dy = (int)src[src_idx]*2 - src[src_idx - 1*src_step] - src[src_idx + 1*src_step];\n"31" dst[dst_idx] = convert_uchar_sat(sqrt((float)(dx*dx + dy*dy)) * scale);\n"32" }\n"33" else\n"34" {\n"35" dst[dst_idx] = 0;\n"36" }\n"37" }\n"38"}\n";3940int main(int argc, char** argv)41{42const char* keys =43"{ i input | | specify input image }"44"{ h help | | print help message }";4546cv::CommandLineParser args(argc, argv, keys);47if (args.has("help"))48{49cout << "Usage : " << argv[0] << " [options]" << endl;50cout << "Available options:" << endl;51args.printMessage();52return EXIT_SUCCESS;53}5455cv::ocl::Context ctx = cv::ocl::Context::getDefault();56if (!ctx.ptr())57{58cerr << "OpenCL is not available" << endl;59return 1;60}61cv::ocl::Device device = cv::ocl::Device::getDefault();62if (!device.compilerAvailable())63{64cerr << "OpenCL compiler is not available" << endl;65return 1;66}676869UMat src;70{71string image_file = args.get<string>("i");72if (!image_file.empty())73{74Mat image = imread(image_file);75if (image.empty())76{77cout << "error read image: " << image_file << endl;78return 1;79}80cvtColor(image, src, COLOR_BGR2GRAY);81}82else83{84Mat frame(cv::Size(640, 480), CV_8U, Scalar::all(128));85Point p(frame.cols / 2, frame.rows / 2);86line(frame, Point(0, frame.rows / 2), Point(frame.cols, frame.rows / 2), 1);87circle(frame, p, 200, Scalar(32, 32, 32), 8, LINE_AA);88string str = "OpenCL";89int baseLine = 0;90Size box = getTextSize(str, FONT_HERSHEY_COMPLEX, 2, 5, &baseLine);91putText(frame, str, Point((frame.cols - box.width) / 2, (frame.rows - box.height) / 2 + baseLine),92FONT_HERSHEY_COMPLEX, 2, Scalar(255, 255, 255), 5, LINE_AA);93frame.copyTo(src);94}95}969798cv::String module_name; // empty to disable OpenCL cache99100{101cout << "OpenCL program source: " << endl;102cout << "======================================================================================================" << endl;103cout << opencl_kernel_src << endl;104cout << "======================================================================================================" << endl;105//! [Define OpenCL program source]106cv::ocl::ProgramSource source(module_name, "simple", opencl_kernel_src, "");107//! [Define OpenCL program source]108109//! [Compile/build OpenCL for current OpenCL device]110cv::String errmsg;111cv::ocl::Program program(source, "", errmsg);112if (program.ptr() == NULL)113{114cerr << "Can't compile OpenCL program:" << endl << errmsg << endl;115return 1;116}117//! [Compile/build OpenCL for current OpenCL device]118119if (!errmsg.empty())120{121cout << "OpenCL program build log:" << endl << errmsg << endl;122}123124//! [Get OpenCL kernel by name]125cv::ocl::Kernel k("magnutude_filter_8u", program);126if (k.empty())127{128cerr << "Can't get OpenCL kernel" << endl;129return 1;130}131//! [Get OpenCL kernel by name]132133UMat result(src.size(), CV_8UC1);134135//! [Define kernel parameters and run]136size_t globalSize[2] = {(size_t)src.cols, (size_t)src.rows};137size_t localSize[2] = {8, 8};138bool executionResult = k139.args(140cv::ocl::KernelArg::ReadOnlyNoSize(src), // size is not used (similar to 'dst' size)141cv::ocl::KernelArg::WriteOnly(result),142(float)2.0143)144.run(2, globalSize, localSize, true);145if (!executionResult)146{147cerr << "OpenCL kernel launch failed" << endl;148return 1;149}150//! [Define kernel parameters and run]151152imshow("Source", src);153imshow("Result", result);154155for (;;)156{157int key = waitKey();158if (key == 27/*ESC*/ || key == 'q' || key == 'Q')159break;160}161}162return 0;163}164165166