Unverified Commit d7d6360f authored by cudawarped's avatar cudawarped Committed by GitHub

Merge pull request #2396 from cudawarped:fix_python_cudawarping_cudaarithm

Add python bindings to cudaobjdetect, cudawarping and cudaarithm

* Overload cudawarping functions to generate correct python bindings.
Add python wrapper to convolution funciton.

* Added shift and hog.

* Moved cuda python tests to this repo and added python bindings to SURF.

* Fix SURF documentation and allow meanshiftsegmention to create GpuMat internaly if not passed for python bindings consistency.

* Add correct cuda SURF test case.

* Fix python mog and mog2 python bindings, add tests and  correct cudawarping documentation.

* Updated KeyPoints in cuda::ORB::Convert python wrapper to be an output argument.

* Add changes suggested by alalek

* Added changes suggested by asmorkalov
parent 223a3cda
...@@ -274,6 +274,10 @@ CV_EXPORTS_W void bitwise_xor(InputArray src1, InputArray src2, OutputArray dst, ...@@ -274,6 +274,10 @@ CV_EXPORTS_W void bitwise_xor(InputArray src1, InputArray src2, OutputArray dst,
*/ */
CV_EXPORTS void rshift(InputArray src, Scalar_<int> val, OutputArray dst, Stream& stream = Stream::Null()); CV_EXPORTS void rshift(InputArray src, Scalar_<int> val, OutputArray dst, Stream& stream = Stream::Null());
CV_WRAP inline void rshift(InputArray src, Scalar val, OutputArray dst, Stream& stream = Stream::Null()) {
rshift(src, Scalar_<int>(val), dst, stream);
}
/** @brief Performs pixel by pixel right left of an image by a constant value. /** @brief Performs pixel by pixel right left of an image by a constant value.
@param src Source matrix. Supports 1, 3 and 4 channels images with CV_8U , CV_16U or CV_32S @param src Source matrix. Supports 1, 3 and 4 channels images with CV_8U , CV_16U or CV_32S
...@@ -284,6 +288,10 @@ depth. ...@@ -284,6 +288,10 @@ depth.
*/ */
CV_EXPORTS void lshift(InputArray src, Scalar_<int> val, OutputArray dst, Stream& stream = Stream::Null()); CV_EXPORTS void lshift(InputArray src, Scalar_<int> val, OutputArray dst, Stream& stream = Stream::Null());
CV_WRAP inline void lshift(InputArray src, Scalar val, OutputArray dst, Stream& stream = Stream::Null()) {
lshift(src, Scalar_<int>(val), dst, stream);
}
/** @brief Computes the per-element minimum of two matrices (or a matrix and a scalar). /** @brief Computes the per-element minimum of two matrices (or a matrix and a scalar).
@param src1 First source matrix or scalar. @param src1 First source matrix or scalar.
...@@ -858,7 +866,7 @@ public: ...@@ -858,7 +866,7 @@ public:
@param ccorr Flags to evaluate cross-correlation instead of convolution. @param ccorr Flags to evaluate cross-correlation instead of convolution.
@param stream Stream for the asynchronous version. @param stream Stream for the asynchronous version.
*/ */
virtual void convolve(InputArray image, InputArray templ, OutputArray result, bool ccorr = false, Stream& stream = Stream::Null()) = 0; CV_WRAP virtual void convolve(InputArray image, InputArray templ, OutputArray result, bool ccorr = false, Stream& stream = Stream::Null()) = 0;
}; };
/** @brief Creates implementation for cuda::Convolution . /** @brief Creates implementation for cuda::Convolution .
......
#!/usr/bin/env python
import os
import cv2 as cv
import numpy as np
from tests_common import NewOpenCVTests, unittest
class cudaarithm_test(NewOpenCVTests):
def setUp(self):
super(cudaarithm_test, self).setUp()
if not cv.cuda.getCudaEnabledDeviceCount():
self.skipTest("No CUDA-capable device is detected")
def test_cudaarithm(self):
npMat = (np.random.random((128, 128, 3)) * 255).astype(np.uint8)
cuMat = cv.cuda_GpuMat(npMat)
cuMatDst = cv.cuda_GpuMat(cuMat.size(),cuMat.type())
cuMatB = cv.cuda_GpuMat(cuMat.size(),cv.CV_8UC1)
cuMatG = cv.cuda_GpuMat(cuMat.size(),cv.CV_8UC1)
cuMatR = cv.cuda_GpuMat(cuMat.size(),cv.CV_8UC1)
self.assertTrue(np.allclose(cv.cuda.merge(cv.cuda.split(cuMat)),npMat))
cv.cuda.split(cuMat,[cuMatB,cuMatG,cuMatR])
cv.cuda.merge([cuMatB,cuMatG,cuMatR],cuMatDst)
self.assertTrue(np.allclose(cuMatDst.download(),npMat))
shift = (np.random.random((cuMat.channels(),)) * 8).astype(np.uint8).tolist()
self.assertTrue(np.allclose(cv.cuda.rshift(cuMat,shift).download(),npMat >> shift))
cv.cuda.rshift(cuMat,shift,cuMatDst)
self.assertTrue(np.allclose(cuMatDst.download(),npMat >> shift))
self.assertTrue(np.allclose(cv.cuda.lshift(cuMat,shift).download(),(npMat << shift).astype('uint8')))
cv.cuda.lshift(cuMat,shift,cuMatDst)
self.assertTrue(np.allclose(cuMatDst.download(),(npMat << shift).astype('uint8')))
def test_arithmetic(self):
npMat1 = np.random.random((128, 128, 3)) - 0.5
npMat2 = np.random.random((128, 128, 3)) - 0.5
cuMat1 = cv.cuda_GpuMat()
cuMat2 = cv.cuda_GpuMat()
cuMat1.upload(npMat1)
cuMat2.upload(npMat2)
cuMatDst = cv.cuda_GpuMat(cuMat1.size(),cuMat1.type())
self.assertTrue(np.allclose(cv.cuda.add(cuMat1, cuMat2).download(),
cv.add(npMat1, npMat2)))
cv.cuda.add(cuMat1, cuMat2, cuMatDst)
self.assertTrue(np.allclose(cuMatDst.download(),cv.add(npMat1, npMat2)))
self.assertTrue(np.allclose(cv.cuda.subtract(cuMat1, cuMat2).download(),
cv.subtract(npMat1, npMat2)))
cv.cuda.subtract(cuMat1, cuMat2, cuMatDst)
self.assertTrue(np.allclose(cuMatDst.download(),cv.subtract(npMat1, npMat2)))
self.assertTrue(np.allclose(cv.cuda.multiply(cuMat1, cuMat2).download(),
cv.multiply(npMat1, npMat2)))
cv.cuda.multiply(cuMat1, cuMat2, cuMatDst)
self.assertTrue(np.allclose(cuMatDst.download(),cv.multiply(npMat1, npMat2)))
self.assertTrue(np.allclose(cv.cuda.divide(cuMat1, cuMat2).download(),
cv.divide(npMat1, npMat2)))
cv.cuda.divide(cuMat1, cuMat2, cuMatDst)
self.assertTrue(np.allclose(cuMatDst.download(),cv.divide(npMat1, npMat2)))
self.assertTrue(np.allclose(cv.cuda.absdiff(cuMat1, cuMat2).download(),
cv.absdiff(npMat1, npMat2)))
cv.cuda.absdiff(cuMat1, cuMat2, cuMatDst)
self.assertTrue(np.allclose(cuMatDst.download(),cv.absdiff(npMat1, npMat2)))
self.assertTrue(np.allclose(cv.cuda.compare(cuMat1, cuMat2, cv.CMP_GE).download(),
cv.compare(npMat1, npMat2, cv.CMP_GE)))
cuMatDst1 = cv.cuda_GpuMat(cuMat1.size(),cv.CV_8UC3)
cv.cuda.compare(cuMat1, cuMat2, cv.CMP_GE, cuMatDst1)
self.assertTrue(np.allclose(cuMatDst1.download(),cv.compare(npMat1, npMat2, cv.CMP_GE)))
self.assertTrue(np.allclose(cv.cuda.abs(cuMat1).download(),
np.abs(npMat1)))
cv.cuda.abs(cuMat1, cuMatDst)
self.assertTrue(np.allclose(cuMatDst.download(),np.abs(npMat1)))
self.assertTrue(np.allclose(cv.cuda.sqrt(cv.cuda.sqr(cuMat1)).download(),
cv.cuda.abs(cuMat1).download()))
cv.cuda.sqr(cuMat1, cuMatDst)
cv.cuda.sqrt(cuMatDst, cuMatDst)
self.assertTrue(np.allclose(cuMatDst.download(),cv.cuda.abs(cuMat1).download()))
self.assertTrue(np.allclose(cv.cuda.log(cv.cuda.exp(cuMat1)).download(),
npMat1))
cv.cuda.exp(cuMat1, cuMatDst)
cv.cuda.log(cuMatDst, cuMatDst)
self.assertTrue(np.allclose(cuMatDst.download(),npMat1))
self.assertTrue(np.allclose(cv.cuda.pow(cuMat1, 2).download(),
cv.pow(npMat1, 2)))
cv.cuda.pow(cuMat1, 2, cuMatDst)
self.assertTrue(np.allclose(cuMatDst.download(),cv.pow(npMat1, 2)))
def test_logical(self):
npMat1 = (np.random.random((128, 128)) * 255).astype(np.uint8)
npMat2 = (np.random.random((128, 128)) * 255).astype(np.uint8)
cuMat1 = cv.cuda_GpuMat()
cuMat2 = cv.cuda_GpuMat()
cuMat1.upload(npMat1)
cuMat2.upload(npMat2)
cuMatDst = cv.cuda_GpuMat(cuMat1.size(),cuMat1.type())
self.assertTrue(np.allclose(cv.cuda.bitwise_or(cuMat1, cuMat2).download(),
cv.bitwise_or(npMat1, npMat2)))
cv.cuda.bitwise_or(cuMat1, cuMat2, cuMatDst)
self.assertTrue(np.allclose(cuMatDst.download(),cv.bitwise_or(npMat1, npMat2)))
self.assertTrue(np.allclose(cv.cuda.bitwise_and(cuMat1, cuMat2).download(),
cv.bitwise_and(npMat1, npMat2)))
cv.cuda.bitwise_and(cuMat1, cuMat2, cuMatDst)
self.assertTrue(np.allclose(cuMatDst.download(),cv.bitwise_and(npMat1, npMat2)))
self.assertTrue(np.allclose(cv.cuda.bitwise_xor(cuMat1, cuMat2).download(),
cv.bitwise_xor(npMat1, npMat2)))
cv.cuda.bitwise_xor(cuMat1, cuMat2, cuMatDst)
self.assertTrue(np.allclose(cuMatDst.download(),cv.bitwise_xor(npMat1, npMat2)))
self.assertTrue(np.allclose(cv.cuda.bitwise_not(cuMat1).download(),
cv.bitwise_not(npMat1)))
cv.cuda.bitwise_not(cuMat1, cuMatDst)
self.assertTrue(np.allclose(cuMatDst.download(),cv.bitwise_not(npMat1)))
self.assertTrue(np.allclose(cv.cuda.min(cuMat1, cuMat2).download(),
cv.min(npMat1, npMat2)))
cv.cuda.min(cuMat1, cuMat2, cuMatDst)
self.assertTrue(np.allclose(cuMatDst.download(),cv.min(npMat1, npMat2)))
self.assertTrue(np.allclose(cv.cuda.max(cuMat1, cuMat2).download(),
cv.max(npMat1, npMat2)))
cv.cuda.max(cuMat1, cuMat2, cuMatDst)
self.assertTrue(np.allclose(cuMatDst.download(),cv.max(npMat1, npMat2)))
def test_convolution(self):
npMat = (np.random.random((128, 128)) * 255).astype(np.float32)
npDims = np.array(npMat.shape)
kernel = (np.random.random((3, 3)) * 1).astype(np.float32)
kernelDims = np.array(kernel.shape)
iS = (kernelDims/2).astype(int)
iE = npDims - kernelDims + iS
cuMat = cv.cuda_GpuMat(npMat)
cuKernel= cv.cuda_GpuMat(kernel)
cuMatDst = cv.cuda_GpuMat(tuple(npDims - kernelDims + 1), cuMat.type())
conv = cv.cuda.createConvolution()
self.assertTrue(np.allclose(conv.convolve(cuMat,cuKernel,ccorr=True).download(),
cv.filter2D(npMat,-1,kernel,anchor=(-1,-1))[iS[0]:iE[0]+1,iS[1]:iE[1]+1]))
conv.convolve(cuMat,cuKernel,cuMatDst,True)
self.assertTrue(np.allclose(cuMatDst.download(),
cv.filter2D(npMat,-1,kernel,anchor=(-1,-1))[iS[0]:iE[0]+1,iS[1]:iE[1]+1]))
if __name__ == '__main__':
NewOpenCVTests.bootstrap()
\ No newline at end of file
...@@ -85,7 +85,11 @@ public: ...@@ -85,7 +85,11 @@ public:
CV_WRAP virtual void apply(InputArray image, OutputArray fgmask, double learningRate, Stream& stream) = 0; CV_WRAP virtual void apply(InputArray image, OutputArray fgmask, double learningRate, Stream& stream) = 0;
using cv::BackgroundSubtractor::getBackgroundImage; using cv::BackgroundSubtractor::getBackgroundImage;
CV_WRAP virtual void getBackgroundImage(OutputArray backgroundImage, Stream& stream) const = 0; virtual void getBackgroundImage(OutputArray backgroundImage, Stream& stream) const = 0;
CV_WRAP inline void getBackgroundImage(CV_OUT GpuMat& backgroundImage, Stream& stream) {
getBackgroundImage(OutputArray(backgroundImage), stream);
}
CV_WRAP virtual int getHistory() const = 0; CV_WRAP virtual int getHistory() const = 0;
CV_WRAP virtual void setHistory(int nframes) = 0; CV_WRAP virtual void setHistory(int nframes) = 0;
...@@ -131,7 +135,11 @@ public: ...@@ -131,7 +135,11 @@ public:
CV_WRAP virtual void apply(InputArray image, OutputArray fgmask, double learningRate, Stream& stream) = 0; CV_WRAP virtual void apply(InputArray image, OutputArray fgmask, double learningRate, Stream& stream) = 0;
CV_WRAP virtual void getBackgroundImage(OutputArray backgroundImage, Stream& stream) const = 0; virtual void getBackgroundImage(OutputArray backgroundImage, Stream& stream) const = 0;
CV_WRAP inline void getBackgroundImage(CV_OUT GpuMat &backgroundImage, Stream& stream) {
getBackgroundImage(OutputArray(backgroundImage), stream);
}
}; };
/** @brief Creates MOG2 Background Subtractor /** @brief Creates MOG2 Background Subtractor
......
#!/usr/bin/env python
import os
import cv2 as cv
import numpy as np
from tests_common import NewOpenCVTests, unittest
class cudabgsegm_test(NewOpenCVTests):
def setUp(self):
super(cudabgsegm_test, self).setUp()
if not cv.cuda.getCudaEnabledDeviceCount():
self.skipTest("No CUDA-capable device is detected")
def test_cudabgsegm(self):
lr = 0.05
sz = (128,128,1)
npMat = (np.random.random(sz) * 255).astype(np.uint8)
cuMat = cv.cuda_GpuMat(npMat)
cuMatBg = cv.cuda_GpuMat(cuMat.size(),cuMat.type())
cuMatFg = cv.cuda_GpuMat(cuMat.size(),cuMat.type())
mog = cv.cuda.createBackgroundSubtractorMOG()
mog.apply(cuMat, lr, cv.cuda.Stream_Null(), cuMatFg)
mog.getBackgroundImage(cv.cuda.Stream_Null(),cuMatBg)
self.assertTrue(sz[:2] == cuMatFg.size() == cuMatBg.size())
self.assertTrue(sz[2] == cuMatFg.channels() == cuMatBg.channels())
self.assertTrue(cv.CV_8UC1 == cuMatFg.type() == cuMatBg.type())
mog = cv.cuda.createBackgroundSubtractorMOG()
self.assertTrue(np.allclose(cuMatFg.download(),mog.apply(cuMat, lr, cv.cuda.Stream_Null()).download()))
self.assertTrue(np.allclose(cuMatBg.download(),mog.getBackgroundImage(cv.cuda.Stream_Null()).download()))
mog2 = cv.cuda.createBackgroundSubtractorMOG2()
mog2.apply(cuMat, lr, cv.cuda.Stream_Null(), cuMatFg)
mog2.getBackgroundImage(cv.cuda.Stream_Null(),cuMatBg)
self.assertTrue(sz[:2] == cuMatFg.size() == cuMatBg.size())
self.assertTrue(sz[2] == cuMatFg.channels() == cuMatBg.channels())
self.assertTrue(cv.CV_8UC1 == cuMatFg.type() == cuMatBg.type())
mog2 = cv.cuda.createBackgroundSubtractorMOG2()
self.assertTrue(np.allclose(cuMatFg.download(),mog2.apply(cuMat, lr, cv.cuda.Stream_Null()).download()))
self.assertTrue(np.allclose(cuMatBg.download(),mog2.getBackgroundImage(cv.cuda.Stream_Null()).download()))
if __name__ == '__main__':
NewOpenCVTests.bootstrap()
\ No newline at end of file
#!/usr/bin/env python
import os
import cv2 as cv
import numpy as np
from tests_common import NewOpenCVTests, unittest
class cudacodec_test(NewOpenCVTests):
def setUp(self):
super(cudacodec_test, self).setUp()
if not cv.cuda.getCudaEnabledDeviceCount():
self.skipTest("No CUDA-capable device is detected")
@unittest.skipIf('OPENCV_TEST_DATA_PATH' not in os.environ,
"OPENCV_TEST_DATA_PATH is not defined")
def test_reader(self):
#Test the functionality but not the results of the video reader
vid_path = os.environ['OPENCV_TEST_DATA_PATH'] + '/cv/video/1920x1080.avi'
try:
reader = cv.cudacodec.createVideoReader(vid_path)
ret, gpu_mat = reader.nextFrame()
self.assertTrue(ret)
self.assertTrue('GpuMat' in str(type(gpu_mat)), msg=type(gpu_mat))
#TODO: print(cv.utils.dumpInputArray(gpu_mat)) # - no support for GpuMat
# not checking output, therefore sepearate tests for different signatures is unecessary
ret, _gpu_mat2 = reader.nextFrame(gpu_mat)
#TODO: self.assertTrue(gpu_mat == gpu_mat2)
self.assertTrue(ret)
except cv.error as e:
notSupported = (e.code == cv.Error.StsNotImplemented or e.code == cv.Error.StsUnsupportedFormat or e.code == cv.Error.GPU_API_CALL_ERROR)
self.assertTrue(notSupported)
if e.code == cv.Error.StsNotImplemented:
self.skipTest("NVCUVID is not installed")
elif e.code == cv.Error.StsUnsupportedFormat:
self.skipTest("GPU hardware video decoder missing or video format not supported")
elif e.code == cv.Error.GPU_API_CALL_ERRROR:
self.skipTest("GPU hardware video decoder is missing")
else:
self.skipTest(e.err)
def test_writer_existence(self):
#Test at least the existence of wrapped functions for now
try:
_writer = cv.cudacodec.createVideoWriter("tmp", (128, 128), 30)
except cv.error as e:
self.assertEqual(e.code, cv.Error.StsNotImplemented)
self.skipTest("NVCUVENC is not installed")
self.assertTrue(True) #It is sufficient that no exceptions have been there
if __name__ == '__main__':
NewOpenCVTests.bootstrap()
\ No newline at end of file
...@@ -414,7 +414,7 @@ public: ...@@ -414,7 +414,7 @@ public:
/** Converts keypoints array from internal representation to standard vector. */ /** Converts keypoints array from internal representation to standard vector. */
CV_WRAP virtual void convert(InputArray gpu_keypoints, CV_WRAP virtual void convert(InputArray gpu_keypoints,
std::vector<KeyPoint>& keypoints) = 0; CV_OUT std::vector<KeyPoint>& keypoints) = 0;
}; };
// //
......
#!/usr/bin/env python
import os
import cv2 as cv
import numpy as np
from tests_common import NewOpenCVTests, unittest
class cudafeatures2d_test(NewOpenCVTests):
def setUp(self):
super(cudafeatures2d_test, self).setUp()
if not cv.cuda.getCudaEnabledDeviceCount():
self.skipTest("No CUDA-capable device is detected")
def test_cudafeatures2d(self):
npMat1 = self.get_sample("samples/data/right01.jpg")
npMat2 = self.get_sample("samples/data/right02.jpg")
cuMat1 = cv.cuda_GpuMat()
cuMat2 = cv.cuda_GpuMat()
cuMat1.upload(npMat1)
cuMat2.upload(npMat2)
cuMat1 = cv.cuda.cvtColor(cuMat1, cv.COLOR_RGB2GRAY)
cuMat2 = cv.cuda.cvtColor(cuMat2, cv.COLOR_RGB2GRAY)
fast = cv.cuda_FastFeatureDetector.create()
_kps = fast.detectAsync(cuMat1)
orb = cv.cuda_ORB.create()
_kps1, descs1 = orb.detectAndComputeAsync(cuMat1, None)
_kps2, descs2 = orb.detectAndComputeAsync(cuMat2, None)
self.assertTrue(len(orb.convert(_kps1)) == _kps1.size()[0])
self.assertTrue(len(orb.convert(_kps2)) == _kps2.size()[0])
bf = cv.cuda_DescriptorMatcher.createBFMatcher(cv.NORM_HAMMING)
matches = bf.match(descs1, descs2)
self.assertGreater(len(matches), 0)
matches = bf.knnMatch(descs1, descs2, 2)
self.assertGreater(len(matches), 0)
matches = bf.radiusMatch(descs1, descs2, 0.1)
self.assertGreater(len(matches), 0)
self.assertTrue(True) #It is sufficient that no exceptions have been there
if __name__ == '__main__':
NewOpenCVTests.bootstrap()
\ No newline at end of file
#!/usr/bin/env python
import os
import cv2 as cv
import numpy as np
from tests_common import NewOpenCVTests, unittest
class cudafilters_test(NewOpenCVTests):
def setUp(self):
super(cudafilters_test, self).setUp()
if not cv.cuda.getCudaEnabledDeviceCount():
self.skipTest("No CUDA-capable device is detected")
def test_existence(self):
#Test at least the existence of wrapped functions for now
_filter = cv.cuda.createBoxFilter(cv.CV_8UC1, -1, (3, 3))
_filter = cv.cuda.createLinearFilter(cv.CV_8UC4, -1, np.eye(3))
_filter = cv.cuda.createLaplacianFilter(cv.CV_16UC1, -1, ksize=3)
_filter = cv.cuda.createSeparableLinearFilter(cv.CV_8UC1, -1, np.eye(3), np.eye(3))
_filter = cv.cuda.createDerivFilter(cv.CV_8UC1, -1, 1, 1, 3)
_filter = cv.cuda.createSobelFilter(cv.CV_8UC1, -1, 1, 1)
_filter = cv.cuda.createScharrFilter(cv.CV_8UC1, -1, 1, 0)
_filter = cv.cuda.createGaussianFilter(cv.CV_8UC1, -1, (3, 3), 16)
_filter = cv.cuda.createMorphologyFilter(cv.MORPH_DILATE, cv.CV_32FC1, np.eye(3))
_filter = cv.cuda.createBoxMaxFilter(cv.CV_8UC1, (3, 3))
_filter = cv.cuda.createBoxMinFilter(cv.CV_8UC1, (3, 3))
_filter = cv.cuda.createRowSumFilter(cv.CV_8UC1, cv.CV_32FC1, 3)
_filter = cv.cuda.createColumnSumFilter(cv.CV_8UC1, cv.CV_32FC1, 3)
_filter = cv.cuda.createMedianFilter(cv.CV_8UC1, 3)
self.assertTrue(True) #It is sufficient that no exceptions have been there
def test_laplacian(self):
npMat = (np.random.random((128, 128)) * 255).astype(np.uint16)
cuMat = cv.cuda_GpuMat()
cuMat.upload(npMat)
self.assertTrue(np.allclose(cv.cuda.createLaplacianFilter(cv.CV_16UC1, -1, ksize=3).apply(cuMat).download(),
cv.Laplacian(npMat, cv.CV_16UC1, ksize=3)))
if __name__ == '__main__':
NewOpenCVTests.bootstrap()
\ No newline at end of file
#!/usr/bin/env python
import os
import cv2 as cv
import numpy as np
from tests_common import NewOpenCVTests, unittest
class cudaimgproc_test(NewOpenCVTests):
def setUp(self):
super(cudaimgproc_test, self).setUp()
if not cv.cuda.getCudaEnabledDeviceCount():
self.skipTest("No CUDA-capable device is detected")
def test_cudaimgproc(self):
npC1 = (np.random.random((128, 128)) * 255).astype(np.uint8)
npC3 = (np.random.random((128, 128, 3)) * 255).astype(np.uint8)
npC4 = (np.random.random((128, 128, 4)) * 255).astype(np.uint8)
cuC1 = cv.cuda_GpuMat()
cuC3 = cv.cuda_GpuMat()
cuC4 = cv.cuda_GpuMat()
cuC1.upload(npC1)
cuC3.upload(npC3)
cuC4.upload(npC4)
cv.cuda.cvtColor(cuC3, cv.COLOR_RGB2HSV)
cv.cuda.demosaicing(cuC1, cv.cuda.COLOR_BayerGR2BGR_MHT)
cv.cuda.gammaCorrection(cuC3)
cv.cuda.alphaComp(cuC4, cuC4, cv.cuda.ALPHA_XOR)
cv.cuda.calcHist(cuC1)
cv.cuda.equalizeHist(cuC1)
cv.cuda.evenLevels(3, 0, 255)
cv.cuda.meanShiftFiltering(cuC4, 10, 5)
cv.cuda.meanShiftProc(cuC4, 10, 5)
cv.cuda.bilateralFilter(cuC3, 3, 16, 3)
cv.cuda.blendLinear
cuRes = cv.cuda.meanShiftSegmentation(cuC4, 10, 5, 5)
cuDst = cv.cuda_GpuMat(cuC4.size(),cuC4.type())
cv.cuda.meanShiftSegmentation(cuC4, 10, 5, 5, cuDst)
self.assertTrue(np.allclose(cuRes.download(),cuDst.download()))
clahe = cv.cuda.createCLAHE()
clahe.apply(cuC1, cv.cuda_Stream.Null())
histLevels = cv.cuda.histEven(cuC3, 20, 0, 255)
cv.cuda.histRange(cuC1, histLevels)
detector = cv.cuda.createCannyEdgeDetector(0, 100)
detector.detect(cuC1)
detector = cv.cuda.createHoughLinesDetector(3, np.pi / 180, 20)
detector.detect(cuC1)
detector = cv.cuda.createHoughSegmentDetector(3, np.pi / 180, 20, 5)
detector.detect(cuC1)
detector = cv.cuda.createHoughCirclesDetector(3, 20, 10, 10, 20, 100)
detector.detect(cuC1)
detector = cv.cuda.createGeneralizedHoughBallard()
#BUG: detect accept only Mat!
#Even if generate_gpumat_decls is set to True, it only wraps overload CUDA functions.
#The problem is that Mat and GpuMat are not fully compatible to enable system-wide overloading
#detector.detect(cuC1, cuC1, cuC1)
detector = cv.cuda.createGeneralizedHoughGuil()
#BUG: same as above..
#detector.detect(cuC1, cuC1, cuC1)
detector = cv.cuda.createHarrisCorner(cv.CV_8UC1, 15, 5, 1)
detector.compute(cuC1)
detector = cv.cuda.createMinEigenValCorner(cv.CV_8UC1, 15, 5, 1)
detector.compute(cuC1)
detector = cv.cuda.createGoodFeaturesToTrackDetector(cv.CV_8UC1)
detector.detect(cuC1)
matcher = cv.cuda.createTemplateMatching(cv.CV_8UC1, cv.TM_CCOEFF_NORMED)
matcher.match(cuC3, cuC3)
self.assertTrue(True) #It is sufficient that no exceptions have been there
def test_cvtColor(self):
npMat = (np.random.random((128, 128, 3)) * 255).astype(np.uint8)
cuMat = cv.cuda_GpuMat()
cuMat.upload(npMat)
self.assertTrue(np.allclose(cv.cuda.cvtColor(cuMat, cv.COLOR_BGR2HSV).download(),
cv.cvtColor(npMat, cv.COLOR_BGR2HSV)))
if __name__ == '__main__':
NewOpenCVTests.bootstrap()
\ No newline at end of file
...@@ -388,7 +388,15 @@ void cv::cuda::meanShiftSegmentation(InputArray _src, OutputArray _dst, int sp, ...@@ -388,7 +388,15 @@ void cv::cuda::meanShiftSegmentation(InputArray _src, OutputArray _dst, int sp,
dstcol[3] = 255; dstcol[3] = 255;
} }
} }
dst.copyTo(_dst);
if (_dst.kind() == _InputArray::CUDA_GPU_MAT)
{
GpuMat dstGpuMat = getOutputMat(_dst, src.size(), src.type(), stream);
dstGpuMat.upload(dst, stream);
}
else {
dst.copyTo(_dst);
}
} }
#endif // #if !defined (HAVE_CUDA) || defined (CUDA_DISABLER) #endif // #if !defined (HAVE_CUDA) || defined (CUDA_DISABLER)
...@@ -162,6 +162,22 @@ public: ...@@ -162,6 +162,22 @@ public:
std::vector<Point>& found_locations, std::vector<Point>& found_locations,
std::vector<double>* confidences = NULL) = 0; std::vector<double>* confidences = NULL) = 0;
CV_WRAP inline void detect(InputArray img,
CV_OUT std::vector<Point>& found_locations,
CV_OUT std::vector<double>& confidences) {
detect(img, found_locations, &confidences);
}
/** @brief Performs object detection without a multi-scale window.
@param img Source image. CV_8UC1 and CV_8UC4 types are supported for now.
@param found_locations Left-top corner points of detected objects boundaries.
*/
CV_WRAP inline void detectWithoutConf(InputArray img,
CV_OUT std::vector<Point>& found_locations) {
detect(img, found_locations, NULL);
}
/** @brief Performs object detection with a multi-scale window. /** @brief Performs object detection with a multi-scale window.
@param img Source image. See cuda::HOGDescriptor::detect for type limitations. @param img Source image. See cuda::HOGDescriptor::detect for type limitations.
...@@ -172,6 +188,22 @@ public: ...@@ -172,6 +188,22 @@ public:
std::vector<Rect>& found_locations, std::vector<Rect>& found_locations,
std::vector<double>* confidences = NULL) = 0; std::vector<double>* confidences = NULL) = 0;
CV_WRAP inline void detectMultiScale(InputArray img,
CV_OUT std::vector<Rect>& found_locations,
CV_OUT std::vector<double>& confidences) {
detectMultiScale(img, found_locations, &confidences);
}
/** @brief Performs object detection with a multi-scale window.
@param img Source image. See cuda::HOGDescriptor::detect for type limitations.
@param found_locations Detected objects boundaries.
*/
CV_WRAP inline void detectMultiScaleWithoutConf(InputArray img,
CV_OUT std::vector<Rect>& found_locations) {
detectMultiScale(img, found_locations, NULL);
}
/** @brief Returns block descriptors computed for the whole image. /** @brief Returns block descriptors computed for the whole image.
@param img Source image. See cuda::HOGDescriptor::detect for type limitations. @param img Source image. See cuda::HOGDescriptor::detect for type limitations.
......
#!/usr/bin/env python
import os
import cv2 as cv
import numpy as np
from tests_common import NewOpenCVTests, unittest
class cudaobjdetect_test(NewOpenCVTests):
def setUp(self):
super(cudaobjdetect_test, self).setUp()
if not cv.cuda.getCudaEnabledDeviceCount():
self.skipTest("No CUDA-capable device is detected")
@unittest.skipIf('OPENCV_TEST_DATA_PATH' not in os.environ,
"OPENCV_TEST_DATA_PATH is not defined")
def test_hog(self):
img_path = os.environ['OPENCV_TEST_DATA_PATH'] + '/gpu/caltech/image_00000009_0.png'
npMat = cv.cvtColor(cv.imread(img_path),cv.COLOR_BGR2BGRA)
cuMat = cv.cuda_GpuMat(npMat)
cuHog = cv.cuda.HOG_create()
cuHog.setSVMDetector(cuHog.getDefaultPeopleDetector())
loc, conf = cuHog.detect(cuMat)
self.assertTrue(len(loc) == len(conf) and len(loc) > 0 and len(loc[0]) == 2)
loc = cuHog.detectWithoutConf(cuMat)
self.assertTrue(len(loc) > 0 and len(loc[0]) == 2)
loc = cuHog.detectMultiScaleWithoutConf(cuMat)
self.assertTrue(len(loc) > 0 and len(loc[0]) == 4)
cuHog.setGroupThreshold(0)
loc, conf = cuHog.detectMultiScale(cuMat)
self.assertTrue(len(loc) == len(conf) and len(loc) > 0 and len(loc[0]) == 4)
if __name__ == '__main__':
NewOpenCVTests.bootstrap()
\ No newline at end of file
...@@ -112,7 +112,7 @@ CV_EXPORTS_W void resize(InputArray src, OutputArray dst, Size dsize, double fx= ...@@ -112,7 +112,7 @@ CV_EXPORTS_W void resize(InputArray src, OutputArray dst, Size dsize, double fx=
@param src Source image. CV_8U , CV_16U , CV_32S , or CV_32F depth and 1, 3, or 4 channels are @param src Source image. CV_8U , CV_16U , CV_32S , or CV_32F depth and 1, 3, or 4 channels are
supported. supported.
@param dst Destination image with the same type as src . The size is dsize . @param dst Destination image with the same type as src . The size is dsize .
@param M *2x3* transformation matrix. @param M *2x3* Mat or UMat transformation matrix.
@param dsize Size of the destination image. @param dsize Size of the destination image.
@param flags Combination of interpolation methods (see resize) and the optional flag @param flags Combination of interpolation methods (see resize) and the optional flag
WARP_INVERSE_MAP specifying that M is an inverse transformation ( dst=\>src ). Only WARP_INVERSE_MAP specifying that M is an inverse transformation ( dst=\>src ). Only
...@@ -123,12 +123,22 @@ INTER_NEAREST , INTER_LINEAR , and INTER_CUBIC interpolation methods are support ...@@ -123,12 +123,22 @@ INTER_NEAREST , INTER_LINEAR , and INTER_CUBIC interpolation methods are support
@sa warpAffine @sa warpAffine
*/ */
CV_EXPORTS_W void warpAffine(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags = INTER_LINEAR, CV_EXPORTS void warpAffine(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags = INTER_LINEAR,
int borderMode = BORDER_CONSTANT, Scalar borderValue = Scalar(), Stream& stream = Stream::Null()); int borderMode = BORDER_CONSTANT, Scalar borderValue = Scalar(), Stream& stream = Stream::Null());
CV_WRAP inline void warpAffine(InputArray src, OutputArray dst, UMat M, Size dsize, int flags = INTER_LINEAR,
int borderMode = BORDER_CONSTANT, Scalar borderValue = Scalar(), Stream& stream = Stream::Null()) {
warpAffine(src, dst, InputArray(M), dsize, flags, borderMode, borderValue, stream);
}
CV_WRAP inline void warpAffine(InputArray src, OutputArray dst, Mat M, Size dsize, int flags = INTER_LINEAR,
int borderMode = BORDER_CONSTANT, Scalar borderValue = Scalar(), Stream& stream = Stream::Null()) {
warpAffine(src, dst, InputArray(M), dsize, flags, borderMode, borderValue, stream);
}
/** @brief Builds transformation maps for affine transformation. /** @brief Builds transformation maps for affine transformation.
@param M *2x3* transformation matrix. @param M *2x3* Mat or UMat transformation matrix.
@param inverse Flag specifying that M is an inverse transformation ( dst=\>src ). @param inverse Flag specifying that M is an inverse transformation ( dst=\>src ).
@param dsize Size of the destination image. @param dsize Size of the destination image.
@param xmap X values with CV_32FC1 type. @param xmap X values with CV_32FC1 type.
...@@ -137,14 +147,22 @@ CV_EXPORTS_W void warpAffine(InputArray src, OutputArray dst, InputArray M, Size ...@@ -137,14 +147,22 @@ CV_EXPORTS_W void warpAffine(InputArray src, OutputArray dst, InputArray M, Size
@sa cuda::warpAffine , cuda::remap @sa cuda::warpAffine , cuda::remap
*/ */
CV_EXPORTS_W void buildWarpAffineMaps(InputArray M, bool inverse, Size dsize, OutputArray xmap, OutputArray ymap, Stream& stream = Stream::Null()); CV_EXPORTS void buildWarpAffineMaps(InputArray M, bool inverse, Size dsize, OutputArray xmap, OutputArray ymap, Stream& stream = Stream::Null());
CV_WRAP inline void buildWarpAffineMaps(UMat M, bool inverse, Size dsize, CV_OUT GpuMat& xmap, CV_OUT GpuMat& ymap, Stream& stream = Stream::Null()) {
buildWarpAffineMaps(InputArray(M), inverse, dsize, OutputArray(xmap), OutputArray(ymap), stream);
}
CV_WRAP inline void buildWarpAffineMaps(Mat M, bool inverse, Size dsize, CV_OUT GpuMat& xmap, CV_OUT GpuMat& ymap, Stream& stream = Stream::Null()) {
buildWarpAffineMaps(InputArray(M), inverse, dsize, OutputArray(xmap), OutputArray(ymap), stream);
}
/** @brief Applies a perspective transformation to an image. /** @brief Applies a perspective transformation to an image.
@param src Source image. CV_8U , CV_16U , CV_32S , or CV_32F depth and 1, 3, or 4 channels are @param src Source image. CV_8U , CV_16U , CV_32S , or CV_32F depth and 1, 3, or 4 channels are
supported. supported.
@param dst Destination image with the same type as src . The size is dsize . @param dst Destination image with the same type as src . The size is dsize .
@param M *3x3* transformation matrix. @param M *3x3* Mat or UMat transformation matrix.
@param dsize Size of the destination image. @param dsize Size of the destination image.
@param flags Combination of interpolation methods (see resize ) and the optional flag @param flags Combination of interpolation methods (see resize ) and the optional flag
WARP_INVERSE_MAP specifying that M is the inverse transformation ( dst =\> src ). Only WARP_INVERSE_MAP specifying that M is the inverse transformation ( dst =\> src ). Only
...@@ -155,12 +173,22 @@ INTER_NEAREST , INTER_LINEAR , and INTER_CUBIC interpolation methods are support ...@@ -155,12 +173,22 @@ INTER_NEAREST , INTER_LINEAR , and INTER_CUBIC interpolation methods are support
@sa warpPerspective @sa warpPerspective
*/ */
CV_EXPORTS_W void warpPerspective(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags = INTER_LINEAR, CV_EXPORTS void warpPerspective(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags = INTER_LINEAR,
int borderMode = BORDER_CONSTANT, Scalar borderValue = Scalar(), Stream& stream = Stream::Null()); int borderMode = BORDER_CONSTANT, Scalar borderValue = Scalar(), Stream& stream = Stream::Null());
CV_WRAP inline void warpPerspective(InputArray src, OutputArray dst, UMat M, Size dsize, int flags = INTER_LINEAR,
int borderMode = BORDER_CONSTANT, Scalar borderValue = Scalar(), Stream& stream = Stream::Null()) {
warpPerspective(src, dst, InputArray(M), dsize, flags, borderMode, borderValue, stream);
}
CV_WRAP inline void warpPerspective(InputArray src, OutputArray dst, Mat M, Size dsize, int flags = INTER_LINEAR,
int borderMode = BORDER_CONSTANT, Scalar borderValue = Scalar(), Stream& stream = Stream::Null()) {
warpPerspective(src, dst, InputArray(M), dsize, flags, borderMode, borderValue, stream);
}
/** @brief Builds transformation maps for perspective transformation. /** @brief Builds transformation maps for perspective transformation.
@param M *3x3* transformation matrix. @param M *3x3* Mat or UMat transformation matrix.
@param inverse Flag specifying that M is an inverse transformation ( dst=\>src ). @param inverse Flag specifying that M is an inverse transformation ( dst=\>src ).
@param dsize Size of the destination image. @param dsize Size of the destination image.
@param xmap X values with CV_32FC1 type. @param xmap X values with CV_32FC1 type.
...@@ -169,7 +197,15 @@ CV_EXPORTS_W void warpPerspective(InputArray src, OutputArray dst, InputArray M, ...@@ -169,7 +197,15 @@ CV_EXPORTS_W void warpPerspective(InputArray src, OutputArray dst, InputArray M,
@sa cuda::warpPerspective , cuda::remap @sa cuda::warpPerspective , cuda::remap
*/ */
CV_EXPORTS_W void buildWarpPerspectiveMaps(InputArray M, bool inverse, Size dsize, OutputArray xmap, OutputArray ymap, Stream& stream = Stream::Null()); CV_EXPORTS void buildWarpPerspectiveMaps(InputArray M, bool inverse, Size dsize, OutputArray xmap, OutputArray ymap, Stream& stream = Stream::Null());
CV_WRAP inline void buildWarpPerspectiveMaps(UMat M, bool inverse, Size dsize, CV_OUT GpuMat& xmap, CV_OUT GpuMat& ymap, Stream& stream = Stream::Null()) {
buildWarpPerspectiveMaps(InputArray(M), inverse, dsize, OutputArray(xmap), OutputArray(ymap), stream);
}
CV_WRAP inline void buildWarpPerspectiveMaps(Mat M, bool inverse, Size dsize, CV_OUT GpuMat& xmap, CV_OUT GpuMat& ymap, Stream& stream = Stream::Null()) {
buildWarpPerspectiveMaps(InputArray(M), inverse, dsize, OutputArray(xmap), OutputArray(ymap), stream);
}
/** @brief Rotates an image around the origin (0,0) and then shifts it. /** @brief Rotates an image around the origin (0,0) and then shifts it.
......
#!/usr/bin/env python
import os
import cv2 as cv
import numpy as np
from tests_common import NewOpenCVTests, unittest
def create_affine_transform_matrix(size,angle):
return np.array([[np.cos(angle), -np.sin(angle), size[1]/2], [np.sin(angle), np.cos(angle), 0]])
def create_perspective_transform_matrix(size,angle):
return np.vstack([create_affine_transform_matrix(size,angle),[0, 0, 1]])
class cudawarping_test(NewOpenCVTests):
def setUp(self):
super(cudawarping_test, self).setUp()
if not cv.cuda.getCudaEnabledDeviceCount():
self.skipTest("No CUDA-capable device is detected")
def test_resize(self):
dstSz = (256,256)
interp = cv.INTER_NEAREST
npMat = (np.random.random((128,128,3))*255).astype(np.uint8)
cuMat = cv.cuda_GpuMat(npMat)
cuMatDst = cv.cuda_GpuMat(dstSz,cuMat.type())
self.assertTrue(np.allclose(cv.cuda.resize(cuMat,dstSz,interpolation=interp).download(),
cv.resize(npMat,dstSz,interpolation=interp)))
cv.cuda.resize(cuMat,dstSz,cuMatDst,interpolation=interp)
self.assertTrue(np.allclose(cuMatDst.download(),cv.resize(npMat,dstSz,interpolation=interp)))
def test_warp(self):
npMat = (np.random.random((128,128,3))*255).astype(np.uint8)
size = npMat.shape[:2]
M1 = create_affine_transform_matrix(size,np.pi/2)
cuMat = cv.cuda_GpuMat(npMat)
cuMatDst = cv.cuda_GpuMat(size,cuMat.type())
borderType = cv.BORDER_REFLECT101
self.assertTrue(np.allclose(cv.cuda.warpAffine(cuMat,M1,size,borderMode=borderType).download(),
cv.warpAffine(npMat,M1,size, borderMode=borderType)))
cv.cuda.warpAffine(cuMat,M1,size,cuMatDst,borderMode=borderType)
self.assertTrue(np.allclose(cuMatDst.download(),cv.warpAffine(npMat,M1,size,borderMode=borderType)))
interpolation = cv.INTER_NEAREST
flags = interpolation | cv.WARP_INVERSE_MAP
dst_gold = cv.warpAffine(npMat, M1, size, flags = flags)
cuMaps = cv.cuda.buildWarpAffineMaps(M1,True,size)
dst = cv.remap(npMat, cuMaps[0].download(), cuMaps[1].download(),interpolation)
self.assertTrue(np.allclose(dst,dst_gold))
xmap = cv.cuda_GpuMat(size,cv.CV_32FC1)
ymap = cv.cuda_GpuMat(size,cv.CV_32FC1)
cv.cuda.buildWarpAffineMaps(M1,True,size,xmap,ymap)
dst = cv.remap(npMat, xmap.download(), ymap.download(),interpolation)
self.assertTrue(np.allclose(dst,dst_gold))
M2 = create_perspective_transform_matrix(size,np.pi/2)
np.allclose(cv.cuda.warpPerspective(cuMat,M2,size,borderMode=borderType).download(),
cv.warpPerspective(npMat,M2,size,borderMode=borderType))
cv.cuda.warpPerspective(cuMat,M2,size,cuMatDst,borderMode=borderType)
self.assertTrue(np.allclose(cuMatDst.download(),cv.warpPerspective(npMat,M2,size,borderMode=borderType)))
dst_gold = cv.warpPerspective(npMat, M2, size, flags = flags)
cuMaps = cv.cuda.buildWarpPerspectiveMaps(M2,True,size)
dst = cv.remap(npMat, cuMaps[0].download(), cuMaps[1].download(),interpolation)
self.assertTrue(np.allclose(dst,dst_gold))
cv.cuda.buildWarpPerspectiveMaps(M2,True,size,xmap,ymap)
dst = cv.remap(npMat, xmap.download(), ymap.download(),interpolation)
self.assertTrue(np.allclose(dst,dst_gold))
if __name__ == '__main__':
NewOpenCVTests.bootstrap()
\ No newline at end of file
...@@ -83,7 +83,7 @@ between function calls. ...@@ -83,7 +83,7 @@ between function calls.
opencv_source_code/samples/gpu/surf_keypoint_matcher.cpp opencv_source_code/samples/gpu/surf_keypoint_matcher.cpp
*/ */
class CV_EXPORTS SURF_CUDA class CV_EXPORTS_W SURF_CUDA
{ {
public: public:
enum KeypointLayout enum KeypointLayout
...@@ -104,15 +104,28 @@ public: ...@@ -104,15 +104,28 @@ public:
explicit SURF_CUDA(double _hessianThreshold, int _nOctaves=4, explicit SURF_CUDA(double _hessianThreshold, int _nOctaves=4,
int _nOctaveLayers=2, bool _extended=false, float _keypointsRatio=0.01f, bool _upright = false); int _nOctaveLayers=2, bool _extended=false, float _keypointsRatio=0.01f, bool _upright = false);
/**
@param _hessianThreshold Threshold for hessian keypoint detector used in SURF.
@param _nOctaves Number of pyramid octaves the keypoint detector will use.
@param _nOctaveLayers Number of octave layers within each octave.
@param _extended Extended descriptor flag (true - use extended 128-element descriptors; false - use
64-element descriptors).
@param _keypointsRatio
@param _upright Up-right or rotated features flag (true - do not compute orientation of features;
false - compute orientation).
*/
CV_WRAP static Ptr<SURF_CUDA> create(double _hessianThreshold, int _nOctaves = 4,
int _nOctaveLayers = 2, bool _extended = false, float _keypointsRatio = 0.01f, bool _upright = false);
//! returns the descriptor size in float's (64 or 128) //! returns the descriptor size in float's (64 or 128)
int descriptorSize() const; CV_WRAP int descriptorSize() const;
//! returns the default norm type //! returns the default norm type
int defaultNorm() const; CV_WRAP int defaultNorm() const;
//! upload host keypoints to device memory //! upload host keypoints to device memory
void uploadKeypoints(const std::vector<KeyPoint>& keypoints, GpuMat& keypointsGPU); void uploadKeypoints(const std::vector<KeyPoint>& keypoints, GpuMat& keypointsGPU);
//! download keypoints from device to host memory //! download keypoints from device to host memory
void downloadKeypoints(const GpuMat& keypointsGPU, std::vector<KeyPoint>& keypoints); CV_WRAP void downloadKeypoints(const GpuMat& keypointsGPU, CV_OUT std::vector<KeyPoint>& keypoints);
//! download descriptors from device to host memory //! download descriptors from device to host memory
void downloadDescriptors(const GpuMat& descriptorsGPU, std::vector<float>& descriptors); void downloadDescriptors(const GpuMat& descriptorsGPU, std::vector<float>& descriptors);
...@@ -133,24 +146,47 @@ public: ...@@ -133,24 +146,47 @@ public:
void operator()(const GpuMat& img, const GpuMat& mask, GpuMat& keypoints, GpuMat& descriptors, void operator()(const GpuMat& img, const GpuMat& mask, GpuMat& keypoints, GpuMat& descriptors,
bool useProvidedKeypoints = false); bool useProvidedKeypoints = false);
/** @brief Finds the keypoints using fast hessian detector used in SURF
@param img Source image, currently supports only CV_8UC1 images.
@param mask A mask image same size as src and of type CV_8UC1.
@param keypoints Detected keypoints.
*/
CV_WRAP inline void detect(const GpuMat& img, const GpuMat& mask, CV_OUT GpuMat& keypoints) {
(*this)(img, mask, keypoints);
}
void operator()(const GpuMat& img, const GpuMat& mask, std::vector<KeyPoint>& keypoints); void operator()(const GpuMat& img, const GpuMat& mask, std::vector<KeyPoint>& keypoints);
void operator()(const GpuMat& img, const GpuMat& mask, std::vector<KeyPoint>& keypoints, GpuMat& descriptors, void operator()(const GpuMat& img, const GpuMat& mask, std::vector<KeyPoint>& keypoints, GpuMat& descriptors,
bool useProvidedKeypoints = false); bool useProvidedKeypoints = false);
/** @brief Finds the keypoints and computes their descriptors using fast hessian detector used in SURF
@param img Source image, currently supports only CV_8UC1 images.
@param mask A mask image same size as src and of type CV_8UC1.
@param keypoints Detected keypoints.
@param descriptors Keypoint descriptors.
@param useProvidedKeypoints Compute descriptors for the user-provided keypoints and recompute keypoints direction.
*/
CV_WRAP inline void detectWithDescriptors(const GpuMat& img, const GpuMat& mask, CV_OUT GpuMat& keypoints, CV_OUT GpuMat& descriptors,
bool useProvidedKeypoints = false) {
(*this)(img, mask, keypoints, descriptors, useProvidedKeypoints);
}
void operator()(const GpuMat& img, const GpuMat& mask, std::vector<KeyPoint>& keypoints, std::vector<float>& descriptors, void operator()(const GpuMat& img, const GpuMat& mask, std::vector<KeyPoint>& keypoints, std::vector<float>& descriptors,
bool useProvidedKeypoints = false); bool useProvidedKeypoints = false);
void releaseMemory(); void releaseMemory();
// SURF parameters // SURF parameters
double hessianThreshold; CV_PROP double hessianThreshold;
int nOctaves; CV_PROP int nOctaves;
int nOctaveLayers; CV_PROP int nOctaveLayers;
bool extended; CV_PROP bool extended;
bool upright; CV_PROP bool upright;
//! max keypoints = min(keypointsRatio * img.size().area(), 65535) //! max keypoints = min(keypointsRatio * img.size().area(), 65535)
float keypointsRatio; CV_PROP float keypointsRatio;
GpuMat sum, mask1, maskSum; GpuMat sum, mask1, maskSum;
......
#!/usr/bin/env python
import os
import cv2 as cv
import numpy as np
from tests_common import NewOpenCVTests, unittest
class xfeatures2d_test(NewOpenCVTests):
def setUp(self):
super(xfeatures2d_test, self).setUp()
if not cv.cuda.getCudaEnabledDeviceCount():
self.skipTest("No CUDA-capable device is detected")
@unittest.skipIf('OPENCV_TEST_DATA_PATH' not in os.environ,
"OPENCV_TEST_DATA_PATH is not defined")
def test_surf(self):
img_path = os.environ['OPENCV_TEST_DATA_PATH'] + "/gpu/features2d/aloe.png"
hessianThreshold = 100
nOctaves = 3
nOctaveLayers = 2
extended = False
keypointsRatio = 0.05
upright = False
npMat = cv.cvtColor(cv.imread(img_path),cv.COLOR_BGR2GRAY)
cuMat = cv.cuda_GpuMat(npMat)
try:
cuSurf = cv.cuda_SURF_CUDA.create(hessianThreshold,nOctaves,nOctaveLayers,extended,keypointsRatio,upright)
surf = cv.xfeatures2d_SURF.create(hessianThreshold,nOctaves,nOctaveLayers,extended,upright)
except cv.error as e:
self.assertEqual(e.code, cv.Error.StsNotImplemented)
self.skipTest("OPENCV_ENABLE_NONFREE is not enabled in this build.")
cuKeypoints = cuSurf.detect(cuMat,cv.cuda_GpuMat())
keypointsHost = cuSurf.downloadKeypoints(cuKeypoints)
keypoints = surf.detect(npMat)
self.assertTrue(len(keypointsHost) == len(keypoints))
cuKeypoints, cuDescriptors = cuSurf.detectWithDescriptors(cuMat,cv.cuda_GpuMat(),cuKeypoints,useProvidedKeypoints=True)
keypointsHost = cuSurf.downloadKeypoints(cuKeypoints)
descriptorsHost = cuDescriptors.download()
keypoints, descriptors = surf.compute(npMat,keypoints)
self.assertTrue(len(keypointsHost) == len(keypoints) and descriptorsHost.shape == descriptors.shape)
if __name__ == '__main__':
NewOpenCVTests.bootstrap()
\ No newline at end of file
...@@ -54,6 +54,7 @@ using namespace cv::cuda; ...@@ -54,6 +54,7 @@ using namespace cv::cuda;
cv::cuda::SURF_CUDA::SURF_CUDA() { throw_no_nonfree } cv::cuda::SURF_CUDA::SURF_CUDA() { throw_no_nonfree }
cv::cuda::SURF_CUDA::SURF_CUDA(double, int, int, bool, float, bool) { throw_no_nonfree } cv::cuda::SURF_CUDA::SURF_CUDA(double, int, int, bool, float, bool) { throw_no_nonfree }
Ptr<SURF_CUDA> cv::cuda::SURF_CUDA::create(double, int, int, bool, float, bool) { throw_no_nonfree }
int cv::cuda::SURF_CUDA::descriptorSize() const { throw_no_nonfree } int cv::cuda::SURF_CUDA::descriptorSize() const { throw_no_nonfree }
int cv::cuda::SURF_CUDA::defaultNorm() const { throw_no_nonfree } int cv::cuda::SURF_CUDA::defaultNorm() const { throw_no_nonfree }
void cv::cuda::SURF_CUDA::uploadKeypoints(const std::vector<KeyPoint>&, GpuMat&) { throw_no_nonfree } void cv::cuda::SURF_CUDA::uploadKeypoints(const std::vector<KeyPoint>&, GpuMat&) { throw_no_nonfree }
...@@ -71,6 +72,7 @@ void cv::cuda::SURF_CUDA::releaseMemory() { throw_no_nonfree } ...@@ -71,6 +72,7 @@ void cv::cuda::SURF_CUDA::releaseMemory() { throw_no_nonfree }
cv::cuda::SURF_CUDA::SURF_CUDA() { throw_no_cuda(); } cv::cuda::SURF_CUDA::SURF_CUDA() { throw_no_cuda(); }
cv::cuda::SURF_CUDA::SURF_CUDA(double, int, int, bool, float, bool) { throw_no_cuda(); } cv::cuda::SURF_CUDA::SURF_CUDA(double, int, int, bool, float, bool) { throw_no_cuda(); }
Ptr<SURF_CUDA> cv::cuda::SURF_CUDA::create(double, int, int, bool, float, bool) { throw_no_cuda(); }
int cv::cuda::SURF_CUDA::descriptorSize() const { throw_no_cuda(); } int cv::cuda::SURF_CUDA::descriptorSize() const { throw_no_cuda(); }
int cv::cuda::SURF_CUDA::defaultNorm() const { throw_no_cuda(); } int cv::cuda::SURF_CUDA::defaultNorm() const { throw_no_cuda(); }
void cv::cuda::SURF_CUDA::uploadKeypoints(const std::vector<KeyPoint>&, GpuMat&) { throw_no_cuda(); } void cv::cuda::SURF_CUDA::uploadKeypoints(const std::vector<KeyPoint>&, GpuMat&) { throw_no_cuda(); }
...@@ -451,6 +453,12 @@ void cv::cuda::SURF_CUDA::releaseMemory() ...@@ -451,6 +453,12 @@ void cv::cuda::SURF_CUDA::releaseMemory()
maxPosBuffer.release(); maxPosBuffer.release();
} }
Ptr<SURF_CUDA> cv::cuda::SURF_CUDA::create(double _hessianThreshold, int _nOctaves,
int _nOctaveLayers, bool _extended, float _keypointsRatio, bool _upright)
{
return makePtr<SURF_CUDA>(_hessianThreshold, _nOctaves, _nOctaveLayers, _extended, _keypointsRatio, _upright);
}
#endif // !defined (OPENCV_ENABLE_NONFREE) #endif // !defined (OPENCV_ENABLE_NONFREE)
#endif #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment