Merge remote-tracking branch 'origin/2.4' into merge-2.4
[profile/ivi/opencv.git] / modules / ocl / src / build_warps.cpp
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 //  By downloading, copying, installing or using the software you agree to this license.
6 //  If you do not agree to this license, do not download, install,
7 //  copy or use the software.
8 //
9 //
10 //                           License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2010-2012, Multicoreware, Inc., all rights reserved.
14 // Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
15 // Third party copyrights are property of their respective owners.
16 //
17 // @Authors
18 //    Peng Xiao, pengxiao@multicorewareinc.com
19 //
20 // Redistribution and use in source and binary forms, with or without modification,
21 // are permitted provided that the following conditions are met:
22 //
23 //   * Redistribution's of source code must retain the above copyright notice,
24 //     this list of conditions and the following disclaimer.
25 //
26 //   * Redistribution's in binary form must reproduce the above copyright notice,
27 //     this list of conditions and the following disclaimer in the documentation
28 //     and/or other materials provided with the distribution.
29 //
30 //   * The name of the copyright holders may not be used to endorse or promote products
31 //     derived from this software without specific prior written permission.
32 //
33 // This software is provided by the copyright holders and contributors as is and
34 // any express or implied warranties, including, but not limited to, the implied
35 // warranties of merchantability and fitness for a particular purpose are disclaimed.
36 // In no event shall the Intel Corporation or contributors be liable for any direct,
37 // indirect, incidental, special, exemplary, or consequential damages
38 // (including, but not limited to, procurement of substitute goods or services;
39 // loss of use, data, or profits; or business interruption) however caused
40 // and on any theory of liability, whether in contract, strict liability,
41 // or tort (including negligence or otherwise) arising in any way out of
42 // the use of this software, even if advised of the possibility of such damage.
43 //
44 //M*/
45
46 #include "precomp.hpp"
47 #include "opencl_kernels.hpp"
48
49 using namespace cv;
50 using namespace cv::ocl;
51
52 //////////////////////////////////////////////////////////////////////////////
53 // buildWarpPlaneMaps
54
55 void cv::ocl::buildWarpPlaneMaps(Size /*src_size*/, Rect dst_roi, const Mat &K, const Mat &R, const Mat &T,
56                                  float scale, oclMat &xmap, oclMat &ymap)
57 {
58     CV_Assert(K.size() == Size(3, 3) && K.type() == CV_32F);
59     CV_Assert(R.size() == Size(3, 3) && R.type() == CV_32F);
60     CV_Assert((T.size() == Size(3, 1) || T.size() == Size(1, 3)) && T.type() == CV_32F && T.isContinuous());
61
62     Mat K_Rinv = K * R.t();
63     CV_Assert(K_Rinv.isContinuous());
64
65     Mat KRT_mat(1, 12, CV_32FC1); // 9 + 3
66     KRT_mat(Range::all(), Range(0, 8)) = K_Rinv.reshape(1, 1);
67     KRT_mat(Range::all(), Range(9, 11)) = T;
68
69     oclMat KRT_oclMat(KRT_mat);
70     // transfer K_Rinv and T into a single cl_mem
71     xmap.create(dst_roi.size(), CV_32F);
72     ymap.create(dst_roi.size(), CV_32F);
73
74     int tl_u = dst_roi.tl().x;
75     int tl_v = dst_roi.tl().y;
76
77     int xmap_step = xmap.step / xmap.elemSize(), xmap_offset = xmap.offset / xmap.elemSize();
78     int ymap_step = ymap.step / ymap.elemSize(), ymap_offset = ymap.offset / ymap.elemSize();
79
80     std::vector< std::pair<size_t, const void *> > args;
81     args.push_back( std::make_pair( sizeof(cl_mem), (void *)&xmap.data));
82     args.push_back( std::make_pair( sizeof(cl_mem), (void *)&ymap.data));
83     args.push_back( std::make_pair( sizeof(cl_mem), (void *)&KRT_mat.data));
84     args.push_back( std::make_pair( sizeof(cl_int), (void *)&tl_u));
85     args.push_back( std::make_pair( sizeof(cl_int), (void *)&tl_v));
86     args.push_back( std::make_pair( sizeof(cl_int), (void *)&xmap.cols));
87     args.push_back( std::make_pair( sizeof(cl_int), (void *)&xmap.rows));
88     args.push_back( std::make_pair( sizeof(cl_int), (void *)&xmap_step));
89     args.push_back( std::make_pair( sizeof(cl_int), (void *)&ymap_step));
90     args.push_back( std::make_pair( sizeof(cl_int), (void *)&xmap_offset));
91     args.push_back( std::make_pair( sizeof(cl_int), (void *)&ymap_offset));
92     args.push_back( std::make_pair( sizeof(cl_float), (void *)&scale));
93
94     size_t globalThreads[3] = { xmap.cols, xmap.rows, 1 };
95     size_t localThreads[3]  = { 32, 8, 1 };
96
97     openCLExecuteKernel(Context::getContext(), &build_warps, "buildWarpPlaneMaps", globalThreads, localThreads, args, -1, -1);
98 }
99
100 //////////////////////////////////////////////////////////////////////////////
101 // buildWarpCylyndricalMaps
102
103 void cv::ocl::buildWarpCylindricalMaps(Size /*src_size*/, Rect dst_roi, const Mat &K, const Mat &R, float scale,
104                                        oclMat &xmap, oclMat &ymap)
105 {
106     CV_Assert(K.size() == Size(3, 3) && K.type() == CV_32F);
107     CV_Assert(R.size() == Size(3, 3) && R.type() == CV_32F);
108
109     Mat K_Rinv = K * R.t();
110     CV_Assert(K_Rinv.isContinuous());
111
112     oclMat KR_oclMat(K_Rinv.reshape(1, 1));
113
114     xmap.create(dst_roi.size(), CV_32F);
115     ymap.create(dst_roi.size(), CV_32F);
116
117     int tl_u = dst_roi.tl().x;
118     int tl_v = dst_roi.tl().y;
119
120     int xmap_step = xmap.step / xmap.elemSize(), xmap_offset = xmap.offset / xmap.elemSize();
121     int ymap_step = ymap.step / ymap.elemSize(), ymap_offset = ymap.offset / ymap.elemSize();
122
123     std::vector< std::pair<size_t, const void *> > args;
124     args.push_back( std::make_pair( sizeof(cl_mem), (void *)&xmap.data));
125     args.push_back( std::make_pair( sizeof(cl_mem), (void *)&ymap.data));
126     args.push_back( std::make_pair( sizeof(cl_mem), (void *)&KR_oclMat.data));
127     args.push_back( std::make_pair( sizeof(cl_int), (void *)&tl_u));
128     args.push_back( std::make_pair( sizeof(cl_int), (void *)&tl_v));
129     args.push_back( std::make_pair( sizeof(cl_int), (void *)&xmap.cols));
130     args.push_back( std::make_pair( sizeof(cl_int), (void *)&xmap.rows));
131     args.push_back( std::make_pair( sizeof(cl_int), (void *)&xmap_step));
132     args.push_back( std::make_pair( sizeof(cl_int), (void *)&ymap_step));
133     args.push_back( std::make_pair( sizeof(cl_int), (void *)&xmap_offset));
134     args.push_back( std::make_pair( sizeof(cl_int), (void *)&ymap_offset));
135     args.push_back( std::make_pair( sizeof(cl_float), (void *)&scale));
136
137     size_t globalThreads[3] = { xmap.cols, xmap.rows, 1 };
138     size_t localThreads[3]  = { 32, 8, 1 };
139
140     openCLExecuteKernel(Context::getContext(), &build_warps, "buildWarpCylindricalMaps", globalThreads, localThreads, args, -1, -1);
141 }
142
143 //////////////////////////////////////////////////////////////////////////////
144 // buildWarpSphericalMaps
145
146 void cv::ocl::buildWarpSphericalMaps(Size /*src_size*/, Rect dst_roi, const Mat &K, const Mat &R, float scale,
147                                      oclMat &xmap, oclMat &ymap)
148 {
149     CV_Assert(K.size() == Size(3, 3) && K.type() == CV_32F);
150     CV_Assert(R.size() == Size(3, 3) && R.type() == CV_32F);
151
152     Mat K_Rinv = K * R.t();
153     CV_Assert(K_Rinv.isContinuous());
154
155     oclMat KR_oclMat(K_Rinv.reshape(1, 1));
156     // transfer K_Rinv, R_Kinv into a single cl_mem
157     xmap.create(dst_roi.size(), CV_32F);
158     ymap.create(dst_roi.size(), CV_32F);
159
160     int tl_u = dst_roi.tl().x;
161     int tl_v = dst_roi.tl().y;
162
163     int xmap_step = xmap.step / xmap.elemSize(), xmap_offset = xmap.offset / xmap.elemSize();
164     int ymap_step = ymap.step / ymap.elemSize(), ymap_offset = ymap.offset / ymap.elemSize();
165
166     std::vector< std::pair<size_t, const void *> > args;
167     args.push_back( std::make_pair( sizeof(cl_mem), (void *)&xmap.data));
168     args.push_back( std::make_pair( sizeof(cl_mem), (void *)&ymap.data));
169     args.push_back( std::make_pair( sizeof(cl_mem), (void *)&KR_oclMat.data));
170     args.push_back( std::make_pair( sizeof(cl_int), (void *)&tl_u));
171     args.push_back( std::make_pair( sizeof(cl_int), (void *)&tl_v));
172     args.push_back( std::make_pair( sizeof(cl_int), (void *)&xmap.cols));
173     args.push_back( std::make_pair( sizeof(cl_int), (void *)&xmap.rows));
174     args.push_back( std::make_pair( sizeof(cl_int), (void *)&xmap_step));
175     args.push_back( std::make_pair( sizeof(cl_int), (void *)&ymap_step));
176     args.push_back( std::make_pair( sizeof(cl_int), (void *)&xmap_offset));
177     args.push_back( std::make_pair( sizeof(cl_int), (void *)&ymap_offset));
178     args.push_back( std::make_pair( sizeof(cl_float), (void *)&scale));
179
180     size_t globalThreads[3] = { xmap.cols, xmap.rows, 1 };
181     size_t localThreads[3]  = { 32, 8, 1 };
182     openCLExecuteKernel(Context::getContext(), &build_warps, "buildWarpSphericalMaps", globalThreads, localThreads, args, -1, -1);
183 }
184
185 //////////////////////////////////////////////////////////////////////////////
186 // buildWarpAffineMaps
187
188 void cv::ocl::buildWarpAffineMaps(const Mat &M, bool inverse, Size dsize, oclMat &xmap, oclMat &ymap)
189 {
190     CV_Assert(M.rows == 2 && M.cols == 3);
191     CV_Assert(dsize.area());
192
193     xmap.create(dsize, CV_32FC1);
194     ymap.create(dsize, CV_32FC1);
195
196     float coeffs[2 * 3];
197     Mat coeffsMat(2, 3, CV_32F, (void *)coeffs);
198
199     if (inverse)
200         M.convertTo(coeffsMat, coeffsMat.type());
201     else
202     {
203         cv::Mat iM;
204         invertAffineTransform(M, iM);
205         iM.convertTo(coeffsMat, coeffsMat.type());
206     }
207
208     int xmap_step = xmap.step / xmap.elemSize(), xmap_offset = xmap.offset / xmap.elemSize();
209     int ymap_step = ymap.step / ymap.elemSize(), ymap_offset = ymap.offset / ymap.elemSize();
210
211     oclMat coeffsOclMat(coeffsMat.reshape(1, 1));
212
213     std::vector< std::pair<size_t, const void *> > args;
214     args.push_back( std::make_pair( sizeof(cl_mem), (void *)&xmap.data));
215     args.push_back( std::make_pair( sizeof(cl_mem), (void *)&ymap.data));
216     args.push_back( std::make_pair( sizeof(cl_mem), (void *)&coeffsOclMat.data));
217     args.push_back( std::make_pair( sizeof(cl_int), (void *)&xmap.cols));
218     args.push_back( std::make_pair( sizeof(cl_int), (void *)&xmap.rows));
219     args.push_back( std::make_pair( sizeof(cl_int), (void *)&xmap_step));
220     args.push_back( std::make_pair( sizeof(cl_int), (void *)&ymap_step));
221     args.push_back( std::make_pair( sizeof(cl_int), (void *)&xmap_offset));
222     args.push_back( std::make_pair( sizeof(cl_int), (void *)&ymap_offset));
223
224     size_t globalThreads[3] = { xmap.cols, xmap.rows, 1 };
225     size_t localThreads[3]  = { 32, 8, 1 };
226     openCLExecuteKernel(Context::getContext(), &build_warps, "buildWarpAffineMaps", globalThreads, localThreads, args, -1, -1);
227 }
228
229 //////////////////////////////////////////////////////////////////////////////
230 // buildWarpPerspectiveMaps
231
232 void cv::ocl::buildWarpPerspectiveMaps(const Mat &M, bool inverse, Size dsize, oclMat &xmap, oclMat &ymap)
233 {
234     CV_Assert(M.rows == 3 && M.cols == 3);
235     CV_Assert(dsize.area() > 0);
236
237     xmap.create(dsize, CV_32FC1);
238     ymap.create(dsize, CV_32FC1);
239
240     float coeffs[3 * 3];
241     Mat coeffsMat(3, 3, CV_32F, (void *)coeffs);
242
243     if (inverse)
244         M.convertTo(coeffsMat, coeffsMat.type());
245     else
246     {
247         cv::Mat iM;
248         invert(M, iM);
249         iM.convertTo(coeffsMat, coeffsMat.type());
250     }
251
252     oclMat coeffsOclMat(coeffsMat.reshape(1, 1));
253
254     int xmap_step = xmap.step / xmap.elemSize(), xmap_offset = xmap.offset / xmap.elemSize();
255     int ymap_step = ymap.step / ymap.elemSize(), ymap_offset = ymap.offset / ymap.elemSize();
256
257     std::vector< std::pair<size_t, const void *> > args;
258     args.push_back( std::make_pair( sizeof(cl_mem), (void *)&xmap.data));
259     args.push_back( std::make_pair( sizeof(cl_mem), (void *)&ymap.data));
260     args.push_back( std::make_pair( sizeof(cl_mem), (void *)&coeffsOclMat.data));
261     args.push_back( std::make_pair( sizeof(cl_int), (void *)&xmap.cols));
262     args.push_back( std::make_pair( sizeof(cl_int), (void *)&xmap.rows));
263     args.push_back( std::make_pair( sizeof(cl_int), (void *)&xmap_step));
264     args.push_back( std::make_pair( sizeof(cl_int), (void *)&ymap_step));
265     args.push_back( std::make_pair( sizeof(cl_int), (void *)&xmap_offset));
266     args.push_back( std::make_pair( sizeof(cl_int), (void *)&ymap_offset));
267
268     size_t globalThreads[3] = { xmap.cols, xmap.rows, 1 };
269
270     openCLExecuteKernel(Context::getContext(), &build_warps, "buildWarpPerspectiveMaps", globalThreads, NULL, args, -1, -1);
271 }