Commit 49ec8ba7 authored by Vladislav Vinogradov's avatar Vladislav Vinogradov

fixed bug in gpu filter engine (incorrect buffer type) and in vector's saturate_cast.

changed buffer type in linear filters to float.
added support of 1 channel image to linear filters.
added support of BORDER_REFLECT101, BORDER_REPLICATE and BORDER_CONSTANT border type to gpu linear filters.
minor fix in tests.
update comments in gpu.hpp.
parent 108ab940
...@@ -388,7 +388,7 @@ namespace cv ...@@ -388,7 +388,7 @@ namespace cv
CV_EXPORTS void divide(const GpuMat& a, const Scalar& sc, GpuMat& c); CV_EXPORTS void divide(const GpuMat& a, const Scalar& sc, GpuMat& c);
//! transposes the matrix //! transposes the matrix
//! supports only CV_8UC1 type //! supports CV_8UC1, CV_8SC1, CV_8UC4, CV_8SC4, CV_16UC2, CV_16SC2, CV_32SC1, CV_32FC1 type
CV_EXPORTS void transpose(const GpuMat& src1, GpuMat& dst); CV_EXPORTS void transpose(const GpuMat& src1, GpuMat& dst);
//! computes element-wise absolute difference of two arrays (c = abs(a - b)) //! computes element-wise absolute difference of two arrays (c = abs(a - b))
...@@ -725,11 +725,11 @@ namespace cv ...@@ -725,11 +725,11 @@ namespace cv
}; };
//! returns the non-separable filter engine with the specified filter //! returns the non-separable filter engine with the specified filter
CV_EXPORTS Ptr<FilterEngine_GPU> createFilter2D_GPU(const Ptr<BaseFilter_GPU> filter2D); CV_EXPORTS Ptr<FilterEngine_GPU> createFilter2D_GPU(const Ptr<BaseFilter_GPU> filter2D, int srcType, int dstType);
//! returns the separable filter engine with the specified filters //! returns the separable filter engine with the specified filters
CV_EXPORTS Ptr<FilterEngine_GPU> createSeparableFilter_GPU(const Ptr<BaseRowFilter_GPU>& rowFilter, CV_EXPORTS Ptr<FilterEngine_GPU> createSeparableFilter_GPU(const Ptr<BaseRowFilter_GPU>& rowFilter,
const Ptr<BaseColumnFilter_GPU>& columnFilter); const Ptr<BaseColumnFilter_GPU>& columnFilter, int srcType, int bufType, int dstType);
//! returns horizontal 1D box filter //! returns horizontal 1D box filter
//! supports only CV_8UC1 source type and CV_32FC1 sum type //! supports only CV_8UC1 source type and CV_32FC1 sum type
...@@ -767,23 +767,40 @@ namespace cv ...@@ -767,23 +767,40 @@ namespace cv
CV_EXPORTS Ptr<FilterEngine_GPU> createLinearFilter_GPU(int srcType, int dstType, const Mat& kernel, CV_EXPORTS Ptr<FilterEngine_GPU> createLinearFilter_GPU(int srcType, int dstType, const Mat& kernel,
const Point& anchor = Point(-1,-1)); const Point& anchor = Point(-1,-1));
//! returns the primitive row filter with the specified kernel //! returns the primitive row filter with the specified kernel.
//! supports only CV_8UC1, CV_8UC4, CV_16SC1, CV_16SC2, CV_32SC1, CV_32FC1 source type.
//! there are two version of algorithm: NPP and OpenCV.
//! NPP calls when srcType == CV_8UC1 or srcType == CV_8UC4 and bufType == srcType,
//! otherwise calls OpenCV version.
//! NPP supports only BORDER_CONSTANT border type.
//! OpenCV version supports only CV_32F as buffer depth and
//! BORDER_REFLECT101, BORDER_REPLICATE and BORDER_CONSTANT border types.
CV_EXPORTS Ptr<BaseRowFilter_GPU> getLinearRowFilter_GPU(int srcType, int bufType, const Mat& rowKernel, CV_EXPORTS Ptr<BaseRowFilter_GPU> getLinearRowFilter_GPU(int srcType, int bufType, const Mat& rowKernel,
int anchor = -1); int anchor = -1, int borderType = BORDER_CONSTANT);
//! returns the primitive column filter with the specified kernel //! returns the primitive column filter with the specified kernel.
//! supports only CV_8UC1, CV_8UC4, CV_16SC1, CV_16SC2, CV_32SC1, CV_32FC1 dst type.
//! there are two version of algorithm: NPP and OpenCV.
//! NPP calls when dstType == CV_8UC1 or dstType == CV_8UC4 and bufType == dstType,
//! otherwise calls OpenCV version.
//! NPP supports only BORDER_CONSTANT border type.
//! OpenCV version supports only CV_32F as buffer depth and
//! BORDER_REFLECT101, BORDER_REPLICATE and BORDER_CONSTANT border types.
CV_EXPORTS Ptr<BaseColumnFilter_GPU> getLinearColumnFilter_GPU(int bufType, int dstType, const Mat& columnKernel, CV_EXPORTS Ptr<BaseColumnFilter_GPU> getLinearColumnFilter_GPU(int bufType, int dstType, const Mat& columnKernel,
int anchor = -1); int anchor = -1, int borderType = BORDER_CONSTANT);
//! returns the separable linear filter engine //! returns the separable linear filter engine
CV_EXPORTS Ptr<FilterEngine_GPU> createSeparableLinearFilter_GPU(int srcType, int dstType, const Mat& rowKernel, CV_EXPORTS Ptr<FilterEngine_GPU> createSeparableLinearFilter_GPU(int srcType, int dstType, const Mat& rowKernel,
const Mat& columnKernel, const Point& anchor = Point(-1,-1)); const Mat& columnKernel, const Point& anchor = Point(-1,-1), int rowBorderType = BORDER_DEFAULT,
int columnBorderType = -1);
//! returns filter engine for the generalized Sobel operator //! 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); CV_EXPORTS Ptr<FilterEngine_GPU> createDerivFilter_GPU(int srcType, int dstType, int dx, int dy, int ksize,
int rowBorderType = BORDER_DEFAULT, int columnBorderType = -1);
//! returns the Gaussian filter engine //! returns the Gaussian filter engine
CV_EXPORTS Ptr<FilterEngine_GPU> createGaussianFilter_GPU(int type, Size ksize, double sigma1, double sigma2 = 0); CV_EXPORTS Ptr<FilterEngine_GPU> createGaussianFilter_GPU(int type, Size ksize, double sigma1, double sigma2 = 0,
int rowBorderType = BORDER_DEFAULT, int columnBorderType = -1);
//! returns maximum filter //! returns maximum filter
CV_EXPORTS Ptr<BaseFilter_GPU> getMaxFilter_GPU(int srcType, int dstType, const Size& ksize, Point anchor = Point(-1,-1)); CV_EXPORTS Ptr<BaseFilter_GPU> getMaxFilter_GPU(int srcType, int dstType, const Size& ksize, Point anchor = Point(-1,-1));
...@@ -812,16 +829,19 @@ namespace cv ...@@ -812,16 +829,19 @@ namespace cv
//! applies separable 2D linear filter to the image //! 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, CV_EXPORTS void sepFilter2D(const GpuMat& src, GpuMat& dst, int ddepth, const Mat& kernelX, const Mat& kernelY,
Point anchor = Point(-1,-1)); Point anchor = Point(-1,-1), int rowBorderType = BORDER_DEFAULT, int columnBorderType = -1);
//! applies generalized Sobel operator to the image //! 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); CV_EXPORTS void Sobel(const GpuMat& src, GpuMat& dst, int ddepth, int dx, int dy, int ksize = 3, double scale = 1,
int rowBorderType = BORDER_DEFAULT, int columnBorderType = -1);
//! applies the vertical or horizontal Scharr operator to the image //! 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); CV_EXPORTS void Scharr(const GpuMat& src, GpuMat& dst, int ddepth, int dx, int dy, double scale = 1,
int rowBorderType = BORDER_DEFAULT, int columnBorderType = -1);
//! smooths the image using Gaussian filter. //! smooths the image using Gaussian filter.
CV_EXPORTS void GaussianBlur(const GpuMat& src, GpuMat& dst, Size ksize, double sigma1, double sigma2 = 0); CV_EXPORTS void GaussianBlur(const GpuMat& src, GpuMat& dst, Size ksize, double sigma1, double sigma2 = 0,
int rowBorderType = BORDER_DEFAULT, int columnBorderType = -1);
//! applies Laplacian operator to the image //! applies Laplacian operator to the image
//! supports only ksize = 1 and ksize = 3 //! supports only ksize = 1 and ksize = 3
......
...@@ -277,12 +277,12 @@ namespace cv { namespace gpu { namespace mathfunc ...@@ -277,12 +277,12 @@ namespace cv { namespace gpu { namespace mathfunc
void cv::gpu::transpose(const GpuMat& src, GpuMat& dst) void cv::gpu::transpose(const GpuMat& src, GpuMat& dst)
{ {
CV_Assert(src.type() == CV_8UC1 || src.type() == CV_8UC4 || src.type() == CV_8SC4 CV_Assert(src.type() == CV_8UC1 || src.type() == CV_8SC1 || src.type() == CV_8UC4 || src.type() == CV_8SC4
|| src.type() == CV_16UC2 || src.type() == CV_16SC2 || src.type() == CV_32SC1 || src.type() == CV_32FC1); || src.type() == CV_16UC2 || src.type() == CV_16SC2 || src.type() == CV_32SC1 || src.type() == CV_32FC1);
dst.create( src.cols, src.rows, src.type() ); dst.create( src.cols, src.rows, src.type() );
if (src.type() == CV_8UC1) if (src.type() == CV_8UC1 || src.type() == CV_8SC1)
{ {
NppiSize sz; NppiSize sz;
sz.width = src.cols; sz.width = src.cols;
......
This diff is collapsed.
...@@ -59,7 +59,8 @@ namespace cv ...@@ -59,7 +59,8 @@ namespace cv
enum enum
{ {
BORDER_REFLECT101_GPU = 0, BORDER_REFLECT101_GPU = 0,
BORDER_REPLICATE_GPU BORDER_REPLICATE_GPU,
BORDER_CONSTANT_GPU
}; };
// Converts CPU border extrapolation mode into GPU internal analogue. // Converts CPU border extrapolation mode into GPU internal analogue.
......
This diff is collapsed.
...@@ -972,6 +972,12 @@ bool cv::gpu::tryConvertToGpuBorderType(int cpuBorderType, int& gpuBorderType) ...@@ -972,6 +972,12 @@ bool cv::gpu::tryConvertToGpuBorderType(int cpuBorderType, int& gpuBorderType)
gpuBorderType = cv::gpu::BORDER_REPLICATE_GPU; gpuBorderType = cv::gpu::BORDER_REPLICATE_GPU;
return true; return true;
} }
if (cpuBorderType == cv::BORDER_CONSTANT)
{
gpuBorderType = cv::gpu::BORDER_CONSTANT_GPU;
return true;
}
return false; return false;
} }
......
...@@ -107,7 +107,7 @@ protected: ...@@ -107,7 +107,7 @@ protected:
if (!compareMatches(matchesCPU, matchesGPU)) if (!compareMatches(matchesCPU, matchesGPU))
{ {
ts->printf(CvTS::LOG, "Match FAIL"); ts->printf(CvTS::LOG, "Match FAIL\n");
ts->set_failed_test_info(CvTS::FAIL_MISMATCH); ts->set_failed_test_info(CvTS::FAIL_MISMATCH);
return; return;
} }
...@@ -119,7 +119,7 @@ protected: ...@@ -119,7 +119,7 @@ protected:
if (!compareMatches(knnMatchesCPU, knnMatchesGPU)) if (!compareMatches(knnMatchesCPU, knnMatchesGPU))
{ {
ts->printf(CvTS::LOG, "KNN Match FAIL"); ts->printf(CvTS::LOG, "KNN Match FAIL\n");
ts->set_failed_test_info(CvTS::FAIL_MISMATCH); ts->set_failed_test_info(CvTS::FAIL_MISMATCH);
return; return;
} }
...@@ -131,7 +131,7 @@ protected: ...@@ -131,7 +131,7 @@ protected:
if (!compareMatches(radiusMatchesCPU, radiusMatchesGPU)) if (!compareMatches(radiusMatchesCPU, radiusMatchesGPU))
{ {
ts->printf(CvTS::LOG, "Radius Match FAIL"); ts->printf(CvTS::LOG, "Radius Match FAIL\n");
ts->set_failed_test_info(CvTS::FAIL_MISMATCH); ts->set_failed_test_info(CvTS::FAIL_MISMATCH);
return; return;
} }
......
...@@ -80,7 +80,8 @@ protected: ...@@ -80,7 +80,8 @@ protected:
double res = norm(m1ROI, m2ROI, NORM_INF); double res = norm(m1ROI, m2ROI, NORM_INF);
if (res <= 1) // Max difference (2.0) in GaussianBlur
if (res <= 2)
return CvTS::OK; return CvTS::OK;
ts->printf(CvTS::LOG, "Norm: %f\n", res); ts->printf(CvTS::LOG, "Norm: %f\n", res);
...@@ -166,8 +167,6 @@ struct CV_GpuNppImageSobelTest : public CV_GpuNppFilterTest ...@@ -166,8 +167,6 @@ struct CV_GpuNppImageSobelTest : public CV_GpuNppFilterTest
int test(const Mat& img) int test(const Mat& img)
{ {
if (img.type() != CV_8UC1)
return CvTS::OK;
int ksizes[] = {3, 5, 7}; int ksizes[] = {3, 5, 7};
int ksizes_num = sizeof(ksizes) / sizeof(int); int ksizes_num = sizeof(ksizes) / sizeof(int);
...@@ -183,10 +182,8 @@ struct CV_GpuNppImageSobelTest : public CV_GpuNppFilterTest ...@@ -183,10 +182,8 @@ struct CV_GpuNppImageSobelTest : public CV_GpuNppFilterTest
cv::Sobel(img, cpudst, -1, dx, dy, ksizes[i]); cv::Sobel(img, cpudst, -1, dx, dy, ksizes[i]);
GpuMat gpu1(img); GpuMat gpu1(img);
gpu1.convertTo(gpu1, CV_32S);
GpuMat gpudst; GpuMat gpudst;
cv::gpu::Sobel(gpu1, gpudst, -1, dx, dy, ksizes[i]); cv::gpu::Sobel(gpu1, gpudst, -1, dx, dy, ksizes[i]);
gpudst.convertTo(gpudst, CV_8U);
if (CheckNorm(cpudst, gpudst, Size(ksizes[i], ksizes[i])) != CvTS::OK) if (CheckNorm(cpudst, gpudst, Size(ksizes[i], ksizes[i])) != CvTS::OK)
test_res = CvTS::FAIL_GENERIC; test_res = CvTS::FAIL_GENERIC;
...@@ -204,20 +201,15 @@ struct CV_GpuNppImageScharrTest : public CV_GpuNppFilterTest ...@@ -204,20 +201,15 @@ struct CV_GpuNppImageScharrTest : public CV_GpuNppFilterTest
int test(const Mat& img) int test(const Mat& img)
{ {
if (img.type() != CV_8UC1)
return CvTS::OK;
int dx = 1, dy = 0; int dx = 1, dy = 0;
Mat cpudst; Mat cpudst;
cv::Scharr(img, cpudst, -1, dx, dy); cv::Scharr(img, cpudst, -1, dx, dy);
GpuMat gpu1(img); GpuMat gpu1(img);
gpu1.convertTo(gpu1, CV_32S);
GpuMat gpudst; GpuMat gpudst;
cv::gpu::Scharr(gpu1, gpudst, -1, dx, dy); cv::gpu::Scharr(gpu1, gpudst, -1, dx, dy);
gpudst.convertTo(gpudst, CV_8U);
return CheckNorm(cpudst, gpudst, Size(3, 3)); return CheckNorm(cpudst, gpudst, Size(3, 3));
} }
}; };
...@@ -244,7 +236,7 @@ struct CV_GpuNppImageGaussianBlurTest : public CV_GpuNppFilterTest ...@@ -244,7 +236,7 @@ struct CV_GpuNppImageGaussianBlurTest : public CV_GpuNppFilterTest
{ {
cv::Size ksize(ksizes[i], ksizes[j]); cv::Size ksize(ksizes[i], ksizes[j]);
ts->printf(CvTS::LOG, "ksize = (%dx%d)\t", ksizes[i], ksizes[j]); ts->printf(CvTS::LOG, "ksize = (%dx%d)\t\n", ksizes[i], ksizes[j]);
Mat cpudst; Mat cpudst;
cv::GaussianBlur(img, cpudst, ksize, sigma1); cv::GaussianBlur(img, cpudst, ksize, sigma1);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment