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