From a9fdc1bdff6b57c65efc835349d6fb75c1f18a21 Mon Sep 17 00:00:00 2001 From: Vladislav Vinogradov Date: Mon, 8 Aug 2011 13:05:50 +0000 Subject: [PATCH] added buffered version of cornerHarris, cornerMinEigenVal, histEven and histRange --- modules/gpu/include/opencv2/gpu/gpu.hpp | 6 + .../gpu/src/{imgproc_gpu.cpp => imgproc.cpp} | 109 +++++++++++------- 2 files changed, 73 insertions(+), 42 deletions(-) rename modules/gpu/src/{imgproc_gpu.cpp => imgproc.cpp} (92%) diff --git a/modules/gpu/include/opencv2/gpu/gpu.hpp b/modules/gpu/include/opencv2/gpu/gpu.hpp index c7330666df..168433d206 100644 --- a/modules/gpu/include/opencv2/gpu/gpu.hpp +++ b/modules/gpu/include/opencv2/gpu/gpu.hpp @@ -862,9 +862,11 @@ namespace cv //! computes Harris cornerness criteria at each image pixel CV_EXPORTS void cornerHarris(const GpuMat& src, GpuMat& dst, int blockSize, int ksize, double k, int borderType=BORDER_REFLECT101); + CV_EXPORTS void cornerHarris(const GpuMat& src, GpuMat& dst, GpuMat& Dx, GpuMat& Dy, int blockSize, int ksize, double k, int borderType=BORDER_REFLECT101); //! computes minimum eigen value of 2x2 derivative covariation matrix at each pixel - the cornerness criteria CV_EXPORTS void cornerMinEigenVal(const GpuMat& src, GpuMat& dst, int blockSize, int ksize, int borderType=BORDER_REFLECT101); + CV_EXPORTS void cornerMinEigenVal(const GpuMat& src, GpuMat& dst, GpuMat& Dx, GpuMat& Dy, int blockSize, int ksize, int borderType=BORDER_REFLECT101); //! performs per-element multiplication of two full (not packed) Fourier spectrums //! supports 32FC2 matrixes only (interleaved format) @@ -1096,22 +1098,26 @@ namespace cv //! Supports CV_8UC1, CV_16UC1 and CV_16SC1 source types. //! Output hist will have one row and histSize cols and CV_32SC1 type. CV_EXPORTS void histEven(const GpuMat& src, GpuMat& hist, int histSize, int lowerLevel, int upperLevel, Stream& stream = Stream::Null()); + CV_EXPORTS void histEven(const GpuMat& src, GpuMat& hist, GpuMat& buf, int histSize, int lowerLevel, int upperLevel, Stream& stream = Stream::Null()); //! Calculates histogram with evenly distributed bins for four-channel source. //! All channels of source are processed separately. //! Supports CV_8UC4, CV_16UC4 and CV_16SC4 source types. //! Output hist[i] will have one row and histSize[i] cols and CV_32SC1 type. CV_EXPORTS void histEven(const GpuMat& src, GpuMat hist[4], int histSize[4], int lowerLevel[4], int upperLevel[4], Stream& stream = Stream::Null()); + CV_EXPORTS void histEven(const GpuMat& src, GpuMat hist[4], GpuMat& buf, int histSize[4], int lowerLevel[4], int upperLevel[4], Stream& stream = Stream::Null()); //! Calculates histogram with bins determined by levels array. //! levels must have one row and CV_32SC1 type if source has integer type or CV_32FC1 otherwise. //! Supports CV_8UC1, CV_16UC1, CV_16SC1 and CV_32FC1 source types. //! Output hist will have one row and (levels.cols-1) cols and CV_32SC1 type. CV_EXPORTS void histRange(const GpuMat& src, GpuMat& hist, const GpuMat& levels, Stream& stream = Stream::Null()); + CV_EXPORTS void histRange(const GpuMat& src, GpuMat& hist, const GpuMat& levels, GpuMat& buf, Stream& stream = Stream::Null()); //! Calculates histogram with bins determined by levels array. //! All levels must have one row and CV_32SC1 type if source has integer type or CV_32FC1 otherwise. //! All channels of source are processed separately. //! Supports CV_8UC4, CV_16UC4, CV_16SC4 and CV_32FC4 source types. //! Output hist[i] will have one row and (levels[i].cols-1) cols and CV_32SC1 type. CV_EXPORTS void histRange(const GpuMat& src, GpuMat hist[4], const GpuMat levels[4], Stream& stream = Stream::Null()); + CV_EXPORTS void histRange(const GpuMat& src, GpuMat hist[4], const GpuMat levels[4], GpuMat& buf, Stream& stream = Stream::Null()); //! Calculates histogram for 8u one channel image //! Output hist will have one row, 256 cols and CV32SC1 type. diff --git a/modules/gpu/src/imgproc_gpu.cpp b/modules/gpu/src/imgproc.cpp similarity index 92% rename from modules/gpu/src/imgproc_gpu.cpp rename to modules/gpu/src/imgproc.cpp index 83185131c1..de35c39217 100644 --- a/modules/gpu/src/imgproc_gpu.cpp +++ b/modules/gpu/src/imgproc.cpp @@ -68,16 +68,22 @@ void cv::gpu::columnSum(const GpuMat&, GpuMat&) { throw_nogpu(); } void cv::gpu::rectStdDev(const GpuMat&, const GpuMat&, GpuMat&, const Rect&, Stream&) { throw_nogpu(); } void cv::gpu::evenLevels(GpuMat&, int, int, int) { throw_nogpu(); } void cv::gpu::histEven(const GpuMat&, GpuMat&, int, int, int, Stream&) { throw_nogpu(); } +void cv::gpu::histEven(const GpuMat&, GpuMat&, GpuMat&, int, int, int, Stream&) { throw_nogpu(); } void cv::gpu::histEven(const GpuMat&, GpuMat*, int*, int*, int*, Stream&) { throw_nogpu(); } +void cv::gpu::histEven(const GpuMat&, GpuMat*, GpuMat&, int*, int*, int*, Stream&) { throw_nogpu(); } void cv::gpu::histRange(const GpuMat&, GpuMat&, const GpuMat&, Stream&) { throw_nogpu(); } +void cv::gpu::histRange(const GpuMat&, GpuMat&, const GpuMat&, GpuMat&, Stream&) { throw_nogpu(); } void cv::gpu::histRange(const GpuMat&, GpuMat*, const GpuMat*, Stream&) { throw_nogpu(); } +void cv::gpu::histRange(const GpuMat&, GpuMat*, const GpuMat*, GpuMat&, Stream&) { throw_nogpu(); } void cv::gpu::calcHist(const GpuMat&, GpuMat&, Stream&) { throw_nogpu(); } void cv::gpu::calcHist(const GpuMat&, GpuMat&, GpuMat&, Stream&) { throw_nogpu(); } void cv::gpu::equalizeHist(const GpuMat&, GpuMat&, Stream&) { throw_nogpu(); } void cv::gpu::equalizeHist(const GpuMat&, GpuMat&, GpuMat&, Stream&) { throw_nogpu(); } void cv::gpu::equalizeHist(const GpuMat&, GpuMat&, GpuMat&, GpuMat&, Stream&) { throw_nogpu(); } void cv::gpu::cornerHarris(const GpuMat&, GpuMat&, int, int, double, int) { throw_nogpu(); } +void cv::gpu::cornerHarris(const GpuMat&, GpuMat&, GpuMat&, GpuMat&, int, int, double, int) { throw_nogpu(); } void cv::gpu::cornerMinEigenVal(const GpuMat&, GpuMat&, int, int, int) { throw_nogpu(); } +void cv::gpu::cornerMinEigenVal(const GpuMat&, GpuMat&, GpuMat&, GpuMat&, int, int, int) { throw_nogpu(); } void cv::gpu::mulSpectrums(const GpuMat&, const GpuMat&, GpuMat&, int, bool) { throw_nogpu(); } void cv::gpu::mulAndScaleSpectrums(const GpuMat&, const GpuMat&, GpuMat&, int, float, bool) { throw_nogpu(); } void cv::gpu::dft(const GpuMat&, GpuMat&, Size, int) { throw_nogpu(); } @@ -127,15 +133,9 @@ void cv::gpu::remap(const GpuMat& src, GpuMat& dst, const GpuMat& xmap, const Gp CV_Assert((src.type() == CV_8U || src.type() == CV_8UC3) && xmap.type() == CV_32F && ymap.type() == CV_32F); - GpuMat out; - if (dst.data != src.data) - out = dst; + dst.create(xmap.size(), src.type()); - out.create(xmap.size(), src.type()); - - callers[src.channels() - 1](src, xmap, ymap, out); - - dst = out; + callers[src.channels() - 1](src, xmap, ymap, dst); } //////////////////////////////////////////////////////////////////////// @@ -199,14 +199,9 @@ namespace template void drawColorDisp_caller(const GpuMat& src, GpuMat& dst, int ndisp, const cudaStream_t& stream) { - GpuMat out; - if (dst.data != src.data) - out = dst; - out.create(src.size(), CV_8UC4); + dst.create(src.size(), CV_8UC4); - imgproc::drawColorDisp_gpu((DevMem2D_)src, out, ndisp, stream); - - dst = out; + imgproc::drawColorDisp_gpu((DevMem2D_)src, dst, ndisp, stream); } typedef void (*drawColorDisp_caller_t)(const GpuMat& src, GpuMat& dst, int ndisp, const cudaStream_t& stream); @@ -806,7 +801,7 @@ namespace { typedef typename NppHistogramEvenFuncC1::src_t src_t; - static void hist(const GpuMat& src, GpuMat& hist, int histSize, int lowerLevel, int upperLevel, cudaStream_t stream) + static void hist(const GpuMat& src, GpuMat& hist, GpuMat& buffer, int histSize, int lowerLevel, int upperLevel, cudaStream_t stream) { int levels = histSize + 1; hist.create(1, histSize, CV_32S); @@ -815,11 +810,10 @@ namespace sz.width = src.cols; sz.height = src.rows; - GpuMat buffer; int buf_size; - get_buf_size(sz, levels, &buf_size); - buffer.create(1, buf_size, CV_8U); + + ensureSizeIsEnough(1, buf_size, CV_8U, buffer); NppStreamHandler h(stream); @@ -835,7 +829,7 @@ namespace { typedef typename NppHistogramEvenFuncC4::src_t src_t; - static void hist(const GpuMat& src, GpuMat hist[4], int histSize[4], int lowerLevel[4], int upperLevel[4], cudaStream_t stream) + static void hist(const GpuMat& src, GpuMat hist[4], GpuMat& buffer, int histSize[4], int lowerLevel[4], int upperLevel[4], cudaStream_t stream) { int levels[] = {histSize[0] + 1, histSize[1] + 1, histSize[2] + 1, histSize[3] + 1}; hist[0].create(1, histSize[0], CV_32S); @@ -849,11 +843,10 @@ namespace Npp32s* pHist[] = {hist[0].ptr(), hist[1].ptr(), hist[2].ptr(), hist[3].ptr()}; - GpuMat buffer; int buf_size; - get_buf_size(sz, levels, &buf_size); - buffer.create(1, buf_size, CV_8U); + + ensureSizeIsEnough(1, buf_size, CV_8U, buffer); NppStreamHandler h(stream); @@ -908,7 +901,7 @@ namespace typedef typename NppHistogramRangeFuncC1::level_t level_t; enum {LEVEL_TYPE_CODE=NppHistogramRangeFuncC1::LEVEL_TYPE_CODE}; - static void hist(const GpuMat& src, GpuMat& hist, const GpuMat& levels, cudaStream_t stream) + static void hist(const GpuMat& src, GpuMat& hist, const GpuMat& levels, GpuMat& buffer, cudaStream_t stream) { CV_Assert(levels.type() == LEVEL_TYPE_CODE && levels.rows == 1); @@ -918,11 +911,10 @@ namespace sz.width = src.cols; sz.height = src.rows; - GpuMat buffer; int buf_size; - get_buf_size(sz, levels.cols, &buf_size); - buffer.create(1, buf_size, CV_8U); + + ensureSizeIsEnough(1, buf_size, CV_8U, buffer); NppStreamHandler h(stream); @@ -939,7 +931,7 @@ namespace typedef typename NppHistogramRangeFuncC1::level_t level_t; enum {LEVEL_TYPE_CODE=NppHistogramRangeFuncC1::LEVEL_TYPE_CODE}; - static void hist(const GpuMat& src, GpuMat hist[4], const GpuMat levels[4], cudaStream_t stream) + static void hist(const GpuMat& src, GpuMat hist[4], const GpuMat levels[4], GpuMat& buffer, cudaStream_t stream) { CV_Assert(levels[0].type() == LEVEL_TYPE_CODE && levels[0].rows == 1); CV_Assert(levels[1].type() == LEVEL_TYPE_CODE && levels[1].rows == 1); @@ -959,11 +951,10 @@ namespace sz.width = src.cols; sz.height = src.rows; - GpuMat buffer; int buf_size; - get_buf_size(sz, nLevels, &buf_size); - buffer.create(1, buf_size, CV_8U); + + ensureSizeIsEnough(1, buf_size, CV_8U, buffer); NppStreamHandler h(stream); @@ -983,10 +974,16 @@ void cv::gpu::evenLevels(GpuMat& levels, int nLevels, int lowerLevel, int upperL } void cv::gpu::histEven(const GpuMat& src, GpuMat& hist, int histSize, int lowerLevel, int upperLevel, Stream& stream) +{ + GpuMat buf; + histEven(src, hist, buf, histSize, lowerLevel, upperLevel, stream); +} + +void cv::gpu::histEven(const GpuMat& src, GpuMat& hist, GpuMat& buf, int histSize, int lowerLevel, int upperLevel, Stream& stream) { CV_Assert(src.type() == CV_8UC1 || src.type() == CV_16UC1 || src.type() == CV_16SC1 ); - typedef void (*hist_t)(const GpuMat& src, GpuMat& hist, int levels, int lowerLevel, int upperLevel, cudaStream_t stream); + typedef void (*hist_t)(const GpuMat& src, GpuMat& hist, GpuMat& buf, int levels, int lowerLevel, int upperLevel, cudaStream_t stream); static const hist_t hist_callers[] = { NppHistogramEvenC1::hist, @@ -995,14 +992,20 @@ void cv::gpu::histEven(const GpuMat& src, GpuMat& hist, int histSize, int lowerL NppHistogramEvenC1::hist }; - hist_callers[src.depth()](src, hist, histSize, lowerLevel, upperLevel, StreamAccessor::getStream(stream)); + hist_callers[src.depth()](src, hist, buf, histSize, lowerLevel, upperLevel, StreamAccessor::getStream(stream)); } void cv::gpu::histEven(const GpuMat& src, GpuMat hist[4], int histSize[4], int lowerLevel[4], int upperLevel[4], Stream& stream) +{ + GpuMat buf; + histEven(src, hist, buf, histSize, lowerLevel, upperLevel, stream); +} + +void cv::gpu::histEven(const GpuMat& src, GpuMat hist[4], GpuMat& buf, int histSize[4], int lowerLevel[4], int upperLevel[4], Stream& stream) { CV_Assert(src.type() == CV_8UC4 || src.type() == CV_16UC4 || src.type() == CV_16SC4 ); - typedef void (*hist_t)(const GpuMat& src, GpuMat hist[4], int levels[4], int lowerLevel[4], int upperLevel[4], cudaStream_t stream); + typedef void (*hist_t)(const GpuMat& src, GpuMat hist[4], GpuMat& buf, int levels[4], int lowerLevel[4], int upperLevel[4], cudaStream_t stream); static const hist_t hist_callers[] = { NppHistogramEvenC4::hist, @@ -1011,14 +1014,21 @@ void cv::gpu::histEven(const GpuMat& src, GpuMat hist[4], int histSize[4], int l NppHistogramEvenC4::hist }; - hist_callers[src.depth()](src, hist, histSize, lowerLevel, upperLevel, StreamAccessor::getStream(stream)); + hist_callers[src.depth()](src, hist, buf, histSize, lowerLevel, upperLevel, StreamAccessor::getStream(stream)); } void cv::gpu::histRange(const GpuMat& src, GpuMat& hist, const GpuMat& levels, Stream& stream) +{ + GpuMat buf; + histRange(src, hist, levels, buf, stream); +} + + +void cv::gpu::histRange(const GpuMat& src, GpuMat& hist, const GpuMat& levels, GpuMat& buf, Stream& stream) { CV_Assert(src.type() == CV_8UC1 || src.type() == CV_16UC1 || src.type() == CV_16SC1 || src.type() == CV_32FC1); - typedef void (*hist_t)(const GpuMat& src, GpuMat& hist, const GpuMat& levels, cudaStream_t stream); + typedef void (*hist_t)(const GpuMat& src, GpuMat& hist, const GpuMat& levels, GpuMat& buf, cudaStream_t stream); static const hist_t hist_callers[] = { NppHistogramRangeC1::hist, @@ -1029,14 +1039,20 @@ void cv::gpu::histRange(const GpuMat& src, GpuMat& hist, const GpuMat& levels, S NppHistogramRangeC1::hist }; - hist_callers[src.depth()](src, hist, levels, StreamAccessor::getStream(stream)); + hist_callers[src.depth()](src, hist, levels, buf, StreamAccessor::getStream(stream)); } void cv::gpu::histRange(const GpuMat& src, GpuMat hist[4], const GpuMat levels[4], Stream& stream) +{ + GpuMat buf; + histRange(src, hist, levels, buf, stream); +} + +void cv::gpu::histRange(const GpuMat& src, GpuMat hist[4], const GpuMat levels[4], GpuMat& buf, Stream& stream) { CV_Assert(src.type() == CV_8UC4 || src.type() == CV_16UC4 || src.type() == CV_16SC4 || src.type() == CV_32FC4); - typedef void (*hist_t)(const GpuMat& src, GpuMat hist[4], const GpuMat levels[4], cudaStream_t stream); + typedef void (*hist_t)(const GpuMat& src, GpuMat hist[4], const GpuMat levels[4], GpuMat& buf, cudaStream_t stream); static const hist_t hist_callers[] = { NppHistogramRangeC4::hist, @@ -1047,7 +1063,7 @@ void cv::gpu::histRange(const GpuMat& src, GpuMat hist[4], const GpuMat levels[4 NppHistogramRangeC4::hist }; - hist_callers[src.depth()](src, hist, levels, StreamAccessor::getStream(stream)); + hist_callers[src.depth()](src, hist, levels, buf, StreamAccessor::getStream(stream)); } namespace cv { namespace gpu { namespace histograms @@ -1151,7 +1167,6 @@ namespace scale *= 255.; scale = 1./scale; - GpuMat tmp_buf(src.size(), CV_32F); Dx.create(src.size(), CV_32F); Dy.create(src.size(), CV_32F); @@ -1209,6 +1224,12 @@ bool cv::gpu::tryConvertToGpuBorderType(int cpuBorderType, int& gpuBorderType) } void cv::gpu::cornerHarris(const GpuMat& src, GpuMat& dst, int blockSize, int ksize, double k, int borderType) +{ + GpuMat Dx, Dy; + cornerHarris(src, dst, Dx, Dy, blockSize, ksize, k, borderType); +} + +void cv::gpu::cornerHarris(const GpuMat& src, GpuMat& dst, GpuMat& Dx, GpuMat& Dy, int blockSize, int ksize, double k, int borderType) { CV_Assert(borderType == cv::BORDER_REFLECT101 || borderType == cv::BORDER_REPLICATE); @@ -1216,13 +1237,18 @@ void cv::gpu::cornerHarris(const GpuMat& src, GpuMat& dst, int blockSize, int ks int gpuBorderType; CV_Assert(tryConvertToGpuBorderType(borderType, gpuBorderType)); - GpuMat Dx, Dy; extractCovData(src, Dx, Dy, blockSize, ksize, borderType); dst.create(src.size(), CV_32F); imgproc::cornerHarris_caller(blockSize, (float)k, Dx, Dy, dst, gpuBorderType); } void cv::gpu::cornerMinEigenVal(const GpuMat& src, GpuMat& dst, int blockSize, int ksize, int borderType) +{ + GpuMat Dx, Dy; + cornerMinEigenVal(src, dst, Dx, Dy, blockSize, ksize, borderType); +} + +void cv::gpu::cornerMinEigenVal(const GpuMat& src, GpuMat& dst, GpuMat& Dx, GpuMat& Dy, int blockSize, int ksize, int borderType) { CV_Assert(borderType == cv::BORDER_REFLECT101 || borderType == cv::BORDER_REPLICATE); @@ -1230,7 +1256,6 @@ void cv::gpu::cornerMinEigenVal(const GpuMat& src, GpuMat& dst, int blockSize, i int gpuBorderType; CV_Assert(tryConvertToGpuBorderType(borderType, gpuBorderType)); - GpuMat Dx, Dy; extractCovData(src, Dx, Dy, blockSize, ksize, borderType); dst.create(src.size(), CV_32F); imgproc::cornerMinEigenVal_caller(blockSize, Dx, Dy, dst, gpuBorderType);