diff --git a/modules/gpu/src/cascadeclassifier.cpp b/modules/gpu/src/cascadeclassifier.cpp index 0f1da83cef..74867b48dd 100644 --- a/modules/gpu/src/cascadeclassifier.cpp +++ b/modules/gpu/src/cascadeclassifier.cpp @@ -458,7 +458,7 @@ public: // generate integral for scale gpu::resize(image, src, level.sFrame, 0, 0, cv::INTER_LINEAR); - gpu::integralBuffered(src, sint, buff); + gpu::integral(src, sint, buff); // calculate job int totalWidth = level.workArea.width / step; diff --git a/modules/gpuarithm/doc/arithm.rst b/modules/gpuarithm/doc/arithm.rst index 8a051bc49c..2f1d74df5e 100644 --- a/modules/gpuarithm/doc/arithm.rst +++ b/modules/gpuarithm/doc/arithm.rst @@ -6,10 +6,10 @@ Arithm Operations on Matrices gpu::gemm ------------------- +--------- Performs generalized matrix multiplication. -.. ocv:function:: void gpu::gemm(const GpuMat& src1, const GpuMat& src2, double alpha, const GpuMat& src3, double beta, GpuMat& dst, int flags = 0, Stream& stream = Stream::Null()) +.. ocv:function:: void gpu::gemm(InputArray src1, InputArray src2, double alpha, InputArray src3, double beta, OutputArray dst, int flags = 0, Stream& stream = Stream::Null()) :param src1: First multiplied input matrix that should have ``CV_32FC1`` , ``CV_64FC1`` , ``CV_32FC2`` , or ``CV_64FC2`` type. @@ -44,38 +44,40 @@ The function performs generalized matrix multiplication similar to the ``gemm`` gpu::mulSpectrums ---------------------- +----------------- Performs a per-element multiplication of two Fourier spectrums. -.. ocv:function:: void gpu::mulSpectrums( const GpuMat& a, const GpuMat& b, GpuMat& c, int flags, bool conjB=false, Stream& stream=Stream::Null() ) +.. ocv:function:: void gpu::mulSpectrums(InputArray src1, InputArray src2, OutputArray dst, int flags, bool conjB=false, Stream& stream = Stream::Null()) - :param a: First spectrum. + :param src1: First spectrum. - :param b: Second spectrum with the same size and type as ``a`` . + :param src2: Second spectrum with the same size and type as ``a`` . - :param c: Destination spectrum. + :param dst: Destination spectrum. :param flags: Mock parameter used for CPU/GPU interfaces similarity. :param conjB: Optional flag to specify if the second spectrum needs to be conjugated before the multiplication. - Only full (not packed) ``CV_32FC2`` complex spectrums in the interleaved format are supported for now. + :param stream: Stream for the asynchronous version. + +Only full (not packed) ``CV_32FC2`` complex spectrums in the interleaved format are supported for now. .. seealso:: :ocv:func:`mulSpectrums` gpu::mulAndScaleSpectrums ------------------------------ +------------------------- Performs a per-element multiplication of two Fourier spectrums and scales the result. -.. ocv:function:: void gpu::mulAndScaleSpectrums( const GpuMat& a, const GpuMat& b, GpuMat& c, int flags, float scale, bool conjB=false, Stream& stream=Stream::Null() ) +.. ocv:function:: void gpu::mulAndScaleSpectrums(InputArray src1, InputArray src2, OutputArray dst, int flags, float scale, bool conjB=false, Stream& stream = Stream::Null()) - :param a: First spectrum. + :param src1: First spectrum. - :param b: Second spectrum with the same size and type as ``a`` . + :param src2: Second spectrum with the same size and type as ``a`` . - :param c: Destination spectrum. + :param dst: Destination spectrum. :param flags: Mock parameter used for CPU/GPU interfaces similarity. @@ -83,17 +85,17 @@ Performs a per-element multiplication of two Fourier spectrums and scales the re :param conjB: Optional flag to specify if the second spectrum needs to be conjugated before the multiplication. - Only full (not packed) ``CV_32FC2`` complex spectrums in the interleaved format are supported for now. +Only full (not packed) ``CV_32FC2`` complex spectrums in the interleaved format are supported for now. .. seealso:: :ocv:func:`mulSpectrums` gpu::dft ------------- +-------- Performs a forward or inverse discrete Fourier transform (1D or 2D) of the floating point matrix. -.. ocv:function:: void gpu::dft( const GpuMat& src, GpuMat& dst, Size dft_size, int flags=0, Stream& stream=Stream::Null() ) +.. ocv:function:: void gpu::dft(InputArray src, OutputArray dst, Size dft_size, int flags=0, Stream& stream = Stream::Null()) :param src: Source matrix (real or complex). @@ -125,46 +127,25 @@ The source matrix should be continuous, otherwise reallocation and data copying -gpu::ConvolveBuf +gpu::Convolution ---------------- -.. ocv:struct:: gpu::ConvolveBuf +.. ocv:class:: gpu::Convolution : public Algorithm -Class providing a memory buffer for :ocv:func:`gpu::convolve` function, plus it allows to adjust some specific parameters. :: +Base class for convolution (or cross-correlation) operator. :: - struct CV_EXPORTS ConvolveBuf + class CV_EXPORTS Convolution : public Algorithm { - Size result_size; - Size block_size; - Size user_block_size; - Size dft_size; - int spect_len; - - GpuMat image_spect, templ_spect, result_spect; - GpuMat image_block, templ_block, result_data; - - void create(Size image_size, Size templ_size); - static Size estimateBlockSize(Size result_size, Size templ_size); + public: + virtual void convolve(InputArray image, InputArray templ, OutputArray result, bool ccorr = false, Stream& stream = Stream::Null()) = 0; }; -You can use field `user_block_size` to set specific block size for :ocv:func:`gpu::convolve` function. If you leave its default value `Size(0,0)` then automatic estimation of block size will be used (which is optimized for speed). By varying `user_block_size` you can reduce memory requirements at the cost of speed. - -gpu::ConvolveBuf::create ------------------------- -.. ocv:function:: gpu::ConvolveBuf::create(Size image_size, Size templ_size) - -Constructs a buffer for :ocv:func:`gpu::convolve` function with respective arguments. - - - -gpu::convolve ------------------ +gpu::Convolution::convolve +--------------------------- Computes a convolution (or cross-correlation) of two images. -.. ocv:function:: void gpu::convolve(const GpuMat& image, const GpuMat& templ, GpuMat& result, bool ccorr=false) - -.. ocv:function:: void gpu::convolve( const GpuMat& image, const GpuMat& templ, GpuMat& result, bool ccorr, ConvolveBuf& buf, Stream& stream=Stream::Null() ) +.. ocv:function:: void gpu::Convolution::convolve(InputArray image, InputArray templ, OutputArray result, bool ccorr = false, Stream& stream = Stream::Null()) :param image: Source image. Only ``CV_32FC1`` images are supported for now. @@ -174,38 +155,16 @@ Computes a convolution (or cross-correlation) of two images. :param ccorr: Flags to evaluate cross-correlation instead of convolution. - :param buf: Optional buffer to avoid extra memory allocations and to adjust some specific parameters. See :ocv:struct:`gpu::ConvolveBuf`. - :param stream: Stream for the asynchronous version. .. seealso:: :ocv:func:`gpu::filter2D` -gpu::integral ------------------ -Computes an integral image. +gpu::createConvolution +---------------------- +Creates implementation for :ocv:class:`gpu::Convolution` . -.. ocv:function:: void gpu::integral(const GpuMat& src, GpuMat& sum, Stream& stream = Stream::Null()) +.. ocv:function:: Ptr createConvolution(Size user_block_size = Size()) - :param src: Source image. Only ``CV_8UC1`` images are supported for now. - - :param sum: Integral image containing 32-bit unsigned integer values packed into ``CV_32SC1`` . - - :param stream: Stream for the asynchronous version. - -.. seealso:: :ocv:func:`integral` - - - -gpu::sqrIntegral --------------------- -Computes a squared integral image. - -.. ocv:function:: void gpu::sqrIntegral(const GpuMat& src, GpuMat& sqsum, Stream& stream = Stream::Null()) - - :param src: Source image. Only ``CV_8UC1`` images are supported for now. - - :param sqsum: Squared integral image containing 64-bit unsigned integer values packed into ``CV_64FC1`` . - - :param stream: Stream for the asynchronous version. + :param user_block_size: Block size. If you leave default value `Size(0,0)` then automatic estimation of block size will be used (which is optimized for speed). By varying `user_block_size` you can reduce memory requirements at the cost of speed. diff --git a/modules/gpuarithm/doc/core.rst b/modules/gpuarithm/doc/core.rst index 50599bcf2a..624ea3e7b3 100644 --- a/modules/gpuarithm/doc/core.rst +++ b/modules/gpuarithm/doc/core.rst @@ -6,12 +6,12 @@ Core Operations on Matrices gpu::merge --------------- +---------- Makes a multi-channel matrix out of several single-channel matrices. -.. ocv:function:: void gpu::merge(const GpuMat* src, size_t n, GpuMat& dst, Stream& stream = Stream::Null()) +.. ocv:function:: void gpu::merge(const GpuMat* src, size_t n, OutputArray dst, Stream& stream = Stream::Null()) -.. ocv:function:: void gpu::merge(const vector& src, GpuMat& dst, Stream& stream = Stream::Null()) +.. ocv:function:: void gpu::merge(const std::vector& src, OutputArray dst, Stream& stream = Stream::Null()) :param src: Array/vector of source matrices. @@ -26,12 +26,12 @@ Makes a multi-channel matrix out of several single-channel matrices. gpu::split --------------- +---------- Copies each plane of a multi-channel matrix into an array. -.. ocv:function:: void gpu::split(const GpuMat& src, GpuMat* dst, Stream& stream = Stream::Null()) +.. ocv:function:: void gpu::split(InputArray src, GpuMat* dst, Stream& stream = Stream::Null()) -.. ocv:function:: void gpu::split(const GpuMat& src, vector& dst, Stream& stream = Stream::Null()) +.. ocv:function:: void gpu::split(InputArray src, vector& dst, Stream& stream = Stream::Null()) :param src: Source matrix. @@ -43,15 +43,95 @@ Copies each plane of a multi-channel matrix into an array. +gpu::transpose +-------------- +Transposes a matrix. + +.. ocv:function:: void gpu::transpose(InputArray src1, OutputArray dst, Stream& stream = Stream::Null()) + + :param src1: Source matrix. 1-, 4-, 8-byte element sizes are supported for now. + + :param dst: Destination matrix. + + :param stream: Stream for the asynchronous version. + +.. seealso:: :ocv:func:`transpose` + + + +gpu::flip +--------- +Flips a 2D matrix around vertical, horizontal, or both axes. + +.. ocv:function:: void gpu::flip(InputArray src, OutputArray dst, int flipCode, Stream& stream = Stream::Null()) + + :param src: Source matrix. Supports 1, 3 and 4 channels images with ``CV_8U``, ``CV_16U``, ``CV_32S`` or ``CV_32F`` depth. + + :param dst: Destination matrix. + + :param flipCode: Flip mode for the source: + + * ``0`` Flips around x-axis. + + * ``> 0`` Flips around y-axis. + + * ``< 0`` Flips around both axes. + + :param stream: Stream for the asynchronous version. + +.. seealso:: :ocv:func:`flip` + + + +gpu::LookUpTable +---------------- +.. ocv:class:: gpu::LookUpTable : public Algorithm + +Base class for transform using lookup table. :: + + class CV_EXPORTS LookUpTable : public Algorithm + { + public: + virtual void transform(InputArray src, OutputArray dst, Stream& stream = Stream::Null()) = 0; + }; + +.. seealso:: :ocv:func:`LUT` + + + +gpu::LookUpTable::transform +--------------------------- +Transforms the source matrix into the destination matrix using the given look-up table: ``dst(I) = lut(src(I))`` . + +.. ocv:function:: void gpu::LookUpTable::transform(InputArray src, OutputArray dst, Stream& stream = Stream::Null()) + + :param src: Source matrix. ``CV_8UC1`` and ``CV_8UC3`` matrices are supported for now. + + :param dst: Destination matrix. + + :param stream: Stream for the asynchronous version. + + + +gpu::createLookUpTable +---------------------- +Creates implementation for :ocv:class:`gpu::LookUpTable` . + +.. ocv:function:: Ptr createLookUpTable(InputArray lut) + + :param lut: Look-up table of 256 elements. It is a continuous ``CV_8U`` matrix. + + + gpu::copyMakeBorder ----------------------- Forms a border around an image. -.. ocv:function:: void gpu::copyMakeBorder(const GpuMat& src, GpuMat& dst, int top, int bottom, int left, int right, int borderType, const Scalar& value = Scalar(), Stream& stream = Stream::Null()) +.. ocv:function:: void gpu::copyMakeBorder(InputArray src, OutputArray dst, int top, int bottom, int left, int right, int borderType, Scalar value = Scalar(), Stream& stream = Stream::Null()) - :param src: Source image. ``CV_8UC1`` , ``CV_8UC4`` , ``CV_32SC1`` , and ``CV_32FC1`` types are supported. + :param src: Source image. ``CV_8UC1`` , ``CV_8UC4`` , ``CV_32SC1`` , and ``CV_32FC1`` types are supported. - :param dst: Destination image with the same type as ``src``. The size is ``Size(src.cols+left+right, src.rows+top+bottom)`` . + :param dst: Destination image with the same type as ``src``. The size is ``Size(src.cols+left+right, src.rows+top+bottom)`` . :param top: @@ -68,61 +148,3 @@ Forms a border around an image. :param stream: Stream for the asynchronous version. .. seealso:: :ocv:func:`copyMakeBorder` - - - -gpu::transpose ------------------- -Transposes a matrix. - -.. ocv:function:: void gpu::transpose( const GpuMat& src1, GpuMat& dst, Stream& stream=Stream::Null() ) - - :param src1: Source matrix. 1-, 4-, 8-byte element sizes are supported for now (CV_8UC1, CV_8UC4, CV_16UC2, CV_32FC1, etc). - - :param dst: Destination matrix. - - :param stream: Stream for the asynchronous version. - -.. seealso:: :ocv:func:`transpose` - - - -gpu::flip -------------- -Flips a 2D matrix around vertical, horizontal, or both axes. - -.. ocv:function:: void gpu::flip( const GpuMat& a, GpuMat& b, int flipCode, Stream& stream=Stream::Null() ) - - :param a: Source matrix. Supports 1, 3 and 4 channels images with ``CV_8U``, ``CV_16U``, ``CV_32S`` or ``CV_32F`` depth. - - :param b: Destination matrix. - - :param flipCode: Flip mode for the source: - - * ``0`` Flips around x-axis. - - * ``>0`` Flips around y-axis. - - * ``<0`` Flips around both axes. - - :param stream: Stream for the asynchronous version. - -.. seealso:: :ocv:func:`flip` - - - -gpu::LUT ------------- -Transforms the source matrix into the destination matrix using the given look-up table: ``dst(I) = lut(src(I))`` - -.. ocv:function:: void gpu::LUT(const GpuMat& src, const Mat& lut, GpuMat& dst, Stream& stream = Stream::Null()) - - :param src: Source matrix. ``CV_8UC1`` and ``CV_8UC3`` matrices are supported for now. - - :param lut: Look-up table of 256 elements. It is a continuous ``CV_8U`` matrix. - - :param dst: Destination matrix with the same depth as ``lut`` and the same number of channels as ``src`` . - - :param stream: Stream for the asynchronous version. - -.. seealso:: :ocv:func:`LUT` diff --git a/modules/gpuarithm/doc/element_operations.rst b/modules/gpuarithm/doc/element_operations.rst index eae2ad7a2a..eb616c1c39 100644 --- a/modules/gpuarithm/doc/element_operations.rst +++ b/modules/gpuarithm/doc/element_operations.rst @@ -6,20 +6,16 @@ Per-element Operations gpu::add ------------- +-------- Computes a matrix-matrix or matrix-scalar sum. -.. ocv:function:: void gpu::add( const GpuMat& a, const GpuMat& b, GpuMat& c, const GpuMat& mask=GpuMat(), int dtype=-1, Stream& stream=Stream::Null() ) +.. ocv:function:: void gpu::add(InputArray src1, InputArray src2, OutputArray dst, InputArray mask = noArray(), int dtype = -1, Stream& stream = Stream::Null()) -.. ocv:function:: void gpu::add( const GpuMat& a, const Scalar& sc, GpuMat& c, const GpuMat& mask=GpuMat(), int dtype=-1, Stream& stream=Stream::Null() ) + :param src1: First source matrix or scalar. - :param a: First source matrix. + :param src2: Second source matrix or scalar. Matrix should have the same size and type as ``src1`` . - :param b: Second source matrix to be added to ``a`` . Matrix should have the same size and type as ``a`` . - - :param sc: A scalar to be added to ``a`` . - - :param c: Destination matrix that has the same size and number of channels as the input array(s). The depth is defined by ``dtype`` or ``a`` depth. + :param dst: Destination matrix that has the same size and number of channels as the input array(s). The depth is defined by ``dtype`` or ``src1`` depth. :param mask: Optional operation mask, 8-bit single channel array, that specifies elements of the destination array to be changed. @@ -32,20 +28,16 @@ Computes a matrix-matrix or matrix-scalar sum. gpu::subtract ------------------ +------------- Computes a matrix-matrix or matrix-scalar difference. -.. ocv:function:: void gpu::subtract( const GpuMat& a, const GpuMat& b, GpuMat& c, const GpuMat& mask=GpuMat(), int dtype=-1, Stream& stream=Stream::Null() ) +.. ocv:function:: void gpu::subtract(InputArray src1, InputArray src2, OutputArray dst, InputArray mask = noArray(), int dtype = -1, Stream& stream = Stream::Null()) -.. ocv:function:: void gpu::subtract( const GpuMat& a, const Scalar& sc, GpuMat& c, const GpuMat& mask=GpuMat(), int dtype=-1, Stream& stream=Stream::Null() ) + :param src1: First source matrix or scalar. - :param a: First source matrix. + :param src2: Second source matrix or scalar. Matrix should have the same size and type as ``src1`` . - :param b: Second source matrix to be added to ``a`` . Matrix should have the same size and type as ``a`` . - - :param sc: A scalar to be added to ``a`` . - - :param c: Destination matrix that has the same size and number of channels as the input array(s). The depth is defined by ``dtype`` or ``a`` depth. + :param dst: Destination matrix that has the same size and number of channels as the input array(s). The depth is defined by ``dtype`` or ``src1`` depth. :param mask: Optional operation mask, 8-bit single channel array, that specifies elements of the destination array to be changed. @@ -58,20 +50,16 @@ Computes a matrix-matrix or matrix-scalar difference. gpu::multiply ------------------ +------------- Computes a matrix-matrix or matrix-scalar per-element product. -.. ocv:function:: void gpu::multiply( const GpuMat& a, const GpuMat& b, GpuMat& c, double scale=1, int dtype=-1, Stream& stream=Stream::Null() ) +.. ocv:function:: void gpu::multiply(InputArray src1, InputArray src2, OutputArray dst, double scale = 1, int dtype = -1, Stream& stream = Stream::Null()) -.. ocv:function:: void gpu::multiply( const GpuMat& a, const Scalar& sc, GpuMat& c, double scale=1, int dtype=-1, Stream& stream=Stream::Null() ) + :param src1: First source matrix or scalar. - :param a: First source matrix. + :param src2: Second source matrix or scalar. - :param b: Second source matrix to be multiplied by ``a`` elements. - - :param sc: A scalar to be multiplied by ``a`` elements. - - :param c: Destination matrix that has the same size and number of channels as the input array(s). The depth is defined by ``dtype`` or ``a`` depth. + :param dst: Destination matrix that has the same size and number of channels as the input array(s). The depth is defined by ``dtype`` or ``src1`` depth. :param scale: Optional scale factor. @@ -87,19 +75,15 @@ gpu::divide ----------- Computes a matrix-matrix or matrix-scalar division. -.. ocv:function:: void gpu::divide( const GpuMat& a, const GpuMat& b, GpuMat& c, double scale=1, int dtype=-1, Stream& stream=Stream::Null() ) +.. ocv:function:: void gpu::divide(InputArray src1, InputArray src2, OutputArray dst, double scale = 1, int dtype = -1, Stream& stream = Stream::Null()) -.. ocv:function:: void gpu::divide(const GpuMat& a, const Scalar& sc, GpuMat& c, double scale = 1, int dtype = -1, Stream& stream = Stream::Null()) +.. ocv:function:: void gpu::divide(double src1, InputArray src2, OutputArray dst, int dtype = -1, Stream& stream = Stream::Null()) -.. ocv:function:: void gpu::divide( double scale, const GpuMat& b, GpuMat& c, int dtype=-1, Stream& stream=Stream::Null() ) + :param src1: First source matrix or a scalar. - :param a: First source matrix or a scalar. + :param src2: Second source matrix or scalar. - :param b: Second source matrix. The ``a`` elements are divided by it. - - :param sc: A scalar to be divided by the elements of ``a`` matrix. - - :param c: Destination matrix that has the same size and number of channels as the input array(s). The depth is defined by ``dtype`` or ``a`` depth. + :param dst: Destination matrix that has the same size and number of channels as the input array(s). The depth is defined by ``dtype`` or ``src1`` depth. :param scale: Optional scale factor. @@ -113,11 +97,296 @@ This function, in contrast to :ocv:func:`divide`, uses a round-down rounding mod +gpu::absdiff +------------ +Computes per-element absolute difference of two matrices (or of a matrix and scalar). + +.. ocv:function:: void gpu::absdiff(InputArray src1, InputArray src2, OutputArray dst, Stream& stream = Stream::Null()) + + :param src1: First source matrix or scalar. + + :param src2: Second source matrix or scalar. + + :param dst: Destination matrix that has the same size and type as the input array(s). + + :param stream: Stream for the asynchronous version. + +.. seealso:: :ocv:func:`absdiff` + + + +gpu::abs +-------- +Computes an absolute value of each matrix element. + +.. ocv:function:: void gpu::abs(InputArray src, OutputArray dst, Stream& stream = Stream::Null()) + + :param src: Source matrix. + + :param dst: Destination matrix with the same size and type as ``src`` . + + :param stream: Stream for the asynchronous version. + +.. seealso:: :ocv:func:`abs` + + + +gpu::sqr +-------- +Computes a square value of each matrix element. + +.. ocv:function:: void gpu::sqr(InputArray src, OutputArray dst, Stream& stream = Stream::Null()) + + :param src: Source matrix. + + :param dst: Destination matrix with the same size and type as ``src`` . + + :param stream: Stream for the asynchronous version. + + + +gpu::sqrt +--------- +Computes a square root of each matrix element. + +.. ocv:function:: void gpu::sqrt(InputArray src, OutputArray dst, Stream& stream = Stream::Null()) + + :param src: Source matrix. + + :param dst: Destination matrix with the same size and type as ``src`` . + + :param stream: Stream for the asynchronous version. + +.. seealso:: :ocv:func:`sqrt` + + + +gpu::exp +-------- +Computes an exponent of each matrix element. + +.. ocv:function:: void gpu::exp(InputArray src, OutputArray dst, Stream& stream = Stream::Null()) + + :param src: Source matrix. + + :param dst: Destination matrix with the same size and type as ``src`` . + + :param stream: Stream for the asynchronous version. + +.. seealso:: :ocv:func:`exp` + + + +gpu::log +-------- +Computes a natural logarithm of absolute value of each matrix element. + +.. ocv:function:: void gpu::log(InputArray src, OutputArray dst, Stream& stream = Stream::Null()) + + :param src: Source matrix. + + :param dst: Destination matrix with the same size and type as ``src`` . + + :param stream: Stream for the asynchronous version. + +.. seealso:: :ocv:func:`log` + + + +gpu::pow +-------- +Raises every matrix element to a power. + +.. ocv:function:: void gpu::pow(InputArray src, double power, OutputArray dst, Stream& stream = Stream::Null()) + + :param src: Source matrix. + + :param power: Exponent of power. + + :param dst: Destination matrix with the same size and type as ``src`` . + + :param stream: Stream for the asynchronous version. + +The function ``pow`` raises every element of the input matrix to ``power`` : + +.. math:: + + \texttt{dst} (I) = \fork{\texttt{src}(I)^power}{if \texttt{power} is integer}{|\texttt{src}(I)|^power}{otherwise} + +.. seealso:: :ocv:func:`pow` + + + +gpu::compare +------------ +Compares elements of two matrices (or of a matrix and scalar). + +.. ocv:function:: void gpu::compare(InputArray src1, InputArray src2, OutputArray dst, int cmpop, Stream& stream = Stream::Null()) + + :param src1: First source matrix or scalar. + + :param src2: Second source matrix or scalar. + + :param dst: Destination matrix that has the same size and type as the input array(s). + + :param cmpop: Flag specifying the relation between the elements to be checked: + + * **CMP_EQ:** ``a(.) == b(.)`` + * **CMP_GT:** ``a(.) < b(.)`` + * **CMP_GE:** ``a(.) <= b(.)`` + * **CMP_LT:** ``a(.) < b(.)`` + * **CMP_LE:** ``a(.) <= b(.)`` + * **CMP_NE:** ``a(.) != b(.)`` + + :param stream: Stream for the asynchronous version. + +.. seealso:: :ocv:func:`compare` + + + +gpu::bitwise_not +---------------- +Performs a per-element bitwise inversion. + +.. ocv:function:: void gpu::bitwise_not(InputArray src, OutputArray dst, InputArray mask = noArray(), Stream& stream = Stream::Null()) + + :param src: Source matrix. + + :param dst: Destination matrix with the same size and type as ``src`` . + + :param mask: Optional operation mask. 8-bit single channel image. + + :param stream: Stream for the asynchronous version. + + + +gpu::bitwise_or +--------------- +Performs a per-element bitwise disjunction of two matrices (or of matrix and scalar). + +.. ocv:function:: void gpu::bitwise_or(InputArray src1, InputArray src2, OutputArray dst, InputArray mask = noArray(), Stream& stream = Stream::Null()) + + :param src1: First source matrix or scalar. + + :param src2: Second source matrix or scalar. + + :param dst: Destination matrix that has the same size and type as the input array(s). + + :param mask: Optional operation mask. 8-bit single channel image. + + :param stream: Stream for the asynchronous version. + + + +gpu::bitwise_and +---------------- +Performs a per-element bitwise conjunction of two matrices (or of matrix and scalar). + +.. ocv:function:: void gpu::bitwise_and(InputArray src1, InputArray src2, OutputArray dst, InputArray mask = noArray(), Stream& stream = Stream::Null()) + + :param src1: First source matrix or scalar. + + :param src2: Second source matrix or scalar. + + :param dst: Destination matrix that has the same size and type as the input array(s). + + :param mask: Optional operation mask. 8-bit single channel image. + + :param stream: Stream for the asynchronous version. + + + +gpu::bitwise_xor +---------------- +Performs a per-element bitwise ``exclusive or`` operation of two matrices (or of matrix and scalar). + +.. ocv:function:: void gpu::bitwise_xor(InputArray src1, InputArray src2, OutputArray dst, InputArray mask = noArray(), Stream& stream = Stream::Null()) + + :param src1: First source matrix or scalar. + + :param src2: Second source matrix or scalar. + + :param dst: Destination matrix that has the same size and type as the input array(s). + + :param mask: Optional operation mask. 8-bit single channel image. + + :param stream: Stream for the asynchronous version. + + + +gpu::rshift +----------- +Performs pixel by pixel right shift of an image by a constant value. + +.. ocv:function:: void gpu::rshift(InputArray src, Scalar_ val, OutputArray dst, Stream& stream = Stream::Null()) + + :param src: Source matrix. Supports 1, 3 and 4 channels images with integers elements. + + :param val: Constant values, one per channel. + + :param dst: Destination matrix with the same size and type as ``src`` . + + :param stream: Stream for the asynchronous version. + + + +gpu::lshift +----------- +Performs pixel by pixel right left of an image by a constant value. + +.. ocv:function:: void gpu::lshift(InputArray src, Scalar_ val, OutputArray dst, Stream& stream = Stream::Null()) + + :param src: Source matrix. Supports 1, 3 and 4 channels images with ``CV_8U`` , ``CV_16U`` or ``CV_32S`` depth. + + :param val: Constant values, one per channel. + + :param dst: Destination matrix with the same size and type as ``src`` . + + :param stream: Stream for the asynchronous version. + + + +gpu::min +-------- +Computes the per-element minimum of two matrices (or a matrix and a scalar). + +.. ocv:function:: void gpu::min(InputArray src1, InputArray src2, OutputArray dst, Stream& stream = Stream::Null()) + + :param src1: First source matrix or scalar. + + :param src2: Second source matrix or scalar. + + :param dst: Destination matrix that has the same size and type as the input array(s). + + :param stream: Stream for the asynchronous version. + +.. seealso:: :ocv:func:`min` + + + +gpu::max +-------- +Computes the per-element maximum of two matrices (or a matrix and a scalar). + +.. ocv:function:: void gpu::max(InputArray src1, InputArray src2, OutputArray dst, Stream& stream = Stream::Null()) + + :param src1: First source matrix or scalar. + + :param src2: Second source matrix or scalar. + + :param dst: Destination matrix that has the same size and type as the input array(s). + + :param stream: Stream for the asynchronous version. + +.. seealso:: :ocv:func:`max` + + + gpu::addWeighted ---------------- Computes the weighted sum of two arrays. -.. ocv:function:: void gpu::addWeighted(const GpuMat& src1, double alpha, const GpuMat& src2, double beta, double gamma, GpuMat& dst, int dtype = -1, Stream& stream = Stream::Null()) +.. ocv:function:: void gpu::addWeighted(InputArray src1, double alpha, InputArray src2, double beta, double gamma, OutputArray dst, int dtype = -1, Stream& stream = Stream::Null()) :param src1: First source array. @@ -147,311 +416,11 @@ where ``I`` is a multi-dimensional index of array elements. In case of multi-cha -gpu::abs ------------- -Computes an absolute value of each matrix element. - -.. ocv:function:: void gpu::abs(const GpuMat& src, GpuMat& dst, Stream& stream = Stream::Null()) - - :param src: Source matrix. Supports ``CV_16S`` and ``CV_32F`` depth. - - :param dst: Destination matrix with the same size and type as ``src`` . - - :param stream: Stream for the asynchronous version. - -.. seealso:: :ocv:func:`abs` - - - -gpu::sqr ------------- -Computes a square value of each matrix element. - -.. ocv:function:: void gpu::sqr(const GpuMat& src, GpuMat& dst, Stream& stream = Stream::Null()) - - :param src: Source matrix. Supports ``CV_8U`` , ``CV_16U`` , ``CV_16S`` and ``CV_32F`` depth. - - :param dst: Destination matrix with the same size and type as ``src`` . - - :param stream: Stream for the asynchronous version. - - - -gpu::sqrt ------------- -Computes a square root of each matrix element. - -.. ocv:function:: void gpu::sqrt(const GpuMat& src, GpuMat& dst, Stream& stream = Stream::Null()) - - :param src: Source matrix. Supports ``CV_8U`` , ``CV_16U`` , ``CV_16S`` and ``CV_32F`` depth. - - :param dst: Destination matrix with the same size and type as ``src`` . - - :param stream: Stream for the asynchronous version. - -.. seealso:: :ocv:func:`sqrt` - - - -gpu::exp ------------- -Computes an exponent of each matrix element. - -.. ocv:function:: void gpu::exp( const GpuMat& a, GpuMat& b, Stream& stream=Stream::Null() ) - - :param a: Source matrix. Supports ``CV_8U`` , ``CV_16U`` , ``CV_16S`` and ``CV_32F`` depth. - - :param b: Destination matrix with the same size and type as ``a`` . - - :param stream: Stream for the asynchronous version. - -.. seealso:: :ocv:func:`exp` - - - -gpu::log ------------- -Computes a natural logarithm of absolute value of each matrix element. - -.. ocv:function:: void gpu::log( const GpuMat& a, GpuMat& b, Stream& stream=Stream::Null() ) - - :param a: Source matrix. Supports ``CV_8U`` , ``CV_16U`` , ``CV_16S`` and ``CV_32F`` depth. - - :param b: Destination matrix with the same size and type as ``a`` . - - :param stream: Stream for the asynchronous version. - -.. seealso:: :ocv:func:`log` - - - -gpu::pow ------------- -Raises every matrix element to a power. - -.. ocv:function:: void gpu::pow(const GpuMat& src, double power, GpuMat& dst, Stream& stream = Stream::Null()) - - :param src: Source matrix. Supports all type, except ``CV_64F`` depth. - - :param power: Exponent of power. - - :param dst: Destination matrix with the same size and type as ``src`` . - - :param stream: Stream for the asynchronous version. - -The function ``pow`` raises every element of the input matrix to ``p`` : - -.. math:: - - \texttt{dst} (I) = \fork{\texttt{src}(I)^p}{if \texttt{p} is integer}{|\texttt{src}(I)|^p}{otherwise} - -.. seealso:: :ocv:func:`pow` - - - -gpu::absdiff ----------------- -Computes per-element absolute difference of two matrices (or of a matrix and scalar). - -.. ocv:function:: void gpu::absdiff( const GpuMat& a, const GpuMat& b, GpuMat& c, Stream& stream=Stream::Null() ) - -.. ocv:function:: void gpu::absdiff( const GpuMat& a, const Scalar& s, GpuMat& c, Stream& stream=Stream::Null() ) - - :param a: First source matrix. - - :param b: Second source matrix to be added to ``a`` . - - :param s: A scalar to be added to ``a`` . - - :param c: Destination matrix with the same size and type as ``a`` . - - :param stream: Stream for the asynchronous version. - -.. seealso:: :ocv:func:`absdiff` - - - -gpu::compare ----------------- -Compares elements of two matrices. - -.. ocv:function:: void gpu::compare( const GpuMat& a, const GpuMat& b, GpuMat& c, int cmpop, Stream& stream=Stream::Null() ) - -.. ocv:function:: void gpu::compare(const GpuMat& a, Scalar sc, GpuMat& c, int cmpop, Stream& stream = Stream::Null()) - - :param a: First source matrix. - - :param b: Second source matrix with the same size and type as ``a`` . - - :param sc: A scalar to be compared with ``a`` . - - :param c: Destination matrix with the same size as ``a`` and the ``CV_8UC1`` type. - - :param cmpop: Flag specifying the relation between the elements to be checked: - - * **CMP_EQ:** ``a(.) == b(.)`` - * **CMP_GT:** ``a(.) < b(.)`` - * **CMP_GE:** ``a(.) <= b(.)`` - * **CMP_LT:** ``a(.) < b(.)`` - * **CMP_LE:** ``a(.) <= b(.)`` - * **CMP_NE:** ``a(.) != b(.)`` - - :param stream: Stream for the asynchronous version. - -.. seealso:: :ocv:func:`compare` - - - -gpu::bitwise_not --------------------- -Performs a per-element bitwise inversion. - -.. ocv:function:: void gpu::bitwise_not(const GpuMat& src, GpuMat& dst, const GpuMat& mask=GpuMat(), Stream& stream = Stream::Null()) - - :param src: Source matrix. - - :param dst: Destination matrix with the same size and type as ``src`` . - - :param mask: Optional operation mask. 8-bit single channel image. - - :param stream: Stream for the asynchronous version. - - - -gpu::bitwise_or -------------------- -Performs a per-element bitwise disjunction of two matrices or of matrix and scalar. - -.. ocv:function:: void gpu::bitwise_or(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, const GpuMat& mask=GpuMat(), Stream& stream = Stream::Null()) -.. ocv:function:: void gpu::bitwise_or(const GpuMat& src1, const Scalar& sc, GpuMat& dst, Stream& stream = Stream::Null()) - - :param src1: First source matrix. - - :param src2: Second source matrix with the same size and type as ``src1`` . - - :param dst: Destination matrix with the same size and type as ``src1`` . - - :param mask: Optional operation mask. 8-bit single channel image. - - :param stream: Stream for the asynchronous version. - - - -gpu::bitwise_and --------------------- -Performs a per-element bitwise conjunction of two matrices or of matrix and scalar. - -.. ocv:function:: void gpu::bitwise_and(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, const GpuMat& mask=GpuMat(), Stream& stream = Stream::Null()) -.. ocv:function:: void gpu::bitwise_and(const GpuMat& src1, const Scalar& sc, GpuMat& dst, Stream& stream = Stream::Null()) - - :param src1: First source matrix. - - :param src2: Second source matrix with the same size and type as ``src1`` . - - :param dst: Destination matrix with the same size and type as ``src1`` . - - :param mask: Optional operation mask. 8-bit single channel image. - - :param stream: Stream for the asynchronous version. - - - -gpu::bitwise_xor --------------------- -Performs a per-element bitwise ``exclusive or`` operation of two matrices of matrix and scalar. - -.. ocv:function:: void gpu::bitwise_xor(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, const GpuMat& mask=GpuMat(), Stream& stream = Stream::Null()) -.. ocv:function:: void gpu::bitwise_xor(const GpuMat& src1, const Scalar& sc, GpuMat& dst, Stream& stream = Stream::Null()) - - :param src1: First source matrix. - - :param src2: Second source matrix with the same size and type as ``src1`` . - - :param dst: Destination matrix with the same size and type as ``src1`` . - - :param mask: Optional operation mask. 8-bit single channel image. - - :param stream: Stream for the asynchronous version. - - - -gpu::rshift --------------------- -Performs pixel by pixel right shift of an image by a constant value. - -.. ocv:function:: void gpu::rshift( const GpuMat& src, Scalar_ sc, GpuMat& dst, Stream& stream=Stream::Null() ) - - :param src: Source matrix. Supports 1, 3 and 4 channels images with integers elements. - - :param sc: Constant values, one per channel. - - :param dst: Destination matrix with the same size and type as ``src`` . - - :param stream: Stream for the asynchronous version. - - - -gpu::lshift --------------------- -Performs pixel by pixel right left of an image by a constant value. - -.. ocv:function:: void gpu::lshift( const GpuMat& src, Scalar_ sc, GpuMat& dst, Stream& stream=Stream::Null() ) - - :param src: Source matrix. Supports 1, 3 and 4 channels images with ``CV_8U`` , ``CV_16U`` or ``CV_32S`` depth. - - :param sc: Constant values, one per channel. - - :param dst: Destination matrix with the same size and type as ``src`` . - - :param stream: Stream for the asynchronous version. - - - -gpu::min ------------- -Computes the per-element minimum of two matrices (or a matrix and a scalar). - -.. ocv:function:: void gpu::min(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, Stream& stream = Stream::Null()) - -.. ocv:function:: void gpu::min(const GpuMat& src1, double src2, GpuMat& dst, Stream& stream = Stream::Null()) - - :param src1: First source matrix. - - :param src2: Second source matrix or a scalar to compare ``src1`` elements with. - - :param dst: Destination matrix with the same size and type as ``src1`` . - - :param stream: Stream for the asynchronous version. - -.. seealso:: :ocv:func:`min` - - - -gpu::max ------------- -Computes the per-element maximum of two matrices (or a matrix and a scalar). - -.. ocv:function:: void gpu::max(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, Stream& stream = Stream::Null()) - -.. ocv:function:: void gpu::max(const GpuMat& src1, double src2, GpuMat& dst, Stream& stream = Stream::Null()) - - :param src1: First source matrix. - - :param src2: Second source matrix or a scalar to compare ``src1`` elements with. - - :param dst: Destination matrix with the same size and type as ``src1`` . - - :param stream: Stream for the asynchronous version. - -.. seealso:: :ocv:func:`max` - - - gpu::threshold ------------------- +-------------- Applies a fixed-level threshold to each array element. -.. ocv:function:: double gpu::threshold(const GpuMat& src, GpuMat& dst, double thresh, double maxval, int type, Stream& stream = Stream::Null()) +.. ocv:function:: double gpu::threshold(InputArray src, OutputArray dst, double thresh, double maxval, int type, Stream& stream = Stream::Null()) :param src: Source array (single-channel). @@ -470,12 +439,12 @@ Applies a fixed-level threshold to each array element. gpu::magnitude ------------------- +-------------- Computes magnitudes of complex matrix elements. -.. ocv:function:: void gpu::magnitude( const GpuMat& xy, GpuMat& magnitude, Stream& stream=Stream::Null() ) +.. ocv:function:: void gpu::magnitude(InputArray xy, OutputArray magnitude, Stream& stream = Stream::Null()) -.. ocv:function:: void gpu::magnitude(const GpuMat& x, const GpuMat& y, GpuMat& magnitude, Stream& stream = Stream::Null()) +.. ocv:function:: void gpu::magnitude(InputArray x, InputArray y, OutputArray magnitude, Stream& stream = Stream::Null()) :param xy: Source complex matrix in the interleaved format ( ``CV_32FC2`` ). @@ -492,12 +461,12 @@ Computes magnitudes of complex matrix elements. gpu::magnitudeSqr ---------------------- +----------------- Computes squared magnitudes of complex matrix elements. -.. ocv:function:: void gpu::magnitudeSqr( const GpuMat& xy, GpuMat& magnitude, Stream& stream=Stream::Null() ) +.. ocv:function:: void gpu::magnitudeSqr(InputArray xy, OutputArray magnitude, Stream& stream=Stream::Null() ) -.. ocv:function:: void gpu::magnitudeSqr(const GpuMat& x, const GpuMat& y, GpuMat& magnitude, Stream& stream = Stream::Null()) +.. ocv:function:: void gpu::magnitudeSqr(InputArray x, InputArray y, OutputArray magnitude, Stream& stream = Stream::Null()) :param xy: Source complex matrix in the interleaved format ( ``CV_32FC2`` ). @@ -512,10 +481,10 @@ Computes squared magnitudes of complex matrix elements. gpu::phase --------------- +---------- Computes polar angles of complex matrix elements. -.. ocv:function:: void gpu::phase(const GpuMat& x, const GpuMat& y, GpuMat& angle, bool angleInDegrees=false, Stream& stream = Stream::Null()) +.. ocv:function:: void gpu::phase(InputArray x, InputArray y, OutputArray angle, bool angleInDegrees = false, Stream& stream = Stream::Null()) :param x: Source matrix containing real components ( ``CV_32FC1`` ). @@ -532,10 +501,10 @@ Computes polar angles of complex matrix elements. gpu::cartToPolar --------------------- +---------------- Converts Cartesian coordinates into polar. -.. ocv:function:: void gpu::cartToPolar(const GpuMat& x, const GpuMat& y, GpuMat& magnitude, GpuMat& angle, bool angleInDegrees=false, Stream& stream = Stream::Null()) +.. ocv:function:: void gpu::cartToPolar(InputArray x, InputArray y, OutputArray magnitude, OutputArray angle, bool angleInDegrees = false, Stream& stream = Stream::Null()) :param x: Source matrix containing real components ( ``CV_32FC1`` ). @@ -554,10 +523,10 @@ Converts Cartesian coordinates into polar. gpu::polarToCart --------------------- +---------------- Converts polar coordinates into Cartesian. -.. ocv:function:: void gpu::polarToCart(const GpuMat& magnitude, const GpuMat& angle, GpuMat& x, GpuMat& y, bool angleInDegrees=false, Stream& stream = Stream::Null()) +.. ocv:function:: void gpu::polarToCart(InputArray magnitude, InputArray angle, OutputArray x, OutputArray y, bool angleInDegrees = false, Stream& stream = Stream::Null()) :param magnitude: Source matrix containing magnitudes ( ``CV_32FC1`` ). diff --git a/modules/gpuarithm/doc/reductions.rst b/modules/gpuarithm/doc/reductions.rst index 938efc35bb..b34c2d860d 100644 --- a/modules/gpuarithm/doc/reductions.rst +++ b/modules/gpuarithm/doc/reductions.rst @@ -6,16 +6,16 @@ Matrix Reductions gpu::norm -------------- +--------- Returns the norm of a matrix (or difference of two matrices). -.. ocv:function:: double gpu::norm(const GpuMat& src1, int normType=NORM_L2) +.. ocv:function:: double gpu::norm(InputArray src1, int normType) -.. ocv:function:: double gpu::norm(const GpuMat& src1, int normType, GpuMat& buf) +.. ocv:function:: double gpu::norm(InputArray src1, int normType, GpuMat& buf) -.. ocv:function:: double gpu::norm(const GpuMat& src1, int normType, const GpuMat& mask, GpuMat& buf) +.. ocv:function:: double gpu::norm(InputArray src1, int normType, InputArray mask, GpuMat& buf) -.. ocv:function:: double gpu::norm(const GpuMat& src1, const GpuMat& src2, int normType=NORM_L2) +.. ocv:function:: double gpu::norm(InputArray src1, InputArray src2, int normType=NORM_L2) :param src1: Source matrix. Any matrices except 64F are supported. @@ -32,14 +32,14 @@ Returns the norm of a matrix (or difference of two matrices). gpu::sum ------------- +-------- Returns the sum of matrix elements. -.. ocv:function:: Scalar gpu::sum(const GpuMat& src) +.. ocv:function:: Scalar gpu::sum(InputArray src) -.. ocv:function:: Scalar gpu::sum(const GpuMat& src, GpuMat& buf) +.. ocv:function:: Scalar gpu::sum(InputArray src, GpuMat& buf) -.. ocv:function:: Scalar gpu::sum(const GpuMat& src, const GpuMat& mask, GpuMat& buf) +.. ocv:function:: Scalar gpu::sum(InputArray src, InputArray mask, GpuMat& buf) :param src: Source image of any depth except for ``CV_64F`` . @@ -52,14 +52,14 @@ Returns the sum of matrix elements. gpu::absSum ---------------- +----------- Returns the sum of absolute values for matrix elements. -.. ocv:function:: Scalar gpu::absSum(const GpuMat& src) +.. ocv:function:: Scalar gpu::absSum(InputArray src) -.. ocv:function:: Scalar gpu::absSum(const GpuMat& src, GpuMat& buf) +.. ocv:function:: Scalar gpu::absSum(InputArray src, GpuMat& buf) -.. ocv:function:: Scalar gpu::absSum(const GpuMat& src, const GpuMat& mask, GpuMat& buf) +.. ocv:function:: Scalar gpu::absSum(InputArray src, InputArray mask, GpuMat& buf) :param src: Source image of any depth except for ``CV_64F`` . @@ -70,14 +70,14 @@ Returns the sum of absolute values for matrix elements. gpu::sqrSum ---------------- +----------- Returns the squared sum of matrix elements. -.. ocv:function:: Scalar gpu::sqrSum(const GpuMat& src) +.. ocv:function:: Scalar gpu::sqrSum(InputArray src) -.. ocv:function:: Scalar gpu::sqrSum(const GpuMat& src, GpuMat& buf) +.. ocv:function:: Scalar gpu::sqrSum(InputArray src, GpuMat& buf) -.. ocv:function:: Scalar gpu::sqrSum(const GpuMat& src, const GpuMat& mask, GpuMat& buf) +.. ocv:function:: Scalar gpu::sqrSum(InputArray src, InputArray mask, GpuMat& buf) :param src: Source image of any depth except for ``CV_64F`` . @@ -88,12 +88,12 @@ Returns the squared sum of matrix elements. gpu::minMax ---------------- +----------- Finds global minimum and maximum matrix elements and returns their values. -.. ocv:function:: void gpu::minMax(const GpuMat& src, double* minVal, double* maxVal=0, const GpuMat& mask=GpuMat()) +.. ocv:function:: void gpu::minMax(InputArray src, double* minVal, double* maxVal=0, InputArray mask=noArray()) -.. ocv:function:: void gpu::minMax(const GpuMat& src, double* minVal, double* maxVal, const GpuMat& mask, GpuMat& buf) +.. ocv:function:: void gpu::minMax(InputArray src, double* minVal, double* maxVal, InputArray mask, GpuMat& buf) :param src: Single-channel source image. @@ -112,12 +112,12 @@ The function does not work with ``CV_64F`` images on GPUs with the compute capab gpu::minMaxLoc ------------------- +-------------- Finds global minimum and maximum matrix elements and returns their values with locations. -.. ocv:function:: void gpu::minMaxLoc(const GpuMat& src, double* minVal, double* maxVal=0, Point* minLoc=0, Point* maxLoc=0, const GpuMat& mask=GpuMat()) +.. ocv:function:: void gpu::minMaxLoc(InputArray src, double* minVal, double* maxVal=0, Point* minLoc=0, Point* maxLoc=0, InputArray mask=noArray()) -.. ocv:function:: void gpu::minMaxLoc(const GpuMat& src, double* minVal, double* maxVal, Point* minLoc, Point* maxLoc, const GpuMat& mask, GpuMat& valbuf, GpuMat& locbuf) +.. ocv:function:: void gpu::minMaxLoc(InputArray src, double* minVal, double* maxVal, Point* minLoc, Point* maxLoc, InputArray mask, GpuMat& valbuf, GpuMat& locbuf) :param src: Single-channel source image. @@ -142,12 +142,12 @@ Finds global minimum and maximum matrix elements and returns their values with l gpu::countNonZero ---------------------- +----------------- Counts non-zero matrix elements. -.. ocv:function:: int gpu::countNonZero(const GpuMat& src) +.. ocv:function:: int gpu::countNonZero(InputArray src) -.. ocv:function:: int gpu::countNonZero(const GpuMat& src, GpuMat& buf) +.. ocv:function:: int gpu::countNonZero(InputArray src, GpuMat& buf) :param src: Single-channel source image. @@ -163,7 +163,7 @@ gpu::reduce ----------- Reduces a matrix to a vector. -.. ocv:function:: void gpu::reduce(const GpuMat& mtx, GpuMat& vec, int dim, int reduceOp, int dtype = -1, Stream& stream = Stream::Null()) +.. ocv:function:: void gpu::reduce(InputArray mtx, OutputArray vec, int dim, int reduceOp, int dtype = -1, Stream& stream = Stream::Null()) :param mtx: Source 2D matrix. @@ -183,48 +183,20 @@ Reduces a matrix to a vector. :param dtype: When it is negative, the destination vector will have the same type as the source matrix. Otherwise, its type will be ``CV_MAKE_TYPE(CV_MAT_DEPTH(dtype), mtx.channels())`` . + :param stream: Stream for the asynchronous version. + The function ``reduce`` reduces the matrix to a vector by treating the matrix rows/columns as a set of 1D vectors and performing the specified operation on the vectors until a single row/column is obtained. For example, the function can be used to compute horizontal and vertical projections of a raster image. In case of ``CV_REDUCE_SUM`` and ``CV_REDUCE_AVG`` , the output may have a larger element bit-depth to preserve accuracy. And multi-channel arrays are also supported in these two reduction modes. .. seealso:: :ocv:func:`reduce` -gpu::normalize --------------- -Normalizes the norm or value range of an array. - -.. ocv:function:: void gpu::normalize(const GpuMat& src, GpuMat& dst, double alpha = 1, double beta = 0, int norm_type = NORM_L2, int dtype = -1, const GpuMat& mask = GpuMat()) - -.. ocv:function:: void gpu::normalize(const GpuMat& src, GpuMat& dst, double a, double b, int norm_type, int dtype, const GpuMat& mask, GpuMat& norm_buf, GpuMat& cvt_buf) - - :param src: input array. - - :param dst: output array of the same size as ``src`` . - - :param alpha: norm value to normalize to or the lower range boundary in case of the range normalization. - - :param beta: upper range boundary in case of the range normalization; it is not used for the norm normalization. - - :param normType: normalization type (see the details below). - - :param dtype: when negative, the output array has the same type as ``src``; otherwise, it has the same number of channels as ``src`` and the depth ``=CV_MAT_DEPTH(dtype)``. - - :param mask: optional operation mask. - - :param norm_buf: Optional buffer to avoid extra memory allocations. It is resized automatically. - - :param cvt_buf: Optional buffer to avoid extra memory allocations. It is resized automatically. - -.. seealso:: :ocv:func:`normalize` - - - gpu::meanStdDev -------------------- +--------------- Computes a mean value and a standard deviation of matrix elements. -.. ocv:function:: void gpu::meanStdDev(const GpuMat& mtx, Scalar& mean, Scalar& stddev) -.. ocv:function:: void gpu::meanStdDev(const GpuMat& mtx, Scalar& mean, Scalar& stddev, GpuMat& buf) +.. ocv:function:: void gpu::meanStdDev(InputArray mtx, Scalar& mean, Scalar& stddev) +.. ocv:function:: void gpu::meanStdDev(InputArray mtx, Scalar& mean, Scalar& stddev, GpuMat& buf) :param mtx: Source matrix. ``CV_8UC1`` matrices are supported for now. @@ -239,10 +211,10 @@ Computes a mean value and a standard deviation of matrix elements. gpu::rectStdDev -------------------- +--------------- Computes a standard deviation of integral images. -.. ocv:function:: void gpu::rectStdDev(const GpuMat& src, const GpuMat& sqr, GpuMat& dst, const Rect& rect, Stream& stream = Stream::Null()) +.. ocv:function:: void gpu::rectStdDev(InputArray src, InputArray sqr, OutputArray dst, Rect rect, Stream& stream = Stream::Null()) :param src: Source image. Only the ``CV_32SC1`` type is supported. @@ -253,3 +225,71 @@ Computes a standard deviation of integral images. :param rect: Rectangular window. :param stream: Stream for the asynchronous version. + + + +gpu::normalize +-------------- +Normalizes the norm or value range of an array. + +.. ocv:function:: void gpu::normalize(InputArray src, OutputArray dst, double alpha = 1, double beta = 0, int norm_type = NORM_L2, int dtype = -1, InputArray mask = noArray()) + +.. ocv:function:: void gpu::normalize(InputArray src, OutputArray dst, double alpha, double beta, int norm_type, int dtype, InputArray mask, GpuMat& norm_buf, GpuMat& cvt_buf) + + :param src: Input array. + + :param dst: Output array of the same size as ``src`` . + + :param alpha: Norm value to normalize to or the lower range boundary in case of the range normalization. + + :param beta: Upper range boundary in case of the range normalization; it is not used for the norm normalization. + + :param normType: Normalization type ( ``NORM_MINMAX`` , ``NORM_L2`` , ``NORM_L1`` or ``NORM_INF`` ). + + :param dtype: When negative, the output array has the same type as ``src``; otherwise, it has the same number of channels as ``src`` and the depth ``=CV_MAT_DEPTH(dtype)``. + + :param mask: Optional operation mask. + + :param norm_buf: Optional buffer to avoid extra memory allocations. It is resized automatically. + + :param cvt_buf: Optional buffer to avoid extra memory allocations. It is resized automatically. + +.. seealso:: :ocv:func:`normalize` + + + +gpu::integral +------------- +Computes an integral image. + +.. ocv:function:: void gpu::integral(InputArray src, OutputArray sum, Stream& stream = Stream::Null()) + +.. ocv:function:: void gpu::integral(InputArray src, OutputArray sum, GpuMat& buffer, Stream& stream = Stream::Null()) + + :param src: Source image. Only ``CV_8UC1`` images are supported for now. + + :param sum: Integral image containing 32-bit unsigned integer values packed into ``CV_32SC1`` . + + :param buffer: Optional buffer to avoid extra memory allocations. It is resized automatically. + + :param stream: Stream for the asynchronous version. + +.. seealso:: :ocv:func:`integral` + + + +gpu::sqrIntegral +---------------- +Computes a squared integral image. + +.. ocv:function:: void gpu::sqrIntegral(InputArray src, OutputArray sqsum, Stream& stream = Stream::Null()) + +.. ocv:function:: void gpu::sqrIntegral(InputArray src, OutputArray sqsum, GpuMat& buf, Stream& stream = Stream::Null()) + + :param src: Source image. Only ``CV_8UC1`` images are supported for now. + + :param sqsum: Squared integral image containing 64-bit unsigned integer values packed into ``CV_64FC1`` . + + :param buf: Optional buffer to avoid extra memory allocations. It is resized automatically. + + :param stream: Stream for the asynchronous version. diff --git a/modules/gpuarithm/include/opencv2/gpuarithm.hpp b/modules/gpuarithm/include/opencv2/gpuarithm.hpp index 4edc29ba4d..8fbe296d80 100644 --- a/modules/gpuarithm/include/opencv2/gpuarithm.hpp +++ b/modules/gpuarithm/include/opencv2/gpuarithm.hpp @@ -49,263 +49,317 @@ #include "opencv2/core/gpu.hpp" +#if defined __GNUC__ + #define __OPENCV_GPUARITHM_DEPR_BEFORE__ + #define __OPENCV_GPUARITHM_DEPR_AFTER__ __attribute__ ((deprecated)) +#elif (defined WIN32 || defined _WIN32) + #define __OPENCV_GPUARITHM_DEPR_BEFORE__ __declspec(deprecated) + #define __OPENCV_GPUARITHM_DEPR_AFTER__ +#else + #define __OPENCV_GPUARITHM_DEPR_BEFORE__ + #define __OPENCV_GPUARITHM_DEPR_AFTER__ +#endif + namespace cv { namespace gpu { -//! adds one matrix to another (c = a + b) -CV_EXPORTS void add(const GpuMat& a, const GpuMat& b, GpuMat& c, const GpuMat& mask = GpuMat(), int dtype = -1, Stream& stream = Stream::Null()); -//! adds scalar to a matrix (c = a + s) -CV_EXPORTS void add(const GpuMat& a, const Scalar& sc, GpuMat& c, const GpuMat& mask = GpuMat(), int dtype = -1, Stream& stream = Stream::Null()); +//! adds one matrix to another (dst = src1 + src2) +CV_EXPORTS void add(InputArray src1, InputArray src2, OutputArray dst, InputArray mask = noArray(), int dtype = -1, Stream& stream = Stream::Null()); -//! subtracts one matrix from another (c = a - b) -CV_EXPORTS void subtract(const GpuMat& a, const GpuMat& b, GpuMat& c, const GpuMat& mask = GpuMat(), int dtype = -1, Stream& stream = Stream::Null()); -//! subtracts scalar from a matrix (c = a - s) -CV_EXPORTS void subtract(const GpuMat& a, const Scalar& sc, GpuMat& c, const GpuMat& mask = GpuMat(), int dtype = -1, Stream& stream = Stream::Null()); +//! subtracts one matrix from another (dst = src1 - src2) +CV_EXPORTS void subtract(InputArray src1, InputArray src2, OutputArray dst, InputArray mask = noArray(), int dtype = -1, Stream& stream = Stream::Null()); -//! computes element-wise weighted product of the two arrays (c = scale * a * b) -CV_EXPORTS void multiply(const GpuMat& a, const GpuMat& b, GpuMat& c, double scale = 1, int dtype = -1, Stream& stream = Stream::Null()); -//! weighted multiplies matrix to a scalar (c = scale * a * s) -CV_EXPORTS void multiply(const GpuMat& a, const Scalar& sc, GpuMat& c, double scale = 1, int dtype = -1, Stream& stream = Stream::Null()); +//! computes element-wise weighted product of the two arrays (dst = scale * src1 * src2) +CV_EXPORTS void multiply(InputArray src1, InputArray src2, OutputArray dst, double scale = 1, int dtype = -1, Stream& stream = Stream::Null()); + +//! computes element-wise weighted quotient of the two arrays (dst = scale * (src1 / src2)) +CV_EXPORTS void divide(InputArray src1, InputArray src2, OutputArray dst, double scale = 1, int dtype = -1, Stream& stream = Stream::Null()); -//! computes element-wise weighted quotient of the two arrays (c = a / b) -CV_EXPORTS void divide(const GpuMat& a, const GpuMat& b, GpuMat& c, double scale = 1, int dtype = -1, Stream& stream = Stream::Null()); -//! computes element-wise weighted quotient of matrix and scalar (c = a / s) -CV_EXPORTS void divide(const GpuMat& a, const Scalar& sc, GpuMat& c, double scale = 1, int dtype = -1, Stream& stream = Stream::Null()); //! computes element-wise weighted reciprocal of an array (dst = scale/src2) -CV_EXPORTS void divide(double scale, const GpuMat& b, GpuMat& c, int dtype = -1, Stream& stream = Stream::Null()); +static inline void divide(double src1, InputArray src2, OutputArray dst, int dtype = -1, Stream& stream = Stream::Null()) +{ + divide(src1, src2, dst, 1.0, dtype, stream); +} + +//! computes element-wise absolute difference of two arrays (dst = abs(src1 - src2)) +CV_EXPORTS void absdiff(InputArray src1, InputArray src2, OutputArray dst, Stream& stream = Stream::Null()); + +//! computes absolute value of each matrix element +CV_EXPORTS void abs(InputArray src, OutputArray dst, Stream& stream = Stream::Null()); + +//! computes square of each pixel in an image +CV_EXPORTS void sqr(InputArray src, OutputArray dst, Stream& stream = Stream::Null()); + +//! computes square root of each pixel in an image +CV_EXPORTS void sqrt(InputArray src, OutputArray dst, Stream& stream = Stream::Null()); + +//! computes exponent of each matrix element +CV_EXPORTS void exp(InputArray src, OutputArray dst, Stream& stream = Stream::Null()); + +//! computes natural logarithm of absolute value of each matrix element +CV_EXPORTS void log(InputArray src, OutputArray dst, Stream& stream = Stream::Null()); + +//! computes power of each matrix element: +//! (dst(i,j) = pow( src(i,j) , power), if src.type() is integer +//! (dst(i,j) = pow(fabs(src(i,j)), power), otherwise +CV_EXPORTS void pow(InputArray src, double power, OutputArray dst, Stream& stream = Stream::Null()); + +//! compares elements of two arrays (dst = src1 src2) +CV_EXPORTS void compare(InputArray src1, InputArray src2, OutputArray dst, int cmpop, Stream& stream = Stream::Null()); + +//! performs per-elements bit-wise inversion +CV_EXPORTS void bitwise_not(InputArray src, OutputArray dst, InputArray mask = noArray(), Stream& stream = Stream::Null()); + +//! calculates per-element bit-wise disjunction of two arrays +CV_EXPORTS void bitwise_or(InputArray src1, InputArray src2, OutputArray dst, InputArray mask = noArray(), Stream& stream = Stream::Null()); + +//! calculates per-element bit-wise conjunction of two arrays +CV_EXPORTS void bitwise_and(InputArray src1, InputArray src2, OutputArray dst, InputArray mask = noArray(), Stream& stream = Stream::Null()); + +//! calculates per-element bit-wise "exclusive or" operation +CV_EXPORTS void bitwise_xor(InputArray src1, InputArray src2, OutputArray dst, InputArray mask = noArray(), Stream& stream = Stream::Null()); + +//! pixel by pixel right shift of an image by a constant value +//! supports 1, 3 and 4 channels images with integers elements +CV_EXPORTS void rshift(InputArray src, Scalar_ val, OutputArray dst, Stream& stream = Stream::Null()); + +//! pixel by pixel left shift of an image by a constant value +//! supports 1, 3 and 4 channels images with CV_8U, CV_16U or CV_32S depth +CV_EXPORTS void lshift(InputArray src, Scalar_ val, OutputArray dst, Stream& stream = Stream::Null()); + +//! computes per-element minimum of two arrays (dst = min(src1, src2)) +CV_EXPORTS void min(InputArray src1, InputArray src2, OutputArray dst, Stream& stream = Stream::Null()); + +//! computes per-element maximum of two arrays (dst = max(src1, src2)) +CV_EXPORTS void max(InputArray src1, InputArray src2, OutputArray dst, Stream& stream = Stream::Null()); //! computes the weighted sum of two arrays (dst = alpha*src1 + beta*src2 + gamma) -CV_EXPORTS void addWeighted(const GpuMat& src1, double alpha, const GpuMat& src2, double beta, double gamma, GpuMat& dst, +CV_EXPORTS void addWeighted(InputArray src1, double alpha, InputArray src2, double beta, double gamma, OutputArray dst, int dtype = -1, Stream& stream = Stream::Null()); //! adds scaled array to another one (dst = alpha*src1 + src2) -static inline void scaleAdd(const GpuMat& src1, double alpha, const GpuMat& src2, GpuMat& dst, Stream& stream = Stream::Null()) +static inline void scaleAdd(InputArray src1, double alpha, InputArray src2, OutputArray dst, Stream& stream = Stream::Null()) { addWeighted(src1, alpha, src2, 1.0, 0.0, dst, -1, stream); } -//! computes element-wise absolute difference of two arrays (c = abs(a - b)) -CV_EXPORTS void absdiff(const GpuMat& a, const GpuMat& b, GpuMat& c, Stream& stream = Stream::Null()); -//! computes element-wise absolute difference of array and scalar (c = abs(a - s)) -CV_EXPORTS void absdiff(const GpuMat& a, const Scalar& s, GpuMat& c, Stream& stream = Stream::Null()); +//! applies fixed threshold to the image +CV_EXPORTS double threshold(InputArray src, OutputArray dst, double thresh, double maxval, int type, Stream& stream = Stream::Null()); -//! computes absolute value of each matrix element -//! supports CV_16S and CV_32F depth -CV_EXPORTS void abs(const GpuMat& src, GpuMat& dst, Stream& stream = Stream::Null()); +//! computes magnitude of complex (x(i).re, x(i).im) vector +//! supports only CV_32FC2 type +CV_EXPORTS void magnitude(InputArray xy, OutputArray magnitude, Stream& stream = Stream::Null()); -//! computes square of each pixel in an image -//! supports CV_8U, CV_16U, CV_16S and CV_32F depth -CV_EXPORTS void sqr(const GpuMat& src, GpuMat& dst, Stream& stream = Stream::Null()); +//! computes squared magnitude of complex (x(i).re, x(i).im) vector +//! supports only CV_32FC2 type +CV_EXPORTS void magnitudeSqr(InputArray xy, OutputArray magnitude, Stream& stream = Stream::Null()); -//! computes square root of each pixel in an image -//! supports CV_8U, CV_16U, CV_16S and CV_32F depth -CV_EXPORTS void sqrt(const GpuMat& src, GpuMat& dst, Stream& stream = Stream::Null()); +//! computes magnitude of each (x(i), y(i)) vector +//! supports only floating-point source +CV_EXPORTS void magnitude(InputArray x, InputArray y, OutputArray magnitude, Stream& stream = Stream::Null()); -//! computes exponent of each matrix element (b = e**a) -//! supports CV_8U, CV_16U, CV_16S and CV_32F depth -CV_EXPORTS void exp(const GpuMat& a, GpuMat& b, Stream& stream = Stream::Null()); +//! computes squared magnitude of each (x(i), y(i)) vector +//! supports only floating-point source +CV_EXPORTS void magnitudeSqr(InputArray x, InputArray y, OutputArray magnitude, Stream& stream = Stream::Null()); -//! computes natural logarithm of absolute value of each matrix element: b = log(abs(a)) -//! supports CV_8U, CV_16U, CV_16S and CV_32F depth -CV_EXPORTS void log(const GpuMat& a, GpuMat& b, Stream& stream = Stream::Null()); +//! computes angle of each (x(i), y(i)) vector +//! supports only floating-point source +CV_EXPORTS void phase(InputArray x, InputArray y, OutputArray angle, bool angleInDegrees = false, Stream& stream = Stream::Null()); -//! computes power of each matrix element: -// (dst(i,j) = pow( src(i,j) , power), if src.type() is integer -// (dst(i,j) = pow(fabs(src(i,j)), power), otherwise -//! supports all, except depth == CV_64F -CV_EXPORTS void pow(const GpuMat& src, double power, GpuMat& dst, Stream& stream = Stream::Null()); +//! converts Cartesian coordinates to polar +//! supports only floating-point source +CV_EXPORTS void cartToPolar(InputArray x, InputArray y, OutputArray magnitude, OutputArray angle, bool angleInDegrees = false, Stream& stream = Stream::Null()); -//! compares elements of two arrays (c = a b) -CV_EXPORTS void compare(const GpuMat& a, const GpuMat& b, GpuMat& c, int cmpop, Stream& stream = Stream::Null()); -CV_EXPORTS void compare(const GpuMat& a, Scalar sc, GpuMat& c, int cmpop, Stream& stream = Stream::Null()); +//! converts polar coordinates to Cartesian +//! supports only floating-point source +CV_EXPORTS void polarToCart(InputArray magnitude, InputArray angle, OutputArray x, OutputArray y, bool angleInDegrees = false, Stream& stream = Stream::Null()); -//! performs per-elements bit-wise inversion -CV_EXPORTS void bitwise_not(const GpuMat& src, GpuMat& dst, const GpuMat& mask=GpuMat(), Stream& stream = Stream::Null()); +//! makes multi-channel array out of several single-channel arrays +CV_EXPORTS void merge(const GpuMat* src, size_t n, OutputArray dst, Stream& stream = Stream::Null()); +CV_EXPORTS void merge(const std::vector& src, OutputArray dst, Stream& stream = Stream::Null()); -//! calculates per-element bit-wise disjunction of two arrays -CV_EXPORTS void bitwise_or(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, const GpuMat& mask=GpuMat(), Stream& stream = Stream::Null()); -//! calculates per-element bit-wise disjunction of array and scalar -//! supports 1, 3 and 4 channels images with CV_8U, CV_16U or CV_32S depth -CV_EXPORTS void bitwise_or(const GpuMat& src1, const Scalar& sc, GpuMat& dst, Stream& stream = Stream::Null()); - -//! calculates per-element bit-wise conjunction of two arrays -CV_EXPORTS void bitwise_and(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, const GpuMat& mask=GpuMat(), Stream& stream = Stream::Null()); -//! calculates per-element bit-wise conjunction of array and scalar -//! supports 1, 3 and 4 channels images with CV_8U, CV_16U or CV_32S depth -CV_EXPORTS void bitwise_and(const GpuMat& src1, const Scalar& sc, GpuMat& dst, Stream& stream = Stream::Null()); - -//! calculates per-element bit-wise "exclusive or" operation -CV_EXPORTS void bitwise_xor(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, const GpuMat& mask=GpuMat(), Stream& stream = Stream::Null()); -//! calculates per-element bit-wise "exclusive or" of array and scalar -//! supports 1, 3 and 4 channels images with CV_8U, CV_16U or CV_32S depth -CV_EXPORTS void bitwise_xor(const GpuMat& src1, const Scalar& sc, GpuMat& dst, Stream& stream = Stream::Null()); - -//! pixel by pixel right shift of an image by a constant value -//! supports 1, 3 and 4 channels images with integers elements -CV_EXPORTS void rshift(const GpuMat& src, Scalar_ sc, GpuMat& dst, Stream& stream = Stream::Null()); - -//! pixel by pixel left shift of an image by a constant value -//! supports 1, 3 and 4 channels images with CV_8U, CV_16U or CV_32S depth -CV_EXPORTS void lshift(const GpuMat& src, Scalar_ sc, GpuMat& dst, Stream& stream = Stream::Null()); - -//! computes per-element minimum of two arrays (dst = min(src1, src2)) -CV_EXPORTS void min(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, Stream& stream = Stream::Null()); - -//! computes per-element minimum of array and scalar (dst = min(src1, src2)) -CV_EXPORTS void min(const GpuMat& src1, double src2, GpuMat& dst, Stream& stream = Stream::Null()); - -//! computes per-element maximum of two arrays (dst = max(src1, src2)) -CV_EXPORTS void max(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, Stream& stream = Stream::Null()); - -//! computes per-element maximum of array and scalar (dst = max(src1, src2)) -CV_EXPORTS void max(const GpuMat& src1, double src2, GpuMat& dst, Stream& stream = Stream::Null()); - -//! implements generalized matrix product algorithm GEMM from BLAS -CV_EXPORTS void gemm(const GpuMat& src1, const GpuMat& src2, double alpha, - const GpuMat& src3, double beta, GpuMat& dst, int flags = 0, Stream& stream = Stream::Null()); +//! copies each plane of a multi-channel array to a dedicated array +CV_EXPORTS void split(InputArray src, GpuMat* dst, Stream& stream = Stream::Null()); +CV_EXPORTS void split(InputArray src, std::vector& dst, Stream& stream = Stream::Null()); //! transposes the matrix //! supports matrix with element size = 1, 4 and 8 bytes (CV_8UC1, CV_8UC4, CV_16UC2, CV_32FC1, etc) -CV_EXPORTS void transpose(const GpuMat& src1, GpuMat& dst, Stream& stream = Stream::Null()); +CV_EXPORTS void transpose(InputArray src1, OutputArray dst, Stream& stream = Stream::Null()); //! reverses the order of the rows, columns or both in a matrix //! supports 1, 3 and 4 channels images with CV_8U, CV_16U, CV_32S or CV_32F depth -CV_EXPORTS void flip(const GpuMat& a, GpuMat& b, int flipCode, Stream& stream = Stream::Null()); +CV_EXPORTS void flip(InputArray src, OutputArray dst, int flipCode, Stream& stream = Stream::Null()); //! transforms 8-bit unsigned integers using lookup table: dst(i)=lut(src(i)) //! destination array will have the depth type as lut and the same channels number as source //! supports CV_8UC1, CV_8UC3 types -CV_EXPORTS void LUT(const GpuMat& src, const Mat& lut, GpuMat& dst, Stream& stream = Stream::Null()); +class CV_EXPORTS LookUpTable : public Algorithm +{ +public: + virtual void transform(InputArray src, OutputArray dst, Stream& stream = Stream::Null()) = 0; +}; +CV_EXPORTS Ptr createLookUpTable(InputArray lut); -//! makes multi-channel array out of several single-channel arrays -CV_EXPORTS void merge(const GpuMat* src, size_t n, GpuMat& dst, Stream& stream = Stream::Null()); +__OPENCV_GPUARITHM_DEPR_BEFORE__ void LUT(InputArray src, InputArray lut, OutputArray dst, Stream& stream = Stream::Null()) __OPENCV_GPUARITHM_DEPR_AFTER__; +inline void LUT(InputArray src, InputArray lut, OutputArray dst, Stream& stream) +{ + createLookUpTable(lut)->transform(src, dst, stream); +} -//! makes multi-channel array out of several single-channel arrays -CV_EXPORTS void merge(const std::vector& src, GpuMat& dst, Stream& stream = Stream::Null()); - -//! copies each plane of a multi-channel array to a dedicated array -CV_EXPORTS void split(const GpuMat& src, GpuMat* dst, Stream& stream = Stream::Null()); - -//! copies each plane of a multi-channel array to a dedicated array -CV_EXPORTS void split(const GpuMat& src, std::vector& dst, Stream& stream = Stream::Null()); - -//! computes magnitude of complex (x(i).re, x(i).im) vector -//! supports only CV_32FC2 type -CV_EXPORTS void magnitude(const GpuMat& xy, GpuMat& magnitude, Stream& stream = Stream::Null()); - -//! computes squared magnitude of complex (x(i).re, x(i).im) vector -//! supports only CV_32FC2 type -CV_EXPORTS void magnitudeSqr(const GpuMat& xy, GpuMat& magnitude, Stream& stream = Stream::Null()); - -//! computes magnitude of each (x(i), y(i)) vector -//! supports only floating-point source -CV_EXPORTS void magnitude(const GpuMat& x, const GpuMat& y, GpuMat& magnitude, Stream& stream = Stream::Null()); - -//! computes squared magnitude of each (x(i), y(i)) vector -//! supports only floating-point source -CV_EXPORTS void magnitudeSqr(const GpuMat& x, const GpuMat& y, GpuMat& magnitude, Stream& stream = Stream::Null()); - -//! computes angle (angle(i)) of each (x(i), y(i)) vector -//! supports only floating-point source -CV_EXPORTS void phase(const GpuMat& x, const GpuMat& y, GpuMat& angle, bool angleInDegrees = false, Stream& stream = Stream::Null()); - -//! converts Cartesian coordinates to polar -//! supports only floating-point source -CV_EXPORTS void cartToPolar(const GpuMat& x, const GpuMat& y, GpuMat& magnitude, GpuMat& angle, bool angleInDegrees = false, Stream& stream = Stream::Null()); - -//! converts polar coordinates to Cartesian -//! supports only floating-point source -CV_EXPORTS void polarToCart(const GpuMat& magnitude, const GpuMat& angle, GpuMat& x, GpuMat& y, bool angleInDegrees = false, Stream& stream = Stream::Null()); - -//! scales and shifts array elements so that either the specified norm (alpha) or the minimum (alpha) and maximum (beta) array values get the specified values -CV_EXPORTS void normalize(const GpuMat& src, GpuMat& dst, double alpha = 1, double beta = 0, - int norm_type = NORM_L2, int dtype = -1, const GpuMat& mask = GpuMat()); -CV_EXPORTS void normalize(const GpuMat& src, GpuMat& dst, double a, double b, - int norm_type, int dtype, const GpuMat& mask, GpuMat& norm_buf, GpuMat& cvt_buf); +//! copies 2D array to a larger destination array and pads borders with user-specifiable constant +CV_EXPORTS void copyMakeBorder(InputArray src, OutputArray dst, int top, int bottom, int left, int right, int borderType, + Scalar value = Scalar(), Stream& stream = Stream::Null()); //! computes norm of array //! supports NORM_INF, NORM_L1, NORM_L2 //! supports all matrices except 64F -CV_EXPORTS double norm(const GpuMat& src1, int normType=NORM_L2); -CV_EXPORTS double norm(const GpuMat& src1, int normType, GpuMat& buf); -CV_EXPORTS double norm(const GpuMat& src1, int normType, const GpuMat& mask, GpuMat& buf); +CV_EXPORTS double norm(InputArray src1, int normType, InputArray mask, GpuMat& buf); +static inline double norm(InputArray src, int normType) +{ + GpuMat buf; + return norm(src, normType, GpuMat(), buf); +} +static inline double norm(InputArray src, int normType, GpuMat& buf) +{ + return norm(src, normType, GpuMat(), buf); +} //! computes norm of the difference between two arrays //! supports NORM_INF, NORM_L1, NORM_L2 //! supports only CV_8UC1 type -CV_EXPORTS double norm(const GpuMat& src1, const GpuMat& src2, int normType=NORM_L2); +CV_EXPORTS double norm(InputArray src1, InputArray src2, GpuMat& buf, int normType=NORM_L2); +static inline double norm(InputArray src1, InputArray src2, int normType=NORM_L2) +{ + GpuMat buf; + return norm(src1, src2, buf, normType); +} //! computes sum of array elements //! supports only single channel images -CV_EXPORTS Scalar sum(const GpuMat& src); -CV_EXPORTS Scalar sum(const GpuMat& src, GpuMat& buf); -CV_EXPORTS Scalar sum(const GpuMat& src, const GpuMat& mask, GpuMat& buf); +CV_EXPORTS Scalar sum(InputArray src, InputArray mask, GpuMat& buf); +static inline Scalar sum(InputArray src) +{ + GpuMat buf; + return sum(src, GpuMat(), buf); +} +static inline Scalar sum(InputArray src, GpuMat& buf) +{ + return sum(src, GpuMat(), buf); +} //! computes sum of array elements absolute values //! supports only single channel images -CV_EXPORTS Scalar absSum(const GpuMat& src); -CV_EXPORTS Scalar absSum(const GpuMat& src, GpuMat& buf); -CV_EXPORTS Scalar absSum(const GpuMat& src, const GpuMat& mask, GpuMat& buf); +CV_EXPORTS Scalar absSum(InputArray src, InputArray mask, GpuMat& buf); +static inline Scalar absSum(InputArray src) +{ + GpuMat buf; + return absSum(src, GpuMat(), buf); +} +static inline Scalar absSum(InputArray src, GpuMat& buf) +{ + return absSum(src, GpuMat(), buf); +} //! computes squared sum of array elements //! supports only single channel images -CV_EXPORTS Scalar sqrSum(const GpuMat& src); -CV_EXPORTS Scalar sqrSum(const GpuMat& src, GpuMat& buf); -CV_EXPORTS Scalar sqrSum(const GpuMat& src, const GpuMat& mask, GpuMat& buf); +CV_EXPORTS Scalar sqrSum(InputArray src, InputArray mask, GpuMat& buf); +static inline Scalar sqrSum(InputArray src) +{ + GpuMat buf; + return sqrSum(src, GpuMat(), buf); +} +static inline Scalar sqrSum(InputArray src, GpuMat& buf) +{ + return sqrSum(src, GpuMat(), buf); +} //! finds global minimum and maximum array elements and returns their values -CV_EXPORTS void minMax(const GpuMat& src, double* minVal, double* maxVal=0, const GpuMat& mask=GpuMat()); -CV_EXPORTS void minMax(const GpuMat& src, double* minVal, double* maxVal, const GpuMat& mask, GpuMat& buf); +CV_EXPORTS void minMax(InputArray src, double* minVal, double* maxVal, InputArray mask, GpuMat& buf); +static inline void minMax(InputArray src, double* minVal, double* maxVal=0, InputArray mask=noArray()) +{ + GpuMat buf; + minMax(src, minVal, maxVal, mask, buf); +} //! finds global minimum and maximum array elements and returns their values with locations -CV_EXPORTS void minMaxLoc(const GpuMat& src, double* minVal, double* maxVal=0, Point* minLoc=0, Point* maxLoc=0, - const GpuMat& mask=GpuMat()); -CV_EXPORTS void minMaxLoc(const GpuMat& src, double* minVal, double* maxVal, Point* minLoc, Point* maxLoc, - const GpuMat& mask, GpuMat& valbuf, GpuMat& locbuf); +CV_EXPORTS void minMaxLoc(InputArray src, double* minVal, double* maxVal, Point* minLoc, Point* maxLoc, + InputArray mask, GpuMat& valbuf, GpuMat& locbuf); +static inline void minMaxLoc(InputArray src, double* minVal, double* maxVal=0, Point* minLoc=0, Point* maxLoc=0, + InputArray mask=noArray()) +{ + GpuMat valBuf, locBuf; + minMaxLoc(src, minVal, maxVal, minLoc, maxLoc, mask, valBuf, locBuf); +} //! counts non-zero array elements -CV_EXPORTS int countNonZero(const GpuMat& src); -CV_EXPORTS int countNonZero(const GpuMat& src, GpuMat& buf); +CV_EXPORTS int countNonZero(InputArray src, GpuMat& buf); +static inline int countNonZero(const GpuMat& src) +{ + GpuMat buf; + return countNonZero(src, buf); +} //! reduces a matrix to a vector -CV_EXPORTS void reduce(const GpuMat& mtx, GpuMat& vec, int dim, int reduceOp, int dtype = -1, Stream& stream = Stream::Null()); +CV_EXPORTS void reduce(InputArray mtx, OutputArray vec, int dim, int reduceOp, int dtype = -1, Stream& stream = Stream::Null()); //! computes mean value and standard deviation of all or selected array elements //! supports only CV_8UC1 type -CV_EXPORTS void meanStdDev(const GpuMat& mtx, Scalar& mean, Scalar& stddev); -//! buffered version -CV_EXPORTS void meanStdDev(const GpuMat& mtx, Scalar& mean, Scalar& stddev, GpuMat& buf); +CV_EXPORTS void meanStdDev(InputArray mtx, Scalar& mean, Scalar& stddev, GpuMat& buf); +static inline void meanStdDev(InputArray src, Scalar& mean, Scalar& stddev) +{ + GpuMat buf; + meanStdDev(src, mean, stddev, buf); +} //! computes the standard deviation of integral images //! supports only CV_32SC1 source type and CV_32FC1 sqr type //! output will have CV_32FC1 type -CV_EXPORTS void rectStdDev(const GpuMat& src, const GpuMat& sqr, GpuMat& dst, const Rect& rect, Stream& stream = Stream::Null()); +CV_EXPORTS void rectStdDev(InputArray src, InputArray sqr, OutputArray dst, Rect rect, Stream& stream = Stream::Null()); -//! copies 2D array to a larger destination array and pads borders with user-specifiable constant -CV_EXPORTS void copyMakeBorder(const GpuMat& src, GpuMat& dst, int top, int bottom, int left, int right, int borderType, - const Scalar& value = Scalar(), Stream& stream = Stream::Null()); - -//! applies fixed threshold to the image -CV_EXPORTS double threshold(const GpuMat& src, GpuMat& dst, double thresh, double maxval, int type, Stream& stream = Stream::Null()); +//! scales and shifts array elements so that either the specified norm (alpha) or the minimum (alpha) and maximum (beta) array values get the specified values +CV_EXPORTS void normalize(InputArray src, OutputArray dst, double alpha, double beta, + int norm_type, int dtype, InputArray mask, GpuMat& norm_buf, GpuMat& cvt_buf); +static inline void normalize(InputArray src, OutputArray dst, double alpha = 1, double beta = 0, + int norm_type = NORM_L2, int dtype = -1, InputArray mask = noArray()) +{ + GpuMat norm_buf; + GpuMat cvt_buf; + normalize(src, dst, alpha, beta, norm_type, dtype, mask, norm_buf, cvt_buf); +} //! computes the integral image //! sum will have CV_32S type, but will contain unsigned int values //! supports only CV_8UC1 source type -CV_EXPORTS void integral(const GpuMat& src, GpuMat& sum, Stream& stream = Stream::Null()); -//! buffered version -CV_EXPORTS void integralBuffered(const GpuMat& src, GpuMat& sum, GpuMat& buffer, Stream& stream = Stream::Null()); +CV_EXPORTS void integral(InputArray src, OutputArray sum, GpuMat& buffer, Stream& stream = Stream::Null()); +static inline void integralBuffered(InputArray src, OutputArray sum, GpuMat& buffer, Stream& stream = Stream::Null()) +{ + integral(src, sum, buffer, stream); +} +static inline void integral(InputArray src, OutputArray sum, Stream& stream = Stream::Null()) +{ + GpuMat buffer; + integral(src, sum, buffer, stream); +} //! computes squared integral image //! result matrix will have 64F type, but will contain 64U values //! supports source images of 8UC1 type only -CV_EXPORTS void sqrIntegral(const GpuMat& src, GpuMat& sqsum, Stream& stream = Stream::Null()); +CV_EXPORTS void sqrIntegral(InputArray src, OutputArray sqsum, GpuMat& buf, Stream& stream = Stream::Null()); +static inline void sqrIntegral(InputArray src, OutputArray sqsum, Stream& stream = Stream::Null()) +{ + GpuMat buffer; + sqrIntegral(src, sqsum, buffer, stream); +} + +CV_EXPORTS void gemm(InputArray src1, InputArray src2, double alpha, + InputArray src3, double beta, OutputArray dst, int flags = 0, Stream& stream = Stream::Null()); //! performs per-element multiplication of two full (not packed) Fourier spectrums //! supports 32FC2 matrixes only (interleaved format) -CV_EXPORTS void mulSpectrums(const GpuMat& a, const GpuMat& b, GpuMat& c, int flags, bool conjB=false, Stream& stream = Stream::Null()); +CV_EXPORTS void mulSpectrums(InputArray src1, InputArray src2, OutputArray dst, int flags, bool conjB=false, Stream& stream = Stream::Null()); //! performs per-element multiplication of two full (not packed) Fourier spectrums //! supports 32FC2 matrixes only (interleaved format) -CV_EXPORTS void mulAndScaleSpectrums(const GpuMat& a, const GpuMat& b, GpuMat& c, int flags, float scale, bool conjB=false, Stream& stream = Stream::Null()); +CV_EXPORTS void mulAndScaleSpectrums(InputArray src1, InputArray src2, OutputArray dst, int flags, float scale, bool conjB=false, Stream& stream = Stream::Null()); //! Performs a forward or inverse discrete Fourier transform (1D or 2D) of floating point matrix. //! Param dft_size is the size of DFT transform. @@ -318,9 +372,25 @@ CV_EXPORTS void mulAndScaleSpectrums(const GpuMat& a, const GpuMat& b, GpuMat& c //! in CUFFT's format. Result as full complex matrix for such kind of transform cannot be retrieved. //! //! For complex-to-real transform it is assumed that the source matrix is packed in CUFFT's format. -CV_EXPORTS void dft(const GpuMat& src, GpuMat& dst, Size dft_size, int flags=0, Stream& stream = Stream::Null()); +CV_EXPORTS void dft(InputArray src, OutputArray dst, Size dft_size, int flags=0, Stream& stream = Stream::Null()); -struct CV_EXPORTS ConvolveBuf +//! computes convolution (or cross-correlation) of two images using discrete Fourier transform +//! supports source images of 32FC1 type only +//! result matrix will have 32FC1 type +class CV_EXPORTS Convolution : public Algorithm +{ +public: + virtual void convolve(InputArray image, InputArray templ, OutputArray result, bool ccorr = false, Stream& stream = Stream::Null()) = 0; +}; +CV_EXPORTS Ptr createConvolution(Size user_block_size = Size()); + +__OPENCV_GPUARITHM_DEPR_BEFORE__ void convolve(InputArray image, InputArray templ, OutputArray result, bool ccorr = false, Stream& stream = Stream::Null()) __OPENCV_GPUARITHM_DEPR_AFTER__; +inline void convolve(InputArray image, InputArray templ, OutputArray result, bool ccorr , Stream& stream) +{ + createConvolution()->convolve(image, templ, result, ccorr, stream); +} + +struct ConvolveBuf { Size result_size; Size block_size; @@ -331,16 +401,19 @@ struct CV_EXPORTS ConvolveBuf GpuMat image_spect, templ_spect, result_spect; GpuMat image_block, templ_block, result_data; - void create(Size image_size, Size templ_size); - static Size estimateBlockSize(Size result_size, Size templ_size); + void create(Size, Size){} + static Size estimateBlockSize(Size, Size){ return Size(); } }; -//! computes convolution (or cross-correlation) of two images using discrete Fourier transform -//! supports source images of 32FC1 type only -//! result matrix will have 32FC1 type -CV_EXPORTS void convolve(const GpuMat& image, const GpuMat& templ, GpuMat& result, bool ccorr = false); -CV_EXPORTS void convolve(const GpuMat& image, const GpuMat& templ, GpuMat& result, bool ccorr, ConvolveBuf& buf, Stream& stream = Stream::Null()); +__OPENCV_GPUARITHM_DEPR_BEFORE__ void convolve(InputArray image, InputArray templ, OutputArray result, bool ccorr, ConvolveBuf& buf, Stream& stream = Stream::Null()) __OPENCV_GPUARITHM_DEPR_AFTER__; +inline void convolve(InputArray image, InputArray templ, OutputArray result, bool ccorr, ConvolveBuf& buf, Stream& stream) +{ + createConvolution(buf.user_block_size)->convolve(image, templ, result, ccorr, stream); +} }} // namespace cv { namespace gpu { +#undef __OPENCV_GPUARITHM_DEPR_BEFORE__ +#undef __OPENCV_GPUARITHM_DEPR_AFTER__ + #endif /* __OPENCV_GPUARITHM_HPP__ */ diff --git a/modules/gpuarithm/perf/perf_arithm.cpp b/modules/gpuarithm/perf/perf_arithm.cpp index b553fc2126..dfeafa0fa4 100644 --- a/modules/gpuarithm/perf/perf_arithm.cpp +++ b/modules/gpuarithm/perf/perf_arithm.cpp @@ -228,10 +228,11 @@ PERF_TEST_P(Sz_KernelSz_Ccorr, Convolve, cv::gpu::GpuMat d_templ = cv::gpu::createContinuous(templ_size, templ_size, CV_32FC1); d_templ.upload(templ); - cv::gpu::GpuMat dst; - cv::gpu::ConvolveBuf d_buf; + cv::Ptr convolution = cv::gpu::createConvolution(); - TEST_CYCLE() cv::gpu::convolve(d_image, d_templ, dst, ccorr, d_buf); + cv::gpu::GpuMat dst; + + TEST_CYCLE() convolution->convolve(d_image, d_templ, dst, ccorr); GPU_SANITY_CHECK(dst); } @@ -265,7 +266,7 @@ PERF_TEST_P(Sz, Integral, cv::gpu::GpuMat dst; cv::gpu::GpuMat d_buf; - TEST_CYCLE() cv::gpu::integralBuffered(d_src, dst, d_buf); + TEST_CYCLE() cv::gpu::integral(d_src, dst, d_buf); GPU_SANITY_CHECK(dst); } @@ -293,9 +294,9 @@ PERF_TEST_P(Sz, IntegralSqr, if (PERF_RUN_GPU()) { const cv::gpu::GpuMat d_src(src); - cv::gpu::GpuMat dst; + cv::gpu::GpuMat dst, buf; - TEST_CYCLE() cv::gpu::sqrIntegral(d_src, dst); + TEST_CYCLE() cv::gpu::sqrIntegral(d_src, dst, buf); GPU_SANITY_CHECK(dst); } diff --git a/modules/gpuarithm/perf/perf_core.cpp b/modules/gpuarithm/perf/perf_core.cpp index eab6d87366..0add472ca3 100644 --- a/modules/gpuarithm/perf/perf_core.cpp +++ b/modules/gpuarithm/perf/perf_core.cpp @@ -224,10 +224,12 @@ PERF_TEST_P(Sz_Type, LutOneChannel, if (PERF_RUN_GPU()) { + cv::Ptr lutAlg = cv::gpu::createLookUpTable(lut); + const cv::gpu::GpuMat d_src(src); cv::gpu::GpuMat dst; - TEST_CYCLE() cv::gpu::LUT(d_src, lut, dst); + TEST_CYCLE() lutAlg->transform(d_src, dst); GPU_SANITY_CHECK(dst); } @@ -259,10 +261,12 @@ PERF_TEST_P(Sz_Type, LutMultiChannel, if (PERF_RUN_GPU()) { + cv::Ptr lutAlg = cv::gpu::createLookUpTable(lut); + const cv::gpu::GpuMat d_src(src); cv::gpu::GpuMat dst; - TEST_CYCLE() cv::gpu::LUT(d_src, lut, dst); + TEST_CYCLE() lutAlg->transform(d_src, dst); GPU_SANITY_CHECK(dst); } diff --git a/modules/gpuarithm/perf/perf_reductions.cpp b/modules/gpuarithm/perf/perf_reductions.cpp index 8d73180dc2..c541ce0e28 100644 --- a/modules/gpuarithm/perf/perf_reductions.cpp +++ b/modules/gpuarithm/perf/perf_reductions.cpp @@ -108,9 +108,10 @@ PERF_TEST_P(Sz_Norm, NormDiff, { const cv::gpu::GpuMat d_src1(src1); const cv::gpu::GpuMat d_src2(src2); + cv::gpu::GpuMat d_buf; double gpu_dst; - TEST_CYCLE() gpu_dst = cv::gpu::norm(d_src1, d_src2, normType); + TEST_CYCLE() gpu_dst = cv::gpu::norm(d_src1, d_src2, d_buf, normType); SANITY_CHECK(gpu_dst); diff --git a/modules/gpuarithm/src/arithm.cpp b/modules/gpuarithm/src/arithm.cpp index a6cd1cb62e..6045cf5baf 100644 --- a/modules/gpuarithm/src/arithm.cpp +++ b/modules/gpuarithm/src/arithm.cpp @@ -47,21 +47,14 @@ using namespace cv::gpu; #if !defined (HAVE_CUDA) || defined (CUDA_DISABLER) -void cv::gpu::gemm(const GpuMat&, const GpuMat&, double, const GpuMat&, double, GpuMat&, int, Stream&) { throw_no_cuda(); } +void cv::gpu::gemm(InputArray, InputArray, double, InputArray, double, OutputArray, int, Stream&) { throw_no_cuda(); } -void cv::gpu::integral(const GpuMat&, GpuMat&, Stream&) { throw_no_cuda(); } -void cv::gpu::integralBuffered(const GpuMat&, GpuMat&, GpuMat&, Stream&) { throw_no_cuda(); } +void cv::gpu::mulSpectrums(InputArray, InputArray, OutputArray, int, bool, Stream&) { throw_no_cuda(); } +void cv::gpu::mulAndScaleSpectrums(InputArray, InputArray, OutputArray, int, float, bool, Stream&) { throw_no_cuda(); } -void cv::gpu::sqrIntegral(const GpuMat&, GpuMat&, Stream&) { throw_no_cuda(); } +void cv::gpu::dft(InputArray, OutputArray, Size, int, Stream&) { throw_no_cuda(); } -void cv::gpu::mulSpectrums(const GpuMat&, const GpuMat&, GpuMat&, int, bool, Stream&) { throw_no_cuda(); } -void cv::gpu::mulAndScaleSpectrums(const GpuMat&, const GpuMat&, GpuMat&, int, float, bool, Stream&) { throw_no_cuda(); } - -void cv::gpu::dft(const GpuMat&, GpuMat&, Size, int, Stream&) { throw_no_cuda(); } - -void cv::gpu::ConvolveBuf::create(Size, Size) { throw_no_cuda(); } -void cv::gpu::convolve(const GpuMat&, const GpuMat&, GpuMat&, bool) { throw_no_cuda(); } -void cv::gpu::convolve(const GpuMat&, const GpuMat&, GpuMat&, bool, ConvolveBuf&, Stream&) { throw_no_cuda(); } +Ptr cv::gpu::createConvolution(Size) { throw_no_cuda(); return Ptr(); } #else /* !defined (HAVE_CUDA) */ @@ -169,23 +162,27 @@ namespace //////////////////////////////////////////////////////////////////////// // gemm -void cv::gpu::gemm(const GpuMat& src1, const GpuMat& src2, double alpha, const GpuMat& src3, double beta, GpuMat& dst, int flags, Stream& stream) +void cv::gpu::gemm(InputArray _src1, InputArray _src2, double alpha, InputArray _src3, double beta, OutputArray _dst, int flags, Stream& stream) { #ifndef HAVE_CUBLAS - (void)src1; - (void)src2; - (void)alpha; - (void)src3; - (void)beta; - (void)dst; - (void)flags; - (void)stream; - CV_Error(cv::Error::StsNotImplemented, "The library was build without CUBLAS"); + (void) _src1; + (void) _src2; + (void) alpha; + (void) _src3; + (void) beta; + (void) _dst; + (void) flags; + (void) stream; + CV_Error(:Error::StsNotImplemented, "The library was build without CUBLAS"); #else // CUBLAS works with column-major matrices - CV_Assert(src1.type() == CV_32FC1 || src1.type() == CV_32FC2 || src1.type() == CV_64FC1 || src1.type() == CV_64FC2); - CV_Assert(src2.type() == src1.type() && (src3.empty() || src3.type() == src1.type())); + GpuMat src1 = _src1.getGpuMat(); + GpuMat src2 = _src2.getGpuMat(); + GpuMat src3 = _src3.getGpuMat(); + + CV_Assert( src1.type() == CV_32FC1 || src1.type() == CV_32FC2 || src1.type() == CV_64FC1 || src1.type() == CV_64FC2 ); + CV_Assert( src2.type() == src1.type() && (src3.empty() || src3.type() == src1.type()) ); if (src1.depth() == CV_64F) { @@ -208,10 +205,11 @@ void cv::gpu::gemm(const GpuMat& src1, const GpuMat& src2, double alpha, const G Size src3Size = tr3 ? Size(src3.rows, src3.cols) : src3.size(); Size dstSize(src2Size.width, src1Size.height); - CV_Assert(src1Size.width == src2Size.height); - CV_Assert(src3.empty() || src3Size == dstSize); + CV_Assert( src1Size.width == src2Size.height ); + CV_Assert( src3.empty() || src3Size == dstSize ); - dst.create(dstSize, src1.type()); + _dst.create(dstSize, src1.type()); + GpuMat dst = _dst.getGpuMat(); if (beta != 0) { @@ -294,116 +292,6 @@ void cv::gpu::gemm(const GpuMat& src1, const GpuMat& src2, double alpha, const G #endif } -//////////////////////////////////////////////////////////////////////// -// integral - -void cv::gpu::integral(const GpuMat& src, GpuMat& sum, Stream& s) -{ - GpuMat buffer; - gpu::integralBuffered(src, sum, buffer, s); -} - -namespace cv { namespace gpu { namespace cudev -{ - namespace imgproc - { - void shfl_integral_gpu(const PtrStepSzb& img, PtrStepSz integral, cudaStream_t stream); - } -}}} - -void cv::gpu::integralBuffered(const GpuMat& src, GpuMat& sum, GpuMat& buffer, Stream& s) -{ - CV_Assert(src.type() == CV_8UC1); - - cudaStream_t stream = StreamAccessor::getStream(s); - - cv::Size whole; - cv::Point offset; - - src.locateROI(whole, offset); - - if (deviceSupports(WARP_SHUFFLE_FUNCTIONS) && src.cols <= 2048 - && offset.x % 16 == 0 && ((src.cols + 63) / 64) * 64 <= (static_cast(src.step) - offset.x)) - { - ensureSizeIsEnough(((src.rows + 7) / 8) * 8, ((src.cols + 63) / 64) * 64, CV_32SC1, buffer); - - cv::gpu::cudev::imgproc::shfl_integral_gpu(src, buffer, stream); - - sum.create(src.rows + 1, src.cols + 1, CV_32SC1); - - sum.setTo(Scalar::all(0), s); - - GpuMat inner = sum(Rect(1, 1, src.cols, src.rows)); - GpuMat res = buffer(Rect(0, 0, src.cols, src.rows)); - - res.copyTo(inner, s); - } - else - { -#ifndef HAVE_OPENCV_GPULEGACY - throw_no_cuda(); -#else - sum.create(src.rows + 1, src.cols + 1, CV_32SC1); - - NcvSize32u roiSize; - roiSize.width = src.cols; - roiSize.height = src.rows; - - cudaDeviceProp prop; - cudaSafeCall( cudaGetDeviceProperties(&prop, cv::gpu::getDevice()) ); - - Ncv32u bufSize; - ncvSafeCall( nppiStIntegralGetSize_8u32u(roiSize, &bufSize, prop) ); - ensureSizeIsEnough(1, bufSize, CV_8UC1, buffer); - - NppStStreamHandler h(stream); - - ncvSafeCall( nppiStIntegral_8u32u_C1R(const_cast(src.ptr()), static_cast(src.step), - sum.ptr(), static_cast(sum.step), roiSize, buffer.ptr(), bufSize, prop) ); - - if (stream == 0) - cudaSafeCall( cudaDeviceSynchronize() ); -#endif - } -} - -////////////////////////////////////////////////////////////////////////////// -// sqrIntegral - -void cv::gpu::sqrIntegral(const GpuMat& src, GpuMat& sqsum, Stream& s) -{ -#ifndef HAVE_OPENCV_GPULEGACY - (void) src; - (void) sqsum; - (void) s; - throw_no_cuda(); -#else - CV_Assert(src.type() == CV_8U); - - NcvSize32u roiSize; - roiSize.width = src.cols; - roiSize.height = src.rows; - - cudaDeviceProp prop; - cudaSafeCall( cudaGetDeviceProperties(&prop, cv::gpu::getDevice()) ); - - Ncv32u bufSize; - ncvSafeCall(nppiStSqrIntegralGetSize_8u64u(roiSize, &bufSize, prop)); - GpuMat buf(1, bufSize, CV_8U); - - cudaStream_t stream = StreamAccessor::getStream(s); - - NppStStreamHandler h(stream); - - sqsum.create(src.rows + 1, src.cols + 1, CV_64F); - ncvSafeCall(nppiStSqrIntegral_8u64u_C1R(const_cast(src.ptr(0)), static_cast(src.step), - sqsum.ptr(0), static_cast(sqsum.step), roiSize, buf.ptr(0), bufSize, prop)); - - if (stream == 0) - cudaSafeCall( cudaDeviceSynchronize() ); -#endif -} - ////////////////////////////////////////////////////////////////////////////// // mulSpectrums @@ -418,12 +306,12 @@ namespace cv { namespace gpu { namespace cudev #endif -void cv::gpu::mulSpectrums(const GpuMat& a, const GpuMat& b, GpuMat& c, int flags, bool conjB, Stream& stream) +void cv::gpu::mulSpectrums(InputArray _src1, InputArray _src2, OutputArray _dst, int flags, bool conjB, Stream& stream) { #ifndef HAVE_CUFFT - (void) a; - (void) b; - (void) c; + (void) _src1; + (void) _src2; + (void) _dst; (void) flags; (void) conjB; (void) stream; @@ -432,16 +320,19 @@ void cv::gpu::mulSpectrums(const GpuMat& a, const GpuMat& b, GpuMat& c, int flag (void) flags; typedef void (*Caller)(const PtrStep, const PtrStep, PtrStepSz, cudaStream_t stream); - static Caller callers[] = { cudev::mulSpectrums, cudev::mulSpectrums_CONJ }; - CV_Assert(a.type() == b.type() && a.type() == CV_32FC2); - CV_Assert(a.size() == b.size()); + GpuMat src1 = _src1.getGpuMat(); + GpuMat src2 = _src2.getGpuMat(); - c.create(a.size(), CV_32FC2); + CV_Assert( src1.type() == src2.type() && src1.type() == CV_32FC2 ); + CV_Assert( src1.size() == src2.size() ); + + _dst.create(src1.size(), CV_32FC2); + GpuMat dst = _dst.getGpuMat(); Caller caller = callers[(int)conjB]; - caller(a, b, c, StreamAccessor::getStream(stream)); + caller(src1, src2, dst, StreamAccessor::getStream(stream)); #endif } @@ -459,12 +350,12 @@ namespace cv { namespace gpu { namespace cudev #endif -void cv::gpu::mulAndScaleSpectrums(const GpuMat& a, const GpuMat& b, GpuMat& c, int flags, float scale, bool conjB, Stream& stream) +void cv::gpu::mulAndScaleSpectrums(InputArray _src1, InputArray _src2, OutputArray _dst, int flags, float scale, bool conjB, Stream& stream) { #ifndef HAVE_CUFFT - (void) a; - (void) b; - (void) c; + (void) _src1; + (void) _src2; + (void) _dst; (void) flags; (void) scale; (void) conjB; @@ -476,53 +367,57 @@ void cv::gpu::mulAndScaleSpectrums(const GpuMat& a, const GpuMat& b, GpuMat& c, typedef void (*Caller)(const PtrStep, const PtrStep, float scale, PtrStepSz, cudaStream_t stream); static Caller callers[] = { cudev::mulAndScaleSpectrums, cudev::mulAndScaleSpectrums_CONJ }; - CV_Assert(a.type() == b.type() && a.type() == CV_32FC2); - CV_Assert(a.size() == b.size()); + GpuMat src1 = _src1.getGpuMat(); + GpuMat src2 = _src2.getGpuMat(); - c.create(a.size(), CV_32FC2); + CV_Assert( src1.type() == src2.type() && src1.type() == CV_32FC2); + CV_Assert( src1.size() == src2.size() ); + + _dst.create(src1.size(), CV_32FC2); + GpuMat dst = _dst.getGpuMat(); Caller caller = callers[(int)conjB]; - caller(a, b, scale, c, StreamAccessor::getStream(stream)); + caller(src1, src2, scale, dst, StreamAccessor::getStream(stream)); #endif } ////////////////////////////////////////////////////////////////////////////// // dft -void cv::gpu::dft(const GpuMat& src, GpuMat& dst, Size dft_size, int flags, Stream& stream) +void cv::gpu::dft(InputArray _src, OutputArray _dst, Size dft_size, int flags, Stream& stream) { #ifndef HAVE_CUFFT - (void) src; - (void) dst; + (void) _src; + (void) _dst; (void) dft_size; (void) flags; (void) stream; throw_no_cuda(); #else + GpuMat src = _src.getGpuMat(); - CV_Assert(src.type() == CV_32F || src.type() == CV_32FC2); + CV_Assert( src.type() == CV_32FC1 || src.type() == CV_32FC2 ); // We don't support unpacked output (in the case of real input) - CV_Assert(!(flags & DFT_COMPLEX_OUTPUT)); + CV_Assert( !(flags & DFT_COMPLEX_OUTPUT) ); - bool is_1d_input = (dft_size.height == 1) || (dft_size.width == 1); - int is_row_dft = flags & DFT_ROWS; - int is_scaled_dft = flags & DFT_SCALE; - int is_inverse = flags & DFT_INVERSE; - bool is_complex_input = src.channels() == 2; - bool is_complex_output = !(flags & DFT_REAL_OUTPUT); + const bool is_1d_input = (dft_size.height == 1) || (dft_size.width == 1); + const bool is_row_dft = (flags & DFT_ROWS) != 0; + const bool is_scaled_dft = (flags & DFT_SCALE) != 0; + const bool is_inverse = (flags & DFT_INVERSE) != 0; + const bool is_complex_input = src.channels() == 2; + const bool is_complex_output = !(flags & DFT_REAL_OUTPUT); // We don't support real-to-real transform - CV_Assert(is_complex_input || is_complex_output); + CV_Assert( is_complex_input || is_complex_output ); - GpuMat src_data; + GpuMat src_cont = src; // Make sure here we work with the continuous input, // as CUFFT can't handle gaps - src_data = src; - createContinuous(src.rows, src.cols, src.type(), src_data); - if (src_data.data != src.data) - src.copyTo(src_data); + createContinuous(src.rows, src.cols, src.type(), src_cont); + if (src_cont.data != src.data) + src.copyTo(src_cont, stream); Size dft_size_opt = dft_size; if (is_1d_input && !is_row_dft) @@ -532,17 +427,17 @@ void cv::gpu::dft(const GpuMat& src, GpuMat& dst, Size dft_size, int flags, Stre dft_size_opt.height = std::min(dft_size.width, dft_size.height); } + CV_Assert( dft_size_opt.width > 1 ); + cufftType dft_type = CUFFT_R2C; if (is_complex_input) dft_type = is_complex_output ? CUFFT_C2C : CUFFT_C2R; - CV_Assert(dft_size_opt.width > 1); - cufftHandle plan; if (is_1d_input || is_row_dft) - cufftPlan1d(&plan, dft_size_opt.width, dft_type, dft_size_opt.height); + cufftSafeCall( cufftPlan1d(&plan, dft_size_opt.width, dft_type, dft_size_opt.height) ); else - cufftPlan2d(&plan, dft_size_opt.height, dft_size_opt.width, dft_type); + cufftSafeCall( cufftPlan2d(&plan, dft_size_opt.height, dft_size_opt.width, dft_type) ); cufftSafeCall( cufftSetStream(plan, StreamAccessor::getStream(stream)) ); @@ -550,171 +445,191 @@ void cv::gpu::dft(const GpuMat& src, GpuMat& dst, Size dft_size, int flags, Stre { if (is_complex_output) { - createContinuous(dft_size, CV_32FC2, dst); + createContinuous(dft_size, CV_32FC2, _dst); + GpuMat dst = _dst.getGpuMat(); + cufftSafeCall(cufftExecC2C( - plan, src_data.ptr(), dst.ptr(), + plan, src_cont.ptr(), dst.ptr(), is_inverse ? CUFFT_INVERSE : CUFFT_FORWARD)); } else { - createContinuous(dft_size, CV_32F, dst); + createContinuous(dft_size, CV_32F, _dst); + GpuMat dst = _dst.getGpuMat(); + cufftSafeCall(cufftExecC2R( - plan, src_data.ptr(), dst.ptr())); + plan, src_cont.ptr(), dst.ptr())); } } else { // We could swap dft_size for efficiency. Here we must reflect it if (dft_size == dft_size_opt) - createContinuous(Size(dft_size.width / 2 + 1, dft_size.height), CV_32FC2, dst); + createContinuous(Size(dft_size.width / 2 + 1, dft_size.height), CV_32FC2, _dst); else - createContinuous(Size(dft_size.width, dft_size.height / 2 + 1), CV_32FC2, dst); + createContinuous(Size(dft_size.width, dft_size.height / 2 + 1), CV_32FC2, _dst); + + GpuMat dst = _dst.getGpuMat(); cufftSafeCall(cufftExecR2C( - plan, src_data.ptr(), dst.ptr())); + plan, src_cont.ptr(), dst.ptr())); } - cufftSafeCall(cufftDestroy(plan)); + cufftSafeCall( cufftDestroy(plan) ); if (is_scaled_dft) - multiply(dst, Scalar::all(1. / dft_size.area()), dst, 1, -1, stream); + gpu::multiply(_dst, Scalar::all(1. / dft_size.area()), _dst, 1, -1, stream); #endif } ////////////////////////////////////////////////////////////////////////////// -// convolve +// Convolution -void cv::gpu::ConvolveBuf::create(Size image_size, Size templ_size) +#ifdef HAVE_CUFFT + +namespace { - result_size = Size(image_size.width - templ_size.width + 1, - image_size.height - templ_size.height + 1); - - block_size = user_block_size; - if (user_block_size.width == 0 || user_block_size.height == 0) - block_size = estimateBlockSize(result_size, templ_size); - - dft_size.width = 1 << int(ceil(std::log(block_size.width + templ_size.width - 1.) / std::log(2.))); - dft_size.height = 1 << int(ceil(std::log(block_size.height + templ_size.height - 1.) / std::log(2.))); - - // CUFFT has hard-coded kernels for power-of-2 sizes (up to 8192), - // see CUDA Toolkit 4.1 CUFFT Library Programming Guide - if (dft_size.width > 8192) - dft_size.width = getOptimalDFTSize(block_size.width + templ_size.width - 1); - if (dft_size.height > 8192) - dft_size.height = getOptimalDFTSize(block_size.height + templ_size.height - 1); - - // To avoid wasting time doing small DFTs - dft_size.width = std::max(dft_size.width, 512); - dft_size.height = std::max(dft_size.height, 512); - - createContinuous(dft_size, CV_32F, image_block); - createContinuous(dft_size, CV_32F, templ_block); - createContinuous(dft_size, CV_32F, result_data); - - spect_len = dft_size.height * (dft_size.width / 2 + 1); - createContinuous(1, spect_len, CV_32FC2, image_spect); - createContinuous(1, spect_len, CV_32FC2, templ_spect); - createContinuous(1, spect_len, CV_32FC2, result_spect); - - // Use maximum result matrix block size for the estimated DFT block size - block_size.width = std::min(dft_size.width - templ_size.width + 1, result_size.width); - block_size.height = std::min(dft_size.height - templ_size.height + 1, result_size.height); -} - - -Size cv::gpu::ConvolveBuf::estimateBlockSize(Size result_size, Size /*templ_size*/) -{ - int width = (result_size.width + 2) / 3; - int height = (result_size.height + 2) / 3; - width = std::min(width, result_size.width); - height = std::min(height, result_size.height); - return Size(width, height); -} - - -void cv::gpu::convolve(const GpuMat& image, const GpuMat& templ, GpuMat& result, bool ccorr) -{ - ConvolveBuf buf; - gpu::convolve(image, templ, result, ccorr, buf); -} - -void cv::gpu::convolve(const GpuMat& image, const GpuMat& templ, GpuMat& result, bool ccorr, ConvolveBuf& buf, Stream& stream) -{ -#ifndef HAVE_CUFFT - (void) image; - (void) templ; - (void) result; - (void) ccorr; - (void) buf; - (void) stream; - throw_no_cuda(); -#else - using namespace cv::gpu::cudev::imgproc; - - CV_Assert(image.type() == CV_32F); - CV_Assert(templ.type() == CV_32F); - - buf.create(image.size(), templ.size()); - result.create(buf.result_size, CV_32F); - - Size& block_size = buf.block_size; - Size& dft_size = buf.dft_size; - - GpuMat& image_block = buf.image_block; - GpuMat& templ_block = buf.templ_block; - GpuMat& result_data = buf.result_data; - - GpuMat& image_spect = buf.image_spect; - GpuMat& templ_spect = buf.templ_spect; - GpuMat& result_spect = buf.result_spect; - - cufftHandle planR2C, planC2R; - cufftSafeCall(cufftPlan2d(&planC2R, dft_size.height, dft_size.width, CUFFT_C2R)); - cufftSafeCall(cufftPlan2d(&planR2C, dft_size.height, dft_size.width, CUFFT_R2C)); - - cufftSafeCall( cufftSetStream(planR2C, StreamAccessor::getStream(stream)) ); - cufftSafeCall( cufftSetStream(planC2R, StreamAccessor::getStream(stream)) ); - - GpuMat templ_roi(templ.size(), CV_32F, templ.data, templ.step); - gpu::copyMakeBorder(templ_roi, templ_block, 0, templ_block.rows - templ_roi.rows, 0, - templ_block.cols - templ_roi.cols, 0, Scalar(), stream); - - cufftSafeCall(cufftExecR2C(planR2C, templ_block.ptr(), - templ_spect.ptr())); - - // Process all blocks of the result matrix - for (int y = 0; y < result.rows; y += block_size.height) + class ConvolutionImpl : public Convolution { - for (int x = 0; x < result.cols; x += block_size.width) - { - Size image_roi_size(std::min(x + dft_size.width, image.cols) - x, - std::min(y + dft_size.height, image.rows) - y); - GpuMat image_roi(image_roi_size, CV_32F, (void*)(image.ptr(y) + x), - image.step); - gpu::copyMakeBorder(image_roi, image_block, 0, image_block.rows - image_roi.rows, - 0, image_block.cols - image_roi.cols, 0, Scalar(), stream); + public: + explicit ConvolutionImpl(Size user_block_size_) : user_block_size(user_block_size_) {} - cufftSafeCall(cufftExecR2C(planR2C, image_block.ptr(), - image_spect.ptr())); - gpu::mulAndScaleSpectrums(image_spect, templ_spect, result_spect, 0, - 1.f / dft_size.area(), ccorr, stream); - cufftSafeCall(cufftExecC2R(planC2R, result_spect.ptr(), - result_data.ptr())); + void convolve(InputArray image, InputArray templ, OutputArray result, bool ccorr = false, Stream& stream = Stream::Null()); - Size result_roi_size(std::min(x + block_size.width, result.cols) - x, - std::min(y + block_size.height, result.rows) - y); - GpuMat result_roi(result_roi_size, result.type(), - (void*)(result.ptr(y) + x), result.step); - GpuMat result_block(result_roi_size, result_data.type(), - result_data.ptr(), result_data.step); + private: + void create(Size image_size, Size templ_size); + static Size estimateBlockSize(Size result_size); - result_block.copyTo(result_roi, stream); - } + Size result_size; + Size block_size; + Size user_block_size; + Size dft_size; + int spect_len; + + GpuMat image_spect, templ_spect, result_spect; + GpuMat image_block, templ_block, result_data; + }; + + void ConvolutionImpl::create(Size image_size, Size templ_size) + { + result_size = Size(image_size.width - templ_size.width + 1, + image_size.height - templ_size.height + 1); + + block_size = user_block_size; + if (user_block_size.width == 0 || user_block_size.height == 0) + block_size = estimateBlockSize(result_size); + + dft_size.width = 1 << int(ceil(std::log(block_size.width + templ_size.width - 1.) / std::log(2.))); + dft_size.height = 1 << int(ceil(std::log(block_size.height + templ_size.height - 1.) / std::log(2.))); + + // CUFFT has hard-coded kernels for power-of-2 sizes (up to 8192), + // see CUDA Toolkit 4.1 CUFFT Library Programming Guide + if (dft_size.width > 8192) + dft_size.width = getOptimalDFTSize(block_size.width + templ_size.width - 1); + if (dft_size.height > 8192) + dft_size.height = getOptimalDFTSize(block_size.height + templ_size.height - 1); + + // To avoid wasting time doing small DFTs + dft_size.width = std::max(dft_size.width, 512); + dft_size.height = std::max(dft_size.height, 512); + + createContinuous(dft_size, CV_32F, image_block); + createContinuous(dft_size, CV_32F, templ_block); + createContinuous(dft_size, CV_32F, result_data); + + spect_len = dft_size.height * (dft_size.width / 2 + 1); + createContinuous(1, spect_len, CV_32FC2, image_spect); + createContinuous(1, spect_len, CV_32FC2, templ_spect); + createContinuous(1, spect_len, CV_32FC2, result_spect); + + // Use maximum result matrix block size for the estimated DFT block size + block_size.width = std::min(dft_size.width - templ_size.width + 1, result_size.width); + block_size.height = std::min(dft_size.height - templ_size.height + 1, result_size.height); } - cufftSafeCall(cufftDestroy(planR2C)); - cufftSafeCall(cufftDestroy(planC2R)); + Size ConvolutionImpl::estimateBlockSize(Size result_size) + { + int width = (result_size.width + 2) / 3; + int height = (result_size.height + 2) / 3; + width = std::min(width, result_size.width); + height = std::min(height, result_size.height); + return Size(width, height); + } + + void ConvolutionImpl::convolve(InputArray _image, InputArray _templ, OutputArray _result, bool ccorr, Stream& _stream) + { + GpuMat image = _image.getGpuMat(); + GpuMat templ = _templ.getGpuMat(); + + CV_Assert( image.type() == CV_32FC1 ); + CV_Assert( templ.type() == CV_32FC1 ); + + create(image.size(), templ.size()); + + _result.create(result_size, CV_32FC1); + GpuMat result = _result.getGpuMat(); + + cudaStream_t stream = StreamAccessor::getStream(_stream); + + cufftHandle planR2C, planC2R; + cufftSafeCall( cufftPlan2d(&planC2R, dft_size.height, dft_size.width, CUFFT_C2R) ); + cufftSafeCall( cufftPlan2d(&planR2C, dft_size.height, dft_size.width, CUFFT_R2C) ); + + cufftSafeCall( cufftSetStream(planR2C, stream) ); + cufftSafeCall( cufftSetStream(planC2R, stream) ); + + GpuMat templ_roi(templ.size(), CV_32FC1, templ.data, templ.step); + gpu::copyMakeBorder(templ_roi, templ_block, 0, templ_block.rows - templ_roi.rows, 0, + templ_block.cols - templ_roi.cols, 0, Scalar(), _stream); + + cufftSafeCall( cufftExecR2C(planR2C, templ_block.ptr(), templ_spect.ptr()) ); + + // Process all blocks of the result matrix + for (int y = 0; y < result.rows; y += block_size.height) + { + for (int x = 0; x < result.cols; x += block_size.width) + { + Size image_roi_size(std::min(x + dft_size.width, image.cols) - x, + std::min(y + dft_size.height, image.rows) - y); + GpuMat image_roi(image_roi_size, CV_32F, (void*)(image.ptr(y) + x), + image.step); + gpu::copyMakeBorder(image_roi, image_block, 0, image_block.rows - image_roi.rows, + 0, image_block.cols - image_roi.cols, 0, Scalar(), _stream); + + cufftSafeCall(cufftExecR2C(planR2C, image_block.ptr(), + image_spect.ptr())); + gpu::mulAndScaleSpectrums(image_spect, templ_spect, result_spect, 0, + 1.f / dft_size.area(), ccorr, _stream); + cufftSafeCall(cufftExecC2R(planC2R, result_spect.ptr(), + result_data.ptr())); + + Size result_roi_size(std::min(x + block_size.width, result.cols) - x, + std::min(y + block_size.height, result.rows) - y); + GpuMat result_roi(result_roi_size, result.type(), + (void*)(result.ptr(y) + x), result.step); + GpuMat result_block(result_roi_size, result_data.type(), + result_data.ptr(), result_data.step); + + result_block.copyTo(result_roi, _stream); + } + } + + cufftSafeCall( cufftDestroy(planR2C) ); + cufftSafeCall( cufftDestroy(planC2R) ); + } +} + +#endif + +Ptr cv::gpu::createConvolution(Size user_block_size) +{ +#ifndef HAVE_CUBLAS + (void) user_block_size; + CV_Error(cv::Error::StsNotImplemented, "The library was build without CUFFT"); + return Ptr(); +#else + return new ConvolutionImpl(user_block_size); #endif } diff --git a/modules/gpuarithm/src/core.cpp b/modules/gpuarithm/src/core.cpp index bd0277cde2..22887796ab 100644 --- a/modules/gpuarithm/src/core.cpp +++ b/modules/gpuarithm/src/core.cpp @@ -47,19 +47,19 @@ using namespace cv::gpu; #if !defined (HAVE_CUDA) || defined (CUDA_DISABLER) -void cv::gpu::merge(const GpuMat* /*src*/, size_t /*count*/, GpuMat& /*dst*/, Stream& /*stream*/) { throw_no_cuda(); } -void cv::gpu::merge(const std::vector& /*src*/, GpuMat& /*dst*/, Stream& /*stream*/) { throw_no_cuda(); } +void cv::gpu::merge(const GpuMat*, size_t, OutputArray, Stream&) { throw_no_cuda(); } +void cv::gpu::merge(const std::vector&, OutputArray, Stream&) { throw_no_cuda(); } -void cv::gpu::split(const GpuMat& /*src*/, GpuMat* /*dst*/, Stream& /*stream*/) { throw_no_cuda(); } -void cv::gpu::split(const GpuMat& /*src*/, std::vector& /*dst*/, Stream& /*stream*/) { throw_no_cuda(); } +void cv::gpu::split(InputArray, GpuMat*, Stream&) { throw_no_cuda(); } +void cv::gpu::split(InputArray, std::vector&, Stream&) { throw_no_cuda(); } -void cv::gpu::transpose(const GpuMat&, GpuMat&, Stream&) { throw_no_cuda(); } +void cv::gpu::transpose(InputArray, OutputArray, Stream&) { throw_no_cuda(); } -void cv::gpu::flip(const GpuMat&, GpuMat&, int, Stream&) { throw_no_cuda(); } +void cv::gpu::flip(InputArray, OutputArray, int, Stream&) { throw_no_cuda(); } -void cv::gpu::LUT(const GpuMat&, const Mat&, GpuMat&, Stream&) { throw_no_cuda(); } +Ptr cv::gpu::createLookUpTable(InputArray) { throw_no_cuda(); return Ptr(); } -void cv::gpu::copyMakeBorder(const GpuMat&, GpuMat&, int, int, int, int, int, const Scalar&, Stream&) { throw_no_cuda(); } +void cv::gpu::copyMakeBorder(InputArray, OutputArray, int, int, int, int, int, Scalar, Stream&) { throw_no_cuda(); } #else /* !defined (HAVE_CUDA) */ @@ -70,22 +70,27 @@ namespace cv { namespace gpu { namespace cudev { namespace split_merge { - void merge_caller(const PtrStepSzb* src, PtrStepSzb& dst, int total_channels, size_t elem_size, const cudaStream_t& stream); - void split_caller(const PtrStepSzb& src, PtrStepSzb* dst, int num_channels, size_t elem_size1, const cudaStream_t& stream); + void merge(const PtrStepSzb* src, PtrStepSzb& dst, int total_channels, size_t elem_size, const cudaStream_t& stream); + void split(const PtrStepSzb& src, PtrStepSzb* dst, int num_channels, size_t elem_size1, const cudaStream_t& stream); } }}} namespace { - void merge(const GpuMat* src, size_t n, GpuMat& dst, const cudaStream_t& stream) + void merge_caller(const GpuMat* src, size_t n, OutputArray _dst, Stream& stream) { - using namespace ::cv::gpu::cudev::split_merge; + CV_Assert( src != 0 ); + CV_Assert( n > 0 && n <= 4 ); - CV_Assert(src); - CV_Assert(n > 0); + const int depth = src[0].depth(); + const Size size = src[0].size(); - int depth = src[0].depth(); - Size size = src[0].size(); + for (size_t i = 0; i < n; ++i) + { + CV_Assert( src[i].size() == size ); + CV_Assert( src[i].depth() == depth ); + CV_Assert( src[i].channels() == 1 ); + } if (depth == CV_64F) { @@ -93,43 +98,32 @@ namespace CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); } - bool single_channel_only = true; - int total_channels = 0; - - for (size_t i = 0; i < n; ++i) + if (n == 1) { - CV_Assert(src[i].size() == size); - CV_Assert(src[i].depth() == depth); - single_channel_only = single_channel_only && src[i].channels() == 1; - total_channels += src[i].channels(); + src[0].copyTo(_dst, stream); } - - CV_Assert(single_channel_only); - CV_Assert(total_channels <= 4); - - if (total_channels == 1) - src[0].copyTo(dst); else { - dst.create(size, CV_MAKETYPE(depth, total_channels)); + _dst.create(size, CV_MAKE_TYPE(depth, (int)n)); + GpuMat dst = _dst.getGpuMat(); PtrStepSzb src_as_devmem[4]; for(size_t i = 0; i < n; ++i) src_as_devmem[i] = src[i]; PtrStepSzb dst_as_devmem(dst); - merge_caller(src_as_devmem, dst_as_devmem, total_channels, CV_ELEM_SIZE(depth), stream); + cv::gpu::cudev::split_merge::merge(src_as_devmem, dst_as_devmem, (int)n, CV_ELEM_SIZE(depth), StreamAccessor::getStream(stream)); } } - void split(const GpuMat& src, GpuMat* dst, const cudaStream_t& stream) + void split_caller(const GpuMat& src, GpuMat* dst, Stream& stream) { - using namespace ::cv::gpu::cudev::split_merge; + CV_Assert( dst != 0 ); - CV_Assert(dst); + const int depth = src.depth(); + const int num_channels = src.channels(); - int depth = src.depth(); - int num_channels = src.channels(); + CV_Assert( num_channels <= 4 ); if (depth == CV_64F) { @@ -139,45 +133,45 @@ namespace if (num_channels == 1) { - src.copyTo(dst[0]); + src.copyTo(dst[0], stream); return; } for (int i = 0; i < num_channels; ++i) dst[i].create(src.size(), depth); - CV_Assert(num_channels <= 4); - PtrStepSzb dst_as_devmem[4]; for (int i = 0; i < num_channels; ++i) dst_as_devmem[i] = dst[i]; PtrStepSzb src_as_devmem(src); - split_caller(src_as_devmem, dst_as_devmem, num_channels, src.elemSize1(), stream); + cv::gpu::cudev::split_merge::split(src_as_devmem, dst_as_devmem, num_channels, src.elemSize1(), StreamAccessor::getStream(stream)); } } -void cv::gpu::merge(const GpuMat* src, size_t n, GpuMat& dst, Stream& stream) +void cv::gpu::merge(const GpuMat* src, size_t n, OutputArray dst, Stream& stream) { - ::merge(src, n, dst, StreamAccessor::getStream(stream)); + merge_caller(src, n, dst, stream); } -void cv::gpu::merge(const std::vector& src, GpuMat& dst, Stream& stream) +void cv::gpu::merge(const std::vector& src, OutputArray dst, Stream& stream) { - ::merge(&src[0], src.size(), dst, StreamAccessor::getStream(stream)); + merge_caller(&src[0], src.size(), dst, stream); } -void cv::gpu::split(const GpuMat& src, GpuMat* dst, Stream& stream) +void cv::gpu::split(InputArray _src, GpuMat* dst, Stream& stream) { - ::split(src, dst, StreamAccessor::getStream(stream)); + GpuMat src = _src.getGpuMat(); + split_caller(src, dst, stream); } -void cv::gpu::split(const GpuMat& src, std::vector& dst, Stream& stream) +void cv::gpu::split(InputArray _src, std::vector& dst, Stream& stream) { + GpuMat src = _src.getGpuMat(); dst.resize(src.channels()); if(src.channels() > 0) - ::split(src, &dst[0], StreamAccessor::getStream(stream)); + split_caller(src, &dst[0], stream); } //////////////////////////////////////////////////////////////////////// @@ -188,13 +182,16 @@ namespace arithm template void transpose(PtrStepSz src, PtrStepSz dst, cudaStream_t stream); } -void cv::gpu::transpose(const GpuMat& src, GpuMat& dst, Stream& s) +void cv::gpu::transpose(InputArray _src, OutputArray _dst, Stream& _stream) { + GpuMat src = _src.getGpuMat(); + CV_Assert( src.elemSize() == 1 || src.elemSize() == 4 || src.elemSize() == 8 ); - dst.create( src.cols, src.rows, src.type() ); + _dst.create( src.cols, src.rows, src.type() ); + GpuMat dst = _dst.getGpuMat(); - cudaStream_t stream = StreamAccessor::getStream(s); + cudaStream_t stream = StreamAccessor::getStream(_stream); if (src.elemSize() == 1) { @@ -266,7 +263,7 @@ namespace }; } -void cv::gpu::flip(const GpuMat& src, GpuMat& dst, int flipCode, Stream& stream) +void cv::gpu::flip(InputArray _src, OutputArray _dst, int flipCode, Stream& stream) { typedef void (*func_t)(const GpuMat& src, GpuMat& dst, int flipCode, cudaStream_t stream); static const func_t funcs[6][4] = @@ -279,10 +276,13 @@ void cv::gpu::flip(const GpuMat& src, GpuMat& dst, int flipCode, Stream& stream) {NppMirror::call, 0, NppMirror::call, NppMirror::call} }; + GpuMat src = _src.getGpuMat(); + CV_Assert(src.depth() == CV_8U || src.depth() == CV_16U || src.depth() == CV_32S || src.depth() == CV_32F); CV_Assert(src.channels() == 1 || src.channels() == 3 || src.channels() == 4); - dst.create(src.size(), src.type()); + _dst.create(src.size(), src.type()); + GpuMat dst = _dst.getGpuMat(); funcs[src.depth()][src.channels() - 1](src, dst, flipCode, StreamAccessor::getStream(stream)); } @@ -290,93 +290,214 @@ void cv::gpu::flip(const GpuMat& src, GpuMat& dst, int flipCode, Stream& stream) //////////////////////////////////////////////////////////////////////// // LUT -void cv::gpu::LUT(const GpuMat& src, const Mat& lut, GpuMat& dst, Stream& s) +#if (CUDA_VERSION >= 5000) + +namespace { - const int cn = src.channels(); - - CV_Assert( src.type() == CV_8UC1 || src.type() == CV_8UC3 ); - CV_Assert( lut.depth() == CV_8U ); - CV_Assert( lut.channels() == 1 || lut.channels() == cn ); - CV_Assert( lut.rows * lut.cols == 256 && lut.isContinuous() ); - - dst.create(src.size(), CV_MAKE_TYPE(lut.depth(), cn)); - - NppiSize sz; - sz.height = src.rows; - sz.width = src.cols; - - Mat nppLut; - lut.convertTo(nppLut, CV_32S); - - int nValues3[] = {256, 256, 256}; - - Npp32s pLevels[256]; - for (int i = 0; i < 256; ++i) - pLevels[i] = i; - - const Npp32s* pLevels3[3]; - -#if (CUDA_VERSION <= 4020) - pLevels3[0] = pLevels3[1] = pLevels3[2] = pLevels; -#else - GpuMat d_pLevels; - d_pLevels.upload(Mat(1, 256, CV_32S, pLevels)); - pLevels3[0] = pLevels3[1] = pLevels3[2] = d_pLevels.ptr(); -#endif - - cudaStream_t stream = StreamAccessor::getStream(s); - NppStreamHandler h(stream); - - if (src.type() == CV_8UC1) - { -#if (CUDA_VERSION <= 4020) - nppSafeCall( nppiLUT_Linear_8u_C1R(src.ptr(), static_cast(src.step), - dst.ptr(), static_cast(dst.step), sz, nppLut.ptr(), pLevels, 256) ); -#else - GpuMat d_nppLut(Mat(1, 256, CV_32S, nppLut.data)); - nppSafeCall( nppiLUT_Linear_8u_C1R(src.ptr(), static_cast(src.step), - dst.ptr(), static_cast(dst.step), sz, d_nppLut.ptr(), d_pLevels.ptr(), 256) ); -#endif - } - else + class LookUpTableImpl : public LookUpTable { + public: + LookUpTableImpl(InputArray lut); + + void transform(InputArray src, OutputArray dst, Stream& stream = Stream::Null()); + + private: + int lut_cn; + + int nValues3[3]; const Npp32s* pValues3[3]; + const Npp32s* pLevels3[3]; - Mat nppLut3[3]; - if (nppLut.channels() == 1) + GpuMat d_pLevels; + GpuMat d_nppLut; + GpuMat d_nppLut3[3]; + }; + + LookUpTableImpl::LookUpTableImpl(InputArray _lut) + { + nValues3[0] = nValues3[1] = nValues3[2] = 256; + + Npp32s pLevels[256]; + for (int i = 0; i < 256; ++i) + pLevels[i] = i; + + d_pLevels.upload(Mat(1, 256, CV_32S, pLevels)); + pLevels3[0] = pLevels3[1] = pLevels3[2] = d_pLevels.ptr(); + + GpuMat lut; + if (_lut.kind() == _InputArray::GPU_MAT) + { + lut = _lut.getGpuMat(); + } + else + { + Mat hLut = _lut.getMat(); + CV_Assert( hLut.total() == 256 && hLut.isContinuous() ); + lut.upload(Mat(1, 256, hLut.type(), hLut.data)); + } + + lut_cn = lut.channels(); + + CV_Assert( lut.depth() == CV_8U ); + CV_Assert( lut.rows == 1 && lut.cols == 256 ); + + lut.convertTo(d_nppLut, CV_32S); + + if (lut_cn == 1) { -#if (CUDA_VERSION <= 4020) - pValues3[0] = pValues3[1] = pValues3[2] = nppLut.ptr(); -#else - GpuMat d_nppLut(Mat(1, 256, CV_32S, nppLut.data)); pValues3[0] = pValues3[1] = pValues3[2] = d_nppLut.ptr(); -#endif + } + else + { + gpu::split(d_nppLut, d_nppLut3); + + pValues3[0] = d_nppLut3[0].ptr(); + pValues3[1] = d_nppLut3[1].ptr(); + pValues3[2] = d_nppLut3[2].ptr(); + } + } + + void LookUpTableImpl::transform(InputArray _src, OutputArray _dst, Stream& _stream) + { + GpuMat src = _src.getGpuMat(); + + const int cn = src.channels(); + + CV_Assert( src.type() == CV_8UC1 || src.type() == CV_8UC3 ); + CV_Assert( lut_cn == 1 || lut_cn == cn ); + + _dst.create(src.size(), src.type()); + GpuMat dst = _dst.getGpuMat(); + + cudaStream_t stream = StreamAccessor::getStream(_stream); + + NppStreamHandler h(stream); + + NppiSize sz; + sz.height = src.rows; + sz.width = src.cols; + + if (src.type() == CV_8UC1) + { + nppSafeCall( nppiLUT_Linear_8u_C1R(src.ptr(), static_cast(src.step), + dst.ptr(), static_cast(dst.step), sz, d_nppLut.ptr(), d_pLevels.ptr(), 256) ); + } + else + { + nppSafeCall( nppiLUT_Linear_8u_C3R(src.ptr(), static_cast(src.step), + dst.ptr(), static_cast(dst.step), sz, pValues3, pLevels3, nValues3) ); + } + + if (stream == 0) + cudaSafeCall( cudaDeviceSynchronize() ); + } +} + +#else // (CUDA_VERSION >= 5000) + +namespace +{ + class LookUpTableImpl : public LookUpTable + { + public: + LookUpTableImpl(InputArray lut); + + void transform(InputArray src, OutputArray dst, Stream& stream = Stream::Null()); + + private: + int lut_cn; + + Npp32s pLevels[256]; + int nValues3[3]; + const Npp32s* pValues3[3]; + const Npp32s* pLevels3[3]; + + Mat nppLut; + Mat nppLut3[3]; + }; + + LookUpTableImpl::LookUpTableImpl(InputArray _lut) + { + nValues3[0] = nValues3[1] = nValues3[2] = 256; + + for (int i = 0; i < 256; ++i) + pLevels[i] = i; + pLevels3[0] = pLevels3[1] = pLevels3[2] = pLevels; + + Mat lut; + if (_lut.kind() == _InputArray::GPU_MAT) + { + lut = Mat(_lut.getGpuMat()); + } + else + { + Mat hLut = _lut.getMat(); + CV_Assert( hLut.total() == 256 && hLut.isContinuous() ); + lut = hLut; + } + + lut_cn = lut.channels(); + + CV_Assert( lut.depth() == CV_8U ); + CV_Assert( lut.rows == 1 && lut.cols == 256 ); + + lut.convertTo(nppLut, CV_32S); + + if (lut_cn == 1) + { + pValues3[0] = pValues3[1] = pValues3[2] = nppLut.ptr(); } else { cv::split(nppLut, nppLut3); -#if (CUDA_VERSION <= 4020) pValues3[0] = nppLut3[0].ptr(); pValues3[1] = nppLut3[1].ptr(); pValues3[2] = nppLut3[2].ptr(); -#else - GpuMat d_nppLut0(Mat(1, 256, CV_32S, nppLut3[0].data)); - GpuMat d_nppLut1(Mat(1, 256, CV_32S, nppLut3[1].data)); - GpuMat d_nppLut2(Mat(1, 256, CV_32S, nppLut3[2].data)); - - pValues3[0] = d_nppLut0.ptr(); - pValues3[1] = d_nppLut1.ptr(); - pValues3[2] = d_nppLut2.ptr(); -#endif } - - nppSafeCall( nppiLUT_Linear_8u_C3R(src.ptr(), static_cast(src.step), - dst.ptr(), static_cast(dst.step), sz, pValues3, pLevels3, nValues3) ); } - if (stream == 0) - cudaSafeCall( cudaDeviceSynchronize() ); + void LookUpTableImpl::transform(InputArray _src, OutputArray _dst, Stream& _stream) + { + GpuMat src = _src.getGpuMat(); + + const int cn = src.channels(); + + CV_Assert( src.type() == CV_8UC1 || src.type() == CV_8UC3 ); + CV_Assert( lut_cn == 1 || lut_cn == cn ); + + _dst.create(src.size(), src.type()); + GpuMat dst = _dst.getGpuMat(); + + cudaStream_t stream = StreamAccessor::getStream(_stream); + + NppStreamHandler h(stream); + + NppiSize sz; + sz.height = src.rows; + sz.width = src.cols; + + if (src.type() == CV_8UC1) + { + nppSafeCall( nppiLUT_Linear_8u_C1R(src.ptr(), static_cast(src.step), + dst.ptr(), static_cast(dst.step), sz, nppLut.ptr(), pLevels, 256) ); + } + else + { + nppSafeCall( nppiLUT_Linear_8u_C3R(src.ptr(), static_cast(src.step), + dst.ptr(), static_cast(dst.step), sz, pValues3, pLevels3, nValues3) ); + } + + if (stream == 0) + cudaSafeCall( cudaDeviceSynchronize() ); + } +} + +#endif // (CUDA_VERSION >= 5000) + +Ptr cv::gpu::createLookUpTable(InputArray lut) +{ + return new LookUpTableImpl(lut); } //////////////////////////////////////////////////////////////////////// @@ -408,14 +529,17 @@ typedef Npp32s __attribute__((__may_alias__)) Npp32s_a; typedef Npp32s Npp32s_a; #endif -void cv::gpu::copyMakeBorder(const GpuMat& src, GpuMat& dst, int top, int bottom, int left, int right, int borderType, const Scalar& value, Stream& s) +void cv::gpu::copyMakeBorder(InputArray _src, OutputArray _dst, int top, int bottom, int left, int right, int borderType, Scalar value, Stream& _stream) { - CV_Assert(src.depth() <= CV_32F && src.channels() <= 4); - CV_Assert(borderType == BORDER_REFLECT_101 || borderType == BORDER_REPLICATE || borderType == BORDER_CONSTANT || borderType == BORDER_REFLECT || borderType == BORDER_WRAP); + GpuMat src = _src.getGpuMat(); - dst.create(src.rows + top + bottom, src.cols + left + right, src.type()); + CV_Assert( src.depth() <= CV_32F && src.channels() <= 4 ); + CV_Assert( borderType == BORDER_REFLECT_101 || borderType == BORDER_REPLICATE || borderType == BORDER_CONSTANT || borderType == BORDER_REFLECT || borderType == BORDER_WRAP ); - cudaStream_t stream = StreamAccessor::getStream(s); + _dst.create(src.rows + top + bottom, src.cols + left + right, src.type()); + GpuMat dst = _dst.getGpuMat(); + + cudaStream_t stream = StreamAccessor::getStream(_stream); if (borderType == BORDER_CONSTANT && (src.type() == CV_8UC1 || src.type() == CV_8UC4 || src.type() == CV_32SC1 || src.type() == CV_32FC1)) { diff --git a/modules/gpuarithm/src/cuda/div_inv.cu b/modules/gpuarithm/src/cuda/div_inv.cu deleted file mode 100644 index 9cfda933c7..0000000000 --- a/modules/gpuarithm/src/cuda/div_inv.cu +++ /dev/null @@ -1,144 +0,0 @@ -/*M/////////////////////////////////////////////////////////////////////////////////////// -// -// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. -// -// By downloading, copying, installing or using the software you agree to this license. -// If you do not agree to this license, do not download, install, -// copy or use the software. -// -// -// License Agreement -// For Open Source Computer Vision Library -// -// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. -// Copyright (C) 2009, Willow Garage Inc., all rights reserved. -// Third party copyrights are property of their respective owners. -// -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistribution's of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistribution's in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * The name of the copyright holders may not be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// This software is provided by the copyright holders and contributors "as is" and -// any express or implied warranties, including, but not limited to, the implied -// warranties of merchantability and fitness for a particular purpose are disclaimed. -// In no event shall the Intel Corporation or contributors be liable for any direct, -// indirect, incidental, special, exemplary, or consequential damages -// (including, but not limited to, procurement of substitute goods or services; -// loss of use, data, or profits; or business interruption) however caused -// and on any theory of liability, whether in contract, strict liability, -// or tort (including negligence or otherwise) arising in any way out of -// the use of this software, even if advised of the possibility of such damage. -// -//M*/ - -#if !defined CUDA_DISABLER - -#include "opencv2/core/cuda/common.hpp" -#include "opencv2/core/cuda/functional.hpp" -#include "opencv2/core/cuda/transform.hpp" -#include "opencv2/core/cuda/saturate_cast.hpp" -#include "opencv2/core/cuda/simd_functions.hpp" - -#include "arithm_func_traits.hpp" - -using namespace cv::gpu; -using namespace cv::gpu::cudev; - -namespace arithm -{ - template struct DivInv : unary_function - { - S val; - - __host__ explicit DivInv(S val_) : val(val_) {} - - __device__ __forceinline__ D operator ()(T a) const - { - return a != 0 ? saturate_cast(val / a) : 0; - } - }; -} - -namespace cv { namespace gpu { namespace cudev -{ - template struct TransformFunctorTraits< arithm::DivInv > : arithm::ArithmFuncTraits - { - }; -}}} - -namespace arithm -{ - template - void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream) - { - DivInv op(static_cast(val)); - cudev::transform((PtrStepSz) src1, (PtrStepSz) dst, op, WithOutMask(), stream); - } - - template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - - template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - - //template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - //template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - - //template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - //template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - - //template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - //template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - //template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - //template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - - //template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - //template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - //template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - //template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - //template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - - //template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - //template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - //template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - //template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - //template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - //template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); -} - -#endif // CUDA_DISABLER diff --git a/modules/gpuarithm/src/cuda/div_scalar.cu b/modules/gpuarithm/src/cuda/div_scalar.cu index 42ba90cb0c..464c4adf87 100644 --- a/modules/gpuarithm/src/cuda/div_scalar.cu +++ b/modules/gpuarithm/src/cuda/div_scalar.cu @@ -66,6 +66,18 @@ namespace arithm return saturate_cast(a / val); } }; + + template struct DivScalarInv : unary_function + { + S val; + + explicit DivScalarInv(S val_) : val(val_) {} + + __device__ __forceinline__ D operator ()(T a) const + { + return a != 0 ? saturate_cast(val / a) : 0; + } + }; } namespace cv { namespace gpu { namespace cudev @@ -73,72 +85,84 @@ namespace cv { namespace gpu { namespace cudev template struct TransformFunctorTraits< arithm::DivScalar > : arithm::ArithmFuncTraits { }; + + template struct TransformFunctorTraits< arithm::DivScalarInv > : arithm::ArithmFuncTraits + { + }; }}} namespace arithm { template - void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream) + void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream) { - DivScalar op(static_cast(val)); - cudev::transform((PtrStepSz) src1, (PtrStepSz) dst, op, WithOutMask(), stream); + if (inv) + { + DivScalarInv op(static_cast(val)); + cudev::transform((PtrStepSz) src1, (PtrStepSz) dst, op, WithOutMask(), stream); + } + else + { + DivScalar op(static_cast(val)); + cudev::transform((PtrStepSz) src1, (PtrStepSz) dst, op, WithOutMask(), stream); + } } - template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); + template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); - template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); + template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); - //template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - //template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); + //template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + //template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); - //template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - //template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); + //template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + //template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); - //template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - //template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - //template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - //template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); + //template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + //template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + //template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + //template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); - //template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - //template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - //template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - //template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - //template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); + //template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + //template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + //template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + //template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + //template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); - //template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - //template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - //template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - //template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - //template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - //template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - template void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); + //template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + //template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + //template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + //template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + //template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + //template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); + template void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); } #endif // CUDA_DISABLER diff --git a/modules/gpuarithm/src/cuda/split_merge.cu b/modules/gpuarithm/src/cuda/split_merge.cu index 93aea3791a..388441c634 100644 --- a/modules/gpuarithm/src/cuda/split_merge.cu +++ b/modules/gpuarithm/src/cuda/split_merge.cu @@ -278,7 +278,7 @@ namespace cv { namespace gpu { namespace cudev } - void merge_caller(const PtrStepSzb* src, PtrStepSzb& dst, + void merge(const PtrStepSzb* src, PtrStepSzb& dst, int total_channels, size_t elem_size, const cudaStream_t& stream) { @@ -487,7 +487,7 @@ namespace cv { namespace gpu { namespace cudev } - void split_caller(const PtrStepSzb& src, PtrStepSzb* dst, int num_channels, size_t elem_size1, const cudaStream_t& stream) + void split(const PtrStepSzb& src, PtrStepSzb* dst, int num_channels, size_t elem_size1, const cudaStream_t& stream) { static SplitFunction split_func_tbl[] = { diff --git a/modules/gpuarithm/src/cuda/sub_scalar.cu b/modules/gpuarithm/src/cuda/sub_scalar.cu index 05c0cc703b..619ab4310f 100644 --- a/modules/gpuarithm/src/cuda/sub_scalar.cu +++ b/modules/gpuarithm/src/cuda/sub_scalar.cu @@ -58,12 +58,13 @@ namespace arithm template struct SubScalar : unary_function { S val; + int scale; - __host__ explicit SubScalar(S val_) : val(val_) {} + __host__ SubScalar(S val_, int scale_) : val(val_), scale(scale_) {} __device__ __forceinline__ D operator ()(T a) const { - return saturate_cast(a - val); + return saturate_cast(scale * (a - val)); } }; } @@ -78,9 +79,9 @@ namespace cv { namespace gpu { namespace cudev namespace arithm { template - void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream) + void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream) { - SubScalar op(static_cast(val)); + SubScalar op(static_cast(val), inv ? -1 : 1); if (mask.data) cudev::transform((PtrStepSz) src1, (PtrStepSz) dst, op, mask, stream); @@ -88,61 +89,61 @@ namespace arithm cudev::transform((PtrStepSz) src1, (PtrStepSz) dst, op, WithOutMask(), stream); } - template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - //template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - //template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + //template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + //template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - //template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - //template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + //template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + //template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - //template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - //template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - //template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - //template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + //template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + //template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + //template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + //template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - //template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - //template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - //template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - //template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - //template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + //template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + //template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + //template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + //template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + //template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - //template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - //template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - //template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - //template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - //template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - //template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); - template void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + //template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + //template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + //template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + //template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + //template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + //template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + template void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); } #endif // CUDA_DISABLER diff --git a/modules/gpuarithm/src/element_operations.cpp b/modules/gpuarithm/src/element_operations.cpp index e818331061..3ec4f84f66 100644 --- a/modules/gpuarithm/src/element_operations.cpp +++ b/modules/gpuarithm/src/element_operations.cpp @@ -47,76 +47,119 @@ using namespace cv::gpu; #if !defined (HAVE_CUDA) || defined (CUDA_DISABLER) -void cv::gpu::add(const GpuMat&, const GpuMat&, GpuMat&, const GpuMat&, int, Stream&) { throw_no_cuda(); } -void cv::gpu::add(const GpuMat&, const Scalar&, GpuMat&, const GpuMat&, int, Stream&) { throw_no_cuda(); } +void cv::gpu::add(InputArray, InputArray, OutputArray, InputArray, int, Stream&) { throw_no_cuda(); } +void cv::gpu::subtract(InputArray, InputArray, OutputArray, InputArray, int, Stream&) { throw_no_cuda(); } +void cv::gpu::multiply(InputArray, InputArray, OutputArray, double, int, Stream&) { throw_no_cuda(); } +void cv::gpu::divide(InputArray, InputArray, OutputArray, double, int, Stream&) { throw_no_cuda(); } +void cv::gpu::absdiff(InputArray, InputArray, OutputArray, Stream&) { throw_no_cuda(); } -void cv::gpu::subtract(const GpuMat&, const GpuMat&, GpuMat&, const GpuMat&, int, Stream&) { throw_no_cuda(); } -void cv::gpu::subtract(const GpuMat&, const Scalar&, GpuMat&, const GpuMat&, int, Stream&) { throw_no_cuda(); } +void cv::gpu::abs(InputArray, OutputArray, Stream&) { throw_no_cuda(); } +void cv::gpu::sqr(InputArray, OutputArray, Stream&) { throw_no_cuda(); } +void cv::gpu::sqrt(InputArray, OutputArray, Stream&) { throw_no_cuda(); } +void cv::gpu::exp(InputArray, OutputArray, Stream&) { throw_no_cuda(); } +void cv::gpu::log(InputArray, OutputArray, Stream&) { throw_no_cuda(); } +void cv::gpu::pow(InputArray, double, OutputArray, Stream&) { throw_no_cuda(); } -void cv::gpu::multiply(const GpuMat&, const GpuMat&, GpuMat&, double, int, Stream&) { throw_no_cuda(); } -void cv::gpu::multiply(const GpuMat&, const Scalar&, GpuMat&, double, int, Stream&) { throw_no_cuda(); } +void cv::gpu::compare(InputArray, InputArray, OutputArray, int, Stream&) { throw_no_cuda(); } -void cv::gpu::divide(const GpuMat&, const GpuMat&, GpuMat&, double, int, Stream&) { throw_no_cuda(); } -void cv::gpu::divide(const GpuMat&, const Scalar&, GpuMat&, double, int, Stream&) { throw_no_cuda(); } -void cv::gpu::divide(double, const GpuMat&, GpuMat&, int, Stream&) { throw_no_cuda(); } +void cv::gpu::bitwise_not(InputArray, OutputArray, InputArray, Stream&) { throw_no_cuda(); } +void cv::gpu::bitwise_or(InputArray, InputArray, OutputArray, InputArray, Stream&) { throw_no_cuda(); } +void cv::gpu::bitwise_and(InputArray, InputArray, OutputArray, InputArray, Stream&) { throw_no_cuda(); } +void cv::gpu::bitwise_xor(InputArray, InputArray, OutputArray, InputArray, Stream&) { throw_no_cuda(); } -void cv::gpu::absdiff(const GpuMat&, const GpuMat&, GpuMat&, Stream&) { throw_no_cuda(); } -void cv::gpu::absdiff(const GpuMat&, const Scalar&, GpuMat&, Stream&) { throw_no_cuda(); } +void cv::gpu::rshift(InputArray, Scalar_, OutputArray, Stream&) { throw_no_cuda(); } +void cv::gpu::lshift(InputArray, Scalar_, OutputArray, Stream&) { throw_no_cuda(); } -void cv::gpu::abs(const GpuMat&, GpuMat&, Stream&) { throw_no_cuda(); } +void cv::gpu::min(InputArray, InputArray, OutputArray, Stream&) { throw_no_cuda(); } +void cv::gpu::max(InputArray, InputArray, OutputArray, Stream&) { throw_no_cuda(); } -void cv::gpu::sqr(const GpuMat&, GpuMat&, Stream&) { throw_no_cuda(); } +void cv::gpu::addWeighted(InputArray, double, InputArray, double, double, OutputArray, int, Stream&) { throw_no_cuda(); } -void cv::gpu::sqrt(const GpuMat&, GpuMat&, Stream&) { throw_no_cuda(); } +double cv::gpu::threshold(InputArray, OutputArray, double, double, int, Stream&) {throw_no_cuda(); return 0.0;} -void cv::gpu::exp(const GpuMat&, GpuMat&, Stream&) { throw_no_cuda(); } - -void cv::gpu::log(const GpuMat&, GpuMat&, Stream&) { throw_no_cuda(); } - -void cv::gpu::pow(const GpuMat&, double, GpuMat&, Stream&) { throw_no_cuda(); } - -void cv::gpu::compare(const GpuMat&, const GpuMat&, GpuMat&, int, Stream&) { throw_no_cuda(); } -void cv::gpu::compare(const GpuMat&, Scalar, GpuMat&, int, Stream&) { throw_no_cuda(); } - -void cv::gpu::bitwise_not(const GpuMat&, GpuMat&, const GpuMat&, Stream&) { throw_no_cuda(); } - -void cv::gpu::bitwise_or(const GpuMat&, const GpuMat&, GpuMat&, const GpuMat&, Stream&) { throw_no_cuda(); } -void cv::gpu::bitwise_or(const GpuMat&, const Scalar&, GpuMat&, Stream&) { throw_no_cuda(); } - -void cv::gpu::bitwise_and(const GpuMat&, const GpuMat&, GpuMat&, const GpuMat&, Stream&) { throw_no_cuda(); } -void cv::gpu::bitwise_and(const GpuMat&, const Scalar&, GpuMat&, Stream&) { throw_no_cuda(); } - -void cv::gpu::bitwise_xor(const GpuMat&, const GpuMat&, GpuMat&, const GpuMat&, Stream&) { throw_no_cuda(); } -void cv::gpu::bitwise_xor(const GpuMat&, const Scalar&, GpuMat&, Stream&) { throw_no_cuda(); } - -void cv::gpu::rshift(const GpuMat&, Scalar_, GpuMat&, Stream&) { throw_no_cuda(); } - -void cv::gpu::lshift(const GpuMat&, Scalar_, GpuMat&, Stream&) { throw_no_cuda(); } - -void cv::gpu::min(const GpuMat&, const GpuMat&, GpuMat&, Stream&) { throw_no_cuda(); } -void cv::gpu::min(const GpuMat&, double, GpuMat&, Stream&) { throw_no_cuda(); } - -void cv::gpu::max(const GpuMat&, const GpuMat&, GpuMat&, Stream&) { throw_no_cuda(); } -void cv::gpu::max(const GpuMat&, double, GpuMat&, Stream&) { throw_no_cuda(); } - -void cv::gpu::addWeighted(const GpuMat&, double, const GpuMat&, double, double, GpuMat&, int, Stream&) { throw_no_cuda(); } - -double cv::gpu::threshold(const GpuMat&, GpuMat&, double, double, int, Stream&) {throw_no_cuda(); return 0.0;} - -void cv::gpu::magnitude(const GpuMat&, GpuMat&, Stream&) { throw_no_cuda(); } -void cv::gpu::magnitude(const GpuMat&, const GpuMat&, GpuMat&, Stream&) { throw_no_cuda(); } - -void cv::gpu::magnitudeSqr(const GpuMat&, GpuMat&, Stream&) { throw_no_cuda(); } -void cv::gpu::magnitudeSqr(const GpuMat&, const GpuMat&, GpuMat&, Stream&) { throw_no_cuda(); } - -void cv::gpu::phase(const GpuMat&, const GpuMat&, GpuMat&, bool, Stream&) { throw_no_cuda(); } - -void cv::gpu::cartToPolar(const GpuMat&, const GpuMat&, GpuMat&, GpuMat&, bool, Stream&) { throw_no_cuda(); } - -void cv::gpu::polarToCart(const GpuMat&, const GpuMat&, GpuMat&, GpuMat&, bool, Stream&) { throw_no_cuda(); } +void cv::gpu::magnitude(InputArray, OutputArray, Stream&) { throw_no_cuda(); } +void cv::gpu::magnitude(InputArray, InputArray, OutputArray, Stream&) { throw_no_cuda(); } +void cv::gpu::magnitudeSqr(InputArray, OutputArray, Stream&) { throw_no_cuda(); } +void cv::gpu::magnitudeSqr(InputArray, InputArray, OutputArray, Stream&) { throw_no_cuda(); } +void cv::gpu::phase(InputArray, InputArray, OutputArray, bool, Stream&) { throw_no_cuda(); } +void cv::gpu::cartToPolar(InputArray, InputArray, OutputArray, OutputArray, bool, Stream&) { throw_no_cuda(); } +void cv::gpu::polarToCart(InputArray, InputArray, OutputArray, OutputArray, bool, Stream&) { throw_no_cuda(); } #else +//////////////////////////////////////////////////////////////////////// +// arithm_op + +namespace +{ + typedef void (*mat_mat_func_t)(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, const GpuMat& mask, double scale, Stream& stream, int op); + typedef void (*mat_scalar_func_t)(const GpuMat& src, Scalar val, bool inv, GpuMat& dst, const GpuMat& mask, double scale, Stream& stream, int op); + + void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst, InputArray _mask, double scale, int dtype, Stream& stream, + mat_mat_func_t mat_mat_func, mat_scalar_func_t mat_scalar_func, int op = 0) + { + const int kind1 = _src1.kind(); + const int kind2 = _src2.kind(); + + const bool isScalar1 = (kind1 == _InputArray::MATX); + const bool isScalar2 = (kind2 == _InputArray::MATX); + CV_Assert( !isScalar1 || !isScalar2 ); + + GpuMat src1; + if (!isScalar1) + src1 = _src1.getGpuMat(); + + GpuMat src2; + if (!isScalar2) + src2 = _src2.getGpuMat(); + + Mat scalar; + if (isScalar1) + scalar = _src1.getMat(); + else if (isScalar2) + scalar = _src2.getMat(); + + Scalar val; + if (!scalar.empty()) + { + CV_Assert( scalar.total() <= 4 ); + scalar.convertTo(Mat_(scalar.rows, scalar.cols, &val[0]), CV_64F); + } + + GpuMat mask = _mask.getGpuMat(); + + const int sdepth = src1.empty() ? src2.depth() : src1.depth(); + const int cn = src1.empty() ? src2.channels() : src1.channels(); + const Size size = src1.empty() ? src2.size() : src1.size(); + + if (dtype < 0) + dtype = sdepth; + + const int ddepth = CV_MAT_DEPTH(dtype); + + CV_Assert( sdepth <= CV_64F && ddepth <= CV_64F ); + CV_Assert( !scalar.empty() || (src2.type() == src1.type() && src2.size() == src1.size()) ); + CV_Assert( mask.empty() || (cn == 1 && mask.size() == size && mask.type() == CV_8UC1) ); + + if (sdepth == CV_64F || ddepth == CV_64F) + { + if (!deviceSupports(NATIVE_DOUBLE)) + CV_Error(Error::StsUnsupportedFormat, "The device doesn't support double"); + } + + _dst.create(size, CV_MAKE_TYPE(ddepth, cn)); + GpuMat dst = _dst.getGpuMat(); + + if (isScalar1) + mat_scalar_func(src2, val, true, dst, mask, scale, stream, op); + else if (isScalar2) + mat_scalar_func(src1, val, false, dst, mask, scale, stream, op); + else + mat_mat_func(src1, src2, dst, mask, scale, stream, op); + } +} + + //////////////////////////////////////////////////////////////////////// // Basic arithmetical operations (add subtract multiply divide) @@ -302,98 +345,81 @@ namespace arithm void addMat(PtrStepSzb src1, PtrStepSzb src2, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); } -void cv::gpu::add(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, const GpuMat& mask, int dtype, Stream& s) +static void addMat(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, const GpuMat& mask, double, Stream& _stream, int) { - using namespace arithm; - typedef void (*func_t)(PtrStepSzb src1, PtrStepSzb src2, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); static const func_t funcs[7][7] = { { - addMat, - addMat, - addMat, - addMat, - addMat, - addMat, - addMat + arithm::addMat, + arithm::addMat, + arithm::addMat, + arithm::addMat, + arithm::addMat, + arithm::addMat, + arithm::addMat }, { - addMat, - addMat, - addMat, - addMat, - addMat, - addMat, - addMat + arithm::addMat, + arithm::addMat, + arithm::addMat, + arithm::addMat, + arithm::addMat, + arithm::addMat, + arithm::addMat }, { - 0 /*addMat*/, - 0 /*addMat*/, - addMat, - addMat, - addMat, - addMat, - addMat + 0 /*arithm::addMat*/, + 0 /*arithm::addMat*/, + arithm::addMat, + arithm::addMat, + arithm::addMat, + arithm::addMat, + arithm::addMat }, { - 0 /*addMat*/, - 0 /*addMat*/, - addMat, - addMat, - addMat, - addMat, - addMat + 0 /*arithm::addMat*/, + 0 /*arithm::addMat*/, + arithm::addMat, + arithm::addMat, + arithm::addMat, + arithm::addMat, + arithm::addMat }, { - 0 /*addMat*/, - 0 /*addMat*/, - 0 /*addMat*/, - 0 /*addMat*/, - addMat, - addMat, - addMat + 0 /*arithm::addMat*/, + 0 /*arithm::addMat*/, + 0 /*arithm::addMat*/, + 0 /*arithm::addMat*/, + arithm::addMat, + arithm::addMat, + arithm::addMat }, { - 0 /*addMat*/, - 0 /*addMat*/, - 0 /*addMat*/, - 0 /*addMat*/, - 0 /*addMat*/, - addMat, - addMat + 0 /*arithm::addMat*/, + 0 /*arithm::addMat*/, + 0 /*arithm::addMat*/, + 0 /*arithm::addMat*/, + 0 /*arithm::addMat*/, + arithm::addMat, + arithm::addMat }, { - 0 /*addMat*/, - 0 /*addMat*/, - 0 /*addMat*/, - 0 /*addMat*/, - 0 /*addMat*/, - 0 /*addMat*/, - addMat + 0 /*arithm::addMat*/, + 0 /*arithm::addMat*/, + 0 /*arithm::addMat*/, + 0 /*arithm::addMat*/, + 0 /*arithm::addMat*/, + 0 /*arithm::addMat*/, + arithm::addMat } }; - if (dtype < 0) - dtype = src1.depth(); - const int sdepth = src1.depth(); - const int ddepth = CV_MAT_DEPTH(dtype); + const int ddepth = dst.depth(); const int cn = src1.channels(); - CV_Assert( sdepth <= CV_64F && ddepth <= CV_64F ); - CV_Assert( src2.type() == src1.type() && src2.size() == src1.size() ); - CV_Assert( mask.empty() || (cn == 1 && mask.size() == src1.size() && mask.type() == CV_8U) ); - - if (sdepth == CV_64F || ddepth == CV_64F) - { - if (!deviceSupports(NATIVE_DOUBLE)) - CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); - } - - dst.create(src1.size(), CV_MAKE_TYPE(ddepth, cn)); - - cudaStream_t stream = StreamAccessor::getStream(s); + cudaStream_t stream = StreamAccessor::getStream(_stream); PtrStepSzb src1_(src1.rows, src1.cols * cn, src1.data, src1.step); PtrStepSzb src2_(src1.rows, src1.cols * cn, src2.data, src2.step); @@ -413,10 +439,10 @@ void cv::gpu::add(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, const Gpu { const int vcols = src1_.cols >> 2; - addMat_v4(PtrStepSz(src1_.rows, vcols, (unsigned int*) src1_.data, src1_.step), - PtrStepSz(src1_.rows, vcols, (unsigned int*) src2_.data, src2_.step), - PtrStepSz(src1_.rows, vcols, (unsigned int*) dst_.data, dst_.step), - stream); + arithm::addMat_v4(PtrStepSz(src1_.rows, vcols, (unsigned int*) src1_.data, src1_.step), + PtrStepSz(src1_.rows, vcols, (unsigned int*) src2_.data, src2_.step), + PtrStepSz(src1_.rows, vcols, (unsigned int*) dst_.data, dst_.step), + stream); return; } @@ -424,10 +450,10 @@ void cv::gpu::add(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, const Gpu { const int vcols = src1_.cols >> 1; - addMat_v2(PtrStepSz(src1_.rows, vcols, (unsigned int*) src1_.data, src1_.step), - PtrStepSz(src1_.rows, vcols, (unsigned int*) src2_.data, src2_.step), - PtrStepSz(src1_.rows, vcols, (unsigned int*) dst_.data, dst_.step), - stream); + arithm::addMat_v2(PtrStepSz(src1_.rows, vcols, (unsigned int*) src1_.data, src1_.step), + PtrStepSz(src1_.rows, vcols, (unsigned int*) src2_.data, src2_.step), + PtrStepSz(src1_.rows, vcols, (unsigned int*) dst_.data, dst_.step), + stream); return; } @@ -448,75 +474,73 @@ namespace arithm void addScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); } -void cv::gpu::add(const GpuMat& src, const Scalar& sc, GpuMat& dst, const GpuMat& mask, int dtype, Stream& s) +static void addScalar(const GpuMat& src, Scalar val, bool, GpuMat& dst, const GpuMat& mask, double, Stream& _stream, int) { - using namespace arithm; - typedef void (*func_t)(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); static const func_t funcs[7][7] = { { - addScalar, - addScalar, - addScalar, - addScalar, - addScalar, - addScalar, - addScalar + arithm::addScalar, + arithm::addScalar, + arithm::addScalar, + arithm::addScalar, + arithm::addScalar, + arithm::addScalar, + arithm::addScalar }, { - addScalar, - addScalar, - addScalar, - addScalar, - addScalar, - addScalar, - addScalar + arithm::addScalar, + arithm::addScalar, + arithm::addScalar, + arithm::addScalar, + arithm::addScalar, + arithm::addScalar, + arithm::addScalar }, { - 0 /*addScalar*/, - 0 /*addScalar*/, - addScalar, - addScalar, - addScalar, - addScalar, - addScalar + 0 /*arithm::addScalar*/, + 0 /*arithm::addScalar*/, + arithm::addScalar, + arithm::addScalar, + arithm::addScalar, + arithm::addScalar, + arithm::addScalar }, { - 0 /*addScalar*/, - 0 /*addScalar*/, - addScalar, - addScalar, - addScalar, - addScalar, - addScalar + 0 /*arithm::addScalar*/, + 0 /*arithm::addScalar*/, + arithm::addScalar, + arithm::addScalar, + arithm::addScalar, + arithm::addScalar, + arithm::addScalar }, { - 0 /*addScalar*/, - 0 /*addScalar*/, - 0 /*addScalar*/, - 0 /*addScalar*/, - addScalar, - addScalar, - addScalar + 0 /*arithm::addScalar*/, + 0 /*arithm::addScalar*/, + 0 /*arithm::addScalar*/, + 0 /*arithm::addScalar*/, + arithm::addScalar, + arithm::addScalar, + arithm::addScalar }, { - 0 /*addScalar*/, - 0 /*addScalar*/, - 0 /*addScalar*/, - 0 /*addScalar*/, - 0 /*addScalar*/, - addScalar, - addScalar + 0 /*arithm::addScalar*/, + 0 /*arithm::addScalar*/, + 0 /*arithm::addScalar*/, + 0 /*arithm::addScalar*/, + 0 /*arithm::addScalar*/, + arithm::addScalar, + arithm::addScalar }, { - 0 /*addScalar*/, - 0 /*addScalar*/, - 0 /*addScalar*/, - 0 /*addScalar*/, - 0 /*addScalar*/, - 0 /*addScalar*/, - addScalar + 0 /*arithm::addScalar*/, + 0 /*arithm::addScalar*/, + 0 /*arithm::addScalar*/, + 0 /*arithm::addScalar*/, + 0 /*arithm::addScalar*/, + 0 /*arithm::addScalar*/, + arithm::addScalar } }; @@ -532,31 +556,16 @@ void cv::gpu::add(const GpuMat& src, const Scalar& sc, GpuMat& dst, const GpuMat {0 , 0 , 0 , 0 } }; - if (dtype < 0) - dtype = src.depth(); - const int sdepth = src.depth(); - const int ddepth = CV_MAT_DEPTH(dtype); + const int ddepth = dst.depth(); const int cn = src.channels(); - CV_Assert( sdepth <= CV_64F && ddepth <= CV_64F ); - CV_Assert( cn <= 4 ); - CV_Assert( mask.empty() || (cn == 1 && mask.size() == src.size() && mask.type() == CV_8U) ); - - if (sdepth == CV_64F || ddepth == CV_64F) - { - if (!deviceSupports(NATIVE_DOUBLE)) - CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); - } - - dst.create(src.size(), CV_MAKE_TYPE(ddepth, cn)); - - cudaStream_t stream = StreamAccessor::getStream(s); + cudaStream_t stream = StreamAccessor::getStream(_stream); const npp_func_t npp_func = npp_funcs[sdepth][cn - 1]; if (ddepth == sdepth && cn > 1 && npp_func != 0) { - npp_func(src, sc, dst, stream); + npp_func(src, val, dst, stream); return; } @@ -567,7 +576,12 @@ void cv::gpu::add(const GpuMat& src, const Scalar& sc, GpuMat& dst, const GpuMat if (!func) CV_Error(cv::Error::StsUnsupportedFormat, "Unsupported combination of source and destination types"); - func(src, sc.val[0], dst, mask, stream); + func(src, val[0], dst, mask, stream); +} + +void cv::gpu::add(InputArray src1, InputArray src2, OutputArray dst, InputArray mask, int dtype, Stream& stream) +{ + arithm_op(src1, src2, dst, mask, 1.0, dtype, stream, addMat, addScalar); } //////////////////////////////////////////////////////////////////////// @@ -582,98 +596,81 @@ namespace arithm void subMat(PtrStepSzb src1, PtrStepSzb src2, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); } -void cv::gpu::subtract(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, const GpuMat& mask, int dtype, Stream& s) +static void subMat(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, const GpuMat& mask, double, Stream& _stream, int) { - using namespace arithm; - typedef void (*func_t)(PtrStepSzb src1, PtrStepSzb src2, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); static const func_t funcs[7][7] = { { - subMat, - subMat, - subMat, - subMat, - subMat, - subMat, - subMat + arithm::subMat, + arithm::subMat, + arithm::subMat, + arithm::subMat, + arithm::subMat, + arithm::subMat, + arithm::subMat }, { - subMat, - subMat, - subMat, - subMat, - subMat, - subMat, - subMat + arithm::subMat, + arithm::subMat, + arithm::subMat, + arithm::subMat, + arithm::subMat, + arithm::subMat, + arithm::subMat }, { - 0 /*subMat*/, - 0 /*subMat*/, - subMat, - subMat, - subMat, - subMat, - subMat + 0 /*arithm::subMat*/, + 0 /*arithm::subMat*/, + arithm::subMat, + arithm::subMat, + arithm::subMat, + arithm::subMat, + arithm::subMat }, { - 0 /*subMat*/, - 0 /*subMat*/, - subMat, - subMat, - subMat, - subMat, - subMat + 0 /*arithm::subMat*/, + 0 /*arithm::subMat*/, + arithm::subMat, + arithm::subMat, + arithm::subMat, + arithm::subMat, + arithm::subMat }, { - 0 /*subMat*/, - 0 /*subMat*/, - 0 /*subMat*/, - 0 /*subMat*/, - subMat, - subMat, - subMat + 0 /*arithm::subMat*/, + 0 /*arithm::subMat*/, + 0 /*arithm::subMat*/, + 0 /*arithm::subMat*/, + arithm::subMat, + arithm::subMat, + arithm::subMat }, { - 0 /*subMat*/, - 0 /*subMat*/, - 0 /*subMat*/, - 0 /*subMat*/, - 0 /*subMat*/, - subMat, - subMat + 0 /*arithm::subMat*/, + 0 /*arithm::subMat*/, + 0 /*arithm::subMat*/, + 0 /*arithm::subMat*/, + 0 /*arithm::subMat*/, + arithm::subMat, + arithm::subMat }, { - 0 /*subMat*/, - 0 /*subMat*/, - 0 /*subMat*/, - 0 /*subMat*/, - 0 /*subMat*/, - 0 /*subMat*/, - subMat + 0 /*arithm::subMat*/, + 0 /*arithm::subMat*/, + 0 /*arithm::subMat*/, + 0 /*arithm::subMat*/, + 0 /*arithm::subMat*/, + 0 /*arithm::subMat*/, + arithm::subMat } }; - if (dtype < 0) - dtype = src1.depth(); - const int sdepth = src1.depth(); - const int ddepth = CV_MAT_DEPTH(dtype); + const int ddepth = dst.depth(); const int cn = src1.channels(); - CV_Assert( sdepth <= CV_64F && ddepth <= CV_64F ); - CV_Assert( src2.type() == src1.type() && src2.size() == src1.size() ); - CV_Assert( mask.empty() || (cn == 1 && mask.size() == src1.size() && mask.type() == CV_8U) ); - - if (sdepth == CV_64F || ddepth == CV_64F) - { - if (!deviceSupports(NATIVE_DOUBLE)) - CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); - } - - dst.create(src1.size(), CV_MAKE_TYPE(ddepth, cn)); - - cudaStream_t stream = StreamAccessor::getStream(s); + cudaStream_t stream = StreamAccessor::getStream(_stream); PtrStepSzb src1_(src1.rows, src1.cols * cn, src1.data, src1.step); PtrStepSzb src2_(src1.rows, src1.cols * cn, src2.data, src2.step); @@ -693,10 +690,10 @@ void cv::gpu::subtract(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, cons { const int vcols = src1_.cols >> 2; - subMat_v4(PtrStepSz(src1_.rows, vcols, (unsigned int*) src1_.data, src1_.step), - PtrStepSz(src1_.rows, vcols, (unsigned int*) src2_.data, src2_.step), - PtrStepSz(src1_.rows, vcols, (unsigned int*) dst_.data, dst_.step), - stream); + arithm::subMat_v4(PtrStepSz(src1_.rows, vcols, (unsigned int*) src1_.data, src1_.step), + PtrStepSz(src1_.rows, vcols, (unsigned int*) src2_.data, src2_.step), + PtrStepSz(src1_.rows, vcols, (unsigned int*) dst_.data, dst_.step), + stream); return; } @@ -704,10 +701,10 @@ void cv::gpu::subtract(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, cons { const int vcols = src1_.cols >> 1; - subMat_v2(PtrStepSz(src1_.rows, vcols, (unsigned int*) src1_.data, src1_.step), - PtrStepSz(src1_.rows, vcols, (unsigned int*) src2_.data, src2_.step), - PtrStepSz(src1_.rows, vcols, (unsigned int*) dst_.data, dst_.step), - stream); + arithm::subMat_v2(PtrStepSz(src1_.rows, vcols, (unsigned int*) src1_.data, src1_.step), + PtrStepSz(src1_.rows, vcols, (unsigned int*) src2_.data, src2_.step), + PtrStepSz(src1_.rows, vcols, (unsigned int*) dst_.data, dst_.step), + stream); return; } @@ -725,78 +722,76 @@ void cv::gpu::subtract(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, cons namespace arithm { template - void subScalar(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + void subScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); } -void cv::gpu::subtract(const GpuMat& src, const Scalar& sc, GpuMat& dst, const GpuMat& mask, int dtype, Stream& s) +static void subScalar(const GpuMat& src, Scalar val, bool inv, GpuMat& dst, const GpuMat& mask, double, Stream& _stream, int) { - using namespace arithm; - - typedef void (*func_t)(PtrStepSzb src1, double val, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + typedef void (*func_t)(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); static const func_t funcs[7][7] = { { - subScalar, - subScalar, - subScalar, - subScalar, - subScalar, - subScalar, - subScalar + arithm::subScalar, + arithm::subScalar, + arithm::subScalar, + arithm::subScalar, + arithm::subScalar, + arithm::subScalar, + arithm::subScalar }, { - subScalar, - subScalar, - subScalar, - subScalar, - subScalar, - subScalar, - subScalar + arithm::subScalar, + arithm::subScalar, + arithm::subScalar, + arithm::subScalar, + arithm::subScalar, + arithm::subScalar, + arithm::subScalar }, { - 0 /*subScalar*/, - 0 /*subScalar*/, - subScalar, - subScalar, - subScalar, - subScalar, - subScalar + 0 /*arithm::subScalar*/, + 0 /*arithm::subScalar*/, + arithm::subScalar, + arithm::subScalar, + arithm::subScalar, + arithm::subScalar, + arithm::subScalar }, { - 0 /*subScalar*/, - 0 /*subScalar*/, - subScalar, - subScalar, - subScalar, - subScalar, - subScalar + 0 /*arithm::subScalar*/, + 0 /*arithm::subScalar*/, + arithm::subScalar, + arithm::subScalar, + arithm::subScalar, + arithm::subScalar, + arithm::subScalar }, { - 0 /*subScalar*/, - 0 /*subScalar*/, - 0 /*subScalar*/, - 0 /*subScalar*/, - subScalar, - subScalar, - subScalar + 0 /*arithm::subScalar*/, + 0 /*arithm::subScalar*/, + 0 /*arithm::subScalar*/, + 0 /*arithm::subScalar*/, + arithm::subScalar, + arithm::subScalar, + arithm::subScalar }, { - 0 /*subScalar*/, - 0 /*subScalar*/, - 0 /*subScalar*/, - 0 /*subScalar*/, - 0 /*subScalar*/, - subScalar, - subScalar + 0 /*arithm::subScalar*/, + 0 /*arithm::subScalar*/, + 0 /*arithm::subScalar*/, + 0 /*arithm::subScalar*/, + 0 /*arithm::subScalar*/, + arithm::subScalar, + arithm::subScalar }, { - 0 /*subScalar*/, - 0 /*subScalar*/, - 0 /*subScalar*/, - 0 /*subScalar*/, - 0 /*subScalar*/, - 0 /*subScalar*/, - subScalar + 0 /*arithm::subScalar*/, + 0 /*arithm::subScalar*/, + 0 /*arithm::subScalar*/, + 0 /*arithm::subScalar*/, + 0 /*arithm::subScalar*/, + 0 /*arithm::subScalar*/, + arithm::subScalar } }; @@ -812,31 +807,16 @@ void cv::gpu::subtract(const GpuMat& src, const Scalar& sc, GpuMat& dst, const G {0 , 0 , 0 , 0 } }; - if (dtype < 0) - dtype = src.depth(); - const int sdepth = src.depth(); - const int ddepth = CV_MAT_DEPTH(dtype); + const int ddepth = dst.depth(); const int cn = src.channels(); - CV_Assert( sdepth <= CV_64F && ddepth <= CV_64F ); - CV_Assert( cn <= 4 ); - CV_Assert( mask.empty() || (cn == 1 && mask.size() == src.size() && mask.type() == CV_8U) ); - - if (sdepth == CV_64F || ddepth == CV_64F) - { - if (!deviceSupports(NATIVE_DOUBLE)) - CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); - } - - dst.create(src.size(), CV_MAKE_TYPE(ddepth, cn)); - - cudaStream_t stream = StreamAccessor::getStream(s); + cudaStream_t stream = StreamAccessor::getStream(_stream); const npp_func_t npp_func = npp_funcs[sdepth][cn - 1]; - if (ddepth == sdepth && cn > 1 && npp_func != 0) + if (ddepth == sdepth && cn > 1 && npp_func != 0 && !inv) { - npp_func(src, sc, dst, stream); + npp_func(src, val, dst, stream); return; } @@ -847,7 +827,12 @@ void cv::gpu::subtract(const GpuMat& src, const Scalar& sc, GpuMat& dst, const G if (!func) CV_Error(cv::Error::StsUnsupportedFormat, "Unsupported combination of source and destination types"); - func(src, sc.val[0], dst, mask, stream); + func(src, val[0], inv, dst, mask, stream); +} + +void cv::gpu::subtract(InputArray src1, InputArray src2, OutputArray dst, InputArray mask, int dtype, Stream& stream) +{ + arithm_op(src1, src2, dst, mask, 1.0, dtype, stream, subMat, subScalar); } //////////////////////////////////////////////////////////////////////// @@ -863,127 +848,92 @@ namespace arithm void mulMat(PtrStepSzb src1, PtrStepSzb src2, PtrStepSzb dst, double scale, cudaStream_t stream); } -void cv::gpu::multiply(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, double scale, int dtype, Stream& s) +static void mulMat(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, const GpuMat&, double scale, Stream& _stream, int) { - using namespace arithm; - - cudaStream_t stream = StreamAccessor::getStream(s); - - if (src1.type() == CV_8UC4 && src2.type() == CV_32FC1) + typedef void (*func_t)(PtrStepSzb src1, PtrStepSzb src2, PtrStepSzb dst, double scale, cudaStream_t stream); + static const func_t funcs[7][7] = { - CV_Assert( src1.size() == src2.size() ); - - dst.create(src1.size(), src1.type()); - - mulMat_8uc4_32f(src1, src2, dst, stream); - } - else if (src1.type() == CV_16SC4 && src2.type() == CV_32FC1) - { - CV_Assert( src1.size() == src2.size() ); - - dst.create(src1.size(), src1.type()); - - mulMat_16sc4_32f(src1, src2, dst, stream); - } - else - { - typedef void (*func_t)(PtrStepSzb src1, PtrStepSzb src2, PtrStepSzb dst, double scale, cudaStream_t stream); - static const func_t funcs[7][7] = { - { - mulMat, - mulMat, - mulMat, - mulMat, - mulMat, - mulMat, - mulMat - }, - { - mulMat, - mulMat, - mulMat, - mulMat, - mulMat, - mulMat, - mulMat - }, - { - 0 /*mulMat*/, - 0 /*mulMat*/, - mulMat, - mulMat, - mulMat, - mulMat, - mulMat - }, - { - 0 /*mulMat*/, - 0 /*mulMat*/, - mulMat, - mulMat, - mulMat, - mulMat, - mulMat - }, - { - 0 /*mulMat*/, - 0 /*mulMat*/, - 0 /*mulMat*/, - 0 /*mulMat*/, - mulMat, - mulMat, - mulMat - }, - { - 0 /*mulMat*/, - 0 /*mulMat*/, - 0 /*mulMat*/, - 0 /*mulMat*/, - 0 /*mulMat*/, - mulMat, - mulMat - }, - { - 0 /*mulMat*/, - 0 /*mulMat*/, - 0 /*mulMat*/, - 0 /*mulMat*/, - 0 /*mulMat*/, - 0 /*mulMat*/, - mulMat - } - }; - - if (dtype < 0) - dtype = src1.depth(); - - const int sdepth = src1.depth(); - const int ddepth = CV_MAT_DEPTH(dtype); - const int cn = src1.channels(); - - CV_Assert( sdepth <= CV_64F && ddepth <= CV_64F ); - CV_Assert( src2.type() == src1.type() && src2.size() == src1.size() ); - - if (sdepth == CV_64F || ddepth == CV_64F) + arithm::mulMat, + arithm::mulMat, + arithm::mulMat, + arithm::mulMat, + arithm::mulMat, + arithm::mulMat, + arithm::mulMat + }, { - if (!deviceSupports(NATIVE_DOUBLE)) - CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); + arithm::mulMat, + arithm::mulMat, + arithm::mulMat, + arithm::mulMat, + arithm::mulMat, + arithm::mulMat, + arithm::mulMat + }, + { + 0 /*arithm::mulMat*/, + 0 /*arithm::mulMat*/, + arithm::mulMat, + arithm::mulMat, + arithm::mulMat, + arithm::mulMat, + arithm::mulMat + }, + { + 0 /*arithm::mulMat*/, + 0 /*arithm::mulMat*/, + arithm::mulMat, + arithm::mulMat, + arithm::mulMat, + arithm::mulMat, + arithm::mulMat + }, + { + 0 /*arithm::mulMat*/, + 0 /*arithm::mulMat*/, + 0 /*arithm::mulMat*/, + 0 /*arithm::mulMat*/, + arithm::mulMat, + arithm::mulMat, + arithm::mulMat + }, + { + 0 /*arithm::mulMat*/, + 0 /*arithm::mulMat*/, + 0 /*arithm::mulMat*/, + 0 /*arithm::mulMat*/, + 0 /*arithm::mulMat*/, + arithm::mulMat, + arithm::mulMat + }, + { + 0 /*arithm::mulMat*/, + 0 /*arithm::mulMat*/, + 0 /*arithm::mulMat*/, + 0 /*arithm::mulMat*/, + 0 /*arithm::mulMat*/, + 0 /*arithm::mulMat*/, + arithm::mulMat } + }; - dst.create(src1.size(), CV_MAKE_TYPE(ddepth, cn)); + const int sdepth = src1.depth(); + const int ddepth = dst.depth(); + const int cn = src1.channels(); - PtrStepSzb src1_(src1.rows, src1.cols * cn, src1.data, src1.step); - PtrStepSzb src2_(src1.rows, src1.cols * cn, src2.data, src2.step); - PtrStepSzb dst_(src1.rows, src1.cols * cn, dst.data, dst.step); + cudaStream_t stream = StreamAccessor::getStream(_stream); - const func_t func = funcs[sdepth][ddepth]; + PtrStepSzb src1_(src1.rows, src1.cols * cn, src1.data, src1.step); + PtrStepSzb src2_(src1.rows, src1.cols * cn, src2.data, src2.step); + PtrStepSzb dst_(src1.rows, src1.cols * cn, dst.data, dst.step); - if (!func) - CV_Error(cv::Error::StsUnsupportedFormat, "Unsupported combination of source and destination types"); + const func_t func = funcs[sdepth][ddepth]; - func(src1_, src2_, dst_, scale, stream); - } + if (!func) + CV_Error(cv::Error::StsUnsupportedFormat, "Unsupported combination of source and destination types"); + + func(src1_, src2_, dst_, scale, stream); } namespace arithm @@ -992,75 +942,73 @@ namespace arithm void mulScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); } -void cv::gpu::multiply(const GpuMat& src, const Scalar& sc, GpuMat& dst, double scale, int dtype, Stream& s) +static void mulScalar(const GpuMat& src, Scalar val, bool, GpuMat& dst, const GpuMat&, double scale, Stream& _stream, int) { - using namespace arithm; - typedef void (*func_t)(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); static const func_t funcs[7][7] = { { - mulScalar, - mulScalar, - mulScalar, - mulScalar, - mulScalar, - mulScalar, - mulScalar + arithm::mulScalar, + arithm::mulScalar, + arithm::mulScalar, + arithm::mulScalar, + arithm::mulScalar, + arithm::mulScalar, + arithm::mulScalar }, { - mulScalar, - mulScalar, - mulScalar, - mulScalar, - mulScalar, - mulScalar, - mulScalar + arithm::mulScalar, + arithm::mulScalar, + arithm::mulScalar, + arithm::mulScalar, + arithm::mulScalar, + arithm::mulScalar, + arithm::mulScalar }, { - 0 /*mulScalar*/, - 0 /*mulScalar*/, - mulScalar, - mulScalar, - mulScalar, - mulScalar, - mulScalar + 0 /*arithm::mulScalar*/, + 0 /*arithm::mulScalar*/, + arithm::mulScalar, + arithm::mulScalar, + arithm::mulScalar, + arithm::mulScalar, + arithm::mulScalar }, { - 0 /*mulScalar*/, - 0 /*mulScalar*/, - mulScalar, - mulScalar, - mulScalar, - mulScalar, - mulScalar + 0 /*arithm::mulScalar*/, + 0 /*arithm::mulScalar*/, + arithm::mulScalar, + arithm::mulScalar, + arithm::mulScalar, + arithm::mulScalar, + arithm::mulScalar }, { - 0 /*mulScalar*/, - 0 /*mulScalar*/, - 0 /*mulScalar*/, - 0 /*mulScalar*/, - mulScalar, - mulScalar, - mulScalar + 0 /*arithm::mulScalar*/, + 0 /*arithm::mulScalar*/, + 0 /*arithm::mulScalar*/, + 0 /*arithm::mulScalar*/, + arithm::mulScalar, + arithm::mulScalar, + arithm::mulScalar }, { - 0 /*mulScalar*/, - 0 /*mulScalar*/, - 0 /*mulScalar*/, - 0 /*mulScalar*/, - 0 /*mulScalar*/, - mulScalar, - mulScalar + 0 /*arithm::mulScalar*/, + 0 /*arithm::mulScalar*/, + 0 /*arithm::mulScalar*/, + 0 /*arithm::mulScalar*/, + 0 /*arithm::mulScalar*/, + arithm::mulScalar, + arithm::mulScalar }, { - 0 /*mulScalar*/, - 0 /*mulScalar*/, - 0 /*mulScalar*/, - 0 /*mulScalar*/, - 0 /*mulScalar*/, - 0 /*mulScalar*/, - mulScalar + 0 /*arithm::mulScalar*/, + 0 /*arithm::mulScalar*/, + 0 /*arithm::mulScalar*/, + 0 /*arithm::mulScalar*/, + 0 /*arithm::mulScalar*/, + 0 /*arithm::mulScalar*/, + arithm::mulScalar } }; @@ -1076,32 +1024,21 @@ void cv::gpu::multiply(const GpuMat& src, const Scalar& sc, GpuMat& dst, double {0 , 0, 0 , 0 } }; - if (dtype < 0) - dtype = src.depth(); - const int sdepth = src.depth(); - const int ddepth = CV_MAT_DEPTH(dtype); + const int ddepth = dst.depth(); const int cn = src.channels(); - CV_Assert( sdepth <= CV_64F && ddepth <= CV_64F ); - CV_Assert( cn <= 4 ); + cudaStream_t stream = StreamAccessor::getStream(_stream); - if (sdepth == CV_64F || ddepth == CV_64F) - { - if (!deviceSupports(NATIVE_DOUBLE)) - CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); - } - - dst.create(src.size(), CV_MAKE_TYPE(ddepth, cn)); - - cudaStream_t stream = StreamAccessor::getStream(s); - - const Scalar nsc(sc.val[0] * scale, sc.val[1] * scale, sc.val[2] * scale, sc.val[3] * scale); + val[0] *= scale; + val[1] *= scale; + val[2] *= scale; + val[3] *= scale; const npp_func_t npp_func = npp_funcs[sdepth][cn - 1]; if (ddepth == sdepth && cn > 1 && npp_func != 0) { - npp_func(src, nsc, dst, stream); + npp_func(src, val, dst, stream); return; } @@ -1112,7 +1049,39 @@ void cv::gpu::multiply(const GpuMat& src, const Scalar& sc, GpuMat& dst, double if (!func) CV_Error(cv::Error::StsUnsupportedFormat, "Unsupported combination of source and destination types"); - func(src, nsc.val[0], dst, stream); + func(src, val[0], dst, stream); +} + +void cv::gpu::multiply(InputArray _src1, InputArray _src2, OutputArray _dst, double scale, int dtype, Stream& stream) +{ + if (_src1.type() == CV_8UC4 && _src2.type() == CV_32FC1) + { + GpuMat src1 = _src1.getGpuMat(); + GpuMat src2 = _src2.getGpuMat(); + + CV_Assert( src1.size() == src2.size() ); + + _dst.create(src1.size(), src1.type()); + GpuMat dst = _dst.getGpuMat(); + + arithm::mulMat_8uc4_32f(src1, src2, dst, StreamAccessor::getStream(stream)); + } + else if (_src1.type() == CV_16SC4 && _src2.type() == CV_32FC1) + { + GpuMat src1 = _src1.getGpuMat(); + GpuMat src2 = _src2.getGpuMat(); + + CV_Assert( src1.size() == src2.size() ); + + _dst.create(src1.size(), src1.type()); + GpuMat dst = _dst.getGpuMat(); + + arithm::mulMat_16sc4_32f(src1, src2, dst, StreamAccessor::getStream(stream)); + } + else + { + arithm_op(_src1, _src2, _dst, GpuMat(), scale, dtype, stream, mulMat, mulScalar); + } } //////////////////////////////////////////////////////////////////////// @@ -1128,204 +1097,167 @@ namespace arithm void divMat(PtrStepSzb src1, PtrStepSzb src2, PtrStepSzb dst, double scale, cudaStream_t stream); } -void cv::gpu::divide(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, double scale, int dtype, Stream& s) +static void divMat(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, const GpuMat&, double scale, Stream& _stream, int) { - using namespace arithm; - - cudaStream_t stream = StreamAccessor::getStream(s); - - if (src1.type() == CV_8UC4 && src2.type() == CV_32FC1) + typedef void (*func_t)(PtrStepSzb src1, PtrStepSzb src2, PtrStepSzb dst, double scale, cudaStream_t stream); + static const func_t funcs[7][7] = { - CV_Assert( src1.size() == src2.size() ); - - dst.create(src1.size(), src1.type()); - - divMat_8uc4_32f(src1, src2, dst, stream); - } - else if (src1.type() == CV_16SC4 && src2.type() == CV_32FC1) - { - CV_Assert( src1.size() == src2.size() ); - - dst.create(src1.size(), src1.type()); - - divMat_16sc4_32f(src1, src2, dst, stream); - } - else - { - typedef void (*func_t)(PtrStepSzb src1, PtrStepSzb src2, PtrStepSzb dst, double scale, cudaStream_t stream); - static const func_t funcs[7][7] = { - { - divMat, - divMat, - divMat, - divMat, - divMat, - divMat, - divMat - }, - { - divMat, - divMat, - divMat, - divMat, - divMat, - divMat, - divMat - }, - { - 0 /*divMat*/, - 0 /*divMat*/, - divMat, - divMat, - divMat, - divMat, - divMat - }, - { - 0 /*divMat*/, - 0 /*divMat*/, - divMat, - divMat, - divMat, - divMat, - divMat - }, - { - 0 /*divMat*/, - 0 /*divMat*/, - 0 /*divMat*/, - 0 /*divMat*/, - divMat, - divMat, - divMat - }, - { - 0 /*divMat*/, - 0 /*divMat*/, - 0 /*divMat*/, - 0 /*divMat*/, - 0 /*divMat*/, - divMat, - divMat - }, - { - 0 /*divMat*/, - 0 /*divMat*/, - 0 /*divMat*/, - 0 /*divMat*/, - 0 /*divMat*/, - 0 /*divMat*/, - divMat - } - }; - - if (dtype < 0) - dtype = src1.depth(); - - const int sdepth = src1.depth(); - const int ddepth = CV_MAT_DEPTH(dtype); - const int cn = src1.channels(); - - CV_Assert( sdepth <= CV_64F && ddepth <= CV_64F ); - CV_Assert( src2.type() == src1.type() && src2.size() == src1.size() ); - - if (sdepth == CV_64F || ddepth == CV_64F) + arithm::divMat, + arithm::divMat, + arithm::divMat, + arithm::divMat, + arithm::divMat, + arithm::divMat, + arithm::divMat + }, { - if (!deviceSupports(NATIVE_DOUBLE)) - CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); + arithm::divMat, + arithm::divMat, + arithm::divMat, + arithm::divMat, + arithm::divMat, + arithm::divMat, + arithm::divMat + }, + { + 0 /*arithm::divMat*/, + 0 /*arithm::divMat*/, + arithm::divMat, + arithm::divMat, + arithm::divMat, + arithm::divMat, + arithm::divMat + }, + { + 0 /*arithm::divMat*/, + 0 /*arithm::divMat*/, + arithm::divMat, + arithm::divMat, + arithm::divMat, + arithm::divMat, + arithm::divMat + }, + { + 0 /*arithm::divMat*/, + 0 /*arithm::divMat*/, + 0 /*arithm::divMat*/, + 0 /*arithm::divMat*/, + arithm::divMat, + arithm::divMat, + arithm::divMat + }, + { + 0 /*arithm::divMat*/, + 0 /*arithm::divMat*/, + 0 /*arithm::divMat*/, + 0 /*arithm::divMat*/, + 0 /*arithm::divMat*/, + arithm::divMat, + arithm::divMat + }, + { + 0 /*arithm::divMat*/, + 0 /*arithm::divMat*/, + 0 /*arithm::divMat*/, + 0 /*arithm::divMat*/, + 0 /*arithm::divMat*/, + 0 /*arithm::divMat*/, + arithm::divMat } + }; - dst.create(src1.size(), CV_MAKE_TYPE(ddepth, cn)); + const int sdepth = src1.depth(); + const int ddepth = dst.depth(); + const int cn = src1.channels(); - PtrStepSzb src1_(src1.rows, src1.cols * cn, src1.data, src1.step); - PtrStepSzb src2_(src1.rows, src1.cols * cn, src2.data, src2.step); - PtrStepSzb dst_(src1.rows, src1.cols * cn, dst.data, dst.step); + cudaStream_t stream = StreamAccessor::getStream(_stream); - const func_t func = funcs[sdepth][ddepth]; + PtrStepSzb src1_(src1.rows, src1.cols * cn, src1.data, src1.step); + PtrStepSzb src2_(src1.rows, src1.cols * cn, src2.data, src2.step); + PtrStepSzb dst_(src1.rows, src1.cols * cn, dst.data, dst.step); - if (!func) - CV_Error(cv::Error::StsUnsupportedFormat, "Unsupported combination of source and destination types"); + const func_t func = funcs[sdepth][ddepth]; - func(src1_, src2_, dst_, scale, stream); - } + if (!func) + CV_Error(cv::Error::StsUnsupportedFormat, "Unsupported combination of source and destination types"); + + func(src1_, src2_, dst_, scale, stream); } namespace arithm { template - void divScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); + void divScalar(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); } -void cv::gpu::divide(const GpuMat& src, const Scalar& sc, GpuMat& dst, double scale, int dtype, Stream& s) +static void divScalar(const GpuMat& src, Scalar val, bool inv, GpuMat& dst, const GpuMat&, double scale, Stream& _stream, int) { - using namespace arithm; - - typedef void (*func_t)(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); + typedef void (*func_t)(PtrStepSzb src1, double val, bool inv, PtrStepSzb dst, cudaStream_t stream); static const func_t funcs[7][7] = { { - divScalar, - divScalar, - divScalar, - divScalar, - divScalar, - divScalar, - divScalar + arithm::divScalar, + arithm::divScalar, + arithm::divScalar, + arithm::divScalar, + arithm::divScalar, + arithm::divScalar, + arithm::divScalar }, { - divScalar, - divScalar, - divScalar, - divScalar, - divScalar, - divScalar, - divScalar + arithm::divScalar, + arithm::divScalar, + arithm::divScalar, + arithm::divScalar, + arithm::divScalar, + arithm::divScalar, + arithm::divScalar }, { - 0 /*divScalar*/, - 0 /*divScalar*/, - divScalar, - divScalar, - divScalar, - divScalar, - divScalar + 0 /*arithm::divScalar*/, + 0 /*arithm::divScalar*/, + arithm::divScalar, + arithm::divScalar, + arithm::divScalar, + arithm::divScalar, + arithm::divScalar }, { - 0 /*divScalar*/, - 0 /*divScalar*/, - divScalar, - divScalar, - divScalar, - divScalar, - divScalar + 0 /*arithm::divScalar*/, + 0 /*arithm::divScalar*/, + arithm::divScalar, + arithm::divScalar, + arithm::divScalar, + arithm::divScalar, + arithm::divScalar }, { - 0 /*divScalar*/, - 0 /*divScalar*/, - 0 /*divScalar*/, - 0 /*divScalar*/, - divScalar, - divScalar, - divScalar + 0 /*arithm::divScalar*/, + 0 /*arithm::divScalar*/, + 0 /*arithm::divScalar*/, + 0 /*arithm::divScalar*/, + arithm::divScalar, + arithm::divScalar, + arithm::divScalar }, { - 0 /*divScalar*/, - 0 /*divScalar*/, - 0 /*divScalar*/, - 0 /*divScalar*/, - 0 /*divScalar*/, - divScalar, - divScalar + 0 /*arithm::divScalar*/, + 0 /*arithm::divScalar*/, + 0 /*arithm::divScalar*/, + 0 /*arithm::divScalar*/, + 0 /*arithm::divScalar*/, + arithm::divScalar, + arithm::divScalar }, { - 0 /*divScalar*/, - 0 /*divScalar*/, - 0 /*divScalar*/, - 0 /*divScalar*/, - 0 /*divScalar*/, - 0 /*divScalar*/, - divScalar + 0 /*arithm::divScalar*/, + 0 /*arithm::divScalar*/, + 0 /*arithm::divScalar*/, + 0 /*arithm::divScalar*/, + 0 /*arithm::divScalar*/, + 0 /*arithm::divScalar*/, + arithm::divScalar } }; @@ -1341,32 +1273,31 @@ void cv::gpu::divide(const GpuMat& src, const Scalar& sc, GpuMat& dst, double sc {0 , 0, 0 , 0 } }; - if (dtype < 0) - dtype = src.depth(); - const int sdepth = src.depth(); - const int ddepth = CV_MAT_DEPTH(dtype); + const int ddepth = dst.depth(); const int cn = src.channels(); - CV_Assert( sdepth <= CV_64F && ddepth <= CV_64F ); - CV_Assert( cn <= 4 ); + cudaStream_t stream = StreamAccessor::getStream(_stream); - if (sdepth == CV_64F || ddepth == CV_64F) + if (inv) { - if (!deviceSupports(NATIVE_DOUBLE)) - CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); + val[0] *= scale; + val[1] *= scale; + val[2] *= scale; + val[3] *= scale; + } + else + { + val[0] /= scale; + val[1] /= scale; + val[2] /= scale; + val[3] /= scale; } - dst.create(src.size(), CV_MAKE_TYPE(ddepth, cn)); - - cudaStream_t stream = StreamAccessor::getStream(s); - - const Scalar nsc(sc.val[0] / scale, sc.val[1] / scale, sc.val[2] / scale, sc.val[3] / scale); - const npp_func_t npp_func = npp_funcs[sdepth][cn - 1]; - if (ddepth == sdepth && cn > 1 && npp_func != 0) + if (ddepth == sdepth && cn > 1 && npp_func != 0 && !inv) { - npp_func(src, nsc, dst, stream); + npp_func(src, val, dst, stream); return; } @@ -1377,113 +1308,39 @@ void cv::gpu::divide(const GpuMat& src, const Scalar& sc, GpuMat& dst, double sc if (!func) CV_Error(cv::Error::StsUnsupportedFormat, "Unsupported combination of source and destination types"); - func(src, nsc.val[0], dst, stream); + func(src, val[0], inv, dst, stream); } -namespace arithm +void cv::gpu::divide(InputArray _src1, InputArray _src2, OutputArray _dst, double scale, int dtype, Stream& stream) { - template - void divInv(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); -} - -void cv::gpu::divide(double scale, const GpuMat& src, GpuMat& dst, int dtype, Stream& s) -{ - using namespace arithm; - - typedef void (*func_t)(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); - static const func_t funcs[7][7] = + if (_src1.type() == CV_8UC4 && _src2.type() == CV_32FC1) { - { - divInv, - divInv, - divInv, - divInv, - divInv, - divInv, - divInv - }, - { - divInv, - divInv, - divInv, - divInv, - divInv, - divInv, - divInv - }, - { - 0 /*divInv*/, - 0 /*divInv*/, - divInv, - divInv, - divInv, - divInv, - divInv - }, - { - 0 /*divInv*/, - 0 /*divInv*/, - divInv, - divInv, - divInv, - divInv, - divInv - }, - { - 0 /*divInv*/, - 0 /*divInv*/, - 0 /*divInv*/, - 0 /*divInv*/, - divInv, - divInv, - divInv - }, - { - 0 /*divInv*/, - 0 /*divInv*/, - 0 /*divInv*/, - 0 /*divInv*/, - 0 /*divInv*/, - divInv, - divInv - }, - { - 0 /*divInv*/, - 0 /*divInv*/, - 0 /*divInv*/, - 0 /*divInv*/, - 0 /*divInv*/, - 0 /*divInv*/, - divInv - } - }; + GpuMat src1 = _src1.getGpuMat(); + GpuMat src2 = _src2.getGpuMat(); - if (dtype < 0) - dtype = src.depth(); + CV_Assert( src1.size() == src2.size() ); - const int sdepth = src.depth(); - const int ddepth = CV_MAT_DEPTH(dtype); - const int cn = src.channels(); + _dst.create(src1.size(), src1.type()); + GpuMat dst = _dst.getGpuMat(); - CV_Assert( sdepth <= CV_64F && ddepth <= CV_64F ); - CV_Assert( cn == 1 ); - - if (sdepth == CV_64F || ddepth == CV_64F) - { - if (!deviceSupports(NATIVE_DOUBLE)) - CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); + arithm::divMat_8uc4_32f(src1, src2, dst, StreamAccessor::getStream(stream)); } + else if (_src1.type() == CV_16SC4 && _src2.type() == CV_32FC1) + { + GpuMat src1 = _src1.getGpuMat(); + GpuMat src2 = _src2.getGpuMat(); - dst.create(src.size(), CV_MAKE_TYPE(ddepth, cn)); + CV_Assert( src1.size() == src2.size() ); - cudaStream_t stream = StreamAccessor::getStream(s); + _dst.create(src1.size(), src1.type()); + GpuMat dst = _dst.getGpuMat(); - const func_t func = funcs[sdepth][ddepth]; - - if (!func) - CV_Error(cv::Error::StsUnsupportedFormat, "Unsupported combination of source and destination types"); - - func(src, scale, dst, stream); + arithm::divMat_16sc4_32f(src1, src2, dst, StreamAccessor::getStream(stream)); + } + else + { + arithm_op(_src1, _src2, _dst, GpuMat(), scale, dtype, stream, divMat, divScalar); + } } ////////////////////////////////////////////////////////////////////////////// @@ -1498,37 +1355,24 @@ namespace arithm void absDiffMat(PtrStepSzb src1, PtrStepSzb src2, PtrStepSzb dst, cudaStream_t stream); } -void cv::gpu::absdiff(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, Stream& s) +static void absDiffMat(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, const GpuMat&, double, Stream& _stream, int) { - using namespace arithm; - typedef void (*func_t)(PtrStepSzb src1, PtrStepSzb src2, PtrStepSzb dst, cudaStream_t stream); static const func_t funcs[] = { - absDiffMat, - absDiffMat, - absDiffMat, - absDiffMat, - absDiffMat, - absDiffMat, - absDiffMat + arithm::absDiffMat, + arithm::absDiffMat, + arithm::absDiffMat, + arithm::absDiffMat, + arithm::absDiffMat, + arithm::absDiffMat, + arithm::absDiffMat }; const int depth = src1.depth(); const int cn = src1.channels(); - CV_Assert( depth <= CV_64F ); - CV_Assert( src2.type() == src1.type() && src2.size() == src1.size() ); - - if (depth == CV_64F) - { - if (!deviceSupports(NATIVE_DOUBLE)) - CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); - } - - dst.create(src1.size(), src1.type()); - - cudaStream_t stream = StreamAccessor::getStream(s); + cudaStream_t stream = StreamAccessor::getStream(_stream); PtrStepSzb src1_(src1.rows, src1.cols * cn, src1.data, src1.step); PtrStepSzb src2_(src1.rows, src1.cols * cn, src2.data, src2.step); @@ -1548,10 +1392,10 @@ void cv::gpu::absdiff(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, Strea { const int vcols = src1_.cols >> 2; - absDiffMat_v4(PtrStepSz(src1_.rows, vcols, (unsigned int*) src1_.data, src1_.step), - PtrStepSz(src1_.rows, vcols, (unsigned int*) src2_.data, src2_.step), - PtrStepSz(src1_.rows, vcols, (unsigned int*) dst_.data, dst_.step), - stream); + arithm::absDiffMat_v4(PtrStepSz(src1_.rows, vcols, (unsigned int*) src1_.data, src1_.step), + PtrStepSz(src1_.rows, vcols, (unsigned int*) src2_.data, src2_.step), + PtrStepSz(src1_.rows, vcols, (unsigned int*) dst_.data, dst_.step), + stream); return; } @@ -1559,10 +1403,10 @@ void cv::gpu::absdiff(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, Strea { const int vcols = src1_.cols >> 1; - absDiffMat_v2(PtrStepSz(src1_.rows, vcols, (unsigned int*) src1_.data, src1_.step), - PtrStepSz(src1_.rows, vcols, (unsigned int*) src2_.data, src2_.step), - PtrStepSz(src1_.rows, vcols, (unsigned int*) dst_.data, dst_.step), - stream); + arithm::absDiffMat_v2(PtrStepSz(src1_.rows, vcols, (unsigned int*) src1_.data, src1_.step), + PtrStepSz(src1_.rows, vcols, (unsigned int*) src2_.data, src2_.step), + PtrStepSz(src1_.rows, vcols, (unsigned int*) dst_.data, dst_.step), + stream); return; } @@ -1583,36 +1427,28 @@ namespace arithm void absDiffScalar(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); } -void cv::gpu::absdiff(const GpuMat& src1, const Scalar& src2, GpuMat& dst, Stream& stream) +static void absDiffScalar(const GpuMat& src, Scalar val, bool, GpuMat& dst, const GpuMat&, double, Stream& stream, int) { - using namespace arithm; - typedef void (*func_t)(PtrStepSzb src1, double val, PtrStepSzb dst, cudaStream_t stream); static const func_t funcs[] = { - absDiffScalar, - absDiffScalar, - absDiffScalar, - absDiffScalar, - absDiffScalar, - absDiffScalar, - absDiffScalar + arithm::absDiffScalar, + arithm::absDiffScalar, + arithm::absDiffScalar, + arithm::absDiffScalar, + arithm::absDiffScalar, + arithm::absDiffScalar, + arithm::absDiffScalar }; - const int depth = src1.depth(); + const int depth = src.depth(); - CV_Assert( depth <= CV_64F ); - CV_Assert( src1.channels() == 1 ); + funcs[depth](src, val[0], dst, StreamAccessor::getStream(stream)); +} - if (depth == CV_64F) - { - if (!deviceSupports(NATIVE_DOUBLE)) - CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); - } - - dst.create(src1.size(), src1.type()); - - funcs[depth](src1, src2.val[0], dst, StreamAccessor::getStream(stream)); +void cv::gpu::absdiff(InputArray src1, InputArray src2, OutputArray dst, Stream& stream) +{ + arithm_op(src1, src2, dst, noArray(), 1.0, -1, stream, absDiffMat, absDiffScalar); } ////////////////////////////////////////////////////////////////////////////// @@ -1624,7 +1460,7 @@ namespace arithm void absMat(PtrStepSzb src, PtrStepSzb dst, cudaStream_t stream); } -void cv::gpu::abs(const GpuMat& src, GpuMat& dst, Stream& stream) +void cv::gpu::abs(InputArray _src, OutputArray _dst, Stream& stream) { using namespace arithm; @@ -1640,6 +1476,8 @@ void cv::gpu::abs(const GpuMat& src, GpuMat& dst, Stream& stream) absMat }; + GpuMat src = _src.getGpuMat(); + const int depth = src.depth(); CV_Assert( depth <= CV_64F ); @@ -1651,7 +1489,8 @@ void cv::gpu::abs(const GpuMat& src, GpuMat& dst, Stream& stream) CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); } - dst.create(src.size(), src.type()); + _dst.create(src.size(), src.type()); + GpuMat dst = _dst.getGpuMat(); funcs[depth](src, dst, StreamAccessor::getStream(stream)); } @@ -1665,7 +1504,7 @@ namespace arithm void sqrMat(PtrStepSzb src, PtrStepSzb dst, cudaStream_t stream); } -void cv::gpu::sqr(const GpuMat& src, GpuMat& dst, Stream& stream) +void cv::gpu::sqr(InputArray _src, OutputArray _dst, Stream& stream) { using namespace arithm; @@ -1681,6 +1520,8 @@ void cv::gpu::sqr(const GpuMat& src, GpuMat& dst, Stream& stream) sqrMat }; + GpuMat src = _src.getGpuMat(); + const int depth = src.depth(); CV_Assert( depth <= CV_64F ); @@ -1692,7 +1533,8 @@ void cv::gpu::sqr(const GpuMat& src, GpuMat& dst, Stream& stream) CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); } - dst.create(src.size(), src.type()); + _dst.create(src.size(), src.type()); + GpuMat dst = _dst.getGpuMat(); funcs[depth](src, dst, StreamAccessor::getStream(stream)); } @@ -1706,7 +1548,7 @@ namespace arithm void sqrtMat(PtrStepSzb src, PtrStepSzb dst, cudaStream_t stream); } -void cv::gpu::sqrt(const GpuMat& src, GpuMat& dst, Stream& stream) +void cv::gpu::sqrt(InputArray _src, OutputArray _dst, Stream& stream) { using namespace arithm; @@ -1722,46 +1564,7 @@ void cv::gpu::sqrt(const GpuMat& src, GpuMat& dst, Stream& stream) sqrtMat }; - const int depth = src.depth(); - - CV_Assert( depth <= CV_64F ); - CV_Assert( src.channels() == 1 ); - - if (depth == CV_64F) - { - if (!deviceSupports(NATIVE_DOUBLE)) - CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); - } - - dst.create(src.size(), src.type()); - - funcs[depth](src, dst, StreamAccessor::getStream(stream)); -} - -//////////////////////////////////////////////////////////////////////// -// log - -namespace arithm -{ - template - void logMat(PtrStepSzb src, PtrStepSzb dst, cudaStream_t stream); -} - -void cv::gpu::log(const GpuMat& src, GpuMat& dst, Stream& stream) -{ - using namespace arithm; - - typedef void (*func_t)(PtrStepSzb src, PtrStepSzb dst, cudaStream_t stream); - static const func_t funcs[] = - { - logMat, - logMat, - logMat, - logMat, - logMat, - logMat, - logMat - }; + GpuMat src = _src.getGpuMat(); const int depth = src.depth(); @@ -1774,7 +1577,8 @@ void cv::gpu::log(const GpuMat& src, GpuMat& dst, Stream& stream) CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); } - dst.create(src.size(), src.type()); + _dst.create(src.size(), src.type()); + GpuMat dst = _dst.getGpuMat(); funcs[depth](src, dst, StreamAccessor::getStream(stream)); } @@ -1788,7 +1592,7 @@ namespace arithm void expMat(PtrStepSzb src, PtrStepSzb dst, cudaStream_t stream); } -void cv::gpu::exp(const GpuMat& src, GpuMat& dst, Stream& stream) +void cv::gpu::exp(InputArray _src, OutputArray _dst, Stream& stream) { using namespace arithm; @@ -1804,6 +1608,8 @@ void cv::gpu::exp(const GpuMat& src, GpuMat& dst, Stream& stream) expMat }; + GpuMat src = _src.getGpuMat(); + const int depth = src.depth(); CV_Assert( depth <= CV_64F ); @@ -1815,11 +1621,100 @@ void cv::gpu::exp(const GpuMat& src, GpuMat& dst, Stream& stream) CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); } - dst.create(src.size(), src.type()); + _dst.create(src.size(), src.type()); + GpuMat dst = _dst.getGpuMat(); funcs[depth](src, dst, StreamAccessor::getStream(stream)); } +//////////////////////////////////////////////////////////////////////// +// log + +namespace arithm +{ + template + void logMat(PtrStepSzb src, PtrStepSzb dst, cudaStream_t stream); +} + +void cv::gpu::log(InputArray _src, OutputArray _dst, Stream& stream) +{ + using namespace arithm; + + typedef void (*func_t)(PtrStepSzb src, PtrStepSzb dst, cudaStream_t stream); + static const func_t funcs[] = + { + logMat, + logMat, + logMat, + logMat, + logMat, + logMat, + logMat + }; + + GpuMat src = _src.getGpuMat(); + + const int depth = src.depth(); + + CV_Assert( depth <= CV_64F ); + CV_Assert( src.channels() == 1 ); + + if (depth == CV_64F) + { + if (!deviceSupports(NATIVE_DOUBLE)) + CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); + } + + _dst.create(src.size(), src.type()); + GpuMat dst = _dst.getGpuMat(); + + funcs[depth](src, dst, StreamAccessor::getStream(stream)); +} + +//////////////////////////////////////////////////////////////////////// +// pow + +namespace arithm +{ + template void pow(PtrStepSzb src, double power, PtrStepSzb dst, cudaStream_t stream); +} + +void cv::gpu::pow(InputArray _src, double power, OutputArray _dst, Stream& stream) +{ + typedef void (*func_t)(PtrStepSzb src, double power, PtrStepSzb dst, cudaStream_t stream); + static const func_t funcs[] = + { + arithm::pow, + arithm::pow, + arithm::pow, + arithm::pow, + arithm::pow, + arithm::pow, + arithm::pow + }; + + GpuMat src = _src.getGpuMat(); + + const int depth = src.depth(); + const int cn = src.channels(); + + CV_Assert(depth <= CV_64F); + + if (depth == CV_64F) + { + if (!deviceSupports(NATIVE_DOUBLE)) + CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); + } + + _dst.create(src.size(), src.type()); + GpuMat dst = _dst.getGpuMat(); + + PtrStepSzb src_(src.rows, src.cols * cn, src.data, src.step); + PtrStepSzb dst_(src.rows, src.cols * cn, dst.data, dst.step); + + funcs[depth](src_, power, dst_, StreamAccessor::getStream(stream)); +} + ////////////////////////////////////////////////////////////////////////////// // compare @@ -1836,7 +1731,7 @@ namespace arithm template void cmpMatLe(PtrStepSzb src1, PtrStepSzb src2, PtrStepSzb dst, cudaStream_t stream); } -void cv::gpu::compare(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, int cmpop, Stream& s) +static void cmpMat(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, const GpuMat&, double, Stream& _stream, int cmpop) { using namespace arithm; @@ -1861,19 +1756,7 @@ void cv::gpu::compare(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, int c const int depth = src1.depth(); const int cn = src1.channels(); - CV_Assert( depth <= CV_64F ); - CV_Assert( src2.size() == src1.size() && src2.type() == src1.type() ); - CV_Assert( cmpop >= CMP_EQ && cmpop <= CMP_NE ); - - if (depth == CV_64F) - { - if (!deviceSupports(NATIVE_DOUBLE)) - CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); - } - - dst.create(src1.size(), CV_MAKE_TYPE(CV_8U, cn)); - - cudaStream_t stream = StreamAccessor::getStream(s); + cudaStream_t stream = StreamAccessor::getStream(_stream); static const int codes[] = { @@ -1940,7 +1823,7 @@ namespace } } -void cv::gpu::compare(const GpuMat& src, Scalar sc, GpuMat& dst, int cmpop, Stream& stream) +static void cmpScalar(const GpuMat& src, Scalar val, bool inv, GpuMat& dst, const GpuMat&, double, Stream& stream, int cmpop) { using namespace arithm; @@ -1962,46 +1845,50 @@ void cv::gpu::compare(const GpuMat& src, Scalar sc, GpuMat& dst, int cmpop, Stre castScalar, castScalar, castScalar, castScalar, castScalar, castScalar, castScalar }; + if (inv) + { + // src1 is a scalar; swap it with src2 + cmpop = cmpop == CMP_LT ? CMP_GT : cmpop == CMP_LE ? CMP_GE : + cmpop == CMP_GE ? CMP_LE : cmpop == CMP_GT ? CMP_LT : cmpop; + } + const int depth = src.depth(); const int cn = src.channels(); - CV_Assert( depth <= CV_64F ); - CV_Assert( cn <= 4 ); - CV_Assert( cmpop >= CMP_EQ && cmpop <= CMP_NE ); + cast_func[depth](val); - if (depth == CV_64F) - { - if (!deviceSupports(NATIVE_DOUBLE)) - CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); - } + funcs[depth][cmpop](src, cn, val.val, dst, StreamAccessor::getStream(stream)); +} - dst.create(src.size(), CV_MAKE_TYPE(CV_8U, cn)); - - cast_func[depth](sc); - - funcs[depth][cmpop](src, cn, sc.val, dst, StreamAccessor::getStream(stream)); +void cv::gpu::compare(InputArray src1, InputArray src2, OutputArray dst, int cmpop, Stream& stream) +{ + arithm_op(src1, src2, dst, noArray(), 1.0, CV_8U, stream, cmpMat, cmpScalar, cmpop); } ////////////////////////////////////////////////////////////////////////////// -// Unary bitwise logical operations +// bitwise_not namespace arithm { template void bitMatNot(PtrStepSzb src, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); } -void cv::gpu::bitwise_not(const GpuMat& src, GpuMat& dst, const GpuMat& mask, Stream& s) +void cv::gpu::bitwise_not(InputArray _src, OutputArray _dst, InputArray _mask, Stream& _stream) { using namespace arithm; + GpuMat src = _src.getGpuMat(); + GpuMat mask = _mask.getGpuMat(); + const int depth = src.depth(); CV_Assert( depth <= CV_64F ); CV_Assert( mask.empty() || (mask.type() == CV_8UC1 && mask.size() == src.size()) ); - dst.create(src.size(), src.type()); + _dst.create(src.size(), src.type()); + GpuMat dst = _dst.getGpuMat(); - cudaStream_t stream = StreamAccessor::getStream(s); + cudaStream_t stream = StreamAccessor::getStream(_stream); const int bcols = (int) (src.cols * src.elemSize()); @@ -2035,6 +1922,16 @@ void cv::gpu::bitwise_not(const GpuMat& src, GpuMat& dst, const GpuMat& mask, St ////////////////////////////////////////////////////////////////////////////// // Binary bitwise logical operations +namespace +{ + enum + { + BIT_OP_AND, + BIT_OP_OR, + BIT_OP_XOR + }; +} + namespace arithm { template void bitMatAnd(PtrStepSzb src1, PtrStepSzb src2, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); @@ -2042,19 +1939,31 @@ namespace arithm template void bitMatXor(PtrStepSzb src1, PtrStepSzb src2, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); } -void cv::gpu::bitwise_and(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, const GpuMat& mask, Stream& s) +static void bitMat(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, const GpuMat& mask, double, Stream& _stream, int op) { using namespace arithm; - const int depth = src1.depth(); + typedef void (*func_t)(PtrStepSzb src1, PtrStepSzb src2, PtrStepSzb dst, PtrStepb mask, cudaStream_t stream); + static const func_t funcs32[] = + { + bitMatAnd, + bitMatOr, + bitMatXor + }; + static const func_t funcs16[] = + { + bitMatAnd, + bitMatOr, + bitMatXor + }; + static const func_t funcs8[] = + { + bitMatAnd, + bitMatOr, + bitMatXor + }; - CV_Assert( depth <= CV_64F ); - CV_Assert( src2.size() == src1.size() && src2.type() == src1.type() ); - CV_Assert( mask.empty() || (mask.type() == CV_8UC1 && mask.size() == src1.size()) ); - - dst.create(src1.size(), src1.type()); - - cudaStream_t stream = StreamAccessor::getStream(s); + cudaStream_t stream = StreamAccessor::getStream(_stream); const int bcols = (int) (src1.cols * src1.elemSize()); @@ -2062,8 +1971,7 @@ void cv::gpu::bitwise_and(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, c { const int vcols = bcols >> 2; - bitMatAnd( - PtrStepSzb(src1.rows, vcols, src1.data, src1.step), + funcs32[op](PtrStepSzb(src1.rows, vcols, src1.data, src1.step), PtrStepSzb(src1.rows, vcols, src2.data, src2.step), PtrStepSzb(src1.rows, vcols, dst.data, dst.step), mask, stream); @@ -2072,8 +1980,7 @@ void cv::gpu::bitwise_and(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, c { const int vcols = bcols >> 1; - bitMatAnd( - PtrStepSzb(src1.rows, vcols, src1.data, src1.step), + funcs16[op](PtrStepSzb(src1.rows, vcols, src1.data, src1.step), PtrStepSzb(src1.rows, vcols, src2.data, src2.step), PtrStepSzb(src1.rows, vcols, dst.data, dst.step), mask, stream); @@ -2081,111 +1988,13 @@ void cv::gpu::bitwise_and(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, c else { - bitMatAnd( - PtrStepSzb(src1.rows, bcols, src1.data, src1.step), - PtrStepSzb(src1.rows, bcols, src2.data, src2.step), - PtrStepSzb(src1.rows, bcols, dst.data, dst.step), - mask, stream); + funcs8[op](PtrStepSzb(src1.rows, bcols, src1.data, src1.step), + PtrStepSzb(src1.rows, bcols, src2.data, src2.step), + PtrStepSzb(src1.rows, bcols, dst.data, dst.step), + mask, stream); } } -void cv::gpu::bitwise_or(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, const GpuMat& mask, Stream& s) -{ - using namespace arithm; - - const int depth = src1.depth(); - - CV_Assert( depth <= CV_64F ); - CV_Assert( src2.size() == src1.size() && src2.type() == src1.type() ); - CV_Assert( mask.empty() || (mask.type() == CV_8UC1 && mask.size() == src1.size()) ); - - dst.create(src1.size(), src1.type()); - - cudaStream_t stream = StreamAccessor::getStream(s); - - const int bcols = (int) (src1.cols * src1.elemSize()); - - if ((bcols & 3) == 0) - { - const int vcols = bcols >> 2; - - bitMatOr( - PtrStepSzb(src1.rows, vcols, src1.data, src1.step), - PtrStepSzb(src1.rows, vcols, src2.data, src2.step), - PtrStepSzb(src1.rows, vcols, dst.data, dst.step), - mask, stream); - } - else if ((bcols & 1) == 0) - { - const int vcols = bcols >> 1; - - bitMatOr( - PtrStepSzb(src1.rows, vcols, src1.data, src1.step), - PtrStepSzb(src1.rows, vcols, src2.data, src2.step), - PtrStepSzb(src1.rows, vcols, dst.data, dst.step), - mask, stream); - } - else - { - - bitMatOr( - PtrStepSzb(src1.rows, bcols, src1.data, src1.step), - PtrStepSzb(src1.rows, bcols, src2.data, src2.step), - PtrStepSzb(src1.rows, bcols, dst.data, dst.step), - mask, stream); - } -} - -void cv::gpu::bitwise_xor(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, const GpuMat& mask, Stream& s) -{ - using namespace arithm; - - const int depth = src1.depth(); - - CV_Assert( depth <= CV_64F ); - CV_Assert( src2.size() == src1.size() && src2.type() == src1.type() ); - CV_Assert( mask.empty() || (mask.type() == CV_8UC1 && mask.size() == src1.size()) ); - - dst.create(src1.size(), src1.type()); - - cudaStream_t stream = StreamAccessor::getStream(s); - - const int bcols = (int) (src1.cols * src1.elemSize()); - - if ((bcols & 3) == 0) - { - const int vcols = bcols >> 2; - - bitMatXor( - PtrStepSzb(src1.rows, vcols, src1.data, src1.step), - PtrStepSzb(src1.rows, vcols, src2.data, src2.step), - PtrStepSzb(src1.rows, vcols, dst.data, dst.step), - mask, stream); - } - else if ((bcols & 1) == 0) - { - const int vcols = bcols >> 1; - - bitMatXor( - PtrStepSzb(src1.rows, vcols, src1.data, src1.step), - PtrStepSzb(src1.rows, vcols, src2.data, src2.step), - PtrStepSzb(src1.rows, vcols, dst.data, dst.step), - mask, stream); - } - else - { - - bitMatXor( - PtrStepSzb(src1.rows, bcols, src1.data, src1.step), - PtrStepSzb(src1.rows, bcols, src2.data, src2.step), - PtrStepSzb(src1.rows, bcols, dst.data, dst.step), - mask, stream); - } -} - -////////////////////////////////////////////////////////////////////////////// -// Binary bitwise logical operations with scalars - namespace arithm { template void bitScalarAnd(PtrStepSzb src1, unsigned int src2, PtrStepSzb dst, cudaStream_t stream); @@ -2273,18 +2082,34 @@ namespace }; } -void cv::gpu::bitwise_and(const GpuMat& src, const Scalar& sc, GpuMat& dst, Stream& stream) +static void bitScalar(const GpuMat& src, Scalar val, bool, GpuMat& dst, const GpuMat& mask, double, Stream& stream, int op) { using namespace arithm; typedef void (*func_t)(const GpuMat& src, Scalar sc, GpuMat& dst, cudaStream_t stream); - static const func_t funcs[5][4] = + static const func_t funcs[3][5][4] = { - {BitScalar >::call , 0, NppBitwiseC::call, BitScalar4< bitScalarAnd >::call}, - {0,0,0,0}, - {BitScalar >::call, 0, NppBitwiseC::call, NppBitwiseC::call}, - {0,0,0,0}, - {BitScalar >::call , 0, NppBitwiseC::call, NppBitwiseC::call} + { + {BitScalar >::call , 0, NppBitwiseC::call, BitScalar4< bitScalarAnd >::call}, + {0,0,0,0}, + {BitScalar >::call, 0, NppBitwiseC::call, NppBitwiseC::call}, + {0,0,0,0}, + {BitScalar >::call , 0, NppBitwiseC::call, NppBitwiseC::call} + }, + { + {BitScalar >::call , 0, NppBitwiseC::call, BitScalar4< bitScalarOr >::call}, + {0,0,0,0}, + {BitScalar >::call, 0, NppBitwiseC::call, NppBitwiseC::call}, + {0,0,0,0}, + {BitScalar >::call , 0, NppBitwiseC::call, NppBitwiseC::call} + }, + { + {BitScalar >::call , 0, NppBitwiseC::call, BitScalar4< bitScalarXor >::call}, + {0,0,0,0}, + {BitScalar >::call, 0, NppBitwiseC::call, NppBitwiseC::call}, + {0,0,0,0}, + {BitScalar >::call , 0, NppBitwiseC::call, NppBitwiseC::call} + } }; const int depth = src.depth(); @@ -2292,60 +2117,24 @@ void cv::gpu::bitwise_and(const GpuMat& src, const Scalar& sc, GpuMat& dst, Stre CV_Assert( depth == CV_8U || depth == CV_16U || depth == CV_32S ); CV_Assert( cn == 1 || cn == 3 || cn == 4 ); + CV_Assert( mask.empty() ); - dst.create(src.size(), src.type()); - - funcs[depth][cn - 1](src, sc, dst, StreamAccessor::getStream(stream)); + funcs[op][depth][cn - 1](src, val, dst, StreamAccessor::getStream(stream)); } -void cv::gpu::bitwise_or(const GpuMat& src, const Scalar& sc, GpuMat& dst, Stream& stream) +void cv::gpu::bitwise_or(InputArray src1, InputArray src2, OutputArray dst, InputArray mask, Stream& stream) { - using namespace arithm; - - typedef void (*func_t)(const GpuMat& src, Scalar sc, GpuMat& dst, cudaStream_t stream); - static const func_t funcs[5][4] = - { - {BitScalar >::call , 0, NppBitwiseC::call, BitScalar4< bitScalarOr >::call}, - {0,0,0,0}, - {BitScalar >::call, 0, NppBitwiseC::call, NppBitwiseC::call}, - {0,0,0,0}, - {BitScalar >::call , 0, NppBitwiseC::call, NppBitwiseC::call} - }; - - const int depth = src.depth(); - const int cn = src.channels(); - - CV_Assert( depth == CV_8U || depth == CV_16U || depth == CV_32S ); - CV_Assert( cn == 1 || cn == 3 || cn == 4 ); - - dst.create(src.size(), src.type()); - - funcs[depth][cn - 1](src, sc, dst, StreamAccessor::getStream(stream)); + arithm_op(src1, src2, dst, mask, 1.0, -1, stream, bitMat, bitScalar, BIT_OP_OR); } -void cv::gpu::bitwise_xor(const GpuMat& src, const Scalar& sc, GpuMat& dst, Stream& stream) +void cv::gpu::bitwise_and(InputArray src1, InputArray src2, OutputArray dst, InputArray mask, Stream& stream) { - using namespace arithm; + arithm_op(src1, src2, dst, mask, 1.0, -1, stream, bitMat, bitScalar, BIT_OP_AND); +} - typedef void (*func_t)(const GpuMat& src, Scalar sc, GpuMat& dst, cudaStream_t stream); - static const func_t funcs[5][4] = - { - {BitScalar >::call , 0, NppBitwiseC::call, BitScalar4< bitScalarXor >::call}, - {0,0,0,0}, - {BitScalar >::call, 0, NppBitwiseC::call, NppBitwiseC::call}, - {0,0,0,0}, - {BitScalar >::call , 0, NppBitwiseC::call, NppBitwiseC::call} - }; - - const int depth = src.depth(); - const int cn = src.channels(); - - CV_Assert( depth == CV_8U || depth == CV_16U || depth == CV_32S ); - CV_Assert( cn == 1 || cn == 3 || cn == 4 ); - - dst.create(src.size(), src.type()); - - funcs[depth][cn - 1](src, sc, dst, StreamAccessor::getStream(stream)); +void cv::gpu::bitwise_xor(InputArray src1, InputArray src2, OutputArray dst, InputArray mask, Stream& stream) +{ + arithm_op(src1, src2, dst, mask, 1.0, -1, stream, bitMat, bitScalar, BIT_OP_XOR); } ////////////////////////////////////////////////////////////////////////////// @@ -2404,7 +2193,7 @@ namespace }; } -void cv::gpu::rshift(const GpuMat& src, Scalar_ sc, GpuMat& dst, Stream& stream) +void cv::gpu::rshift(InputArray _src, Scalar_ val, OutputArray _dst, Stream& stream) { typedef void (*func_t)(const GpuMat& src, Scalar_ sc, GpuMat& dst, cudaStream_t stream); static const func_t funcs[5][4] = @@ -2416,15 +2205,18 @@ void cv::gpu::rshift(const GpuMat& src, Scalar_ sc, GpuMat& dst, Stream& st {NppShift::call, 0, NppShift::call, NppShift::call}, }; - CV_Assert(src.depth() < CV_32F); - CV_Assert(src.channels() == 1 || src.channels() == 3 || src.channels() == 4); + GpuMat src = _src.getGpuMat(); - dst.create(src.size(), src.type()); + CV_Assert( src.depth() < CV_32F ); + CV_Assert( src.channels() == 1 || src.channels() == 3 || src.channels() == 4 ); - funcs[src.depth()][src.channels() - 1](src, sc, dst, StreamAccessor::getStream(stream)); + _dst.create(src.size(), src.type()); + GpuMat dst = _dst.getGpuMat(); + + funcs[src.depth()][src.channels() - 1](src, val, dst, StreamAccessor::getStream(stream)); } -void cv::gpu::lshift(const GpuMat& src, Scalar_ sc, GpuMat& dst, Stream& stream) +void cv::gpu::lshift(InputArray _src, Scalar_ val, OutputArray _dst, Stream& stream) { typedef void (*func_t)(const GpuMat& src, Scalar_ sc, GpuMat& dst, cudaStream_t stream); static const func_t funcs[5][4] = @@ -2436,17 +2228,29 @@ void cv::gpu::lshift(const GpuMat& src, Scalar_ sc, GpuMat& dst, Stream& st {NppShift::call, 0, NppShift::call, NppShift::call}, }; - CV_Assert(src.depth() == CV_8U || src.depth() == CV_16U || src.depth() == CV_32S); - CV_Assert(src.channels() == 1 || src.channels() == 3 || src.channels() == 4); + GpuMat src = _src.getGpuMat(); - dst.create(src.size(), src.type()); + CV_Assert( src.depth() == CV_8U || src.depth() == CV_16U || src.depth() == CV_32S ); + CV_Assert( src.channels() == 1 || src.channels() == 3 || src.channels() == 4 ); - funcs[src.depth()][src.channels() - 1](src, sc, dst, StreamAccessor::getStream(stream)); + _dst.create(src.size(), src.type()); + GpuMat dst = _dst.getGpuMat(); + + funcs[src.depth()][src.channels() - 1](src, val, dst, StreamAccessor::getStream(stream)); } ////////////////////////////////////////////////////////////////////////////// // Minimum and maximum operations +namespace +{ + enum + { + MIN_OP, + MAX_OP + }; +} + namespace arithm { void minMat_v4(PtrStepSz src1, PtrStepSz src2, PtrStepSz dst, cudaStream_t stream); @@ -2460,37 +2264,49 @@ namespace arithm template void maxScalar(PtrStepSzb src1, double src2, PtrStepSzb dst, cudaStream_t stream); } -void cv::gpu::min(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, Stream& s) +void minMaxMat(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, const GpuMat&, double, Stream& _stream, int op) { using namespace arithm; typedef void (*func_t)(PtrStepSzb src1, PtrStepSzb src2, PtrStepSzb dst, cudaStream_t stream); - static const func_t funcs[] = + static const func_t funcs[2][7] = { - minMat, - minMat, - minMat, - minMat, - minMat, - minMat, - minMat + { + minMat, + minMat, + minMat, + minMat, + minMat, + minMat, + minMat + }, + { + maxMat, + maxMat, + maxMat, + maxMat, + maxMat, + maxMat, + maxMat + } + }; + + typedef void (*opt_func_t)(PtrStepSz src1, PtrStepSz src2, PtrStepSz dst, cudaStream_t stream); + static const opt_func_t funcs_v4[2] = + { + minMat_v4, maxMat_v4 + }; + static const opt_func_t funcs_v2[2] = + { + minMat_v2, maxMat_v2 }; const int depth = src1.depth(); const int cn = src1.channels(); CV_Assert( depth <= CV_64F ); - CV_Assert( src2.type() == src1.type() && src2.size() == src1.size() ); - if (depth == CV_64F) - { - if (!deviceSupports(NATIVE_DOUBLE)) - CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); - } - - dst.create(src1.size(), src1.type()); - - cudaStream_t stream = StreamAccessor::getStream(s); + cudaStream_t stream = StreamAccessor::getStream(_stream); PtrStepSzb src1_(src1.rows, src1.cols * cn, src1.data, src1.step); PtrStepSzb src2_(src1.rows, src1.cols * cn, src2.data, src2.step); @@ -2510,10 +2326,10 @@ void cv::gpu::min(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, Stream& s { const int vcols = src1_.cols >> 2; - minMat_v4(PtrStepSz(src1_.rows, vcols, (unsigned int*) src1_.data, src1_.step), - PtrStepSz(src1_.rows, vcols, (unsigned int*) src2_.data, src2_.step), - PtrStepSz(src1_.rows, vcols, (unsigned int*) dst_.data, dst_.step), - stream); + funcs_v4[op](PtrStepSz(src1_.rows, vcols, (unsigned int*) src1_.data, src1_.step), + PtrStepSz(src1_.rows, vcols, (unsigned int*) src2_.data, src2_.step), + PtrStepSz(src1_.rows, vcols, (unsigned int*) dst_.data, dst_.step), + stream); return; } @@ -2521,96 +2337,17 @@ void cv::gpu::min(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, Stream& s { const int vcols = src1_.cols >> 1; - minMat_v2(PtrStepSz(src1_.rows, vcols, (unsigned int*) src1_.data, src1_.step), - PtrStepSz(src1_.rows, vcols, (unsigned int*) src2_.data, src2_.step), - PtrStepSz(src1_.rows, vcols, (unsigned int*) dst_.data, dst_.step), - stream); + funcs_v2[op](PtrStepSz(src1_.rows, vcols, (unsigned int*) src1_.data, src1_.step), + PtrStepSz(src1_.rows, vcols, (unsigned int*) src2_.data, src2_.step), + PtrStepSz(src1_.rows, vcols, (unsigned int*) dst_.data, dst_.step), + stream); return; } } } - const func_t func = funcs[depth]; - - if (!func) - CV_Error(cv::Error::StsUnsupportedFormat, "Unsupported combination of source and destination types"); - - func(src1_, src2_, dst_, stream); -} - -void cv::gpu::max(const GpuMat& src1, const GpuMat& src2, GpuMat& dst, Stream& s) -{ - using namespace arithm; - - typedef void (*func_t)(PtrStepSzb src1, PtrStepSzb src2, PtrStepSzb dst, cudaStream_t stream); - static const func_t funcs[] = - { - maxMat, - maxMat, - maxMat, - maxMat, - maxMat, - maxMat, - maxMat - }; - - const int depth = src1.depth(); - const int cn = src1.channels(); - - CV_Assert( depth <= CV_64F ); - CV_Assert( src2.type() == src1.type() && src2.size() == src1.size() ); - - if (depth == CV_64F) - { - if (!deviceSupports(NATIVE_DOUBLE)) - CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); - } - - dst.create(src1.size(), src1.type()); - - cudaStream_t stream = StreamAccessor::getStream(s); - - PtrStepSzb src1_(src1.rows, src1.cols * cn, src1.data, src1.step); - PtrStepSzb src2_(src1.rows, src1.cols * cn, src2.data, src2.step); - PtrStepSzb dst_(src1.rows, src1.cols * cn, dst.data, dst.step); - - if (depth == CV_8U || depth == CV_16U) - { - const intptr_t src1ptr = reinterpret_cast(src1_.data); - const intptr_t src2ptr = reinterpret_cast(src2_.data); - const intptr_t dstptr = reinterpret_cast(dst_.data); - - const bool isAllAligned = (src1ptr & 31) == 0 && (src2ptr & 31) == 0 && (dstptr & 31) == 0; - - if (isAllAligned) - { - if (depth == CV_8U && (src1_.cols & 3) == 0) - { - const int vcols = src1_.cols >> 2; - - maxMat_v4(PtrStepSz(src1_.rows, vcols, (unsigned int*) src1_.data, src1_.step), - PtrStepSz(src1_.rows, vcols, (unsigned int*) src2_.data, src2_.step), - PtrStepSz(src1_.rows, vcols, (unsigned int*) dst_.data, dst_.step), - stream); - - return; - } - else if (depth == CV_16U && (src1_.cols & 1) == 0) - { - const int vcols = src1_.cols >> 1; - - maxMat_v2(PtrStepSz(src1_.rows, vcols, (unsigned int*) src1_.data, src1_.step), - PtrStepSz(src1_.rows, vcols, (unsigned int*) src2_.data, src2_.step), - PtrStepSz(src1_.rows, vcols, (unsigned int*) dst_.data, dst_.step), - stream); - - return; - } - } - } - - const func_t func = funcs[depth]; + const func_t func = funcs[op][depth]; if (!func) CV_Error(cv::Error::StsUnsupportedFormat, "Unsupported combination of source and destination types"); @@ -2626,20 +2363,31 @@ namespace } } -void cv::gpu::min(const GpuMat& src, double val, GpuMat& dst, Stream& stream) +void minMaxScalar(const GpuMat& src, Scalar val, bool, GpuMat& dst, const GpuMat&, double, Stream& stream, int op) { using namespace arithm; typedef void (*func_t)(PtrStepSzb src1, double src2, PtrStepSzb dst, cudaStream_t stream); - static const func_t funcs[] = + static const func_t funcs[2][7] = { - minScalar, - minScalar, - minScalar, - minScalar, - minScalar, - minScalar, - minScalar + { + minScalar, + minScalar, + minScalar, + minScalar, + minScalar, + minScalar, + minScalar + }, + { + maxScalar, + maxScalar, + maxScalar, + maxScalar, + maxScalar, + maxScalar, + maxScalar + } }; typedef double (*cast_func_t)(double sc); @@ -2653,94 +2401,17 @@ void cv::gpu::min(const GpuMat& src, double val, GpuMat& dst, Stream& stream) CV_Assert( depth <= CV_64F ); CV_Assert( src.channels() == 1 ); - if (depth == CV_64F) - { - if (!deviceSupports(NATIVE_DOUBLE)) - CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); - } - - dst.create(src.size(), src.type()); - - funcs[depth](src, cast_func[depth](val), dst, StreamAccessor::getStream(stream)); + funcs[op][depth](src, cast_func[depth](val[0]), dst, StreamAccessor::getStream(stream)); } -void cv::gpu::max(const GpuMat& src, double val, GpuMat& dst, Stream& stream) +void cv::gpu::min(InputArray src1, InputArray src2, OutputArray dst, Stream& stream) { - using namespace arithm; - - typedef void (*func_t)(PtrStepSzb src1, double src2, PtrStepSzb dst, cudaStream_t stream); - static const func_t funcs[] = - { - maxScalar, - maxScalar, - maxScalar, - maxScalar, - maxScalar, - maxScalar, - maxScalar - }; - - typedef double (*cast_func_t)(double sc); - static const cast_func_t cast_func[] = - { - castScalar, castScalar, castScalar, castScalar, castScalar, castScalar, castScalar - }; - - const int depth = src.depth(); - - CV_Assert( depth <= CV_64F ); - CV_Assert( src.channels() == 1 ); - - if (depth == CV_64F) - { - if (!deviceSupports(NATIVE_DOUBLE)) - CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); - } - - dst.create(src.size(), src.type()); - - funcs[depth](src, cast_func[depth](val), dst, StreamAccessor::getStream(stream)); + arithm_op(src1, src2, dst, noArray(), 1.0, -1, stream, minMaxMat, minMaxScalar, MIN_OP); } -//////////////////////////////////////////////////////////////////////// -// pow - -namespace arithm +void cv::gpu::max(InputArray src1, InputArray src2, OutputArray dst, Stream& stream) { - template void pow(PtrStepSzb src, double power, PtrStepSzb dst, cudaStream_t stream); -} - -void cv::gpu::pow(const GpuMat& src, double power, GpuMat& dst, Stream& stream) -{ - typedef void (*func_t)(PtrStepSzb src, double power, PtrStepSzb dst, cudaStream_t stream); - static const func_t funcs[] = - { - arithm::pow, - arithm::pow, - arithm::pow, - arithm::pow, - arithm::pow, - arithm::pow, - arithm::pow - }; - - const int depth = src.depth(); - const int cn = src.channels(); - - CV_Assert(depth <= CV_64F); - - if (depth == CV_64F) - { - if (!deviceSupports(NATIVE_DOUBLE)) - CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); - } - - dst.create(src.size(), src.type()); - - PtrStepSzb src_(src.rows, src.cols * cn, src.data, src.step); - PtrStepSzb dst_(src.rows, src.cols * cn, dst.data, dst.step); - - funcs[depth](src_, power, dst_, StreamAccessor::getStream(stream)); + arithm_op(src1, src2, dst, noArray(), 1.0, -1, stream, minMaxMat, minMaxScalar, MAX_OP); } //////////////////////////////////////////////////////////////////////// @@ -2752,7 +2423,7 @@ namespace arithm void addWeighted(PtrStepSzb src1, double alpha, PtrStepSzb src2, double beta, double gamma, PtrStepSzb dst, cudaStream_t stream); } -void cv::gpu::addWeighted(const GpuMat& src1, double alpha, const GpuMat& src2, double beta, double gamma, GpuMat& dst, int ddepth, Stream& stream) +void cv::gpu::addWeighted(InputArray _src1, double alpha, InputArray _src2, double beta, double gamma, OutputArray _dst, int ddepth, Stream& stream) { typedef void (*func_t)(PtrStepSzb src1, double alpha, PtrStepSzb src2, double beta, double gamma, PtrStepSzb dst, cudaStream_t stream); static const func_t funcs[7][7][7] = @@ -3214,6 +2885,9 @@ void cv::gpu::addWeighted(const GpuMat& src1, double alpha, const GpuMat& src2, } }; + GpuMat src1 = _src1.getGpuMat(); + GpuMat src2 = _src2.getGpuMat(); + int sdepth1 = src1.depth(); int sdepth2 = src2.depth(); ddepth = ddepth >= 0 ? CV_MAT_DEPTH(ddepth) : std::max(sdepth1, sdepth2); @@ -3228,7 +2902,8 @@ void cv::gpu::addWeighted(const GpuMat& src1, double alpha, const GpuMat& src2, CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); } - dst.create(src1.size(), CV_MAKE_TYPE(ddepth, cn)); + _dst.create(src1.size(), CV_MAKE_TYPE(ddepth, cn)); + GpuMat dst = _dst.getGpuMat(); PtrStepSzb src1_(src1.rows, src1.cols * cn, src1.data, src1.step); PtrStepSzb src2_(src1.rows, src1.cols * cn, src2.data, src2.step); @@ -3259,8 +2934,10 @@ namespace arithm void threshold(PtrStepSzb src, PtrStepSzb dst, double thresh, double maxVal, int type, cudaStream_t stream); } -double cv::gpu::threshold(const GpuMat& src, GpuMat& dst, double thresh, double maxVal, int type, Stream& s) +double cv::gpu::threshold(InputArray _src, OutputArray _dst, double thresh, double maxVal, int type, Stream& _stream) { + GpuMat src = _src.getGpuMat(); + const int depth = src.depth(); CV_Assert( src.channels() == 1 && depth <= CV_64F ); @@ -3272,9 +2949,10 @@ double cv::gpu::threshold(const GpuMat& src, GpuMat& dst, double thresh, double CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); } - dst.create(src.size(), src.type()); + _dst.create(src.size(), src.type()); + GpuMat dst = _dst.getGpuMat(); - cudaStream_t stream = StreamAccessor::getStream(s); + cudaStream_t stream = StreamAccessor::getStream(_stream); if (src.type() == CV_32FC1 && type == 2/*THRESH_TRUNC*/) { @@ -3323,12 +3001,10 @@ namespace { typedef NppStatus (*nppMagnitude_t)(const Npp32fc* pSrc, int nSrcStep, Npp32f* pDst, int nDstStep, NppiSize oSizeROI); - inline void npp_magnitude(const GpuMat& src, GpuMat& dst, nppMagnitude_t func, cudaStream_t stream) + void npp_magnitude(const GpuMat& src, GpuMat& dst, nppMagnitude_t func, cudaStream_t stream) { CV_Assert(src.type() == CV_32FC2); - dst.create(src.size(), CV_32FC1); - NppiSize sz; sz.width = src.cols; sz.height = src.rows; @@ -3342,13 +3018,23 @@ namespace } } -void cv::gpu::magnitude(const GpuMat& src, GpuMat& dst, Stream& stream) +void cv::gpu::magnitude(InputArray _src, OutputArray _dst, Stream& stream) { + GpuMat src = _src.getGpuMat(); + + _dst.create(src.size(), CV_32FC1); + GpuMat dst = _dst.getGpuMat(); + npp_magnitude(src, dst, nppiMagnitude_32fc32f_C1R, StreamAccessor::getStream(stream)); } -void cv::gpu::magnitudeSqr(const GpuMat& src, GpuMat& dst, Stream& stream) +void cv::gpu::magnitudeSqr(InputArray _src, OutputArray _dst, Stream& stream) { + GpuMat src = _src.getGpuMat(); + + _dst.create(src.size(), CV_32FC1); + GpuMat dst = _dst.getGpuMat(); + npp_magnitude(src, dst, nppiMagnitudeSqr_32fc32f_C1R, StreamAccessor::getStream(stream)); } @@ -3366,18 +3052,13 @@ namespace cv { namespace gpu { namespace cudev namespace { - inline void cartToPolar_caller(const GpuMat& x, const GpuMat& y, GpuMat* mag, bool magSqr, GpuMat* angle, bool angleInDegrees, cudaStream_t stream) + void cartToPolar_caller(const GpuMat& x, const GpuMat& y, GpuMat* mag, bool magSqr, GpuMat* angle, bool angleInDegrees, cudaStream_t stream) { using namespace ::cv::gpu::cudev::mathfunc; CV_Assert(x.size() == y.size() && x.type() == y.type()); CV_Assert(x.depth() == CV_32F); - if (mag) - mag->create(x.size(), x.type()); - if (angle) - angle->create(x.size(), x.type()); - GpuMat x1cn = x.reshape(1); GpuMat y1cn = y.reshape(1); GpuMat mag1cn = mag ? mag->reshape(1) : GpuMat(); @@ -3386,16 +3067,13 @@ namespace cartToPolar_gpu(x1cn, y1cn, mag1cn, magSqr, angle1cn, angleInDegrees, stream); } - inline void polarToCart_caller(const GpuMat& mag, const GpuMat& angle, GpuMat& x, GpuMat& y, bool angleInDegrees, cudaStream_t stream) + void polarToCart_caller(const GpuMat& mag, const GpuMat& angle, GpuMat& x, GpuMat& y, bool angleInDegrees, cudaStream_t stream) { using namespace ::cv::gpu::cudev::mathfunc; CV_Assert((mag.empty() || mag.size() == angle.size()) && mag.type() == angle.type()); CV_Assert(mag.depth() == CV_32F); - x.create(mag.size(), mag.type()); - y.create(mag.size(), mag.type()); - GpuMat mag1cn = mag.reshape(1); GpuMat angle1cn = angle.reshape(1); GpuMat x1cn = x.reshape(1); @@ -3405,29 +3083,65 @@ namespace } } -void cv::gpu::magnitude(const GpuMat& x, const GpuMat& y, GpuMat& dst, Stream& stream) +void cv::gpu::magnitude(InputArray _x, InputArray _y, OutputArray _dst, Stream& stream) { + GpuMat x = _x.getGpuMat(); + GpuMat y = _y.getGpuMat(); + + _dst.create(x.size(), CV_32FC1); + GpuMat dst = _dst.getGpuMat(); + cartToPolar_caller(x, y, &dst, false, 0, false, StreamAccessor::getStream(stream)); } -void cv::gpu::magnitudeSqr(const GpuMat& x, const GpuMat& y, GpuMat& dst, Stream& stream) +void cv::gpu::magnitudeSqr(InputArray _x, InputArray _y, OutputArray _dst, Stream& stream) { + GpuMat x = _x.getGpuMat(); + GpuMat y = _y.getGpuMat(); + + _dst.create(x.size(), CV_32FC1); + GpuMat dst = _dst.getGpuMat(); + cartToPolar_caller(x, y, &dst, true, 0, false, StreamAccessor::getStream(stream)); } -void cv::gpu::phase(const GpuMat& x, const GpuMat& y, GpuMat& angle, bool angleInDegrees, Stream& stream) +void cv::gpu::phase(InputArray _x, InputArray _y, OutputArray _dst, bool angleInDegrees, Stream& stream) { - cartToPolar_caller(x, y, 0, false, &angle, angleInDegrees, StreamAccessor::getStream(stream)); + GpuMat x = _x.getGpuMat(); + GpuMat y = _y.getGpuMat(); + + _dst.create(x.size(), CV_32FC1); + GpuMat dst = _dst.getGpuMat(); + + cartToPolar_caller(x, y, 0, false, &dst, angleInDegrees, StreamAccessor::getStream(stream)); } -void cv::gpu::cartToPolar(const GpuMat& x, const GpuMat& y, GpuMat& mag, GpuMat& angle, bool angleInDegrees, Stream& stream) +void cv::gpu::cartToPolar(InputArray _x, InputArray _y, OutputArray _mag, OutputArray _angle, bool angleInDegrees, Stream& stream) { + GpuMat x = _x.getGpuMat(); + GpuMat y = _y.getGpuMat(); + + _mag.create(x.size(), CV_32FC1); + GpuMat mag = _mag.getGpuMat(); + + _angle.create(x.size(), CV_32FC1); + GpuMat angle = _angle.getGpuMat(); + cartToPolar_caller(x, y, &mag, false, &angle, angleInDegrees, StreamAccessor::getStream(stream)); } -void cv::gpu::polarToCart(const GpuMat& magnitude, const GpuMat& angle, GpuMat& x, GpuMat& y, bool angleInDegrees, Stream& stream) +void cv::gpu::polarToCart(InputArray _mag, InputArray _angle, OutputArray _x, OutputArray _y, bool angleInDegrees, Stream& stream) { - polarToCart_caller(magnitude, angle, x, y, angleInDegrees, StreamAccessor::getStream(stream)); + GpuMat mag = _mag.getGpuMat(); + GpuMat angle = _angle.getGpuMat(); + + _x.create(mag.size(), CV_32FC1); + GpuMat x = _x.getGpuMat(); + + _y.create(mag.size(), CV_32FC1); + GpuMat y = _y.getGpuMat(); + + polarToCart_caller(mag, angle, x, y, angleInDegrees, StreamAccessor::getStream(stream)); } #endif diff --git a/modules/gpuarithm/src/reductions.cpp b/modules/gpuarithm/src/reductions.cpp index b8b24188d4..248fa9a4e7 100644 --- a/modules/gpuarithm/src/reductions.cpp +++ b/modules/gpuarithm/src/reductions.cpp @@ -47,41 +47,28 @@ using namespace cv::gpu; #if !defined (HAVE_CUDA) || defined (CUDA_DISABLER) -double cv::gpu::norm(const GpuMat&, int) { throw_no_cuda(); return 0.0; } -double cv::gpu::norm(const GpuMat&, int, GpuMat&) { throw_no_cuda(); return 0.0; } -double cv::gpu::norm(const GpuMat&, int, const GpuMat&, GpuMat&) { throw_no_cuda(); return 0.0; } -double cv::gpu::norm(const GpuMat&, const GpuMat&, int) { throw_no_cuda(); return 0.0; } +double cv::gpu::norm(InputArray, int, InputArray, GpuMat&) { throw_no_cuda(); return 0.0; } +double cv::gpu::norm(InputArray, InputArray, GpuMat&, int) { throw_no_cuda(); return 0.0; } -Scalar cv::gpu::sum(const GpuMat&) { throw_no_cuda(); return Scalar(); } -Scalar cv::gpu::sum(const GpuMat&, GpuMat&) { throw_no_cuda(); return Scalar(); } -Scalar cv::gpu::sum(const GpuMat&, const GpuMat&, GpuMat&) { throw_no_cuda(); return Scalar(); } +Scalar cv::gpu::sum(InputArray, InputArray, GpuMat&) { throw_no_cuda(); return Scalar(); } +Scalar cv::gpu::absSum(InputArray, InputArray, GpuMat&) { throw_no_cuda(); return Scalar(); } +Scalar cv::gpu::sqrSum(InputArray, InputArray, GpuMat&) { throw_no_cuda(); return Scalar(); } -Scalar cv::gpu::absSum(const GpuMat&) { throw_no_cuda(); return Scalar(); } -Scalar cv::gpu::absSum(const GpuMat&, GpuMat&) { throw_no_cuda(); return Scalar(); } -Scalar cv::gpu::absSum(const GpuMat&, const GpuMat&, GpuMat&) { throw_no_cuda(); return Scalar(); } +void cv::gpu::minMax(InputArray, double*, double*, InputArray, GpuMat&) { throw_no_cuda(); } +void cv::gpu::minMaxLoc(InputArray, double*, double*, Point*, Point*, InputArray, GpuMat&, GpuMat&) { throw_no_cuda(); } -Scalar cv::gpu::sqrSum(const GpuMat&) { throw_no_cuda(); return Scalar(); } -Scalar cv::gpu::sqrSum(const GpuMat&, GpuMat&) { throw_no_cuda(); return Scalar(); } -Scalar cv::gpu::sqrSum(const GpuMat&, const GpuMat&, GpuMat&) { throw_no_cuda(); return Scalar(); } +int cv::gpu::countNonZero(InputArray, GpuMat&) { throw_no_cuda(); return 0; } -void cv::gpu::minMax(const GpuMat&, double*, double*, const GpuMat&) { throw_no_cuda(); } -void cv::gpu::minMax(const GpuMat&, double*, double*, const GpuMat&, GpuMat&) { throw_no_cuda(); } +void cv::gpu::reduce(InputArray, OutputArray, int, int, int, Stream&) { throw_no_cuda(); } -void cv::gpu::minMaxLoc(const GpuMat&, double*, double*, Point*, Point*, const GpuMat&) { throw_no_cuda(); } -void cv::gpu::minMaxLoc(const GpuMat&, double*, double*, Point*, Point*, const GpuMat&, GpuMat&, GpuMat&) { throw_no_cuda(); } +void cv::gpu::meanStdDev(InputArray, Scalar&, Scalar&, GpuMat&) { throw_no_cuda(); } -int cv::gpu::countNonZero(const GpuMat&) { throw_no_cuda(); return 0; } -int cv::gpu::countNonZero(const GpuMat&, GpuMat&) { throw_no_cuda(); return 0; } +void cv::gpu::rectStdDev(InputArray, InputArray, OutputArray, Rect, Stream&) { throw_no_cuda(); } -void cv::gpu::reduce(const GpuMat&, GpuMat&, int, int, int, Stream&) { throw_no_cuda(); } +void cv::gpu::normalize(InputArray, OutputArray, double, double, int, int, InputArray, GpuMat&, GpuMat&) { throw_no_cuda(); } -void cv::gpu::meanStdDev(const GpuMat&, Scalar&, Scalar&) { throw_no_cuda(); } -void cv::gpu::meanStdDev(const GpuMat&, Scalar&, Scalar&, GpuMat&) { throw_no_cuda(); } - -void cv::gpu::rectStdDev(const GpuMat&, const GpuMat&, GpuMat&, const Rect&, Stream&) { throw_no_cuda(); } - -void cv::gpu::normalize(const GpuMat&, GpuMat&, double, double, int, int, const GpuMat&) { throw_no_cuda(); } -void cv::gpu::normalize(const GpuMat&, GpuMat&, double, double, int, int, const GpuMat&, GpuMat&, GpuMat&) { throw_no_cuda(); } +void cv::gpu::integral(InputArray, OutputArray, GpuMat&, Stream&) { throw_no_cuda(); } +void cv::gpu::sqrIntegral(InputArray, OutputArray, GpuMat&, Stream&) { throw_no_cuda(); } #else @@ -124,21 +111,13 @@ namespace //////////////////////////////////////////////////////////////////////// // norm -double cv::gpu::norm(const GpuMat& src, int normType) +double cv::gpu::norm(InputArray _src, int normType, InputArray _mask, GpuMat& buf) { - GpuMat buf; - return gpu::norm(src, normType, GpuMat(), buf); -} + GpuMat src = _src.getGpuMat(); + GpuMat mask = _mask.getGpuMat(); -double cv::gpu::norm(const GpuMat& src, int normType, GpuMat& buf) -{ - return gpu::norm(src, normType, GpuMat(), buf); -} - -double cv::gpu::norm(const GpuMat& src, int normType, const GpuMat& mask, GpuMat& buf) -{ - CV_Assert(normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2); - CV_Assert(mask.empty() || (mask.type() == CV_8UC1 && mask.size() == src.size() && src.channels() == 1)); + CV_Assert( normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2 ); + CV_Assert( mask.empty() || (mask.type() == CV_8UC1 && mask.size() == src.size() && src.channels() == 1) ); GpuMat src_single_channel = src.reshape(1); @@ -154,13 +133,11 @@ double cv::gpu::norm(const GpuMat& src, int normType, const GpuMat& mask, GpuMat return std::max(std::abs(min_val), std::abs(max_val)); } -double cv::gpu::norm(const GpuMat& src1, const GpuMat& src2, int normType) +double cv::gpu::norm(InputArray _src1, InputArray _src2, GpuMat& buf, int normType) { - CV_Assert(src1.type() == CV_8UC1); - CV_Assert(src1.size() == src2.size() && src1.type() == src2.type()); - CV_Assert(normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2); - #if CUDA_VERSION < 5050 + (void) buf; + typedef NppStatus (*func_t)(const Npp8u* pSrc1, int nSrcStep1, const Npp8u* pSrc2, int nSrcStep2, NppiSize oSizeROI, Npp64f* pRetVal); static const func_t funcs[] = {nppiNormDiff_Inf_8u_C1R, nppiNormDiff_L1_8u_C1R, nppiNormDiff_L2_8u_C1R}; @@ -175,13 +152,18 @@ double cv::gpu::norm(const GpuMat& src1, const GpuMat& src2, int normType) static const buf_size_func_t buf_size_funcs[] = {nppiNormDiffInfGetBufferHostSize_8u_C1R, nppiNormDiffL1GetBufferHostSize_8u_C1R, nppiNormDiffL2GetBufferHostSize_8u_C1R}; #endif + GpuMat src1 = _src1.getGpuMat(); + GpuMat src2 = _src2.getGpuMat(); + + CV_Assert( src1.type() == CV_8UC1 ); + CV_Assert( src1.size() == src2.size() && src1.type() == src2.type() ); + CV_Assert( normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2 ); + NppiSize sz; sz.width = src1.cols; sz.height = src1.rows; - int funcIdx = normType >> 1; - - double retVal; + const int funcIdx = normType >> 1; DeviceBuffer dbuf; @@ -191,13 +173,14 @@ double cv::gpu::norm(const GpuMat& src1, const GpuMat& src2, int normType) int bufSize; buf_size_funcs[funcIdx](sz, &bufSize); - GpuMat buf(1, bufSize, CV_8UC1); + ensureSizeIsEnough(1, bufSize, CV_8UC1, buf); nppSafeCall( funcs[funcIdx](src1.ptr(), static_cast(src1.step), src2.ptr(), static_cast(src2.step), sz, dbuf, buf.data) ); #endif cudaSafeCall( cudaDeviceSynchronize() ); + double retVal; dbuf.download(&retVal); return retVal; @@ -220,19 +203,11 @@ namespace sum void runSqr(PtrStepSzb src, void* buf, double* sum, PtrStepSzb mask); } -Scalar cv::gpu::sum(const GpuMat& src) +Scalar cv::gpu::sum(InputArray _src, InputArray _mask, GpuMat& buf) { - GpuMat buf; - return gpu::sum(src, GpuMat(), buf); -} + GpuMat src = _src.getGpuMat(); + GpuMat mask = _mask.getGpuMat(); -Scalar cv::gpu::sum(const GpuMat& src, GpuMat& buf) -{ - return gpu::sum(src, GpuMat(), buf); -} - -Scalar cv::gpu::sum(const GpuMat& src, const GpuMat& mask, GpuMat& buf) -{ typedef void (*func_t)(PtrStepSzb src, void* buf, double* sum, PtrStepSzb mask); static const func_t funcs[7][5] = { @@ -266,19 +241,11 @@ Scalar cv::gpu::sum(const GpuMat& src, const GpuMat& mask, GpuMat& buf) return Scalar(result[0], result[1], result[2], result[3]); } -Scalar cv::gpu::absSum(const GpuMat& src) +Scalar cv::gpu::absSum(InputArray _src, InputArray _mask, GpuMat& buf) { - GpuMat buf; - return gpu::absSum(src, GpuMat(), buf); -} + GpuMat src = _src.getGpuMat(); + GpuMat mask = _mask.getGpuMat(); -Scalar cv::gpu::absSum(const GpuMat& src, GpuMat& buf) -{ - return gpu::absSum(src, GpuMat(), buf); -} - -Scalar cv::gpu::absSum(const GpuMat& src, const GpuMat& mask, GpuMat& buf) -{ typedef void (*func_t)(PtrStepSzb src, void* buf, double* sum, PtrStepSzb mask); static const func_t funcs[7][5] = { @@ -312,19 +279,11 @@ Scalar cv::gpu::absSum(const GpuMat& src, const GpuMat& mask, GpuMat& buf) return Scalar(result[0], result[1], result[2], result[3]); } -Scalar cv::gpu::sqrSum(const GpuMat& src) +Scalar cv::gpu::sqrSum(InputArray _src, InputArray _mask, GpuMat& buf) { - GpuMat buf; - return gpu::sqrSum(src, GpuMat(), buf); -} + GpuMat src = _src.getGpuMat(); + GpuMat mask = _mask.getGpuMat(); -Scalar cv::gpu::sqrSum(const GpuMat& src, GpuMat& buf) -{ - return gpu::sqrSum(src, GpuMat(), buf); -} - -Scalar cv::gpu::sqrSum(const GpuMat& src, const GpuMat& mask, GpuMat& buf) -{ typedef void (*func_t)(PtrStepSzb src, void* buf, double* sum, PtrStepSzb mask); static const func_t funcs[7][5] = { @@ -369,14 +328,11 @@ namespace minMax void run(const PtrStepSzb src, const PtrStepb mask, double* minval, double* maxval, PtrStepb buf); } -void cv::gpu::minMax(const GpuMat& src, double* minVal, double* maxVal, const GpuMat& mask) +void cv::gpu::minMax(InputArray _src, double* minVal, double* maxVal, InputArray _mask, GpuMat& buf) { - GpuMat buf; - gpu::minMax(src, minVal, maxVal, mask, buf); -} + GpuMat src = _src.getGpuMat(); + GpuMat mask = _mask.getGpuMat(); -void cv::gpu::minMax(const GpuMat& src, double* minVal, double* maxVal, const GpuMat& mask, GpuMat& buf) -{ typedef void (*func_t)(const PtrStepSzb src, const PtrStepb mask, double* minval, double* maxval, PtrStepb buf); static const func_t funcs[] = { @@ -419,15 +375,12 @@ namespace minMaxLoc void run(const PtrStepSzb src, const PtrStepb mask, double* minval, double* maxval, int* minloc, int* maxloc, PtrStepb valbuf, PtrStep locbuf); } -void cv::gpu::minMaxLoc(const GpuMat& src, double* minVal, double* maxVal, Point* minLoc, Point* maxLoc, const GpuMat& mask) +void cv::gpu::minMaxLoc(InputArray _src, double* minVal, double* maxVal, Point* minLoc, Point* maxLoc, + InputArray _mask, GpuMat& valBuf, GpuMat& locBuf) { - GpuMat valBuf, locBuf; - gpu::minMaxLoc(src, minVal, maxVal, minLoc, maxLoc, mask, valBuf, locBuf); -} + GpuMat src = _src.getGpuMat(); + GpuMat mask = _mask.getGpuMat(); -void cv::gpu::minMaxLoc(const GpuMat& src, double* minVal, double* maxVal, Point* minLoc, Point* maxLoc, - const GpuMat& mask, GpuMat& valBuf, GpuMat& locBuf) -{ typedef void (*func_t)(const PtrStepSzb src, const PtrStepb mask, double* minval, double* maxval, int* minloc, int* maxloc, PtrStepb valbuf, PtrStep locbuf); static const func_t funcs[] = { @@ -472,14 +425,10 @@ namespace countNonZero int run(const PtrStepSzb src, PtrStep buf); } -int cv::gpu::countNonZero(const GpuMat& src) +int cv::gpu::countNonZero(InputArray _src, GpuMat& buf) { - GpuMat buf; - return countNonZero(src, buf); -} + GpuMat src = _src.getGpuMat(); -int cv::gpu::countNonZero(const GpuMat& src, GpuMat& buf) -{ typedef int (*func_t)(const PtrStepSzb src, PtrStep buf); static const func_t funcs[] = { @@ -521,8 +470,10 @@ namespace reduce void cols(PtrStepSzb src, void* dst, int cn, int op, cudaStream_t stream); } -void cv::gpu::reduce(const GpuMat& src, GpuMat& dst, int dim, int reduceOp, int dtype, Stream& stream) +void cv::gpu::reduce(InputArray _src, OutputArray _dst, int dim, int reduceOp, int dtype, Stream& stream) { + GpuMat src = _src.getGpuMat(); + CV_Assert( src.channels() <= 4 ); CV_Assert( dim == 0 || dim == 1 ); CV_Assert( reduceOp == REDUCE_SUM || reduceOp == REDUCE_AVG || reduceOp == REDUCE_MAX || reduceOp == REDUCE_MIN ); @@ -530,7 +481,8 @@ void cv::gpu::reduce(const GpuMat& src, GpuMat& dst, int dim, int reduceOp, int if (dtype < 0) dtype = src.depth(); - dst.create(1, dim == 0 ? src.cols : src.rows, CV_MAKE_TYPE(CV_MAT_DEPTH(dtype), src.channels())); + _dst.create(1, dim == 0 ? src.cols : src.rows, CV_MAKE_TYPE(CV_MAT_DEPTH(dtype), src.channels())); + GpuMat dst = _dst.getGpuMat(); if (dim == 0) { @@ -691,15 +643,11 @@ void cv::gpu::reduce(const GpuMat& src, GpuMat& dst, int dim, int reduceOp, int //////////////////////////////////////////////////////////////////////// // meanStdDev -void cv::gpu::meanStdDev(const GpuMat& src, Scalar& mean, Scalar& stddev) +void cv::gpu::meanStdDev(InputArray _src, Scalar& mean, Scalar& stddev, GpuMat& buf) { - GpuMat buf; - meanStdDev(src, mean, stddev, buf); -} + GpuMat src = _src.getGpuMat(); -void cv::gpu::meanStdDev(const GpuMat& src, Scalar& mean, Scalar& stddev, GpuMat& buf) -{ - CV_Assert(src.type() == CV_8UC1); + CV_Assert( src.type() == CV_8UC1 ); if (!deviceSupports(FEATURE_SET_COMPUTE_13)) CV_Error(cv::Error::StsNotImplemented, "Not sufficient compute capebility"); @@ -730,11 +678,15 @@ void cv::gpu::meanStdDev(const GpuMat& src, Scalar& mean, Scalar& stddev, GpuMat ////////////////////////////////////////////////////////////////////////////// // rectStdDev -void cv::gpu::rectStdDev(const GpuMat& src, const GpuMat& sqr, GpuMat& dst, const Rect& rect, Stream& s) +void cv::gpu::rectStdDev(InputArray _src, InputArray _sqr, OutputArray _dst, Rect rect, Stream& _stream) { - CV_Assert(src.type() == CV_32SC1 && sqr.type() == CV_64FC1); + GpuMat src = _src.getGpuMat(); + GpuMat sqr = _sqr.getGpuMat(); - dst.create(src.size(), CV_32FC1); + CV_Assert( src.type() == CV_32SC1 && sqr.type() == CV_64FC1 ); + + _dst.create(src.size(), CV_32FC1); + GpuMat dst = _dst.getGpuMat(); NppiSize sz; sz.width = src.cols; @@ -746,7 +698,7 @@ void cv::gpu::rectStdDev(const GpuMat& src, const GpuMat& sqr, GpuMat& dst, cons nppRect.x = rect.x; nppRect.y = rect.y; - cudaStream_t stream = StreamAccessor::getStream(s); + cudaStream_t stream = StreamAccessor::getStream(_stream); NppStreamHandler h(stream); @@ -760,16 +712,12 @@ void cv::gpu::rectStdDev(const GpuMat& src, const GpuMat& sqr, GpuMat& dst, cons //////////////////////////////////////////////////////////////////////// // normalize -void cv::gpu::normalize(const GpuMat& src, GpuMat& dst, double a, double b, int norm_type, int dtype, const GpuMat& mask) +void cv::gpu::normalize(InputArray _src, OutputArray dst, double a, double b, int norm_type, int dtype, InputArray mask, GpuMat& norm_buf, GpuMat& cvt_buf) { - GpuMat norm_buf; - GpuMat cvt_buf; - normalize(src, dst, a, b, norm_type, dtype, mask, norm_buf, cvt_buf); -} + GpuMat src = _src.getGpuMat(); -void cv::gpu::normalize(const GpuMat& src, GpuMat& dst, double a, double b, int norm_type, int dtype, const GpuMat& mask, GpuMat& norm_buf, GpuMat& cvt_buf) -{ double scale = 1, shift = 0; + if (norm_type == NORM_MINMAX) { double smin = 0, smax = 0; @@ -800,4 +748,116 @@ void cv::gpu::normalize(const GpuMat& src, GpuMat& dst, double a, double b, int } } +//////////////////////////////////////////////////////////////////////// +// integral + +namespace cv { namespace gpu { namespace cudev +{ + namespace imgproc + { + void shfl_integral_gpu(const PtrStepSzb& img, PtrStepSz integral, cudaStream_t stream); + } +}}} + +void cv::gpu::integral(InputArray _src, OutputArray _dst, GpuMat& buffer, Stream& _stream) +{ + GpuMat src = _src.getGpuMat(); + + CV_Assert( src.type() == CV_8UC1 ); + + cudaStream_t stream = StreamAccessor::getStream(_stream); + + cv::Size whole; + cv::Point offset; + src.locateROI(whole, offset); + + if (deviceSupports(WARP_SHUFFLE_FUNCTIONS) && src.cols <= 2048 + && offset.x % 16 == 0 && ((src.cols + 63) / 64) * 64 <= (static_cast(src.step) - offset.x)) + { + ensureSizeIsEnough(((src.rows + 7) / 8) * 8, ((src.cols + 63) / 64) * 64, CV_32SC1, buffer); + + cv::gpu::cudev::imgproc::shfl_integral_gpu(src, buffer, stream); + + _dst.create(src.rows + 1, src.cols + 1, CV_32SC1); + GpuMat dst = _dst.getGpuMat(); + + dst.setTo(Scalar::all(0), _stream); + + GpuMat inner = dst(Rect(1, 1, src.cols, src.rows)); + GpuMat res = buffer(Rect(0, 0, src.cols, src.rows)); + + res.copyTo(inner, _stream); + } + else + { + #ifndef HAVE_OPENCV_GPULEGACY + throw_no_cuda(); + #else + _dst.create(src.rows + 1, src.cols + 1, CV_32SC1); + GpuMat dst = _dst.getGpuMat(); + + NcvSize32u roiSize; + roiSize.width = src.cols; + roiSize.height = src.rows; + + cudaDeviceProp prop; + cudaSafeCall( cudaGetDeviceProperties(&prop, cv::gpu::getDevice()) ); + + Ncv32u bufSize; + ncvSafeCall( nppiStIntegralGetSize_8u32u(roiSize, &bufSize, prop) ); + ensureSizeIsEnough(1, bufSize, CV_8UC1, buffer); + + NppStStreamHandler h(stream); + + ncvSafeCall( nppiStIntegral_8u32u_C1R(const_cast(src.ptr()), static_cast(src.step), + dst.ptr(), static_cast(dst.step), roiSize, buffer.ptr(), bufSize, prop) ); + + if (stream == 0) + cudaSafeCall( cudaDeviceSynchronize() ); + #endif + } +} + +////////////////////////////////////////////////////////////////////////////// +// sqrIntegral + +void cv::gpu::sqrIntegral(InputArray _src, OutputArray _dst, GpuMat& buf, Stream& _stream) +{ +#ifndef HAVE_OPENCV_GPULEGACY + (void) _src; + (void) _dst; + (void) _stream; + throw_no_cuda(); +#else + GpuMat src = _src.getGpuMat(); + + CV_Assert( src.type() == CV_8U ); + + NcvSize32u roiSize; + roiSize.width = src.cols; + roiSize.height = src.rows; + + cudaDeviceProp prop; + cudaSafeCall( cudaGetDeviceProperties(&prop, cv::gpu::getDevice()) ); + + Ncv32u bufSize; + ncvSafeCall(nppiStSqrIntegralGetSize_8u64u(roiSize, &bufSize, prop)); + + ensureSizeIsEnough(1, bufSize, CV_8U, buf); + + cudaStream_t stream = StreamAccessor::getStream(_stream); + + NppStStreamHandler h(stream); + + _dst.create(src.rows + 1, src.cols + 1, CV_64F); + GpuMat dst = _dst.getGpuMat(); + + ncvSafeCall(nppiStSqrIntegral_8u64u_C1R(const_cast(src.ptr(0)), static_cast(src.step), + dst.ptr(0), static_cast(dst.step), roiSize, buf.ptr(0), bufSize, prop)); + + if (stream == 0) + cudaSafeCall( cudaDeviceSynchronize() ); +#endif +} + #endif diff --git a/modules/gpuarithm/test/test_arithm.cpp b/modules/gpuarithm/test/test_arithm.cpp index 93fb0ae845..0534e219d8 100644 --- a/modules/gpuarithm/test/test_arithm.cpp +++ b/modules/gpuarithm/test/test_arithm.cpp @@ -419,8 +419,10 @@ GPU_TEST_P(Convolve, Accuracy) cv::Mat src = randomMat(size, CV_32FC1, 0.0, 100.0); cv::Mat kernel = randomMat(cv::Size(ksize, ksize), CV_32FC1, 0.0, 1.0); + cv::Ptr conv = cv::gpu::createConvolution(); + cv::gpu::GpuMat dst; - cv::gpu::convolve(loadMat(src), loadMat(kernel), dst, ccorr); + conv->convolve(loadMat(src), loadMat(kernel), dst, ccorr); cv::Mat dst_gold; convolveDFT(src, kernel, dst_gold, ccorr); diff --git a/modules/gpuarithm/test/test_core.cpp b/modules/gpuarithm/test/test_core.cpp index 45f796dc59..d465aa4634 100644 --- a/modules/gpuarithm/test/test_core.cpp +++ b/modules/gpuarithm/test/test_core.cpp @@ -323,8 +323,10 @@ GPU_TEST_P(LUT, OneChannel) cv::Mat src = randomMat(size, type); cv::Mat lut = randomMat(cv::Size(256, 1), CV_8UC1); + cv::Ptr lutAlg = cv::gpu::createLookUpTable(lut); + cv::gpu::GpuMat dst = createMat(size, CV_MAKE_TYPE(lut.depth(), src.channels())); - cv::gpu::LUT(loadMat(src, useRoi), lut, dst); + lutAlg->transform(loadMat(src, useRoi), dst); cv::Mat dst_gold; cv::LUT(src, lut, dst_gold); @@ -337,8 +339,10 @@ GPU_TEST_P(LUT, MultiChannel) cv::Mat src = randomMat(size, type); cv::Mat lut = randomMat(cv::Size(256, 1), CV_MAKE_TYPE(CV_8U, src.channels())); + cv::Ptr lutAlg = cv::gpu::createLookUpTable(lut); + cv::gpu::GpuMat dst = createMat(size, CV_MAKE_TYPE(lut.depth(), src.channels()), useRoi); - cv::gpu::LUT(loadMat(src, useRoi), lut, dst); + lutAlg->transform(loadMat(src, useRoi), dst); cv::Mat dst_gold; cv::LUT(src, lut, dst_gold); diff --git a/modules/gpuarithm/test/test_element_operations.cpp b/modules/gpuarithm/test/test_element_operations.cpp index 89f578fdd1..61ea454ead 100644 --- a/modules/gpuarithm/test/test_element_operations.cpp +++ b/modules/gpuarithm/test/test_element_operations.cpp @@ -261,6 +261,94 @@ INSTANTIATE_TEST_CASE_P(GPU_Arithm, Add_Scalar, testing::Combine( DEPTH_PAIRS, WHOLE_SUBMAT)); +//////////////////////////////////////////////////////////////////////////////// +// Add_Scalar_First + +PARAM_TEST_CASE(Add_Scalar_First, cv::gpu::DeviceInfo, cv::Size, std::pair, UseRoi) +{ + cv::gpu::DeviceInfo devInfo; + cv::Size size; + std::pair depth; + bool useRoi; + + virtual void SetUp() + { + devInfo = GET_PARAM(0); + size = GET_PARAM(1); + depth = GET_PARAM(2); + useRoi = GET_PARAM(3); + + cv::gpu::setDevice(devInfo.deviceID()); + } +}; + +GPU_TEST_P(Add_Scalar_First, WithOutMask) +{ + cv::Mat mat = randomMat(size, depth.first); + cv::Scalar val = randomScalar(0, 255); + + if ((depth.first == CV_64F || depth.second == CV_64F) && !supportFeature(devInfo, cv::gpu::NATIVE_DOUBLE)) + { + try + { + cv::gpu::GpuMat dst; + cv::gpu::add(val, loadMat(mat), dst, cv::gpu::GpuMat(), depth.second); + } + catch (const cv::Exception& e) + { + ASSERT_EQ(cv::Error::StsUnsupportedFormat, e.code); + } + } + else + { + cv::gpu::GpuMat dst = createMat(size, depth.second, useRoi); + dst.setTo(cv::Scalar::all(0)); + cv::gpu::add(val, loadMat(mat, useRoi), dst, cv::gpu::GpuMat(), depth.second); + + cv::Mat dst_gold(size, depth.second, cv::Scalar::all(0)); + cv::add(val, mat, dst_gold, cv::noArray(), depth.second); + + EXPECT_MAT_NEAR(dst_gold, dst, depth.first >= CV_32F || depth.second >= CV_32F ? 1e-4 : 0.0); + } +} + +GPU_TEST_P(Add_Scalar_First, WithMask) +{ + cv::Mat mat = randomMat(size, depth.first); + cv::Scalar val = randomScalar(0, 255); + cv::Mat mask = randomMat(size, CV_8UC1, 0.0, 2.0); + + if ((depth.first == CV_64F || depth.second == CV_64F) && !supportFeature(devInfo, cv::gpu::NATIVE_DOUBLE)) + { + try + { + cv::gpu::GpuMat dst; + cv::gpu::add(val, loadMat(mat), dst, cv::gpu::GpuMat(), depth.second); + } + catch (const cv::Exception& e) + { + ASSERT_EQ(cv::Error::StsUnsupportedFormat, e.code); + } + } + else + { + cv::gpu::GpuMat dst = createMat(size, depth.second, useRoi); + dst.setTo(cv::Scalar::all(0)); + cv::gpu::add(val, loadMat(mat, useRoi), dst, loadMat(mask, useRoi), depth.second); + + cv::Mat dst_gold(size, depth.second, cv::Scalar::all(0)); + cv::add(val, mat, dst_gold, mask, depth.second); + + EXPECT_MAT_NEAR(dst_gold, dst, depth.first >= CV_32F || depth.second >= CV_32F ? 1e-4 : 0.0); + } +} + +INSTANTIATE_TEST_CASE_P(GPU_Arithm, Add_Scalar_First, testing::Combine( + ALL_DEVICES, + DIFFERENT_SIZES, + DEPTH_PAIRS, + WHOLE_SUBMAT)); + //////////////////////////////////////////////////////////////////////////////// // Subtract_Array @@ -476,6 +564,94 @@ INSTANTIATE_TEST_CASE_P(GPU_Arithm, Subtract_Scalar, testing::Combine( DEPTH_PAIRS, WHOLE_SUBMAT)); +//////////////////////////////////////////////////////////////////////////////// +// Subtract_Scalar_First + +PARAM_TEST_CASE(Subtract_Scalar_First, cv::gpu::DeviceInfo, cv::Size, std::pair, UseRoi) +{ + cv::gpu::DeviceInfo devInfo; + cv::Size size; + std::pair depth; + bool useRoi; + + virtual void SetUp() + { + devInfo = GET_PARAM(0); + size = GET_PARAM(1); + depth = GET_PARAM(2); + useRoi = GET_PARAM(3); + + cv::gpu::setDevice(devInfo.deviceID()); + } +}; + +GPU_TEST_P(Subtract_Scalar_First, WithOutMask) +{ + cv::Mat mat = randomMat(size, depth.first); + cv::Scalar val = randomScalar(0, 255); + + if ((depth.first == CV_64F || depth.second == CV_64F) && !supportFeature(devInfo, cv::gpu::NATIVE_DOUBLE)) + { + try + { + cv::gpu::GpuMat dst; + cv::gpu::subtract(val, loadMat(mat), dst, cv::gpu::GpuMat(), depth.second); + } + catch (const cv::Exception& e) + { + ASSERT_EQ(cv::Error::StsUnsupportedFormat, e.code); + } + } + else + { + cv::gpu::GpuMat dst = createMat(size, depth.second, useRoi); + dst.setTo(cv::Scalar::all(0)); + cv::gpu::subtract(val, loadMat(mat, useRoi), dst, cv::gpu::GpuMat(), depth.second); + + cv::Mat dst_gold(size, depth.second, cv::Scalar::all(0)); + cv::subtract(val, mat, dst_gold, cv::noArray(), depth.second); + + EXPECT_MAT_NEAR(dst_gold, dst, depth.first >= CV_32F || depth.second >= CV_32F ? 1e-4 : 0.0); + } +} + +GPU_TEST_P(Subtract_Scalar_First, WithMask) +{ + cv::Mat mat = randomMat(size, depth.first); + cv::Scalar val = randomScalar(0, 255); + cv::Mat mask = randomMat(size, CV_8UC1, 0.0, 2.0); + + if ((depth.first == CV_64F || depth.second == CV_64F) && !supportFeature(devInfo, cv::gpu::NATIVE_DOUBLE)) + { + try + { + cv::gpu::GpuMat dst; + cv::gpu::subtract(val, loadMat(mat), dst, cv::gpu::GpuMat(), depth.second); + } + catch (const cv::Exception& e) + { + ASSERT_EQ(cv::Error::StsUnsupportedFormat, e.code); + } + } + else + { + cv::gpu::GpuMat dst = createMat(size, depth.second, useRoi); + dst.setTo(cv::Scalar::all(0)); + cv::gpu::subtract(val, loadMat(mat, useRoi), dst, loadMat(mask, useRoi), depth.second); + + cv::Mat dst_gold(size, depth.second, cv::Scalar::all(0)); + cv::subtract(val, mat, dst_gold, mask, depth.second); + + EXPECT_MAT_NEAR(dst_gold, dst, depth.first >= CV_32F || depth.second >= CV_32F ? 1e-4 : 0.0); + } +} + +INSTANTIATE_TEST_CASE_P(GPU_Arithm, Subtract_Scalar_First, testing::Combine( + ALL_DEVICES, + DIFFERENT_SIZES, + DEPTH_PAIRS, + WHOLE_SUBMAT)); + //////////////////////////////////////////////////////////////////////////////// // Multiply_Array @@ -756,6 +932,93 @@ INSTANTIATE_TEST_CASE_P(GPU_Arithm, Multiply_Scalar, testing::Combine( DEPTH_PAIRS, WHOLE_SUBMAT)); +//////////////////////////////////////////////////////////////////////////////// +// Multiply_Scalar_First + +PARAM_TEST_CASE(Multiply_Scalar_First, cv::gpu::DeviceInfo, cv::Size, std::pair, UseRoi) +{ + cv::gpu::DeviceInfo devInfo; + cv::Size size; + std::pair depth; + bool useRoi; + + virtual void SetUp() + { + devInfo = GET_PARAM(0); + size = GET_PARAM(1); + depth = GET_PARAM(2); + useRoi = GET_PARAM(3); + + cv::gpu::setDevice(devInfo.deviceID()); + } +}; + +GPU_TEST_P(Multiply_Scalar_First, WithOutScale) +{ + cv::Mat mat = randomMat(size, depth.first); + cv::Scalar val = randomScalar(0, 255); + + if ((depth.first == CV_64F || depth.second == CV_64F) && !supportFeature(devInfo, cv::gpu::NATIVE_DOUBLE)) + { + try + { + cv::gpu::GpuMat dst; + cv::gpu::multiply(val, loadMat(mat), dst, 1, depth.second); + } + catch (const cv::Exception& e) + { + ASSERT_EQ(cv::Error::StsUnsupportedFormat, e.code); + } + } + else + { + cv::gpu::GpuMat dst = createMat(size, depth.second, useRoi); + cv::gpu::multiply(val, loadMat(mat, useRoi), dst, 1, depth.second); + + cv::Mat dst_gold; + cv::multiply(val, mat, dst_gold, 1, depth.second); + + EXPECT_MAT_NEAR(dst_gold, dst, 1.0); + } +} + + +GPU_TEST_P(Multiply_Scalar_First, WithScale) +{ + cv::Mat mat = randomMat(size, depth.first); + cv::Scalar val = randomScalar(0, 255); + double scale = randomDouble(0.0, 255.0); + + if ((depth.first == CV_64F || depth.second == CV_64F) && !supportFeature(devInfo, cv::gpu::NATIVE_DOUBLE)) + { + try + { + cv::gpu::GpuMat dst; + cv::gpu::multiply(val, loadMat(mat), dst, scale, depth.second); + } + catch (const cv::Exception& e) + { + ASSERT_EQ(cv::Error::StsUnsupportedFormat, e.code); + } + } + else + { + cv::gpu::GpuMat dst = createMat(size, depth.second, useRoi); + cv::gpu::multiply(val, loadMat(mat, useRoi), dst, scale, depth.second); + + cv::Mat dst_gold; + cv::multiply(val, mat, dst_gold, scale, depth.second); + + EXPECT_MAT_NEAR(dst_gold, dst, 1.0); + } +} + +INSTANTIATE_TEST_CASE_P(GPU_Arithm, Multiply_Scalar_First, testing::Combine( + ALL_DEVICES, + DIFFERENT_SIZES, + DEPTH_PAIRS, + WHOLE_SUBMAT)); + //////////////////////////////////////////////////////////////////////////////// // Divide_Array @@ -1036,9 +1299,9 @@ INSTANTIATE_TEST_CASE_P(GPU_Arithm, Divide_Scalar, testing::Combine( WHOLE_SUBMAT)); //////////////////////////////////////////////////////////////////////////////// -// Divide_Scalar_Inv +// Divide_Scalar_First -PARAM_TEST_CASE(Divide_Scalar_Inv, cv::gpu::DeviceInfo, cv::Size, std::pair, UseRoi) +PARAM_TEST_CASE(Divide_Scalar_First, cv::gpu::DeviceInfo, cv::Size, std::pair, UseRoi) { cv::gpu::DeviceInfo devInfo; cv::Size size; @@ -1056,7 +1319,7 @@ PARAM_TEST_CASE(Divide_Scalar_Inv, cv::gpu::DeviceInfo, cv::Size, std::pair(power); + + if (depth == CV_64F && !supportFeature(devInfo, cv::gpu::NATIVE_DOUBLE)) + { + try + { + cv::gpu::GpuMat dst; + cv::gpu::pow(loadMat(src), power, dst); + } + catch (const cv::Exception& e) + { + ASSERT_EQ(cv::Error::StsUnsupportedFormat, e.code); + } + } + else + { + cv::gpu::GpuMat dst = createMat(size, depth, useRoi); + cv::gpu::pow(loadMat(src, useRoi), power, dst); + + cv::Mat dst_gold; + cv::pow(src, power, dst_gold); + + EXPECT_MAT_NEAR(dst_gold, dst, depth < CV_32F ? 0.0 : 1e-1); + } +} + +INSTANTIATE_TEST_CASE_P(GPU_Arithm, Pow, testing::Combine( + ALL_DEVICES, + DIFFERENT_SIZES, + ALL_DEPTH, + WHOLE_SUBMAT)); + //////////////////////////////////////////////////////////////////////////////// // Compare_Array @@ -2110,65 +2461,6 @@ INSTANTIATE_TEST_CASE_P(GPU_Arithm, Max, testing::Combine( ALL_DEPTH, WHOLE_SUBMAT)); -//////////////////////////////////////////////////////////////////////////////// -// Pow - -PARAM_TEST_CASE(Pow, cv::gpu::DeviceInfo, cv::Size, MatDepth, UseRoi) -{ - cv::gpu::DeviceInfo devInfo; - cv::Size size; - int depth; - bool useRoi; - - virtual void SetUp() - { - devInfo = GET_PARAM(0); - size = GET_PARAM(1); - depth = GET_PARAM(2); - useRoi = GET_PARAM(3); - - cv::gpu::setDevice(devInfo.deviceID()); - } -}; - -GPU_TEST_P(Pow, Accuracy) -{ - cv::Mat src = randomMat(size, depth, 0.0, 10.0); - double power = randomDouble(2.0, 4.0); - - if (src.depth() < CV_32F) - power = static_cast(power); - - if (depth == CV_64F && !supportFeature(devInfo, cv::gpu::NATIVE_DOUBLE)) - { - try - { - cv::gpu::GpuMat dst; - cv::gpu::pow(loadMat(src), power, dst); - } - catch (const cv::Exception& e) - { - ASSERT_EQ(cv::Error::StsUnsupportedFormat, e.code); - } - } - else - { - cv::gpu::GpuMat dst = createMat(size, depth, useRoi); - cv::gpu::pow(loadMat(src, useRoi), power, dst); - - cv::Mat dst_gold; - cv::pow(src, power, dst_gold); - - EXPECT_MAT_NEAR(dst_gold, dst, depth < CV_32F ? 0.0 : 1e-1); - } -} - -INSTANTIATE_TEST_CASE_P(GPU_Arithm, Pow, testing::Combine( - ALL_DEVICES, - DIFFERENT_SIZES, - ALL_DEPTH, - WHOLE_SUBMAT)); - ////////////////////////////////////////////////////////////////////////////// // AddWeighted @@ -2234,6 +2526,54 @@ INSTANTIATE_TEST_CASE_P(GPU_Arithm, AddWeighted, testing::Combine( ALL_DEPTH, WHOLE_SUBMAT)); +/////////////////////////////////////////////////////////////////////////////////////////////////////// +// Threshold + +CV_ENUM(ThreshOp, cv::THRESH_BINARY, cv::THRESH_BINARY_INV, cv::THRESH_TRUNC, cv::THRESH_TOZERO, cv::THRESH_TOZERO_INV) +#define ALL_THRESH_OPS testing::Values(ThreshOp(cv::THRESH_BINARY), ThreshOp(cv::THRESH_BINARY_INV), ThreshOp(cv::THRESH_TRUNC), ThreshOp(cv::THRESH_TOZERO), ThreshOp(cv::THRESH_TOZERO_INV)) + +PARAM_TEST_CASE(Threshold, cv::gpu::DeviceInfo, cv::Size, MatType, ThreshOp, UseRoi) +{ + cv::gpu::DeviceInfo devInfo; + cv::Size size; + int type; + int threshOp; + bool useRoi; + + virtual void SetUp() + { + devInfo = GET_PARAM(0); + size = GET_PARAM(1); + type = GET_PARAM(2); + threshOp = GET_PARAM(3); + useRoi = GET_PARAM(4); + + cv::gpu::setDevice(devInfo.deviceID()); + } +}; + +GPU_TEST_P(Threshold, Accuracy) +{ + cv::Mat src = randomMat(size, type); + double maxVal = randomDouble(20.0, 127.0); + double thresh = randomDouble(0.0, maxVal); + + cv::gpu::GpuMat dst = createMat(src.size(), src.type(), useRoi); + cv::gpu::threshold(loadMat(src, useRoi), dst, thresh, maxVal, threshOp); + + cv::Mat dst_gold; + cv::threshold(src, dst_gold, thresh, maxVal, threshOp); + + EXPECT_MAT_NEAR(dst_gold, dst, 0.0); +} + +INSTANTIATE_TEST_CASE_P(GPU_Arithm, Threshold, testing::Combine( + ALL_DEVICES, + DIFFERENT_SIZES, + testing::Values(MatType(CV_8UC1), MatType(CV_16SC1), MatType(CV_32FC1)), + ALL_THRESH_OPS, + WHOLE_SUBMAT)); + //////////////////////////////////////////////////////////////////////////////// // Magnitude @@ -2452,52 +2792,4 @@ INSTANTIATE_TEST_CASE_P(GPU_Arithm, PolarToCart, testing::Combine( testing::Values(AngleInDegrees(false), AngleInDegrees(true)), WHOLE_SUBMAT)); -/////////////////////////////////////////////////////////////////////////////////////////////////////// -// Threshold - -CV_ENUM(ThreshOp, cv::THRESH_BINARY, cv::THRESH_BINARY_INV, cv::THRESH_TRUNC, cv::THRESH_TOZERO, cv::THRESH_TOZERO_INV) -#define ALL_THRESH_OPS testing::Values(ThreshOp(cv::THRESH_BINARY), ThreshOp(cv::THRESH_BINARY_INV), ThreshOp(cv::THRESH_TRUNC), ThreshOp(cv::THRESH_TOZERO), ThreshOp(cv::THRESH_TOZERO_INV)) - -PARAM_TEST_CASE(Threshold, cv::gpu::DeviceInfo, cv::Size, MatType, ThreshOp, UseRoi) -{ - cv::gpu::DeviceInfo devInfo; - cv::Size size; - int type; - int threshOp; - bool useRoi; - - virtual void SetUp() - { - devInfo = GET_PARAM(0); - size = GET_PARAM(1); - type = GET_PARAM(2); - threshOp = GET_PARAM(3); - useRoi = GET_PARAM(4); - - cv::gpu::setDevice(devInfo.deviceID()); - } -}; - -GPU_TEST_P(Threshold, Accuracy) -{ - cv::Mat src = randomMat(size, type); - double maxVal = randomDouble(20.0, 127.0); - double thresh = randomDouble(0.0, maxVal); - - cv::gpu::GpuMat dst = createMat(src.size(), src.type(), useRoi); - cv::gpu::threshold(loadMat(src, useRoi), dst, thresh, maxVal, threshOp); - - cv::Mat dst_gold; - cv::threshold(src, dst_gold, thresh, maxVal, threshOp); - - EXPECT_MAT_NEAR(dst_gold, dst, 0.0); -} - -INSTANTIATE_TEST_CASE_P(GPU_Arithm, Threshold, testing::Combine( - ALL_DEVICES, - DIFFERENT_SIZES, - testing::Values(MatType(CV_8UC1), MatType(CV_16SC1), MatType(CV_32FC1)), - ALL_THRESH_OPS, - WHOLE_SUBMAT)); - #endif // HAVE_CUDA diff --git a/modules/gpufilters/doc/filtering.rst b/modules/gpufilters/doc/filtering.rst index 348a42510e..79c2ea51cf 100644 --- a/modules/gpufilters/doc/filtering.rst +++ b/modules/gpufilters/doc/filtering.rst @@ -381,7 +381,7 @@ Creates a non-separable linear filter. :param dstType: Output image type. The same type as ``src`` is supported. - :param kernel: 2D array of filter coefficients. Floating-point coefficients will be converted to fixed-point representation before the actual processing. Supports size up to 16. For larger kernels use :ocv:func:`gpu::convolve`. + :param kernel: 2D array of filter coefficients. Floating-point coefficients will be converted to fixed-point representation before the actual processing. Supports size up to 16. For larger kernels use :ocv:class:`gpu::Convolution`. :param anchor: Anchor point. The default value Point(-1, -1) means that the anchor is at the kernel center. @@ -411,7 +411,7 @@ Applies the non-separable 2D linear filter to an image. :param stream: Stream for the asynchronous version. -.. seealso:: :ocv:func:`filter2D`, :ocv:func:`gpu::convolve` +.. seealso:: :ocv:func:`filter2D`, :ocv:class:`gpu::Convolution` diff --git a/modules/gpuimgproc/src/hough.cpp b/modules/gpuimgproc/src/hough.cpp index bc0a8a400d..15e5297623 100644 --- a/modules/gpuimgproc/src/hough.cpp +++ b/modules/gpuimgproc/src/hough.cpp @@ -761,7 +761,7 @@ namespace { buildRTable_gpu(edgePointList.ptr(0), edgePointList.ptr(1), edgePointList.cols, r_table, r_sizes.ptr(), make_short2(templCenter.x, templCenter.y), levels); - min(r_sizes, maxSize, r_sizes); + gpu::min(r_sizes, maxSize, r_sizes); } } diff --git a/modules/gpuimgproc/src/match_template.cpp b/modules/gpuimgproc/src/match_template.cpp index 008d3da1ce..059d41ca9f 100644 --- a/modules/gpuimgproc/src/match_template.cpp +++ b/modules/gpuimgproc/src/match_template.cpp @@ -172,15 +172,16 @@ namespace return; } - gpu::ConvolveBuf convolve_buf; - convolve_buf.user_block_size = buf.user_block_size; + Ptr conv = gpu::createConvolution(buf.user_block_size); if (image.channels() == 1) - gpu::convolve(image.reshape(1), templ.reshape(1), result, true, convolve_buf, stream); + { + conv->convolve(image.reshape(1), templ.reshape(1), result, true, stream); + } else { GpuMat result_; - gpu::convolve(image.reshape(1), templ.reshape(1), result_, true, convolve_buf, stream); + conv->convolve(image.reshape(1), templ.reshape(1), result_, true, stream); extractFirstChannel_32F(result_, result, image.channels(), StreamAccessor::getStream(stream)); } } @@ -268,7 +269,7 @@ namespace buf.image_sums.resize(1); gpu::integral(image, buf.image_sums[0], stream); - unsigned int templ_sum = (unsigned int)sum(templ)[0]; + unsigned int templ_sum = (unsigned int)gpu::sum(templ)[0]; matchTemplatePrepared_CCOFF_8U(templ.cols, templ.rows, buf.image_sums[0], templ_sum, result, StreamAccessor::getStream(stream)); } else diff --git a/modules/nonfree/src/surf_gpu.cpp b/modules/nonfree/src/surf_gpu.cpp index ace9bb53ab..35805470b2 100644 --- a/modules/nonfree/src/surf_gpu.cpp +++ b/modules/nonfree/src/surf_gpu.cpp @@ -142,13 +142,13 @@ namespace bindImgTex(img); - gpu::integralBuffered(img, surf_.sum, surf_.intBuffer); + gpu::integral(img, surf_.sum, surf_.intBuffer); sumOffset = bindSumTex(surf_.sum); if (use_mask) { - min(mask, 1.0, surf_.mask1); - gpu::integralBuffered(surf_.mask1, surf_.maskSum, surf_.intBuffer); + gpu::min(mask, 1.0, surf_.mask1); + gpu::integral(surf_.mask1, surf_.maskSum, surf_.intBuffer); maskOffset = bindMaskSumTex(surf_.maskSum); } } diff --git a/samples/gpu/driver_api_multi.cpp b/samples/gpu/driver_api_multi.cpp index 8b4623f41b..1dfe2123c0 100644 --- a/samples/gpu/driver_api_multi.cpp +++ b/samples/gpu/driver_api_multi.cpp @@ -130,15 +130,15 @@ void Worker::operator()(int device_id) const rng.fill(src, RNG::UNIFORM, 0, 1); // CPU works - transpose(src, dst); + cv::transpose(src, dst); // GPU works GpuMat d_src(src); GpuMat d_dst; - transpose(d_src, d_dst); + gpu::transpose(d_src, d_dst); // Check results - bool passed = norm(dst - Mat(d_dst), NORM_INF) < 1e-3; + bool passed = cv::norm(dst - Mat(d_dst), NORM_INF) < 1e-3; std::cout << "GPU #" << device_id << " (" << DeviceInfo().name() << "): " << (passed ? "passed" : "FAILED") << endl; diff --git a/samples/gpu/farneback_optical_flow.cpp b/samples/gpu/farneback_optical_flow.cpp index c93ceb055f..c2a5d411e4 100644 --- a/samples/gpu/farneback_optical_flow.cpp +++ b/samples/gpu/farneback_optical_flow.cpp @@ -22,9 +22,9 @@ inline T mapVal(T x, T a, T b, T c, T d) static void colorizeFlow(const Mat &u, const Mat &v, Mat &dst) { double uMin, uMax; - minMaxLoc(u, &uMin, &uMax, 0, 0); + cv::minMaxLoc(u, &uMin, &uMax, 0, 0); double vMin, vMax; - minMaxLoc(v, &vMin, &vMax, 0, 0); + cv::minMaxLoc(v, &vMin, &vMax, 0, 0); uMin = ::abs(uMin); uMax = ::abs(uMax); vMin = ::abs(vMin); vMax = ::abs(vMax); float dMax = static_cast(::max(::max(uMin, uMax), ::max(vMin, vMax))); diff --git a/samples/gpu/multi.cpp b/samples/gpu/multi.cpp index 34b111829c..c6e6aa3984 100644 --- a/samples/gpu/multi.cpp +++ b/samples/gpu/multi.cpp @@ -87,15 +87,15 @@ void Worker::operator()(int device_id) const rng.fill(src, RNG::UNIFORM, 0, 1); // CPU works - transpose(src, dst); + cv::transpose(src, dst); // GPU works GpuMat d_src(src); GpuMat d_dst; - transpose(d_src, d_dst); + gpu::transpose(d_src, d_dst); // Check results - bool passed = norm(dst - Mat(d_dst), NORM_INF) < 1e-3; + bool passed = cv::norm(dst - Mat(d_dst), NORM_INF) < 1e-3; std::cout << "GPU #" << device_id << " (" << DeviceInfo().name() << "): " << (passed ? "passed" : "FAILED") << endl;