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) 2000-2008, Intel Corporation, all rights reserved.
14 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
15 // Third party copyrights are property of their respective owners.
16 //
17 // Redistribution and use in source and binary forms, with or without modification,
18 // are permitted provided that the following conditions are met:
19 //
20 //   * Redistribution's of source code must retain the above copyright notice,
21 //     this list of conditions and the following disclaimer.
22 //
23 //   * Redistribution's in binary form must reproduce the above copyright notice,
24 //     this list of conditions and the following disclaimer in the documentation
25 //     and/or other materials provided with the distribution.
26 //
27 //   * The name of the copyright holders may not be used to endorse or promote products
28 //     derived from this software without specific prior written permission.
29 //
30 // This software is provided by the copyright holders and contributors "as is" and
31 // any express or implied warranties, including, but not limited to, the implied
32 // warranties of merchantability and fitness for a particular purpose are disclaimed.
33 // In no event shall the Intel Corporation or contributors be liable for any direct,
34 // indirect, incidental, special, exemplary, or consequential damages
35 // (including, but not limited to, procurement of substitute goods or services;
36 // loss of use, data, or profits; or business interruption) however caused
37 // and on any theory of liability, whether in contract, strict liability,
38 // or tort (including negligence or otherwise) arising in any way out of
39 // the use of this software, even if advised of the possibility of such damage.
40 //
41 //M*/
42 
43 #include "opencv2/opencv_modules.hpp"
44 
45 #ifndef HAVE_OPENCV_CUDEV
46 
47 #error "opencv_cudev is required"
48 
49 #else
50 
51 #include "opencv2/cudaarithm.hpp"
52 #include "opencv2/cudev.hpp"
53 #include "opencv2/core/private.cuda.hpp"
54 
55 using namespace cv;
56 using namespace cv::cuda;
57 using namespace cv::cudev;
58 
magnitude(InputArray _x,InputArray _y,OutputArray _dst,Stream & stream)59 void cv::cuda::magnitude(InputArray _x, InputArray _y, OutputArray _dst, Stream& stream)
60 {
61     GpuMat x = getInputMat(_x, stream);
62     GpuMat y = getInputMat(_y, stream);
63 
64     CV_Assert( x.depth() == CV_32F );
65     CV_Assert( y.type() == x.type() && y.size() == x.size() );
66 
67     GpuMat dst = getOutputMat(_dst, x.size(), CV_32FC1, stream);
68 
69     GpuMat_<float> xc(x.reshape(1));
70     GpuMat_<float> yc(y.reshape(1));
71     GpuMat_<float> magc(dst.reshape(1));
72 
73     gridTransformBinary(xc, yc, magc, magnitude_func<float>(), stream);
74 
75     syncOutput(dst, _dst, stream);
76 }
77 
magnitudeSqr(InputArray _x,InputArray _y,OutputArray _dst,Stream & stream)78 void cv::cuda::magnitudeSqr(InputArray _x, InputArray _y, OutputArray _dst, Stream& stream)
79 {
80     GpuMat x = getInputMat(_x, stream);
81     GpuMat y = getInputMat(_y, stream);
82 
83     CV_Assert( x.depth() == CV_32F );
84     CV_Assert( y.type() == x.type() && y.size() == x.size() );
85 
86     GpuMat dst = getOutputMat(_dst, x.size(), CV_32FC1, stream);
87 
88     GpuMat_<float> xc(x.reshape(1));
89     GpuMat_<float> yc(y.reshape(1));
90     GpuMat_<float> magc(dst.reshape(1));
91 
92     gridTransformBinary(xc, yc, magc, magnitude_sqr_func<float>(), stream);
93 
94     syncOutput(dst, _dst, stream);
95 }
96 
phase(InputArray _x,InputArray _y,OutputArray _dst,bool angleInDegrees,Stream & stream)97 void cv::cuda::phase(InputArray _x, InputArray _y, OutputArray _dst, bool angleInDegrees, Stream& stream)
98 {
99     GpuMat x = getInputMat(_x, stream);
100     GpuMat y = getInputMat(_y, stream);
101 
102     CV_Assert( x.depth() == CV_32F );
103     CV_Assert( y.type() == x.type() && y.size() == x.size() );
104 
105     GpuMat dst = getOutputMat(_dst, x.size(), CV_32FC1, stream);
106 
107     GpuMat_<float> xc(x.reshape(1));
108     GpuMat_<float> yc(y.reshape(1));
109     GpuMat_<float> anglec(dst.reshape(1));
110 
111     if (angleInDegrees)
112         gridTransformBinary(xc, yc, anglec, direction_func<float, true>(), stream);
113     else
114         gridTransformBinary(xc, yc, anglec, direction_func<float, false>(), stream);
115 
116     syncOutput(dst, _dst, stream);
117 }
118 
cartToPolar(InputArray _x,InputArray _y,OutputArray _mag,OutputArray _angle,bool angleInDegrees,Stream & stream)119 void cv::cuda::cartToPolar(InputArray _x, InputArray _y, OutputArray _mag, OutputArray _angle, bool angleInDegrees, Stream& stream)
120 {
121     GpuMat x = getInputMat(_x, stream);
122     GpuMat y = getInputMat(_y, stream);
123 
124     CV_Assert( x.depth() == CV_32F );
125     CV_Assert( y.type() == x.type() && y.size() == x.size() );
126 
127     GpuMat mag = getOutputMat(_mag, x.size(), CV_32FC1, stream);
128     GpuMat angle = getOutputMat(_angle, x.size(), CV_32FC1, stream);
129 
130     GpuMat_<float> xc(x.reshape(1));
131     GpuMat_<float> yc(y.reshape(1));
132     GpuMat_<float> magc(mag.reshape(1));
133     GpuMat_<float> anglec(angle.reshape(1));
134 
135     if (angleInDegrees)
136     {
137         gridTransformTuple(zipPtr(xc, yc),
138                            tie(magc, anglec),
139                            make_tuple(
140                                binaryTupleAdapter<0, 1>(magnitude_func<float>()),
141                                binaryTupleAdapter<0, 1>(direction_func<float, true>())),
142                            stream);
143     }
144     else
145     {
146         gridTransformTuple(zipPtr(xc, yc),
147                            tie(magc, anglec),
148                            make_tuple(
149                                binaryTupleAdapter<0, 1>(magnitude_func<float>()),
150                                binaryTupleAdapter<0, 1>(direction_func<float, false>())),
151                            stream);
152     }
153 
154     syncOutput(mag, _mag, stream);
155     syncOutput(angle, _angle, stream);
156 }
157 
158 namespace
159 {
160     template <bool useMag>
polarToCartImpl(const GlobPtr<float> mag,const GlobPtr<float> angle,GlobPtr<float> xmat,GlobPtr<float> ymat,const float scale,const int rows,const int cols)161     __global__ void polarToCartImpl(const GlobPtr<float> mag, const GlobPtr<float> angle, GlobPtr<float> xmat, GlobPtr<float> ymat, const float scale, const int rows, const int cols)
162     {
163         const int x = blockDim.x * blockIdx.x + threadIdx.x;
164         const int y = blockDim.y * blockIdx.y + threadIdx.y;
165 
166         if (x >= cols || y >= rows)
167             return;
168 
169         const float mag_val = useMag ? mag(y, x) : 1.0f;
170         const float angle_val = angle(y, x);
171 
172         float sin_a, cos_a;
173         ::sincosf(scale * angle_val, &sin_a, &cos_a);
174 
175         xmat(y, x) = mag_val * cos_a;
176         ymat(y, x) = mag_val * sin_a;
177     }
178 }
179 
polarToCart(InputArray _mag,InputArray _angle,OutputArray _x,OutputArray _y,bool angleInDegrees,Stream & _stream)180 void cv::cuda::polarToCart(InputArray _mag, InputArray _angle, OutputArray _x, OutputArray _y, bool angleInDegrees, Stream& _stream)
181 {
182     GpuMat mag = getInputMat(_mag, _stream);
183     GpuMat angle = getInputMat(_angle, _stream);
184 
185     CV_Assert( angle.depth() == CV_32F );
186     CV_Assert( mag.empty() || (mag.type() == angle.type() && mag.size() == angle.size()) );
187 
188     GpuMat x = getOutputMat(_x, angle.size(), CV_32FC1, _stream);
189     GpuMat y = getOutputMat(_y, angle.size(), CV_32FC1, _stream);
190 
191     GpuMat_<float> xc(x.reshape(1));
192     GpuMat_<float> yc(y.reshape(1));
193     GpuMat_<float> magc(mag.reshape(1));
194     GpuMat_<float> anglec(angle.reshape(1));
195 
196     const dim3 block(32, 8);
197     const dim3 grid(divUp(anglec.cols, block.x), divUp(anglec.rows, block.y));
198 
199     const float scale = angleInDegrees ? (CV_PI_F / 180.0f) : 1.0f;
200 
201     cudaStream_t stream = StreamAccessor::getStream(_stream);
202 
203     if (magc.empty())
204         polarToCartImpl<false><<<grid, block, 0, stream>>>(shrinkPtr(magc), shrinkPtr(anglec), shrinkPtr(xc), shrinkPtr(yc), scale, anglec.rows, anglec.cols);
205     else
206         polarToCartImpl<true><<<grid, block, 0, stream>>>(shrinkPtr(magc), shrinkPtr(anglec), shrinkPtr(xc), shrinkPtr(yc), scale, anglec.rows, anglec.cols);
207 
208     CV_CUDEV_SAFE_CALL( cudaGetLastError() );
209 
210     syncOutput(x, _x, _stream);
211     syncOutput(y, _y, _stream);
212 
213     if (stream == 0)
214         CV_CUDEV_SAFE_CALL( cudaDeviceSynchronize() );
215 }
216 
217 #endif
218