added Filter Engine to gpu module.
disabled gpu::sum, gpu::minMax, gpu:Canny until fix crash.
This commit is contained in:
parent
7a3b0785d7
commit
66df8ef06c
@ -407,10 +407,12 @@ namespace cv
|
||||
|
||||
//! computes sum of array elements
|
||||
//! supports CV_8UC1, CV_8UC4 types
|
||||
//! disabled until fix crash
|
||||
CV_EXPORTS Scalar sum(const GpuMat& m);
|
||||
|
||||
//! finds global minimum and maximum array elements and returns their values
|
||||
//! supports only CV_8UC1 type
|
||||
//! disabled until fix npp bug
|
||||
CV_EXPORTS void minMax(const GpuMat& src, double* minVal, double* maxVal = 0);
|
||||
|
||||
//! transforms 8-bit unsigned integers using lookup table: dst(i)=lut(src(i))
|
||||
@ -451,8 +453,10 @@ namespace cv
|
||||
CV_EXPORTS void log(const GpuMat& a, GpuMat& b);
|
||||
|
||||
//! computes magnitude (magnitude(i)) of each (x(i), y(i)) vector
|
||||
//! supports only CV_32FC1 type
|
||||
CV_EXPORTS void magnitude(const GpuMat& x, const GpuMat& y, GpuMat& magnitude);
|
||||
//! computes magnitude (magnitude(i)) of complex (x(i).re, x(i).im) vector
|
||||
//! supports only CV_32FC2 type
|
||||
CV_EXPORTS void magnitude(const GpuMat& x, GpuMat& magnitude);
|
||||
|
||||
////////////////////////////// Image processing //////////////////////////////
|
||||
@ -517,34 +521,169 @@ namespace cv
|
||||
//! supports only CV_32FC1 source type
|
||||
CV_EXPORTS void integral(GpuMat& src, GpuMat& sum, GpuMat& sqsum);
|
||||
|
||||
//! applies Canny edge detector and produces the edge map
|
||||
//! supprots only CV_8UC1 source type
|
||||
//! disabled until fix crash
|
||||
CV_EXPORTS void Canny(const GpuMat& image, GpuMat& edges, double threshold1, double threshold2, int apertureSize = 3);
|
||||
|
||||
//////////////////////////////// Filter Engine ////////////////////////////////
|
||||
|
||||
/*!
|
||||
The Base Class for 1D or Row-wise Filters
|
||||
|
||||
This is the base class for linear or non-linear filters that process 1D data.
|
||||
In particular, such filters are used for the "horizontal" filtering parts in separable filters.
|
||||
*/
|
||||
class CV_EXPORTS BaseRowFilter_GPU
|
||||
{
|
||||
public:
|
||||
BaseRowFilter_GPU(int ksize_, int anchor_) : ksize(ksize_), anchor(anchor_) {}
|
||||
virtual ~BaseRowFilter_GPU() {}
|
||||
virtual void operator()(const GpuMat& src, GpuMat& dst) = 0;
|
||||
int ksize, anchor;
|
||||
};
|
||||
|
||||
/*!
|
||||
The Base Class for Column-wise Filters
|
||||
|
||||
This is the base class for linear or non-linear filters that process columns of 2D arrays.
|
||||
Such filters are used for the "vertical" filtering parts in separable filters.
|
||||
*/
|
||||
class CV_EXPORTS BaseColumnFilter_GPU
|
||||
{
|
||||
public:
|
||||
BaseColumnFilter_GPU(int ksize_, int anchor_) : ksize(ksize_), anchor(anchor_) {}
|
||||
virtual ~BaseColumnFilter_GPU() {}
|
||||
virtual void operator()(const GpuMat& src, GpuMat& dst) = 0;
|
||||
int ksize, anchor;
|
||||
};
|
||||
|
||||
/*!
|
||||
The Base Class for Non-Separable 2D Filters.
|
||||
|
||||
This is the base class for linear or non-linear 2D filters.
|
||||
*/
|
||||
class CV_EXPORTS BaseFilter_GPU
|
||||
{
|
||||
public:
|
||||
BaseFilter_GPU(const Size& ksize_, const Point& anchor_) : ksize(ksize_), anchor(anchor_) {}
|
||||
virtual ~BaseFilter_GPU() {}
|
||||
virtual void operator()(const GpuMat& src, GpuMat& dst) = 0;
|
||||
Size ksize;
|
||||
Point anchor;
|
||||
};
|
||||
|
||||
/*!
|
||||
The Base Class for Filter Engine.
|
||||
|
||||
The class can be used to apply an arbitrary filtering operation to an image.
|
||||
It contains all the necessary intermediate buffers.
|
||||
*/
|
||||
class CV_EXPORTS FilterEngine_GPU
|
||||
{
|
||||
public:
|
||||
virtual ~FilterEngine_GPU() {}
|
||||
|
||||
virtual void apply(const GpuMat& src, GpuMat& dst, Rect roi = Rect(0,0,-1,-1)) = 0;
|
||||
};
|
||||
|
||||
//! returns the non-separable filter engine with the specified filter
|
||||
CV_EXPORTS Ptr<FilterEngine_GPU> createFilter2D_GPU(const Ptr<BaseFilter_GPU> filter2D);
|
||||
|
||||
//! returns the separable filter engine with the specified filters
|
||||
CV_EXPORTS Ptr<FilterEngine_GPU> createSeparableFilter_GPU(const Ptr<BaseRowFilter_GPU>& rowFilter,
|
||||
const Ptr<BaseColumnFilter_GPU>& columnFilter);
|
||||
|
||||
//! returns horizontal 1D box filter
|
||||
//! supports only CV_8UC1 source type and CV_32FC1 sum type
|
||||
CV_EXPORTS Ptr<BaseRowFilter_GPU> getRowSumFilter_GPU(int srcType, int sumType, int ksize, int anchor = -1);
|
||||
|
||||
//! returns vertical 1D box filter
|
||||
//! supports only CV_8UC1 sum type and CV_32FC1 dst type
|
||||
CV_EXPORTS Ptr<BaseColumnFilter_GPU> getColumnSumFilter_GPU(int sumType, int dstType, int ksize, int anchor = -1);
|
||||
|
||||
//! returns 2D box filter
|
||||
//! supports CV_8UC1 and CV_8UC4 source type, dst type must be the same as source type
|
||||
CV_EXPORTS Ptr<BaseFilter_GPU> getBoxFilter_GPU(int srcType, int dstType, const Size& ksize, Point anchor = Point(-1, -1));
|
||||
|
||||
//! returns box filter engine
|
||||
CV_EXPORTS Ptr<FilterEngine_GPU> createBoxFilter_GPU(int srcType, int dstType, const Size& ksize,
|
||||
const Point& anchor = Point(-1,-1));
|
||||
|
||||
//! returns 2D morphological filter
|
||||
//! only MORPH_ERODE and MORPH_DILATE are supported
|
||||
//! supports CV_8UC1 and CV_8UC4 types
|
||||
//! kernel must have CV_8UC1 type, one rows and cols == ksize.width * ksize.height
|
||||
CV_EXPORTS Ptr<BaseFilter_GPU> getMorphologyFilter_GPU(int op, int type, const GpuMat& kernel, const Size& ksize,
|
||||
Point anchor=Point(-1,-1));
|
||||
|
||||
//! returns morphological filter engine. Only MORPH_ERODE and MORPH_DILATE are supported.
|
||||
CV_EXPORTS Ptr<FilterEngine_GPU> createMorphologyFilter_GPU(int op, int type, const Mat& kernel,
|
||||
const Point& anchor = Point(-1,-1), int iterations = 1);
|
||||
|
||||
//! returns 2D filter with the specified kernel
|
||||
//! supports CV_8UC1 and CV_8UC4 types
|
||||
//! kernel must have CV_8UC1 type, one rows and cols == ksize.width * ksize.height
|
||||
CV_EXPORTS Ptr<BaseFilter_GPU> getLinearFilter_GPU(int srcType, int dstType, const GpuMat& kernel, const Size& ksize,
|
||||
Point anchor = Point(-1, -1), int nDivisor = 1);
|
||||
|
||||
//! returns the non-separable linear filter engine
|
||||
CV_EXPORTS Ptr<FilterEngine_GPU> createLinearFilter_GPU(int srcType, int dstType, const Mat& kernel,
|
||||
const Point& anchor = Point(-1,-1));
|
||||
|
||||
//! returns the primitive row filter with the specified kernel
|
||||
CV_EXPORTS Ptr<BaseRowFilter_GPU> getLinearRowFilter_GPU(int srcType, int bufType, const GpuMat& rowKernel,
|
||||
int anchor = -1, int nDivisor = 1);
|
||||
|
||||
//! returns the primitive column filter with the specified kernel
|
||||
CV_EXPORTS Ptr<BaseColumnFilter_GPU> getLinearColumnFilter_GPU(int bufType, int dstType, const GpuMat& columnKernel,
|
||||
int anchor = -1, int nDivisor = 1);
|
||||
|
||||
//! returns the separable linear filter engine
|
||||
CV_EXPORTS Ptr<FilterEngine_GPU> createSeparableLinearFilter_GPU(int srcType, int dstType, const Mat& rowKernel,
|
||||
const Mat& columnKernel, const Point& anchor = Point(-1,-1));
|
||||
|
||||
//! returns filter engine for the generalized Sobel operator
|
||||
CV_EXPORTS Ptr<FilterEngine_GPU> createDerivFilter_GPU(int srcType, int dstType, int dx, int dy, int ksize);
|
||||
|
||||
//! returns the Gaussian filter engine
|
||||
CV_EXPORTS Ptr<FilterEngine_GPU> createGaussianFilter_GPU(int type, Size ksize, double sigma1, double sigma2 = 0);
|
||||
|
||||
//! smooths the image using the normalized box filter
|
||||
//! supports CV_8UC1, CV_8UC4 types and kernel size 3, 5, 7
|
||||
CV_EXPORTS void boxFilter(const GpuMat& src, GpuMat& dst, Size ksize, Point anchor = Point(-1,-1));
|
||||
//! supports CV_8UC1, CV_8UC4 types
|
||||
CV_EXPORTS void boxFilter(const GpuMat& src, GpuMat& dst, int ddepth, Size ksize, Point anchor = Point(-1,-1));
|
||||
|
||||
//! a synonym for normalized box filter
|
||||
static inline void blur(const GpuMat& src, GpuMat& dst, Size ksize, Point anchor = Point(-1,-1)) { boxFilter(src, dst, ksize, anchor); }
|
||||
|
||||
static inline void blur(const GpuMat& src, GpuMat& dst, Size ksize, Point anchor = Point(-1,-1)) { boxFilter(src, dst, -1, ksize, anchor); }
|
||||
|
||||
//! erodes the image (applies the local minimum operator)
|
||||
CV_EXPORTS void erode( const GpuMat& src, GpuMat& dst, const Mat& kernel, Point anchor, int iterations);
|
||||
CV_EXPORTS void erode( const GpuMat& src, GpuMat& dst, const Mat& kernel, Point anchor = Point(-1, -1), int iterations = 1);
|
||||
|
||||
//! dilates the image (applies the local maximum operator)
|
||||
CV_EXPORTS void dilate( const GpuMat& src, GpuMat& dst, const Mat& kernel, Point anchor, int iterations);
|
||||
CV_EXPORTS void dilate( const GpuMat& src, GpuMat& dst, const Mat& kernel, Point anchor = Point(-1, -1), int iterations = 1);
|
||||
|
||||
//! applies an advanced morphological operation to the image
|
||||
CV_EXPORTS void morphologyEx( const GpuMat& src, GpuMat& dst, int op, const Mat& kernel, Point anchor, int iterations);
|
||||
CV_EXPORTS void morphologyEx( const GpuMat& src, GpuMat& dst, int op, const Mat& kernel, Point anchor = Point(-1, -1), int iterations = 1);
|
||||
|
||||
//! 1D mask Window Sum for 8 bit images
|
||||
CV_EXPORTS void sumWindowColumn(const GpuMat& src, GpuMat& dst, int ksize, int anchor = -1);
|
||||
CV_EXPORTS void sumWindowRow(const GpuMat& src, GpuMat& dst, int ksize, int anchor = -1);
|
||||
//! applies non-separable 2D linear filter to the image
|
||||
CV_EXPORTS void filter2D(const GpuMat& src, GpuMat& dst, int ddepth, const Mat& kernel, Point anchor=Point(-1,-1));
|
||||
|
||||
//! applies separable 2D linear filter to the image
|
||||
CV_EXPORTS void sepFilter2D(const GpuMat& src, GpuMat& dst, int ddepth, const Mat& kernelX, const Mat& kernelY,
|
||||
Point anchor = Point(-1,-1));
|
||||
|
||||
//! applies generalized Sobel operator to the image
|
||||
CV_EXPORTS void Sobel(const GpuMat& src, GpuMat& dst, int ddepth, int dx, int dy, int ksize = 3, double scale = 1);
|
||||
|
||||
//! applies the vertical or horizontal Scharr operator to the image
|
||||
CV_EXPORTS void Scharr(const GpuMat& src, GpuMat& dst, int ddepth, int dx, int dy, double scale = 1);
|
||||
|
||||
//! smooths the image using Gaussian filter.
|
||||
CV_EXPORTS void GaussianBlur(const GpuMat& src, GpuMat& dst, Size ksize, double sigma1, double sigma2 = 0);
|
||||
|
||||
//! applies Canny edge detector and produces the edge map.
|
||||
CV_EXPORTS void Canny(const GpuMat& image, GpuMat& edges, double threshold1, double threshold2, int apertureSize = 3);
|
||||
//! applies Laplacian operator to the image
|
||||
//! supports only ksize = 1 and ksize = 3
|
||||
CV_EXPORTS void Laplacian(const GpuMat& src, GpuMat& dst, int ddepth, int ksize = 1, double scale = 1);
|
||||
|
||||
//////////////////////////////// Image Labeling ////////////////////////////////
|
||||
|
||||
|
@ -387,6 +387,7 @@ void cv::gpu::flip(const GpuMat& src, GpuMat& dst, int flipCode)
|
||||
|
||||
Scalar cv::gpu::sum(const GpuMat& src)
|
||||
{
|
||||
CV_Assert(!"disabled until fix crash");
|
||||
CV_Assert(src.type() == CV_8UC1 || src.type() == CV_8UC4);
|
||||
|
||||
NppiSize sz;
|
||||
@ -420,6 +421,7 @@ Scalar cv::gpu::sum(const GpuMat& src)
|
||||
|
||||
void cv::gpu::minMax(const GpuMat& src, double* minVal, double* maxVal)
|
||||
{
|
||||
CV_Assert(!"disabled until fix npp bug");
|
||||
CV_Assert(src.type() == CV_8UC1);
|
||||
|
||||
NppiSize sz;
|
||||
|
@ -48,82 +48,413 @@ using namespace cv::gpu;
|
||||
|
||||
#if !defined (HAVE_CUDA)
|
||||
|
||||
Ptr<FilterEngine_GPU> cv::gpu::createFilter2D_GPU(const Ptr<BaseFilter_GPU>) { throw_nogpu(); return Ptr<FilterEngine_GPU>(0); }
|
||||
Ptr<FilterEngine_GPU> cv::gpu::createSeparableFilter_GPU(const Ptr<BaseRowFilter_GPU>&, const Ptr<BaseColumnFilter_GPU>&) { throw_nogpu(); return Ptr<FilterEngine_GPU>(0); }
|
||||
Ptr<BaseRowFilter_GPU> cv::gpu::getRowSumFilter_GPU(int, int, int, int) { throw_nogpu(); return Ptr<BaseRowFilter_GPU>(0); }
|
||||
Ptr<BaseColumnFilter_GPU> cv::gpu::getColumnSumFilter_GPU(int, int, int, int) { throw_nogpu(); return Ptr<BaseColumnFilter_GPU>(0); }
|
||||
Ptr<BaseFilter_GPU> cv::gpu::getBoxFilter_GPU(int, int, const Size&, Point) { throw_nogpu(); return Ptr<BaseFilter_GPU>(0); }
|
||||
Ptr<FilterEngine_GPU> cv::gpu::createBoxFilter_GPU(int, int, const Size&, const Point&) { throw_nogpu(); return Ptr<FilterEngine_GPU>(0); }
|
||||
Ptr<BaseFilter_GPU> cv::gpu::getMorphologyFilter_GPU(int, int, const GpuMat&, const Size&, Point) { throw_nogpu(); return Ptr<BaseFilter_GPU>(0); }
|
||||
Ptr<FilterEngine_GPU> cv::gpu::createMorphologyFilter_GPU(int, int, const Mat&, const Point&, int) { throw_nogpu(); return Ptr<FilterEngine_GPU>(0); }
|
||||
Ptr<BaseFilter_GPU> cv::gpu::getLinearFilter_GPU(int, int, const GpuMat&, const Size&, Point, int) { throw_nogpu(); return Ptr<BaseFilter_GPU>(0); }
|
||||
Ptr<FilterEngine_GPU> cv::gpu::createLinearFilter_GPU(int, int, const Mat&, const Point&) { throw_nogpu(); return Ptr<FilterEngine_GPU>(0); }
|
||||
Ptr<BaseRowFilter_GPU> cv::gpu::getLinearRowFilter_GPU(int, int, const GpuMat&, int, int) { throw_nogpu(); return Ptr<BaseRowFilter_GPU>(0); }
|
||||
Ptr<BaseColumnFilter_GPU> cv::gpu::getLinearColumnFilter_GPU(int, int, const GpuMat&, int, int) { throw_nogpu(); return Ptr<BaseColumnFilter_GPU>(0); }
|
||||
Ptr<FilterEngine_GPU> cv::gpu::createSeparableLinearFilter_GPU(int, int, const Mat&, const Mat&, const Point&) { throw_nogpu(); return Ptr<FilterEngine_GPU>(0); }
|
||||
Ptr<FilterEngine_GPU> cv::gpu::createDerivFilter_GPU(int, int, int, int, int) { throw_nogpu(); return Ptr<FilterEngine_GPU>(0); }
|
||||
Ptr<FilterEngine_GPU> cv::gpu::createGaussianFilter_GPU(int, Size, double, double) { throw_nogpu(); return Ptr<FilterEngine_GPU>(0); }
|
||||
void cv::gpu::boxFilter(const GpuMat&, GpuMat&, int, Size, Point) { throw_nogpu(); }
|
||||
void cv::gpu::erode( const GpuMat&, GpuMat&, const Mat&, Point, int) { throw_nogpu(); }
|
||||
void cv::gpu::dilate( const GpuMat&, GpuMat&, const Mat&, Point, int) { throw_nogpu(); }
|
||||
void cv::gpu::morphologyEx( const GpuMat&, GpuMat&, int, const Mat&, Point, int) { throw_nogpu(); }
|
||||
void cv::gpu::boxFilter(const GpuMat&, GpuMat&, Size, Point) { throw_nogpu(); }
|
||||
void cv::gpu::sumWindowColumn(const GpuMat&, GpuMat&, int, int) { throw_nogpu(); }
|
||||
void cv::gpu::sumWindowRow(const GpuMat&, GpuMat&, int, int) { throw_nogpu(); }
|
||||
void cv::gpu::filter2D(const GpuMat&, GpuMat&, int, const Mat&, Point) { throw_nogpu(); }
|
||||
void cv::gpu::sepFilter2D(const GpuMat&, GpuMat&, int, const Mat&, const Mat&, Point) { throw_nogpu(); }
|
||||
void cv::gpu::Sobel(const GpuMat&, GpuMat&, int, int, int, int, double) { throw_nogpu(); }
|
||||
void cv::gpu::Scharr(const GpuMat&, GpuMat&, int, int, int, double) { throw_nogpu(); }
|
||||
void cv::gpu::GaussianBlur(const GpuMat&, GpuMat&, Size, double, double) { throw_nogpu(); }
|
||||
void cv::gpu::Laplacian(const GpuMat&, GpuMat&, int, int, double) { throw_nogpu(); }
|
||||
|
||||
#else
|
||||
|
||||
namespace
|
||||
namespace
|
||||
{
|
||||
typedef NppStatus (*npp_morf_func)(const Npp8u*, Npp32s, Npp8u*, Npp32s, NppiSize, const Npp8u*, NppiSize, NppiPoint);
|
||||
|
||||
|
||||
void morphoogy_caller(npp_morf_func func, const GpuMat& src, GpuMat& dst, const Mat& kernel, Point anchor, int iterations)
|
||||
inline void normalizeAnchor(int& anchor, int ksize)
|
||||
{
|
||||
CV_Assert(src.type() == CV_8U || src.type() == CV_8UC4);
|
||||
CV_Assert(kernel.type() == CV_8U && (kernel.cols & 1) != 0 && (kernel.rows & 1) != 0);
|
||||
if (anchor < 0)
|
||||
anchor = ksize >> 1;
|
||||
|
||||
if( anchor.x == -1 )
|
||||
anchor.x = kernel.cols / 2;
|
||||
if( anchor.y == -1 )
|
||||
anchor.y = kernel.rows / 2;
|
||||
CV_Assert(0 <= anchor && anchor < ksize);
|
||||
}
|
||||
|
||||
// in NPP for Cuda 3.1 only such anchor is supported.
|
||||
CV_Assert(anchor.x == 0 && anchor.y == 0);
|
||||
inline void normalizeAnchor(Point& anchor, const Size& ksize)
|
||||
{
|
||||
normalizeAnchor(anchor.x, ksize.width);
|
||||
normalizeAnchor(anchor.y, ksize.height);
|
||||
}
|
||||
|
||||
if (iterations == 0)
|
||||
inline void normalizeROI(Rect& roi, const Size& ksize, const Size& src_size)
|
||||
{
|
||||
if (roi == Rect(0,0,-1,-1))
|
||||
roi = Rect(ksize.width, ksize.height, src_size.width - 2 * ksize.width, src_size.height - 2 * ksize.height);
|
||||
|
||||
CV_Assert(roi.x >= 0 && roi.y >= 0 && roi.width <= src_size.width && roi.height <= src_size.height);
|
||||
}
|
||||
|
||||
inline void normalizeKernel(const Mat& kernel, GpuMat& gpu_krnl, int type = CV_8U, int* nDivisor = 0, bool reverse = false)
|
||||
{
|
||||
int scale = nDivisor && (kernel.depth() == CV_32F || kernel.depth() == CV_64F) ? 256 : 1;
|
||||
if (nDivisor) *nDivisor = scale;
|
||||
|
||||
Mat cont_krnl = (kernel.isContinuous() ? kernel : kernel.clone()).reshape(1, 1);
|
||||
Mat temp;
|
||||
cont_krnl.convertTo(temp, type, scale);
|
||||
|
||||
if (reverse)
|
||||
{
|
||||
int count = temp.cols >> 1;
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
std::swap(temp.at<int>(0, i), temp.at<int>(0, temp.cols - 1 - i));
|
||||
}
|
||||
}
|
||||
|
||||
gpu_krnl.upload(temp);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Filter2D
|
||||
|
||||
namespace
|
||||
{
|
||||
class Filter2DEngine_GPU : public FilterEngine_GPU
|
||||
{
|
||||
public:
|
||||
Filter2DEngine_GPU(const Ptr<BaseFilter_GPU>& filter2D_) : filter2D(filter2D_) {}
|
||||
|
||||
virtual void apply(const GpuMat& src, GpuMat& dst, Rect roi = Rect(0,0,-1,-1))
|
||||
{
|
||||
Size src_size = src.size();
|
||||
|
||||
dst.create(src_size, src.type());
|
||||
|
||||
normalizeROI(roi, filter2D->ksize, src_size);
|
||||
|
||||
GpuMat srcROI = src(roi);
|
||||
GpuMat dstROI = dst(roi);
|
||||
|
||||
(*filter2D)(srcROI, dstROI);
|
||||
}
|
||||
|
||||
Ptr<BaseFilter_GPU> filter2D;
|
||||
};
|
||||
}
|
||||
|
||||
Ptr<FilterEngine_GPU> cv::gpu::createFilter2D_GPU(const Ptr<BaseFilter_GPU> filter2D)
|
||||
{
|
||||
return Ptr<FilterEngine_GPU>(new Filter2DEngine_GPU(filter2D));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SeparableFilter
|
||||
|
||||
namespace
|
||||
{
|
||||
class SeparableFilterEngine_GPU : public FilterEngine_GPU
|
||||
{
|
||||
public:
|
||||
SeparableFilterEngine_GPU(const Ptr<BaseRowFilter_GPU>& rowFilter_, const Ptr<BaseColumnFilter_GPU>& columnFilter_) :
|
||||
rowFilter(rowFilter_), columnFilter(columnFilter_)
|
||||
{
|
||||
ksize = Size(rowFilter->ksize, columnFilter->ksize);
|
||||
}
|
||||
|
||||
virtual void apply(const GpuMat& src, GpuMat& dst, Rect roi = Rect(0,0,-1,-1))
|
||||
{
|
||||
Size src_size = src.size();
|
||||
int src_type = src.type();
|
||||
|
||||
dst.create(src_size, src_type);
|
||||
dstBuf.create(src_size, src_type);
|
||||
|
||||
normalizeROI(roi, ksize, src_size);
|
||||
|
||||
GpuMat srcROI = src(roi);
|
||||
GpuMat dstROI = dst(roi);
|
||||
GpuMat dstBufROI = dstBuf(roi);
|
||||
|
||||
(*rowFilter)(srcROI, dstBufROI);
|
||||
(*columnFilter)(dstBufROI, dstROI);
|
||||
}
|
||||
|
||||
Ptr<BaseRowFilter_GPU> rowFilter;
|
||||
Ptr<BaseColumnFilter_GPU> columnFilter;
|
||||
Size ksize;
|
||||
GpuMat dstBuf;
|
||||
};
|
||||
}
|
||||
|
||||
Ptr<FilterEngine_GPU> cv::gpu::createSeparableFilter_GPU(const Ptr<BaseRowFilter_GPU>& rowFilter,
|
||||
const Ptr<BaseColumnFilter_GPU>& columnFilter)
|
||||
{
|
||||
return Ptr<FilterEngine_GPU>(new SeparableFilterEngine_GPU(rowFilter, columnFilter));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// 1D Sum Filter
|
||||
|
||||
namespace
|
||||
{
|
||||
class NppRowSumFilter : public BaseRowFilter_GPU
|
||||
{
|
||||
public:
|
||||
NppRowSumFilter(int ksize_, int anchor_) : BaseRowFilter_GPU(ksize_, anchor_) {}
|
||||
|
||||
virtual void operator()(const GpuMat& src, GpuMat& dst)
|
||||
{
|
||||
NppiSize sz;
|
||||
sz.width = src.cols;
|
||||
sz.height = src.rows;
|
||||
|
||||
nppSafeCall( nppiSumWindowRow_8u32f_C1R(src.ptr<Npp8u>(), src.step, dst.ptr<Npp32f>(), dst.step, sz, ksize, anchor) );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Ptr<BaseRowFilter_GPU> cv::gpu::getRowSumFilter_GPU(int srcType, int sumType, int ksize, int anchor)
|
||||
{
|
||||
CV_Assert(srcType == CV_8UC1 && sumType == CV_32FC1);
|
||||
|
||||
normalizeAnchor(anchor, ksize);
|
||||
|
||||
return Ptr<BaseRowFilter_GPU>(new NppRowSumFilter(ksize, anchor));
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
class NppColumnSumFilter : public BaseColumnFilter_GPU
|
||||
{
|
||||
public:
|
||||
NppColumnSumFilter(int ksize_, int anchor_) : BaseColumnFilter_GPU(ksize_, anchor_) {}
|
||||
|
||||
virtual void operator()(const GpuMat& src, GpuMat& dst)
|
||||
{
|
||||
NppiSize sz;
|
||||
sz.width = src.cols;
|
||||
sz.height = src.rows;
|
||||
|
||||
nppSafeCall( nppiSumWindowColumn_8u32f_C1R(src.ptr<Npp8u>(), src.step, dst.ptr<Npp32f>(), dst.step, sz, ksize, anchor) );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Ptr<BaseColumnFilter_GPU> cv::gpu::getColumnSumFilter_GPU(int sumType, int dstType, int ksize, int anchor)
|
||||
{
|
||||
CV_Assert(sumType == CV_8UC1 && dstType == CV_32FC1);
|
||||
|
||||
normalizeAnchor(anchor, ksize);
|
||||
|
||||
return Ptr<BaseColumnFilter_GPU>(new NppColumnSumFilter(ksize, anchor));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Box Filter
|
||||
|
||||
namespace
|
||||
{
|
||||
typedef NppStatus (*nppFilterBox_t)(const Npp8u * pSrc, Npp32s nSrcStep, Npp8u * pDst, Npp32s nDstStep, NppiSize oSizeROI,
|
||||
NppiSize oMaskSize, NppiPoint oAnchor);
|
||||
|
||||
class NPPBoxFilter : public BaseFilter_GPU
|
||||
{
|
||||
public:
|
||||
NPPBoxFilter(const Size& ksize_, const Point& anchor_, nppFilterBox_t func_) : BaseFilter_GPU(ksize_, anchor_), func(func_) {}
|
||||
|
||||
virtual void operator()(const GpuMat& src, GpuMat& dst)
|
||||
{
|
||||
NppiSize sz;
|
||||
sz.width = src.cols;
|
||||
sz.height = src.rows;
|
||||
NppiSize oKernelSize;
|
||||
oKernelSize.height = ksize.height;
|
||||
oKernelSize.width = ksize.width;
|
||||
NppiPoint oAnchor;
|
||||
oAnchor.x = anchor.x;
|
||||
oAnchor.y = anchor.y;
|
||||
|
||||
nppSafeCall( func(src.ptr<Npp8u>(), src.step, dst.ptr<Npp8u>(), dst.step, sz, oKernelSize, oAnchor) );
|
||||
}
|
||||
|
||||
nppFilterBox_t func;
|
||||
};
|
||||
}
|
||||
|
||||
Ptr<BaseFilter_GPU> cv::gpu::getBoxFilter_GPU(int srcType, int dstType, const Size& ksize, Point anchor)
|
||||
{
|
||||
static const nppFilterBox_t nppFilterBox_callers[] = {0, nppiFilterBox_8u_C1R, 0, 0, nppiFilterBox_8u_C4R};
|
||||
|
||||
CV_Assert((srcType == CV_8UC1 || srcType == CV_8UC4) && dstType == srcType);
|
||||
|
||||
normalizeAnchor(anchor, ksize);
|
||||
|
||||
return Ptr<BaseFilter_GPU>(new NPPBoxFilter(ksize, anchor, nppFilterBox_callers[CV_MAT_CN(srcType)]));
|
||||
}
|
||||
|
||||
Ptr<FilterEngine_GPU> cv::gpu::createBoxFilter_GPU(int srcType, int dstType, const Size& ksize, const Point& anchor)
|
||||
{
|
||||
Ptr<BaseFilter_GPU> boxFilter = getBoxFilter_GPU(srcType, dstType, ksize, anchor);
|
||||
return createFilter2D_GPU(boxFilter);
|
||||
}
|
||||
|
||||
void cv::gpu::boxFilter(const GpuMat& src, GpuMat& dst, int ddepth, Size ksize, Point anchor)
|
||||
{
|
||||
int sdepth = src.depth(), cn = src.channels();
|
||||
if( ddepth < 0 )
|
||||
ddepth = sdepth;
|
||||
|
||||
dst.create(src.size(), CV_MAKETYPE(ddepth, cn));
|
||||
|
||||
Ptr<FilterEngine_GPU> f = createBoxFilter_GPU(src.type(), dst.type(), ksize, anchor);
|
||||
f->apply(src, dst);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Morphology Filter
|
||||
|
||||
namespace
|
||||
{
|
||||
typedef NppStatus (*nppMorfFilter_t)(const Npp8u*, Npp32s, Npp8u*, Npp32s, NppiSize, const Npp8u*, NppiSize, NppiPoint);
|
||||
|
||||
class NPPMorphFilter : public BaseFilter_GPU
|
||||
{
|
||||
public:
|
||||
NPPMorphFilter(const Size& ksize_, const Point& anchor_, const GpuMat& kernel_, nppMorfFilter_t func_) :
|
||||
BaseFilter_GPU(ksize_, anchor_), kernel(kernel_), func(func_) {}
|
||||
|
||||
virtual void operator()(const GpuMat& src, GpuMat& dst)
|
||||
{
|
||||
NppiSize sz;
|
||||
sz.width = src.cols;
|
||||
sz.height = src.rows;
|
||||
NppiSize oKernelSize;
|
||||
oKernelSize.height = ksize.height;
|
||||
oKernelSize.width = ksize.width;
|
||||
NppiPoint oAnchor;
|
||||
oAnchor.x = anchor.x;
|
||||
oAnchor.y = anchor.y;
|
||||
|
||||
nppSafeCall( func(src.ptr<Npp8u>(), src.step, dst.ptr<Npp8u>(), dst.step, sz, kernel.ptr<Npp8u>(), oKernelSize, oAnchor) );
|
||||
}
|
||||
|
||||
GpuMat kernel;
|
||||
nppMorfFilter_t func;
|
||||
};
|
||||
}
|
||||
|
||||
Ptr<BaseFilter_GPU> cv::gpu::getMorphologyFilter_GPU(int op, int type, const GpuMat& kernel, const Size& ksize, Point anchor)
|
||||
{
|
||||
static const nppMorfFilter_t nppMorfFilter_callers[2][5] =
|
||||
{
|
||||
{0, nppiErode_8u_C1R, 0, 0, nppiErode_8u_C4R },
|
||||
{0, nppiDilate_8u_C1R, 0, 0, nppiDilate_8u_C4R }
|
||||
};
|
||||
|
||||
CV_Assert(op == MORPH_ERODE || op == MORPH_DILATE);
|
||||
CV_Assert(type == CV_8UC1 || type == CV_8UC4);
|
||||
CV_Assert(kernel.type() == CV_8UC1 && kernel.rows == 1 && kernel.cols == ksize.area());
|
||||
|
||||
normalizeAnchor(anchor, ksize);
|
||||
|
||||
return Ptr<BaseFilter_GPU>(new NPPMorphFilter(ksize, anchor, kernel, nppMorfFilter_callers[op][CV_MAT_CN(type)]));
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
class MorphologyFilterEngine_GPU : public Filter2DEngine_GPU
|
||||
{
|
||||
public:
|
||||
MorphologyFilterEngine_GPU(const Ptr<BaseFilter_GPU>& filter2D_, int iters_) :
|
||||
Filter2DEngine_GPU(filter2D_), iters(iters_) {}
|
||||
|
||||
virtual void apply(const GpuMat& src, GpuMat& dst, Rect roi = Rect(0,0,-1,-1))
|
||||
{
|
||||
if (iters > 1)
|
||||
dstBuf.create(src.size(), src.type());
|
||||
|
||||
Filter2DEngine_GPU::apply(src, dst);
|
||||
for(int i = 1; i < iters; ++i)
|
||||
{
|
||||
dst.swap(dstBuf);
|
||||
Filter2DEngine_GPU::apply(dst, dst);
|
||||
}
|
||||
}
|
||||
|
||||
int iters;
|
||||
GpuMat dstBuf;
|
||||
};
|
||||
}
|
||||
|
||||
Ptr<FilterEngine_GPU> cv::gpu::createMorphologyFilter_GPU(int op, int type, const Mat& kernel, const Point& anchor, int iterations)
|
||||
{
|
||||
CV_Assert(iterations > 0);
|
||||
|
||||
Size ksize = kernel.size();
|
||||
|
||||
GpuMat gpu_krnl;
|
||||
normalizeKernel(kernel, gpu_krnl);
|
||||
|
||||
Ptr<BaseFilter_GPU> filter2D = getMorphologyFilter_GPU(op, type, gpu_krnl, ksize, anchor);
|
||||
|
||||
return Ptr<FilterEngine_GPU>(new MorphologyFilterEngine_GPU(filter2D, iterations));
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
void morphOp(int op, const GpuMat& src, GpuMat& dst, const Mat& _kernel, Point anchor, int iterations)
|
||||
{
|
||||
Mat kernel;
|
||||
Size ksize = _kernel.data ? _kernel.size() : Size(3, 3);
|
||||
|
||||
normalizeAnchor(anchor, ksize);
|
||||
|
||||
if (iterations == 0 || _kernel.rows * _kernel.cols == 1)
|
||||
{
|
||||
src.copyTo(dst);
|
||||
return;
|
||||
}
|
||||
|
||||
const Mat& cont_krnl = (kernel.isContinuous() ? kernel : kernel.clone()).reshape(1, 1);
|
||||
GpuMat gpu_krnl(cont_krnl);
|
||||
|
||||
NppiSize sz;
|
||||
sz.width = src.cols;
|
||||
sz.height = src.rows;
|
||||
|
||||
NppiSize mask_sz;
|
||||
mask_sz.width = kernel.cols;
|
||||
mask_sz.height = kernel.rows;
|
||||
|
||||
NppiPoint anc;
|
||||
anc.x = anchor.x;
|
||||
anc.y = anchor.y;
|
||||
|
||||
dst.create(src.size(), src.type());
|
||||
GpuMat dstBuf;
|
||||
if (iterations > 1)
|
||||
dstBuf.create(src.size(), src.type());
|
||||
|
||||
nppSafeCall( func(src.ptr<Npp8u>(), src.step, dst.ptr<Npp8u>(), dst.step, sz, gpu_krnl.ptr<Npp8u>(), mask_sz, anc) );
|
||||
for(int i = 1; i < iterations; ++i)
|
||||
if (!_kernel.data)
|
||||
{
|
||||
dst.swap(dstBuf);
|
||||
nppSafeCall( func(dstBuf.ptr<Npp8u>(), dstBuf.step, dst.ptr<Npp8u>(), dst.step, sz, gpu_krnl.ptr<Npp8u>(), mask_sz, anc) );
|
||||
kernel = getStructuringElement(MORPH_RECT, Size(1 + iterations * 2, 1 + iterations * 2));
|
||||
anchor = Point(iterations, iterations);
|
||||
iterations = 1;
|
||||
}
|
||||
else if (iterations > 1 && countNonZero(_kernel) == _kernel.rows * _kernel.cols)
|
||||
{
|
||||
anchor = Point(anchor.x * iterations, anchor.y * iterations);
|
||||
kernel = getStructuringElement(MORPH_RECT, Size(ksize.width + iterations * (ksize.width - 1),
|
||||
ksize.height + iterations * (ksize.height - 1)), anchor);
|
||||
iterations = 1;
|
||||
}
|
||||
else
|
||||
kernel = _kernel;
|
||||
|
||||
Ptr<FilterEngine_GPU> f = createMorphologyFilter_GPU(op, src.type(), kernel, anchor, iterations);
|
||||
|
||||
f->apply(src, dst);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void cv::gpu::erode( const GpuMat& src, GpuMat& dst, const Mat& kernel, Point anchor, int iterations)
|
||||
{
|
||||
static npp_morf_func funcs[] = {0, nppiErode_8u_C1R, 0, 0, nppiErode_8u_C4R };
|
||||
|
||||
morphoogy_caller(funcs[src.channels()], src, dst, kernel, anchor, iterations);
|
||||
morphOp(MORPH_ERODE, src, dst, kernel, anchor, iterations);
|
||||
}
|
||||
|
||||
void cv::gpu::dilate( const GpuMat& src, GpuMat& dst, const Mat& kernel, Point anchor, int iterations)
|
||||
{
|
||||
static npp_morf_func funcs[] = {0, nppiDilate_8u_C1R, 0, 0, nppiDilate_8u_C4R };
|
||||
morphoogy_caller(funcs[src.channels()], src, dst, kernel, anchor, iterations);
|
||||
morphOp(MORPH_DILATE, src, dst, kernel, anchor, iterations);
|
||||
}
|
||||
|
||||
void cv::gpu::morphologyEx( const GpuMat& src, GpuMat& dst, int op, const Mat& kernel, Point anchor, int iterations)
|
||||
@ -165,195 +496,197 @@ void cv::gpu::morphologyEx( const GpuMat& src, GpuMat& dst, int op, const Mat& k
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// boxFilter
|
||||
|
||||
void cv::gpu::boxFilter(const GpuMat& src, GpuMat& dst, Size ksize, Point anchor)
|
||||
{
|
||||
CV_Assert(src.type() == CV_8UC1 || src.type() == CV_8UC4);
|
||||
CV_Assert(ksize.height == 3 || ksize.height == 5 || ksize.height == 7);
|
||||
CV_Assert(ksize.height == ksize.width);
|
||||
|
||||
if (anchor.x == -1)
|
||||
anchor.x = 0;
|
||||
if (anchor.y == -1)
|
||||
anchor.y = 0;
|
||||
|
||||
CV_Assert(anchor.x == 0 && anchor.y == 0);
|
||||
|
||||
dst.create(src.size(), src.type());
|
||||
|
||||
NppiSize srcsz;
|
||||
srcsz.height = src.rows;
|
||||
srcsz.width = src.cols;
|
||||
NppiSize masksz;
|
||||
masksz.height = ksize.height;
|
||||
masksz.width = ksize.width;
|
||||
NppiPoint anc;
|
||||
anc.x = anchor.x;
|
||||
anc.y = anchor.y;
|
||||
|
||||
if (src.type() == CV_8UC1)
|
||||
{
|
||||
nppSafeCall( nppiFilterBox_8u_C1R(src.ptr<Npp8u>(), src.step, dst.ptr<Npp8u>(), dst.step, srcsz, masksz, anc) );
|
||||
}
|
||||
else
|
||||
{
|
||||
nppSafeCall( nppiFilterBox_8u_C4R(src.ptr<Npp8u>(), src.step, dst.ptr<Npp8u>(), dst.step, srcsz, masksz, anc) );
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// sumWindow Filter
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Linear Filter
|
||||
|
||||
namespace
|
||||
{
|
||||
typedef NppStatus (*nppSumWindow_t)(const Npp8u * pSrc, Npp32s nSrcStep,
|
||||
Npp32f * pDst, Npp32s nDstStep, NppiSize oROI,
|
||||
Npp32s nMaskSize, Npp32s nAnchor);
|
||||
typedef NppStatus (*nppFilter2D_t)(const Npp8u * pSrc, Npp32s nSrcStep, Npp8u * pDst, Npp32s nDstStep, NppiSize oSizeROI,
|
||||
const Npp32s * pKernel, NppiSize oKernelSize, NppiPoint oAnchor, Npp32s nDivisor);
|
||||
|
||||
inline void sumWindowCaller(nppSumWindow_t func, const GpuMat& src, GpuMat& dst, int ksize, int anchor)
|
||||
class NPPLinearFilter : public BaseFilter_GPU
|
||||
{
|
||||
CV_Assert(src.type() == CV_8UC1);
|
||||
|
||||
if (anchor == -1)
|
||||
anchor = ksize / 2;
|
||||
public:
|
||||
NPPLinearFilter(const Size& ksize_, const Point& anchor_, const GpuMat& kernel_, Npp32s nDivisor_, nppFilter2D_t func_) :
|
||||
BaseFilter_GPU(ksize_, anchor_), kernel(kernel_), nDivisor(nDivisor_), func(func_) {}
|
||||
|
||||
NppiSize sz;
|
||||
sz.width = src.cols;
|
||||
sz.height = src.rows;
|
||||
virtual void operator()(const GpuMat& src, GpuMat& dst)
|
||||
{
|
||||
NppiSize sz;
|
||||
sz.width = src.cols;
|
||||
sz.height = src.rows;
|
||||
NppiSize oKernelSize;
|
||||
oKernelSize.height = ksize.height;
|
||||
oKernelSize.width = ksize.width;
|
||||
NppiPoint oAnchor;
|
||||
oAnchor.x = anchor.x;
|
||||
oAnchor.y = anchor.y;
|
||||
|
||||
nppSafeCall( func(src.ptr<Npp8u>(), src.step, dst.ptr<Npp8u>(), dst.step, sz,
|
||||
kernel.ptr<Npp32s>(), oKernelSize, oAnchor, nDivisor) );
|
||||
}
|
||||
|
||||
dst.create(src.size(), CV_32FC1);
|
||||
|
||||
nppSafeCall( func(src.ptr<Npp8u>(), src.step, dst.ptr<Npp32f>(), dst.step, sz, ksize, anchor) );
|
||||
}
|
||||
GpuMat kernel;
|
||||
Npp32s nDivisor;
|
||||
nppFilter2D_t func;
|
||||
};
|
||||
}
|
||||
|
||||
void cv::gpu::sumWindowColumn(const GpuMat& src, GpuMat& dst, int ksize, int anchor)
|
||||
Ptr<BaseFilter_GPU> cv::gpu::getLinearFilter_GPU(int srcType, int dstType, const GpuMat& kernel, const Size& ksize, Point anchor, int nDivisor)
|
||||
{
|
||||
sumWindowCaller(nppiSumWindowColumn_8u32f_C1R, src, dst, ksize, anchor);
|
||||
}
|
||||
static const nppFilter2D_t cppFilter2D_callers[] = {0, nppiFilter_8u_C1R, 0, 0, nppiFilter_8u_C4R};
|
||||
|
||||
void cv::gpu::sumWindowRow(const GpuMat& src, GpuMat& dst, int ksize, int anchor)
|
||||
CV_Assert((srcType == CV_8UC1 || srcType == CV_8UC4) && dstType == srcType);
|
||||
CV_Assert(kernel.type() == CV_32SC1 && kernel.rows == 1 && kernel.cols == ksize.area());
|
||||
|
||||
normalizeAnchor(anchor, ksize);
|
||||
|
||||
return Ptr<BaseFilter_GPU>(new NPPLinearFilter(ksize, anchor, kernel, nDivisor, cppFilter2D_callers[CV_MAT_CN(srcType)]));
|
||||
}
|
||||
|
||||
Ptr<FilterEngine_GPU> cv::gpu::createLinearFilter_GPU(int srcType, int dstType, const Mat& kernel, const Point& anchor)
|
||||
{
|
||||
sumWindowCaller(nppiSumWindowRow_8u32f_C1R, src, dst, ksize, anchor);
|
||||
Size ksize = kernel.size();
|
||||
|
||||
GpuMat gpu_krnl;
|
||||
int nDivisor;
|
||||
normalizeKernel(kernel, gpu_krnl, CV_32S, &nDivisor, true);
|
||||
|
||||
Ptr<BaseFilter_GPU> linearFilter = getLinearFilter_GPU(srcType, dstType, gpu_krnl, ksize, anchor, nDivisor);
|
||||
|
||||
return createFilter2D_GPU(linearFilter);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Filter Engine
|
||||
void cv::gpu::filter2D(const GpuMat& src, GpuMat& dst, int ddepth, const Mat& kernel, Point anchor)
|
||||
{
|
||||
if( ddepth < 0 )
|
||||
ddepth = src.depth();
|
||||
|
||||
dst.create(src.size(), CV_MAKETYPE(ddepth, src.channels()));
|
||||
|
||||
Ptr<FilterEngine_GPU> f = createLinearFilter_GPU(src.type(), dst.type(), kernel, anchor);
|
||||
f->apply(src, dst);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Separable Linear Filter
|
||||
|
||||
namespace
|
||||
{
|
||||
typedef NppStatus (*nppFilter1D_t)(const Npp8u * pSrc, Npp32s nSrcStep, Npp8u * pDst, Npp32s nDstStep, NppiSize oROI,
|
||||
const Npp32s * pKernel, Npp32s nMaskSize, Npp32s nAnchor, Npp32s nDivisor);
|
||||
typedef NppStatus (*nppFilter2D_t)(const Npp8u * pSrc, Npp32s nSrcStep, Npp8u * pDst, Npp32s nDstStep, NppiSize oSizeROI,
|
||||
const Npp32s * pKernel, NppiSize oKernelSize, NppiPoint oAnchor, Npp32s nDivisor);
|
||||
const Npp32s * pKernel, Npp32s nMaskSize, Npp32s nAnchor, Npp32s nDivisor);
|
||||
|
||||
void applyRowFilter(const GpuMat& src, GpuMat& dst, const GpuMat& rowKernel, Npp32s anchor = -1, Npp32s nDivisor = 1)
|
||||
class NppLinearRowFilter : public BaseRowFilter_GPU
|
||||
{
|
||||
static const nppFilter1D_t nppFilter1D_callers[] = {nppiFilterRow_8u_C1R, nppiFilterRow_8u_C4R};
|
||||
public:
|
||||
NppLinearRowFilter(int ksize_, int anchor_, const GpuMat& kernel_, Npp32s nDivisor_, nppFilter1D_t func_) :
|
||||
BaseRowFilter_GPU(ksize_, anchor_), kernel(kernel_), nDivisor(nDivisor_), func(func_) {}
|
||||
|
||||
CV_Assert(src.type() == CV_8UC1 || src.type() == CV_8UC4);
|
||||
|
||||
int kRowSize = rowKernel.cols;
|
||||
|
||||
dst.create(src.size(), src.type());
|
||||
dst = Scalar();
|
||||
|
||||
NppiSize oROI;
|
||||
oROI.width = src.cols - kRowSize + 1;
|
||||
oROI.height = src.rows;
|
||||
|
||||
if (anchor < 0)
|
||||
anchor = kRowSize >> 1;
|
||||
|
||||
GpuMat srcROI = src.colRange(kRowSize-1, oROI.width);
|
||||
GpuMat dstROI = dst.colRange(kRowSize-1, oROI.width);
|
||||
|
||||
nppFilter1D_callers[src.channels() >> 2](srcROI.ptr<Npp8u>(), srcROI.step, dstROI.ptr<Npp8u>(), dstROI.step, oROI,
|
||||
rowKernel.ptr<Npp32s>(), kRowSize, anchor, nDivisor);
|
||||
}
|
||||
|
||||
void applyColumnFilter(const GpuMat& src, GpuMat& dst, const GpuMat& columnKernel, Npp32s anchor = -1, Npp32s nDivisor = 1)
|
||||
{
|
||||
static const nppFilter1D_t nppFilter1D_callers[] = {nppiFilterColumn_8u_C1R, nppiFilterColumn_8u_C4R};
|
||||
|
||||
CV_Assert(src.type() == CV_8UC1 || src.type() == CV_8UC4);
|
||||
|
||||
int kColSize = columnKernel.cols;
|
||||
|
||||
dst.create(src.size(), src.type());
|
||||
dst = Scalar();
|
||||
|
||||
NppiSize oROI;
|
||||
oROI.width = src.cols;
|
||||
oROI.height = src.rows - kColSize + 1;
|
||||
|
||||
if (anchor < 0)
|
||||
anchor = kColSize >> 1;
|
||||
|
||||
GpuMat srcROI = src.rowRange(kColSize-1, oROI.height);
|
||||
GpuMat dstROI = dst.rowRange(kColSize-1, oROI.height);
|
||||
|
||||
nppFilter1D_callers[src.channels() >> 2](srcROI.ptr<Npp8u>(), srcROI.step, dstROI.ptr<Npp8u>(), dstROI.step, oROI,
|
||||
columnKernel.ptr<Npp32s>(), kColSize, anchor, nDivisor);
|
||||
}
|
||||
|
||||
inline void applySeparableFilter(const GpuMat& src, GpuMat& dst, const GpuMat& rowKernel, const GpuMat& columnKernel,
|
||||
const cv::Point& anchor = cv::Point(-1, -1), Npp32s nDivisor = 1)
|
||||
{
|
||||
GpuMat dstBuf;
|
||||
applyRowFilter(src, dstBuf, rowKernel, anchor.x, nDivisor);
|
||||
applyColumnFilter(dstBuf, dst, columnKernel, anchor.y, nDivisor);
|
||||
}
|
||||
|
||||
void makeNppKernel(Mat kernel, GpuMat& dst)
|
||||
{
|
||||
kernel.convertTo(kernel, CV_32S);
|
||||
kernel = kernel.t();
|
||||
int ksize = kernel.cols;
|
||||
for (int i = 0; i < ksize / 2; ++i)
|
||||
virtual void operator()(const GpuMat& src, GpuMat& dst)
|
||||
{
|
||||
std::swap(kernel.at<int>(0, i), kernel.at<int>(0, ksize - 1 - i));
|
||||
NppiSize sz;
|
||||
sz.width = src.cols;
|
||||
sz.height = src.rows;
|
||||
|
||||
nppSafeCall( func(src.ptr<Npp8u>(), src.step, dst.ptr<Npp8u>(), dst.step, sz, kernel.ptr<Npp32s>(), ksize, anchor, nDivisor) );
|
||||
}
|
||||
dst.upload(kernel);
|
||||
}
|
||||
|
||||
void applyFilter2D(const GpuMat& src, GpuMat& dst, const GpuMat& kernel, cv::Point anchor = cv::Point(-1, -1), Npp32s nDivisor = 1)
|
||||
{
|
||||
static const nppFilter2D_t nppFilter2D_callers[] = {nppiFilter_8u_C1R, nppiFilter_8u_C4R};
|
||||
|
||||
CV_Assert(src.type() == CV_8UC1 || src.type() == CV_8UC4);
|
||||
|
||||
dst.create(src.size(), src.type());
|
||||
dst = Scalar();
|
||||
|
||||
NppiSize oROI;
|
||||
oROI.width = src.cols - kernel.cols + 1;
|
||||
oROI.height = src.rows - kernel.rows + 1;
|
||||
|
||||
if (anchor.x < 0)
|
||||
anchor.x = kernel.cols >> 1;
|
||||
if (anchor.y < 0)
|
||||
anchor.y = kernel.rows >> 1;
|
||||
|
||||
GpuMat srcROI = src(Range(kernel.rows-1, oROI.height), Range(kernel.cols-1, oROI.width));
|
||||
GpuMat dstROI = dst(Range(kernel.rows-1, oROI.height), Range(kernel.cols-1, oROI.width));
|
||||
|
||||
NppiSize oKernelSize;
|
||||
oKernelSize.height = kernel.rows;
|
||||
oKernelSize.width = kernel.cols;
|
||||
NppiPoint oAnchor;
|
||||
oAnchor.x = anchor.x;
|
||||
oAnchor.y = anchor.y;
|
||||
|
||||
nppFilter2D_callers[src.channels() >> 2](srcROI.ptr<Npp8u>(), srcROI.step, dstROI.ptr<Npp8u>(), dstROI.step, oROI,
|
||||
kernel.ptr<Npp32s>(), oKernelSize, oAnchor, nDivisor);
|
||||
}
|
||||
GpuMat kernel;
|
||||
Npp32s nDivisor;
|
||||
nppFilter1D_t func;
|
||||
};
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Sobel
|
||||
Ptr<BaseRowFilter_GPU> cv::gpu::getLinearRowFilter_GPU(int srcType, int bufType, const GpuMat& rowKernel, int anchor, int nDivisor)
|
||||
{
|
||||
static const nppFilter1D_t nppFilter1D_callers[] = {0, nppiFilterRow_8u_C1R, 0, 0, nppiFilterRow_8u_C4R};
|
||||
|
||||
CV_Assert((srcType == CV_8UC1 || srcType == CV_8UC4) && bufType == srcType);
|
||||
CV_Assert(rowKernel.type() == CV_32SC1 && rowKernel.rows == 1);
|
||||
|
||||
int ksize = rowKernel.cols;
|
||||
|
||||
normalizeAnchor(anchor, ksize);
|
||||
|
||||
return Ptr<BaseRowFilter_GPU>(new NppLinearRowFilter(ksize, anchor, rowKernel, nDivisor, nppFilter1D_callers[CV_MAT_CN(srcType)]));
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
class NppLinearColumnFilter : public BaseColumnFilter_GPU
|
||||
{
|
||||
public:
|
||||
NppLinearColumnFilter(int ksize_, int anchor_, const GpuMat& kernel_, Npp32s nDivisor_, nppFilter1D_t func_) :
|
||||
BaseColumnFilter_GPU(ksize_, anchor_), kernel(kernel_), nDivisor(nDivisor_), func(func_) {}
|
||||
|
||||
virtual void operator()(const GpuMat& src, GpuMat& dst)
|
||||
{
|
||||
NppiSize sz;
|
||||
sz.width = src.cols;
|
||||
sz.height = src.rows;
|
||||
|
||||
nppSafeCall( func(src.ptr<Npp8u>(), src.step, dst.ptr<Npp8u>(), dst.step, sz, kernel.ptr<Npp32s>(), ksize, anchor, nDivisor) );
|
||||
}
|
||||
|
||||
GpuMat kernel;
|
||||
Npp32s nDivisor;
|
||||
nppFilter1D_t func;
|
||||
};
|
||||
}
|
||||
|
||||
Ptr<BaseColumnFilter_GPU> cv::gpu::getLinearColumnFilter_GPU(int bufType, int dstType, const GpuMat& columnKernel, int anchor, int nDivisor)
|
||||
{
|
||||
static const nppFilter1D_t nppFilter1D_callers[] = {0, nppiFilterColumn_8u_C1R, 0, 0, nppiFilterColumn_8u_C4R};
|
||||
|
||||
CV_Assert((bufType == CV_8UC1 || bufType == CV_8UC4) && dstType == bufType);
|
||||
CV_Assert(columnKernel.type() == CV_32SC1 && columnKernel.rows == 1);
|
||||
|
||||
int ksize = columnKernel.cols;
|
||||
|
||||
normalizeAnchor(anchor, ksize);
|
||||
|
||||
return Ptr<BaseColumnFilter_GPU>(new NppLinearColumnFilter(ksize, anchor, columnKernel, nDivisor, nppFilter1D_callers[CV_MAT_CN(bufType)]));
|
||||
}
|
||||
|
||||
Ptr<FilterEngine_GPU> cv::gpu::createSeparableLinearFilter_GPU(int srcType, int dstType, const Mat& rowKernel, const Mat& columnKernel,
|
||||
const Point& anchor)
|
||||
{
|
||||
int sdepth = CV_MAT_DEPTH(srcType), ddepth = CV_MAT_DEPTH(dstType);
|
||||
int cn = CV_MAT_CN(srcType);
|
||||
int bdepth = std::max(sdepth, ddepth);
|
||||
int bufType = CV_MAKETYPE(bdepth, cn);
|
||||
|
||||
GpuMat gpu_row_krnl, gpu_col_krnl;
|
||||
int nRowDivisor, nColDivisor;
|
||||
normalizeKernel(rowKernel, gpu_row_krnl, CV_32S, &nRowDivisor, true);
|
||||
normalizeKernel(columnKernel, gpu_col_krnl, CV_32S, &nColDivisor, true);
|
||||
|
||||
Ptr<BaseRowFilter_GPU> rowFilter = getLinearRowFilter_GPU(srcType, bufType, gpu_row_krnl, anchor.x, nRowDivisor);
|
||||
Ptr<BaseColumnFilter_GPU> columnFilter = getLinearColumnFilter_GPU(bufType, dstType, gpu_col_krnl, anchor.y, nColDivisor);
|
||||
|
||||
return createSeparableFilter_GPU(rowFilter, columnFilter);
|
||||
}
|
||||
|
||||
void cv::gpu::sepFilter2D(const GpuMat& src, GpuMat& dst, int ddepth, const Mat& kernelX, const Mat& kernelY, Point anchor)
|
||||
{
|
||||
if( ddepth < 0 )
|
||||
ddepth = src.depth();
|
||||
|
||||
dst.create(src.size(), CV_MAKETYPE(ddepth, src.channels()));
|
||||
|
||||
Ptr<FilterEngine_GPU> f = createSeparableLinearFilter_GPU(src.type(), dst.type(), kernelX, kernelY, anchor);
|
||||
f->apply(src, dst);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Deriv Filter
|
||||
|
||||
Ptr<FilterEngine_GPU> cv::gpu::createDerivFilter_GPU(int srcType, int dstType, int dx, int dy, int ksize)
|
||||
{
|
||||
Mat kx, ky;
|
||||
getDerivKernels(kx, ky, dx, dy, ksize, false, CV_32F);
|
||||
return createSeparableLinearFilter_GPU(srcType, dstType, kx, ky);
|
||||
}
|
||||
|
||||
void cv::gpu::Sobel(const GpuMat& src, GpuMat& dst, int ddepth, int dx, int dy, int ksize, double scale)
|
||||
{
|
||||
@ -370,14 +703,73 @@ void cv::gpu::Sobel(const GpuMat& src, GpuMat& dst, int ddepth, int dx, int dy,
|
||||
ky *= scale;
|
||||
}
|
||||
|
||||
GpuMat rowKernel; makeNppKernel(kx, rowKernel);
|
||||
GpuMat columnKernel; makeNppKernel(ky, columnKernel);
|
||||
|
||||
applySeparableFilter(src, dst, rowKernel, columnKernel);
|
||||
sepFilter2D(src, dst, ddepth, kx, ky, Point(-1,-1));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// GaussianBlur
|
||||
void cv::gpu::Scharr(const GpuMat& src, GpuMat& dst, int ddepth, int dx, int dy, double scale)
|
||||
{
|
||||
Mat kx, ky;
|
||||
getDerivKernels(kx, ky, dx, dy, -1, false, CV_32F);
|
||||
|
||||
if( scale != 1 )
|
||||
{
|
||||
// usually the smoothing part is the slowest to compute,
|
||||
// so try to scale it instead of the faster differenciating part
|
||||
if( dx == 0 )
|
||||
kx *= scale;
|
||||
else
|
||||
ky *= scale;
|
||||
}
|
||||
|
||||
sepFilter2D(src, dst, ddepth, kx, ky, Point(-1,-1));
|
||||
}
|
||||
|
||||
void cv::gpu::Laplacian(const GpuMat& src, GpuMat& dst, int ddepth, int ksize, double scale)
|
||||
{
|
||||
CV_Assert(ksize == 1 || ksize == 3);
|
||||
|
||||
static const int K[2][9] =
|
||||
{
|
||||
{0, 1, 0, 1, -4, 1, 0, 1, 0},
|
||||
{2, 0, 2, 0, -8, 0, 2, 0, 2}
|
||||
};
|
||||
Mat kernel(3, 3, CV_32S, (void*)K[ksize == 3]);
|
||||
if (scale != 1)
|
||||
kernel *= scale;
|
||||
|
||||
filter2D(src, dst, ddepth, kernel, Point(-1,-1));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Gaussian Filter
|
||||
|
||||
Ptr<FilterEngine_GPU> cv::gpu::createGaussianFilter_GPU(int type, Size ksize, double sigma1, double sigma2)
|
||||
{
|
||||
int depth = CV_MAT_DEPTH(type);
|
||||
|
||||
if (sigma2 <= 0)
|
||||
sigma2 = sigma1;
|
||||
|
||||
// automatic detection of kernel size from sigma
|
||||
if (ksize.width <= 0 && sigma1 > 0)
|
||||
ksize.width = cvRound(sigma1 * (depth == CV_8U ? 3 : 4)*2 + 1) | 1;
|
||||
if (ksize.height <= 0 && sigma2 > 0)
|
||||
ksize.height = cvRound(sigma2 * (depth == CV_8U ? 3 : 4)*2 + 1) | 1;
|
||||
|
||||
CV_Assert( ksize.width > 0 && ksize.width % 2 == 1 && ksize.height > 0 && ksize.height % 2 == 1 );
|
||||
|
||||
sigma1 = std::max(sigma1, 0.0);
|
||||
sigma2 = std::max(sigma2, 0.0);
|
||||
|
||||
Mat kx = getGaussianKernel( ksize.width, sigma1, std::max(depth, CV_32F) );
|
||||
Mat ky;
|
||||
if( ksize.height == ksize.width && std::abs(sigma1 - sigma2) < DBL_EPSILON )
|
||||
ky = kx;
|
||||
else
|
||||
ky = getGaussianKernel( ksize.height, sigma2, std::max(depth, CV_32F) );
|
||||
|
||||
return createSeparableLinearFilter_GPU(type, type, kx, ky);
|
||||
}
|
||||
|
||||
void cv::gpu::GaussianBlur(const GpuMat& src, GpuMat& dst, Size ksize, double sigma1, double sigma2)
|
||||
{
|
||||
@ -387,38 +779,10 @@ void cv::gpu::GaussianBlur(const GpuMat& src, GpuMat& dst, Size ksize, double si
|
||||
return;
|
||||
}
|
||||
|
||||
int depth = src.depth();
|
||||
if (sigma2 <= 0)
|
||||
sigma2 = sigma1;
|
||||
|
||||
// automatic detection of kernel size from sigma
|
||||
if (ksize.width <= 0 && sigma1 > 0)
|
||||
ksize.width = cvRound(sigma1 * (depth == CV_8U ? 3 : 4) * 2 + 1) | 1;
|
||||
if (ksize.height <= 0 && sigma2 > 0)
|
||||
ksize.height = cvRound(sigma2 * (depth == CV_8U ? 3 : 4) * 2 + 1) | 1;
|
||||
|
||||
CV_Assert(ksize.width > 0 && ksize.width % 2 == 1 && ksize.height > 0 && ksize.height % 2 == 1);
|
||||
|
||||
sigma1 = std::max(sigma1, 0.0);
|
||||
sigma2 = std::max(sigma2, 0.0);
|
||||
dst.create(src.size(), src.type());
|
||||
|
||||
const int scaleFactor = 256;
|
||||
|
||||
Mat kx = getGaussianKernel(ksize.width, sigma1, std::max(depth, CV_32F));
|
||||
kx.convertTo(kx, kx.depth(), scaleFactor);
|
||||
Mat ky;
|
||||
if (ksize.height == ksize.width && std::abs(sigma1 - sigma2) < DBL_EPSILON)
|
||||
ky = kx;
|
||||
else
|
||||
{
|
||||
ky = getGaussianKernel(ksize.height, sigma2, std::max(depth, CV_32F));
|
||||
ky.convertTo(ky, ky.depth(), scaleFactor);
|
||||
}
|
||||
|
||||
GpuMat rowKernel; makeNppKernel(kx, rowKernel);
|
||||
GpuMat columnKernel; makeNppKernel(ky, columnKernel);
|
||||
|
||||
applySeparableFilter(src, dst, rowKernel, columnKernel, cv::Point(-1, -1), scaleFactor);
|
||||
Ptr<FilterEngine_GPU> f = createGaussianFilter_GPU(src.type(), ksize, sigma1, sigma2);
|
||||
f->apply(src, dst);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -992,6 +992,7 @@ void cv::gpu::integral(GpuMat& src, GpuMat& sum, GpuMat& sqsum)
|
||||
|
||||
void cv::gpu::Canny(const GpuMat& image, GpuMat& edges, double threshold1, double threshold2, int apertureSize)
|
||||
{
|
||||
CV_Assert(!"disabled until fix crash");
|
||||
CV_Assert(image.type() == CV_8UC1);
|
||||
|
||||
GpuMat srcDx, srcDy;
|
||||
|
383
tests/gpu/src/filters.cpp
Normal file
383
tests/gpu/src/filters.cpp
Normal file
@ -0,0 +1,383 @@
|
||||
/*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.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, 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 Intel Corporation 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*/
|
||||
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include "gputest.hpp"
|
||||
#include "opencv2/imgproc/imgproc.hpp"
|
||||
#include "opencv2/highgui/highgui.hpp"
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
using namespace gpu;
|
||||
|
||||
class CV_GpuNppFilterTest : public CvTest
|
||||
{
|
||||
public:
|
||||
CV_GpuNppFilterTest(const char* test_name, const char* test_funcs) : CvTest(test_name, test_funcs) {}
|
||||
virtual ~CV_GpuNppFilterTest() {}
|
||||
|
||||
protected:
|
||||
void run(int);
|
||||
virtual int test(const Mat& img) = 0;
|
||||
|
||||
int test8UC1(const Mat& img)
|
||||
{
|
||||
cv::Mat img_C1;
|
||||
cvtColor(img, img_C1, CV_BGR2GRAY);
|
||||
return test(img_C1);
|
||||
}
|
||||
|
||||
int test8UC4(const Mat& img)
|
||||
{
|
||||
cv::Mat img_C4;
|
||||
cvtColor(img, img_C4, CV_BGR2BGRA);
|
||||
return test(img_C4);
|
||||
}
|
||||
|
||||
int CheckNorm(const Mat& m1, const Mat& m2, const Size& ksize)
|
||||
{
|
||||
Rect roi = Rect(ksize.width, ksize.height, m1.cols - 2 * ksize.width, m1.rows - 2 * ksize.height);
|
||||
Mat m1ROI = m1(roi);
|
||||
Mat m2ROI = m2(roi);
|
||||
|
||||
double res = norm(m1ROI, m2ROI, NORM_INF);
|
||||
|
||||
if (res <= 1)
|
||||
return CvTS::OK;
|
||||
|
||||
ts->printf(CvTS::LOG, "\nNorm: %f\n", res);
|
||||
return CvTS::FAIL_GENERIC;
|
||||
}
|
||||
};
|
||||
|
||||
void CV_GpuNppFilterTest::run( int )
|
||||
{
|
||||
cv::Mat img = cv::imread(std::string(ts->get_data_path()) + "stereobp/aloe-L.png");
|
||||
|
||||
if (img.empty())
|
||||
{
|
||||
ts->set_failed_test_info(CvTS::FAIL_MISSING_TEST_DATA);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
//run tests
|
||||
int testResult = CvTS::OK;
|
||||
|
||||
if (test8UC1(img) != CvTS::OK)
|
||||
testResult = CvTS::FAIL_GENERIC;
|
||||
|
||||
if (test8UC4(img) != CvTS::OK)
|
||||
testResult = CvTS::FAIL_GENERIC;
|
||||
|
||||
ts->set_failed_test_info(testResult);
|
||||
}
|
||||
catch(const cv::Exception& e)
|
||||
{
|
||||
if (!check_and_treat_gpu_exception(e, ts))
|
||||
throw;
|
||||
return;
|
||||
}
|
||||
|
||||
ts->set_failed_test_info(CvTS::OK);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// blur
|
||||
struct CV_GpuNppImageBlurTest : public CV_GpuNppFilterTest
|
||||
{
|
||||
CV_GpuNppImageBlurTest() : CV_GpuNppFilterTest( "GPU-NppImageBlur", "blur" ) {}
|
||||
|
||||
int test(const Mat& img)
|
||||
{
|
||||
int ksizes[] = {3, 5, 7};
|
||||
int ksizes_num = sizeof(ksizes) / sizeof(int);
|
||||
|
||||
int test_res = CvTS::OK;
|
||||
|
||||
for (int i = 0; i < ksizes_num; ++i)
|
||||
{
|
||||
for (int j = 0; j < ksizes_num; ++j)
|
||||
{
|
||||
Size ksize(ksizes[i], ksizes[j]);
|
||||
|
||||
ts->printf(CvTS::LOG, "\nksize = (%dx%d)\n", ksizes[i], ksizes[j]);
|
||||
|
||||
Mat cpudst;
|
||||
cv::blur(img, cpudst, ksize);
|
||||
|
||||
GpuMat gpu1(img);
|
||||
GpuMat gpudst;
|
||||
cv::gpu::blur(gpu1, gpudst, ksize);
|
||||
|
||||
if (CheckNorm(cpudst, gpudst, ksize) != CvTS::OK)
|
||||
test_res = CvTS::FAIL_GENERIC;
|
||||
}
|
||||
}
|
||||
|
||||
return test_res;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Sobel
|
||||
struct CV_GpuNppImageSobelTest : public CV_GpuNppFilterTest
|
||||
{
|
||||
CV_GpuNppImageSobelTest() : CV_GpuNppFilterTest( "GPU-NppImageSobel", "Sobel" ) {}
|
||||
|
||||
int test(const Mat& img)
|
||||
{
|
||||
int ksizes[] = {3, 5, 7};
|
||||
int ksizes_num = sizeof(ksizes) / sizeof(int);
|
||||
|
||||
int dx = 1, dy = 0;
|
||||
|
||||
int test_res = CvTS::OK;
|
||||
|
||||
for (int i = 0; i < ksizes_num; ++i)
|
||||
{
|
||||
ts->printf(CvTS::LOG, "\nksize = %d\n", ksizes[i]);
|
||||
|
||||
Mat cpudst;
|
||||
cv::Sobel(img, cpudst, -1, dx, dy, ksizes[i]);
|
||||
|
||||
GpuMat gpu1(img);
|
||||
GpuMat gpudst;
|
||||
cv::gpu::Sobel(gpu1, gpudst, -1, dx, dy, ksizes[i]);
|
||||
|
||||
if (CheckNorm(cpudst, gpudst, Size(ksizes[i], ksizes[i])) != CvTS::OK)
|
||||
test_res = CvTS::FAIL_GENERIC;
|
||||
}
|
||||
|
||||
return test_res;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Scharr
|
||||
struct CV_GpuNppImageScharrTest : public CV_GpuNppFilterTest
|
||||
{
|
||||
CV_GpuNppImageScharrTest() : CV_GpuNppFilterTest( "GPU-NppImageScharr", "Scharr" ) {}
|
||||
|
||||
int test(const Mat& img)
|
||||
{
|
||||
int dx = 1, dy = 0;
|
||||
|
||||
Mat cpudst;
|
||||
cv::Scharr(img, cpudst, -1, dx, dy);
|
||||
|
||||
GpuMat gpu1(img);
|
||||
GpuMat gpudst;
|
||||
cv::gpu::Scharr(gpu1, gpudst, -1, dx, dy);
|
||||
|
||||
return CheckNorm(cpudst, gpudst, Size(3, 3));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// GaussianBlur
|
||||
struct CV_GpuNppImageGaussianBlurTest : public CV_GpuNppFilterTest
|
||||
{
|
||||
CV_GpuNppImageGaussianBlurTest() : CV_GpuNppFilterTest( "GPU-NppImageGaussianBlur", "GaussianBlur" ) {}
|
||||
|
||||
int test(const Mat& img)
|
||||
{
|
||||
int ksizes[] = {3, 5, 7};
|
||||
int ksizes_num = sizeof(ksizes) / sizeof(int);
|
||||
|
||||
int test_res = CvTS::OK;
|
||||
|
||||
const double sigma1 = 3.0;
|
||||
|
||||
for (int i = 0; i < ksizes_num; ++i)
|
||||
{
|
||||
for (int j = 0; j < ksizes_num; ++j)
|
||||
{
|
||||
cv::Size ksize(ksizes[i], ksizes[j]);
|
||||
|
||||
ts->printf(CvTS::LOG, "\nksize = (%dx%d)\n", ksizes[i], ksizes[j]);
|
||||
|
||||
Mat cpudst;
|
||||
cv::GaussianBlur(img, cpudst, ksize, sigma1);
|
||||
|
||||
GpuMat gpu1(img);
|
||||
GpuMat gpudst;
|
||||
cv::gpu::GaussianBlur(gpu1, gpudst, ksize, sigma1);
|
||||
|
||||
if (CheckNorm(cpudst, gpudst, ksize) != CvTS::OK)
|
||||
test_res = CvTS::FAIL_GENERIC;
|
||||
}
|
||||
}
|
||||
|
||||
return test_res;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Laplacian
|
||||
struct CV_GpuNppImageLaplacianTest : public CV_GpuNppFilterTest
|
||||
{
|
||||
CV_GpuNppImageLaplacianTest() : CV_GpuNppFilterTest( "GPU-NppImageLaplacian", "Laplacian" ) {}
|
||||
|
||||
int test(const Mat& img)
|
||||
{
|
||||
int ksizes[] = {1, 3};
|
||||
int ksizes_num = sizeof(ksizes) / sizeof(int);
|
||||
|
||||
int test_res = CvTS::OK;
|
||||
|
||||
for (int i = 0; i < ksizes_num; ++i)
|
||||
{
|
||||
ts->printf(CvTS::LOG, "\nksize = %d\n", ksizes[i]);
|
||||
|
||||
Mat cpudst;
|
||||
cv::Laplacian(img, cpudst, -1, ksizes[i]);
|
||||
|
||||
GpuMat gpu1(img);
|
||||
GpuMat gpudst;
|
||||
cv::gpu::Laplacian(gpu1, gpudst, -1, ksizes[i]);
|
||||
|
||||
if (CheckNorm(cpudst, gpudst, Size(3, 3)) != CvTS::OK)
|
||||
test_res = CvTS::FAIL_GENERIC;
|
||||
}
|
||||
|
||||
return test_res;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Erode
|
||||
class CV_GpuErodeTest : public CV_GpuNppFilterTest
|
||||
{
|
||||
public:
|
||||
CV_GpuErodeTest() : CV_GpuNppFilterTest( "GPU-NppErode", "erode" ) {}
|
||||
|
||||
protected:
|
||||
virtual int test(const Mat& img)
|
||||
{
|
||||
Mat kernel(Mat::ones(3, 3, CV_8U));
|
||||
|
||||
cv::Mat cpuRes;
|
||||
cv::erode(img, cpuRes, kernel);
|
||||
|
||||
GpuMat gpuRes;
|
||||
cv::gpu::erode(GpuMat(img), gpuRes, kernel);
|
||||
|
||||
return CheckNorm(cpuRes, gpuRes, Size(3, 3));
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Dilate
|
||||
class CV_GpuDilateTest : public CV_GpuNppFilterTest
|
||||
{
|
||||
public:
|
||||
CV_GpuDilateTest() : CV_GpuNppFilterTest( "GPU-NppDilate", "dilate" ) {}
|
||||
|
||||
protected:
|
||||
virtual int test(const Mat& img)
|
||||
{
|
||||
Mat kernel(Mat::ones(3, 3, CV_8U));
|
||||
|
||||
cv::Mat cpuRes;
|
||||
cv::dilate(img, cpuRes, kernel);
|
||||
|
||||
GpuMat gpuRes;
|
||||
cv::gpu::dilate(GpuMat(img), gpuRes, kernel);
|
||||
|
||||
return CheckNorm(cpuRes, gpuRes, Size(3, 3));
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// MorphologyEx
|
||||
class CV_GpuMorphExTest : public CV_GpuNppFilterTest
|
||||
{
|
||||
public:
|
||||
CV_GpuMorphExTest() : CV_GpuNppFilterTest( "GPU-NppMorphologyEx", "morphologyEx" ) {}
|
||||
|
||||
protected:
|
||||
virtual int test(const Mat& img)
|
||||
{
|
||||
static int ops[] = { MORPH_OPEN, CV_MOP_CLOSE, CV_MOP_GRADIENT, CV_MOP_TOPHAT, CV_MOP_BLACKHAT};
|
||||
const char *names[] = { "MORPH_OPEN", "CV_MOP_CLOSE", "CV_MOP_GRADIENT", "CV_MOP_TOPHAT", "CV_MOP_BLACKHAT"};
|
||||
int num = sizeof(ops)/sizeof(ops[0]);
|
||||
|
||||
GpuMat kernel(Mat::ones(3, 3, CV_8U));
|
||||
|
||||
int res = CvTS::OK;
|
||||
|
||||
for(int i = 0; i < num; ++i)
|
||||
{
|
||||
ts->printf(CvTS::LOG, "Tesing %s\n", names[i]);
|
||||
|
||||
cv::Mat cpuRes;
|
||||
cv::morphologyEx(img, cpuRes, ops[i], kernel);
|
||||
|
||||
GpuMat gpuRes;
|
||||
cv::gpu::morphologyEx(GpuMat(img), gpuRes, ops[i], kernel);
|
||||
|
||||
if (CvTS::OK != CheckNorm(cpuRes, gpuRes, Size(3, 3)))
|
||||
res = CvTS::FAIL_GENERIC;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////// tests registration /////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CV_GpuNppImageBlurTest CV_GpuNppImageBlur_test;
|
||||
CV_GpuNppImageSobelTest CV_GpuNppImageSobel_test;
|
||||
CV_GpuNppImageScharrTest CV_GpuNppImageScharr_test;
|
||||
CV_GpuNppImageGaussianBlurTest CV_GpuNppImageGaussianBlur_test;
|
||||
CV_GpuNppImageLaplacianTest CV_GpuNppImageLaplacian_test;
|
||||
CV_GpuErodeTest CV_GpuErode_test;
|
||||
CV_GpuDilateTest CV_GpuDilate_test;
|
||||
CV_GpuMorphExTest CV_GpuMorphEx_test;
|
@ -45,25 +45,27 @@ CvTS test_system;
|
||||
|
||||
const char* blacklist[] =
|
||||
{
|
||||
"GPU-NppImageSum", // crash
|
||||
"GPU-MatOperatorAsyncCall", // crash
|
||||
//"GPU-NppErode", // different border interpolation
|
||||
//"GPU-NppMorphologyEx", // different border interpolation
|
||||
|
||||
"GPU-NppImageSum", // crash, probably npp bug
|
||||
"GPU-NppImageMinNax", // npp bug - don't find min/max near right border
|
||||
//"GPU-NppImageDivide", // different round mode
|
||||
//"GPU-NppImageMeanStdDev", // different precision
|
||||
//"GPU-NppImageMinNax", // npp bug - don't find min/max near right border
|
||||
//"GPU-NppImageResize", // different precision in interpolation
|
||||
//"GPU-NppImageWarpAffine", // different precision in interpolation
|
||||
//"GPU-NppImageWarpPerspective", // different precision in interpolation
|
||||
//"GPU-NppImageIntegral", // different precision
|
||||
//"GPU-NppImageBlur", // different precision
|
||||
//"GPU-NppImageExp", // different precision
|
||||
//"GPU-NppImageLog", // different precision
|
||||
//"GPU-NppImageMagnitude", // different precision
|
||||
//"GPU-NppImageSumWindow", // different border interpolation
|
||||
//"GPU-NppImageSobel", // ???
|
||||
//"GPU-NppImageGaussianBlur", // different border interpolation
|
||||
|
||||
"GPU-NppImageCanny", // NPP_TEXTURE_BIND_ERROR
|
||||
//"GPU-NppImageResize", // different precision
|
||||
//"GPU-NppImageWarpAffine", // different precision
|
||||
//"GPU-NppImageWarpPerspective", // different precision
|
||||
//"GPU-NppImageIntegral", // different precision
|
||||
|
||||
//"GPU-NppImageSobel", // ???
|
||||
//"GPU-NppImageScharr", // ???
|
||||
|
||||
//"GPU-NppImageGaussianBlur", // different precision
|
||||
//"GPU-NppMorphologyEx", // different precision?
|
||||
0
|
||||
};
|
||||
|
||||
|
@ -413,167 +413,6 @@ struct CV_GpuNppImageIntegralTest : public CV_GpuImageProcTest
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// blur
|
||||
struct CV_GpuNppImageBlurTest : public CV_GpuImageProcTest
|
||||
{
|
||||
CV_GpuNppImageBlurTest() : CV_GpuImageProcTest( "GPU-NppImageBlur", "blur" ) {}
|
||||
|
||||
int test(const Mat& img)
|
||||
{
|
||||
if (img.type() != CV_8UC1 && img.type() != CV_8UC4)
|
||||
{
|
||||
ts->printf(CvTS::LOG, "\nUnsupported type\n");
|
||||
return CvTS::OK;
|
||||
}
|
||||
|
||||
int ksizes[] = {3, 5, 7};
|
||||
int ksizes_num = sizeof(ksizes) / sizeof(int);
|
||||
|
||||
int test_res = CvTS::OK;
|
||||
|
||||
for (int i = 0; i < ksizes_num; ++i)
|
||||
{
|
||||
ts->printf(CvTS::LOG, "\nksize = %d\n", ksizes[i]);
|
||||
|
||||
Mat cpudst;
|
||||
cv::blur(img, cpudst, Size(ksizes[i], ksizes[i]));
|
||||
|
||||
GpuMat gpu1(img);
|
||||
GpuMat gpudst;
|
||||
cv::gpu::blur(gpu1, gpudst, Size(ksizes[i], ksizes[i]));
|
||||
|
||||
if (CheckNorm(cpudst, gpudst) != CvTS::OK)
|
||||
test_res = CvTS::FAIL_GENERIC;
|
||||
}
|
||||
|
||||
return test_res;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// sumWindow
|
||||
struct CV_GpuNppImageSumWindowTest : public CV_GpuImageProcTest
|
||||
{
|
||||
CV_GpuNppImageSumWindowTest() : CV_GpuImageProcTest( "GPU-NppImageSumWindow", "sumWindow" ) {}
|
||||
|
||||
int test(const Mat& img)
|
||||
{
|
||||
if (img.type() != CV_8UC1)
|
||||
{
|
||||
ts->printf(CvTS::LOG, "\nUnsupported type\n");
|
||||
return CvTS::OK;
|
||||
}
|
||||
|
||||
int ksizes[] = {3, 5, 7};
|
||||
int ksizes_num = sizeof(ksizes) / sizeof(int);
|
||||
|
||||
int test_res = CvTS::OK;
|
||||
|
||||
for (int i = 0; i < ksizes_num; ++i)
|
||||
{
|
||||
ts->printf(CvTS::LOG, "\nksize = %d\n", ksizes[i]);
|
||||
|
||||
Mat cpudst(img.size(), CV_64FC1, Scalar());
|
||||
cv::Ptr<cv::BaseRowFilter> ft = cv::getRowSumFilter(CV_8UC1, CV_64FC1, ksizes[i], 0);
|
||||
for (int y = 0; y < img.rows; ++y)
|
||||
(*ft)(img.ptr(y), cpudst.ptr(y), img.cols, 1);
|
||||
cpudst.convertTo(cpudst, CV_32F);
|
||||
|
||||
GpuMat gpu1(img);
|
||||
GpuMat gpudst;
|
||||
cv::gpu::sumWindowRow(gpu1, gpudst, ksizes[i], 0);
|
||||
|
||||
if (CheckNorm(cpudst, gpudst) != CvTS::OK)
|
||||
test_res = CvTS::FAIL_GENERIC;
|
||||
}
|
||||
|
||||
return test_res;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Sobel
|
||||
struct CV_GpuNppImageSobelTest : public CV_GpuImageProcTest
|
||||
{
|
||||
CV_GpuNppImageSobelTest() : CV_GpuImageProcTest( "GPU-NppImageSobel", "Sobel" ) {}
|
||||
|
||||
int test(const Mat& img)
|
||||
{
|
||||
if (img.type() != CV_8UC1 && img.type() != CV_8UC4)
|
||||
{
|
||||
ts->printf(CvTS::LOG, "\nUnsupported type\n");
|
||||
return CvTS::OK;
|
||||
}
|
||||
|
||||
int ksizes[] = {3, 5, 7};
|
||||
int ksizes_num = sizeof(ksizes) / sizeof(int);
|
||||
|
||||
int dx = 1, dy = 0;
|
||||
|
||||
int test_res = CvTS::OK;
|
||||
|
||||
for (int i = 0; i < ksizes_num; ++i)
|
||||
{
|
||||
ts->printf(CvTS::LOG, "\nksize = %d\n", ksizes[i]);
|
||||
|
||||
Mat cpudst;
|
||||
cv::Sobel(img, cpudst, -1, dx, dy, ksizes[i]);
|
||||
|
||||
GpuMat gpu1(img);
|
||||
GpuMat gpudst;
|
||||
cv::gpu::Sobel(gpu1, gpudst, -1, dx, dy, ksizes[i]);
|
||||
|
||||
if (CheckNorm(cpudst, gpudst) != CvTS::OK)
|
||||
test_res = CvTS::FAIL_GENERIC;
|
||||
}
|
||||
|
||||
return test_res;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// GaussianBlur
|
||||
struct CV_GpuNppImageGaussianBlurTest : public CV_GpuImageProcTest
|
||||
{
|
||||
CV_GpuNppImageGaussianBlurTest() : CV_GpuImageProcTest( "GPU-NppImageGaussianBlur", "GaussianBlur" ) {}
|
||||
|
||||
int test(const Mat& img)
|
||||
{
|
||||
if (img.type() != CV_8UC1 && img.type() != CV_8UC4)
|
||||
{
|
||||
ts->printf(CvTS::LOG, "\nUnsupported type\n");
|
||||
return CvTS::OK;
|
||||
}
|
||||
|
||||
int ksizes[] = {3, 5, 7};
|
||||
int ksizes_num = sizeof(ksizes) / sizeof(int);
|
||||
|
||||
int test_res = CvTS::OK;
|
||||
|
||||
const double sigma1 = 3.0;
|
||||
|
||||
for (int i = 0; i < ksizes_num; ++i)
|
||||
{
|
||||
for (int j = 0; j < ksizes_num; ++j)
|
||||
{
|
||||
ts->printf(CvTS::LOG, "\nksize = (%dx%d)\n", ksizes[i], ksizes[j]);
|
||||
|
||||
Mat cpudst;
|
||||
cv::GaussianBlur(img, cpudst, cv::Size(ksizes[i], ksizes[j]), sigma1);
|
||||
|
||||
GpuMat gpu1(img);
|
||||
GpuMat gpudst;
|
||||
cv::gpu::GaussianBlur(gpu1, gpudst, cv::Size(ksizes[i], ksizes[j]), sigma1);
|
||||
if (CheckNorm(cpudst, gpudst) != CvTS::OK)
|
||||
test_res = CvTS::FAIL_GENERIC;
|
||||
}
|
||||
}
|
||||
|
||||
return test_res;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Canny
|
||||
struct CV_GpuNppImageCannyTest : public CV_GpuImageProcTest
|
||||
@ -705,9 +544,5 @@ CV_GpuNppImageCopyMakeBorderTest CV_GpuNppImageCopyMakeBorder_test;
|
||||
CV_GpuNppImageWarpAffineTest CV_GpuNppImageWarpAffine_test;
|
||||
CV_GpuNppImageWarpPerspectiveTest CV_GpuNppImageWarpPerspective_test;
|
||||
CV_GpuNppImageIntegralTest CV_GpuNppImageIntegral_test;
|
||||
CV_GpuNppImageBlurTest CV_GpuNppImageBlur_test;
|
||||
CV_GpuNppImageSumWindowTest CV_GpuNppImageSumWindow_test;
|
||||
CV_GpuNppImageSobelTest CV_GpuNppImageSobel_test;
|
||||
CV_GpuNppImageGaussianBlurTest CV_GpuNppImageGaussianBlur_test;
|
||||
CV_GpuNppImageCannyTest CV_GpuNppImageCanny_test;
|
||||
CV_GpuCvtColorTest CV_GpuCvtColor_test;
|
@ -1,219 +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.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, 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 Intel Corporation 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*/
|
||||
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include "gputest.hpp"
|
||||
#include "opencv2/imgproc/imgproc.hpp"
|
||||
#include "opencv2/highgui/highgui.hpp"
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
using namespace gpu;
|
||||
|
||||
class CV_GpuNppMorphogyTest : public CvTest
|
||||
{
|
||||
public:
|
||||
CV_GpuNppMorphogyTest(const char* test_name, const char* test_funcs) : CvTest(test_name, test_funcs) {}
|
||||
virtual ~CV_GpuNppMorphogyTest() {}
|
||||
|
||||
protected:
|
||||
void run(int);
|
||||
virtual int test(const Mat& img) = 0;
|
||||
|
||||
int test8UC1(const Mat& img)
|
||||
{
|
||||
cv::Mat img_C1;
|
||||
cvtColor(img, img_C1, CV_BGR2GRAY);
|
||||
return test(img_C1);
|
||||
}
|
||||
|
||||
int test8UC4(const Mat& img)
|
||||
{
|
||||
cv::Mat img_C4;
|
||||
cvtColor(img, img_C4, CV_BGR2BGRA);
|
||||
return test(img_C4);
|
||||
}
|
||||
|
||||
int CheckNorm(const Mat& m1, const Mat& m2)
|
||||
{
|
||||
double res = norm(m1, m2, NORM_INF);
|
||||
|
||||
if (res < std::numeric_limits<double>::epsilon())
|
||||
return CvTS::OK;
|
||||
|
||||
ts->printf(CvTS::LOG, "\nNorm: %f\n", res);
|
||||
return CvTS::FAIL_GENERIC;
|
||||
}
|
||||
};
|
||||
|
||||
void CV_GpuNppMorphogyTest::run( int )
|
||||
{
|
||||
cv::Mat img = cv::imread(std::string(ts->get_data_path()) + "stereobp/aloe-L.png");
|
||||
|
||||
if (img.empty())
|
||||
{
|
||||
ts->set_failed_test_info(CvTS::FAIL_MISSING_TEST_DATA);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
//run tests
|
||||
int testResult = test8UC1(img);
|
||||
if (testResult != CvTS::OK)
|
||||
{
|
||||
ts->set_failed_test_info(testResult);
|
||||
return;
|
||||
}
|
||||
|
||||
testResult = test8UC4(img);
|
||||
if (testResult != CvTS::OK)
|
||||
{
|
||||
ts->set_failed_test_info(testResult);
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch(const cv::Exception& e)
|
||||
{
|
||||
if (!check_and_treat_gpu_exception(e, ts))
|
||||
throw;
|
||||
return;
|
||||
}
|
||||
|
||||
ts->set_failed_test_info(CvTS::OK);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Erode
|
||||
class CV_GpuErodeTest : public CV_GpuNppMorphogyTest
|
||||
{
|
||||
public:
|
||||
CV_GpuErodeTest() : CV_GpuNppMorphogyTest( "GPU-NppErode", "erode" ) {}
|
||||
|
||||
protected:
|
||||
virtual int test(const Mat& img)
|
||||
{
|
||||
GpuMat kernel(Mat::ones(3, 3, CV_8U));
|
||||
Point anchor(0, 0);
|
||||
int iters = 1;
|
||||
|
||||
cv::Mat cpuRes, cpuRes1;
|
||||
cv::erode(img, cpuRes, kernel, anchor, iters);
|
||||
|
||||
GpuMat gpuRes;
|
||||
cv::gpu::erode(GpuMat(img), gpuRes, kernel, anchor, iters);
|
||||
|
||||
return CheckNorm(cpuRes, gpuRes);
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Dilate
|
||||
class CV_GpuDilateTest : public CV_GpuNppMorphogyTest
|
||||
{
|
||||
public:
|
||||
CV_GpuDilateTest() : CV_GpuNppMorphogyTest( "GPU-NppDilate", "dilate" ) {}
|
||||
|
||||
protected:
|
||||
virtual int test(const Mat& img)
|
||||
{
|
||||
GpuMat kernel(Mat::ones(3, 3, CV_8U));
|
||||
Point anchor(0, 0);
|
||||
int iters = 1;
|
||||
|
||||
cv::Mat cpuRes, cpuRes1;
|
||||
cv::dilate(img, cpuRes, kernel, anchor, iters);
|
||||
|
||||
GpuMat gpuRes, gpuRes1;
|
||||
cv::gpu::dilate(GpuMat(img), gpuRes, kernel, anchor, iters);
|
||||
|
||||
return CheckNorm(cpuRes, gpuRes);
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Dilate
|
||||
class CV_GpuMorphExTest : public CV_GpuNppMorphogyTest
|
||||
{
|
||||
public:
|
||||
CV_GpuMorphExTest() : CV_GpuNppMorphogyTest( "GPU-NppMorphologyEx", "dmorphologyExilate" ) {}
|
||||
|
||||
protected:
|
||||
virtual int test(const Mat& img)
|
||||
{
|
||||
static int ops[] = { MORPH_OPEN, CV_MOP_CLOSE, CV_MOP_GRADIENT, CV_MOP_TOPHAT, CV_MOP_BLACKHAT};
|
||||
const char *names[] = { "MORPH_OPEN", "CV_MOP_CLOSE", "CV_MOP_GRADIENT", "CV_MOP_TOPHAT", "CV_MOP_BLACKHAT"};
|
||||
int num = sizeof(ops)/sizeof(ops[0]);
|
||||
|
||||
GpuMat kernel(Mat::ones(3, 3, CV_8U));
|
||||
Point anchor(0, 0);
|
||||
int iters = 1;
|
||||
|
||||
for(int i = 0; i < num; ++i)
|
||||
{
|
||||
ts->printf(CvTS::LOG, "Tesing %s\n", names[i]);
|
||||
|
||||
cv::Mat cpuRes;
|
||||
cv::morphologyEx(img, cpuRes, ops[i], kernel, anchor, iters);
|
||||
|
||||
GpuMat gpuRes;
|
||||
cv::gpu::morphologyEx(GpuMat(img), gpuRes, ops[i], kernel, anchor, iters);
|
||||
|
||||
int res = CheckNorm(cpuRes, gpuRes);
|
||||
if (CvTS::OK != res)
|
||||
return res;
|
||||
}
|
||||
return CvTS::OK;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////// tests registration /////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CV_GpuErodeTest CV_GpuErode_test;
|
||||
CV_GpuDilateTest CV_GpuDilate_test;
|
||||
CV_GpuMorphExTest CV_GpuMorphEx_test;
|
Loading…
Reference in New Issue
Block a user