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