Commit 3e840cb7 authored by Vladislav Vinogradov's avatar Vladislav Vinogradov

added min/max filters to gpu module.

added supports of 4-channels image to gpu::minMax and gpu::cvtColor for RGB <-> YCrCB, RGB <-> YUV and RGB <-> XYZ color conversion.
parent 1cf405d8
...@@ -411,7 +411,7 @@ namespace cv ...@@ -411,7 +411,7 @@ namespace cv
CV_EXPORTS Scalar sum(const GpuMat& m); CV_EXPORTS Scalar sum(const GpuMat& m);
//! finds global minimum and maximum array elements and returns their values //! finds global minimum and maximum array elements and returns their values
//! supports only CV_8UC1 type //! supports CV_8UC1 and CV_8UC4 type
//! disabled until fix npp bug //! disabled until fix npp bug
CV_EXPORTS void minMax(const GpuMat& src, double* minVal, double* maxVal = 0); CV_EXPORTS void minMax(const GpuMat& src, double* minVal, double* maxVal = 0);
...@@ -649,6 +649,12 @@ namespace cv ...@@ -649,6 +649,12 @@ namespace cv
//! 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);
//! returns maximum filter
CV_EXPORTS Ptr<BaseFilter_GPU> getMaxFilter_GPU(int srcType, int dstType, const Size& ksize, Point anchor = Point(-1,-1));
//! returns minimum filter
CV_EXPORTS Ptr<BaseFilter_GPU> getMinFilter_GPU(int srcType, int dstType, const Size& ksize, Point anchor = Point(-1,-1));
//! smooths the image using the normalized box filter //! smooths the image using the normalized box filter
//! supports CV_8UC1, CV_8UC4 types //! supports CV_8UC1, CV_8UC4 types
CV_EXPORTS void boxFilter(const GpuMat& src, GpuMat& dst, int ddepth, Size ksize, Point anchor = Point(-1,-1)); CV_EXPORTS void boxFilter(const GpuMat& src, GpuMat& dst, int ddepth, Size ksize, Point anchor = Point(-1,-1));
......
...@@ -419,24 +419,55 @@ Scalar cv::gpu::sum(const GpuMat& src) ...@@ -419,24 +419,55 @@ Scalar cv::gpu::sum(const GpuMat& src)
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// minMax // minMax
void cv::gpu::minMax(const GpuMat& src, double* minVal, double* maxVal) namespace
{ {
CV_Assert(!"disabled until fix npp bug"); void minMax_c1(const GpuMat& src, double* minVal, double* maxVal)
CV_Assert(src.type() == CV_8UC1); {
NppiSize sz;
sz.width = src.cols;
sz.height = src.rows;
NppiSize sz; Npp8u min_res, max_res;
sz.width = src.cols;
sz.height = src.rows; nppSafeCall( nppiMinMax_8u_C1R(src.ptr<Npp8u>(), src.step, sz, &min_res, &max_res) );
Npp8u min_res, max_res; if (minVal)
*minVal = min_res;
nppSafeCall( nppiMinMax_8u_C1R(src.ptr<Npp8u>(), src.step, sz, &min_res, &max_res) ); if (maxVal)
*maxVal = max_res;
}
void minMax_c4(const GpuMat& src, double* minVal, double* maxVal)
{
NppiSize sz;
sz.width = src.cols;
sz.height = src.rows;
if (minVal) Npp8u* cuMin = nppsMalloc_8u(4);
*minVal = min_res; Npp8u* cuMax = nppsMalloc_8u(4);
nppSafeCall( nppiMinMax_8u_C4R(src.ptr<Npp8u>(), src.step, sz, cuMin, cuMax) );
if (minVal)
cudaMemcpy(minVal, cuMin, 4 * sizeof(Npp8u), cudaMemcpyDeviceToHost);
if (maxVal)
cudaMemcpy(maxVal, cuMax, 4 * sizeof(Npp8u), cudaMemcpyDeviceToHost);
nppsFree(cuMin);
nppsFree(cuMax);
}
}
void cv::gpu::minMax(const GpuMat& src, double* minVal, double* maxVal)
{
typedef void (*minMax_t)(const GpuMat& src, double* minVal, double* maxVal);
static const minMax_t minMax_callers[] = {0, minMax_c1, 0, 0, minMax_c4};
CV_Assert(!"disabled until fix npp bug");
CV_Assert(src.type() == CV_8UC1 || src.type() == CV_8UC4);
if (maxVal) minMax_callers[src.channels()](src, minVal, maxVal);
*maxVal = max_res;
} }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
......
This diff is collapsed.
...@@ -63,6 +63,9 @@ Ptr<BaseColumnFilter_GPU> cv::gpu::getLinearColumnFilter_GPU(int, int, const Gpu ...@@ -63,6 +63,9 @@ Ptr<BaseColumnFilter_GPU> cv::gpu::getLinearColumnFilter_GPU(int, int, const Gpu
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::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::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); } Ptr<FilterEngine_GPU> cv::gpu::createGaussianFilter_GPU(int, Size, double, double) { throw_nogpu(); return Ptr<FilterEngine_GPU>(0); }
Ptr<BaseFilter_GPU> cv::gpu::getMaxFilter_GPU(int, int, const Size&, Point) { throw_nogpu(); return Ptr<BaseFilter_GPU>(0); }
Ptr<BaseFilter_GPU> cv::gpu::getMinFilter_GPU(int, int, const Size&, Point) { throw_nogpu(); return Ptr<BaseFilter_GPU>(0); }
void cv::gpu::boxFilter(const GpuMat&, GpuMat&, int, Size, Point) { throw_nogpu(); } 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::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::dilate( const GpuMat&, GpuMat&, const Mat&, Point, int) { throw_nogpu(); }
...@@ -105,20 +108,20 @@ namespace ...@@ -105,20 +108,20 @@ namespace
int scale = nDivisor && (kernel.depth() == CV_32F || kernel.depth() == CV_64F) ? 256 : 1; int scale = nDivisor && (kernel.depth() == CV_32F || kernel.depth() == CV_64F) ? 256 : 1;
if (nDivisor) *nDivisor = scale; if (nDivisor) *nDivisor = scale;
Mat cont_krnl = (kernel.isContinuous() ? kernel : kernel.clone()).reshape(1, 1); Mat temp(kernel.size(), type);
Mat temp; kernel.convertTo(temp, type, scale);
cont_krnl.convertTo(temp, type, scale); Mat cont_krnl = temp.reshape(1, 1);
if (reverse) if (reverse)
{ {
int count = temp.cols >> 1; int count = cont_krnl.cols >> 1;
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i)
{ {
std::swap(temp.at<int>(0, i), temp.at<int>(0, temp.cols - 1 - i)); std::swap(cont_krnl.at<int>(0, i), cont_krnl.at<int>(0, cont_krnl.cols - 1 - i));
} }
} }
gpu_krnl.upload(temp); gpu_krnl.upload(cont_krnl);
} }
} }
...@@ -785,4 +788,58 @@ void cv::gpu::GaussianBlur(const GpuMat& src, GpuMat& dst, Size ksize, double si ...@@ -785,4 +788,58 @@ void cv::gpu::GaussianBlur(const GpuMat& src, GpuMat& dst, Size ksize, double si
f->apply(src, dst); f->apply(src, dst);
} }
////////////////////////////////////////////////////////////////////////////////////////////////////
// Image Rank Filter
namespace
{
typedef NppStatus (*nppFilterRank_t)(const Npp8u * pSrc, Npp32s nSrcStep, Npp8u * pDst, Npp32s nDstStep, NppiSize oSizeROI,
NppiSize oMaskSize, NppiPoint oAnchor);
class NPPRankFilter : public BaseFilter_GPU
{
public:
NPPRankFilter(const Size& ksize_, const Point& anchor_, nppFilterRank_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) );
}
nppFilterRank_t func;
};
}
Ptr<BaseFilter_GPU> cv::gpu::getMaxFilter_GPU(int srcType, int dstType, const Size& ksize, Point anchor)
{
static const nppFilterRank_t nppFilterRank_callers[] = {0, nppiFilterMax_8u_C1R, 0, 0, nppiFilterMax_8u_C4R};
CV_Assert((srcType == CV_8UC1 || srcType == CV_8UC4) && dstType == srcType);
normalizeAnchor(anchor, ksize);
return Ptr<BaseFilter_GPU>(new NPPRankFilter(ksize, anchor, nppFilterRank_callers[CV_MAT_CN(srcType)]));
}
Ptr<BaseFilter_GPU> cv::gpu::getMinFilter_GPU(int srcType, int dstType, const Size& ksize, Point anchor)
{
static const nppFilterRank_t nppFilterRank_callers[] = {0, nppiFilterMin_8u_C1R, 0, 0, nppiFilterMin_8u_C4R};
CV_Assert((srcType == CV_8UC1 || srcType == CV_8UC4) && dstType == srcType);
normalizeAnchor(anchor, ksize);
return Ptr<BaseFilter_GPU>(new NPPRankFilter(ksize, anchor, nppFilterRank_callers[CV_MAT_CN(srcType)]));
}
#endif #endif
...@@ -98,21 +98,21 @@ namespace cv { namespace gpu ...@@ -98,21 +98,21 @@ namespace cv { namespace gpu
void RGB2Gray_gpu_32f(const DevMem2D& src, int srccn, const DevMem2D& dst, int bidx, cudaStream_t stream); void RGB2Gray_gpu_32f(const DevMem2D& src, int srccn, const DevMem2D& dst, int bidx, cudaStream_t stream);
void RGB5x52Gray_gpu(const DevMem2D& src, int green_bits, const DevMem2D& dst, cudaStream_t stream); void RGB5x52Gray_gpu(const DevMem2D& src, int green_bits, const DevMem2D& dst, cudaStream_t stream);
void RGB2YCrCb_gpu_8u(const DevMem2D& src, int srccn, const DevMem2D& dst, int bidx, const int* coeffs, cudaStream_t stream); void RGB2YCrCb_gpu_8u(const DevMem2D& src, int srccn, const DevMem2D& dst, int dstcn, int bidx, const int* coeffs, cudaStream_t stream);
void RGB2YCrCb_gpu_16u(const DevMem2D& src, int srccn, const DevMem2D& dst, int bidx, const int* coeffs, cudaStream_t stream); void RGB2YCrCb_gpu_16u(const DevMem2D& src, int srccn, const DevMem2D& dst, int dstcn, int bidx, const int* coeffs, cudaStream_t stream);
void RGB2YCrCb_gpu_32f(const DevMem2D& src, int srccn, const DevMem2D& dst, int bidx, const float* coeffs, cudaStream_t stream); void RGB2YCrCb_gpu_32f(const DevMem2D& src, int srccn, const DevMem2D& dst, int dstcn, int bidx, const float* coeffs, cudaStream_t stream);
void YCrCb2RGB_gpu_8u(const DevMem2D& src, const DevMem2D& dst, int dstcn, int bidx, const int* coeffs, cudaStream_t stream); void YCrCb2RGB_gpu_8u(const DevMem2D& src, int srccn, const DevMem2D& dst, int dstcn, int bidx, const int* coeffs, cudaStream_t stream);
void YCrCb2RGB_gpu_16u(const DevMem2D& src, const DevMem2D& dst, int dstcn, int bidx, const int* coeffs, cudaStream_t stream); void YCrCb2RGB_gpu_16u(const DevMem2D& src, int srccn, const DevMem2D& dst, int dstcn, int bidx, const int* coeffs, cudaStream_t stream);
void YCrCb2RGB_gpu_32f(const DevMem2D& src, const DevMem2D& dst, int dstcn, int bidx, const float* coeffs, cudaStream_t stream); void YCrCb2RGB_gpu_32f(const DevMem2D& src, int srccn, const DevMem2D& dst, int dstcn, int bidx, const float* coeffs, cudaStream_t stream);
void RGB2XYZ_gpu_8u(const DevMem2D& src, int srccn, const DevMem2D& dst, const int* coeffs, cudaStream_t stream); void RGB2XYZ_gpu_8u(const DevMem2D& src, int srccn, const DevMem2D& dst, int dstcn, const int* coeffs, cudaStream_t stream);
void RGB2XYZ_gpu_16u(const DevMem2D& src, int srccn, const DevMem2D& dst, const int* coeffs, cudaStream_t stream); void RGB2XYZ_gpu_16u(const DevMem2D& src, int srccn, const DevMem2D& dst, int dstcn, const int* coeffs, cudaStream_t stream);
void RGB2XYZ_gpu_32f(const DevMem2D& src, int srccn, const DevMem2D& dst, const float* coeffs, cudaStream_t stream); void RGB2XYZ_gpu_32f(const DevMem2D& src, int srccn, const DevMem2D& dst, int dstcn, const float* coeffs, cudaStream_t stream);
void XYZ2RGB_gpu_8u(const DevMem2D& src, const DevMem2D& dst, int dstcn, const int* coeffs, cudaStream_t stream); void XYZ2RGB_gpu_8u(const DevMem2D& src, int srccn, const DevMem2D& dst, int dstcn, const int* coeffs, cudaStream_t stream);
void XYZ2RGB_gpu_16u(const DevMem2D& src, const DevMem2D& dst, int dstcn, const int* coeffs, cudaStream_t stream); void XYZ2RGB_gpu_16u(const DevMem2D& src, int srccn, const DevMem2D& dst, int dstcn, const int* coeffs, cudaStream_t stream);
void XYZ2RGB_gpu_32f(const DevMem2D& src, const DevMem2D& dst, int dstcn, const float* coeffs, cudaStream_t stream); void XYZ2RGB_gpu_32f(const DevMem2D& src, int srccn, const DevMem2D& dst, int dstcn, const float* coeffs, cudaStream_t stream);
} }
}} }}
...@@ -361,7 +361,8 @@ namespace ...@@ -361,7 +361,8 @@ namespace
case CV_BGR2YCrCb: case CV_RGB2YCrCb: case CV_BGR2YCrCb: case CV_RGB2YCrCb:
case CV_BGR2YUV: case CV_RGB2YUV: case CV_BGR2YUV: case CV_RGB2YUV:
{ {
CV_Assert( scn == 3 || scn == 4 ); if(dcn <= 0) dcn = 3;
CV_Assert( (scn == 3 || scn == 4) && (dcn == 3 || dcn == 4) );
bidx = code == CV_BGR2YCrCb || code == CV_RGB2YUV ? 0 : 2; bidx = code == CV_BGR2YCrCb || code == CV_RGB2YUV ? 0 : 2;
...@@ -382,14 +383,14 @@ namespace ...@@ -382,14 +383,14 @@ namespace
std::swap(coeffs_i[0], coeffs_i[2]); std::swap(coeffs_i[0], coeffs_i[2]);
} }
out.create(sz, CV_MAKETYPE(depth, 3)); out.create(sz, CV_MAKETYPE(depth, dcn));
if( depth == CV_8U ) if( depth == CV_8U )
improc::RGB2YCrCb_gpu_8u(src, scn, out, bidx, coeffs_i, stream); improc::RGB2YCrCb_gpu_8u(src, scn, out, dcn, bidx, coeffs_i, stream);
else if( depth == CV_16U ) else if( depth == CV_16U )
improc::RGB2YCrCb_gpu_16u(src, scn, out, bidx, coeffs_i, stream); improc::RGB2YCrCb_gpu_16u(src, scn, out, dcn, bidx, coeffs_i, stream);
else else
improc::RGB2YCrCb_gpu_32f(src, scn, out, bidx, coeffs_f, stream); improc::RGB2YCrCb_gpu_32f(src, scn, out, dcn, bidx, coeffs_f, stream);
} }
break; break;
...@@ -398,7 +399,7 @@ namespace ...@@ -398,7 +399,7 @@ namespace
{ {
if (dcn <= 0) dcn = 3; if (dcn <= 0) dcn = 3;
CV_Assert( scn == 3 && (dcn == 3 || dcn == 4) ); CV_Assert( (scn == 3 || scn == 4) && (dcn == 3 || dcn == 4) );
bidx = code == CV_YCrCb2BGR || code == CV_YUV2RGB ? 0 : 2; bidx = code == CV_YCrCb2BGR || code == CV_YUV2RGB ? 0 : 2;
...@@ -414,17 +415,18 @@ namespace ...@@ -414,17 +415,18 @@ namespace
out.create(sz, CV_MAKETYPE(depth, dcn)); out.create(sz, CV_MAKETYPE(depth, dcn));
if( depth == CV_8U ) if( depth == CV_8U )
improc::YCrCb2RGB_gpu_8u(src, out, dcn, bidx, coeffs_i, stream); improc::YCrCb2RGB_gpu_8u(src, scn, out, dcn, bidx, coeffs_i, stream);
else if( depth == CV_16U ) else if( depth == CV_16U )
improc::YCrCb2RGB_gpu_16u(src, out, dcn, bidx, coeffs_i, stream); improc::YCrCb2RGB_gpu_16u(src, scn, out, dcn, bidx, coeffs_i, stream);
else else
improc::YCrCb2RGB_gpu_32f(src, out, dcn, bidx, coeffs_f, stream); improc::YCrCb2RGB_gpu_32f(src, scn, out, dcn, bidx, coeffs_f, stream);
} }
break; break;
case CV_BGR2XYZ: case CV_RGB2XYZ: case CV_BGR2XYZ: case CV_RGB2XYZ:
{ {
CV_Assert( scn == 3 || scn == 4 ); if(dcn <= 0) dcn = 3;
CV_Assert( (scn == 3 || scn == 4) && (dcn == 3 || dcn == 4) );
bidx = code == CV_BGR2XYZ ? 0 : 2; bidx = code == CV_BGR2XYZ ? 0 : 2;
...@@ -457,21 +459,21 @@ namespace ...@@ -457,21 +459,21 @@ namespace
std::swap(coeffs_i[6], coeffs_i[8]); std::swap(coeffs_i[6], coeffs_i[8]);
} }
out.create(sz, CV_MAKETYPE(depth, 3)); out.create(sz, CV_MAKETYPE(depth, dcn));
if( depth == CV_8U ) if( depth == CV_8U )
improc::RGB2XYZ_gpu_8u(src, scn, out, coeffs_i, stream); improc::RGB2XYZ_gpu_8u(src, scn, out, dcn, coeffs_i, stream);
else if( depth == CV_16U ) else if( depth == CV_16U )
improc::RGB2XYZ_gpu_16u(src, scn, out, coeffs_i, stream); improc::RGB2XYZ_gpu_16u(src, scn, out, dcn, coeffs_i, stream);
else else
improc::RGB2XYZ_gpu_32f(src, scn, out, coeffs_f, stream); improc::RGB2XYZ_gpu_32f(src, scn, out, dcn, coeffs_f, stream);
} }
break; break;
case CV_XYZ2BGR: case CV_XYZ2RGB: case CV_XYZ2BGR: case CV_XYZ2RGB:
{ {
if (dcn <= 0) dcn = 3; if (dcn <= 0) dcn = 3;
CV_Assert( scn == 3 && (dcn == 3 || dcn == 4) ); CV_Assert( (scn == 3 || scn == 4) && (dcn == 3 || dcn == 4) );
bidx = code == CV_XYZ2BGR ? 0 : 2; bidx = code == CV_XYZ2BGR ? 0 : 2;
static const float XYZ2sRGB_D65f[] = static const float XYZ2sRGB_D65f[] =
...@@ -506,11 +508,11 @@ namespace ...@@ -506,11 +508,11 @@ namespace
out.create(sz, CV_MAKETYPE(depth, dcn)); out.create(sz, CV_MAKETYPE(depth, dcn));
if( depth == CV_8U ) if( depth == CV_8U )
improc::XYZ2RGB_gpu_8u(src, out, dcn, coeffs_i, stream); improc::XYZ2RGB_gpu_8u(src, scn, out, dcn, coeffs_i, stream);
else if( depth == CV_16U ) else if( depth == CV_16U )
improc::XYZ2RGB_gpu_16u(src, out, dcn, coeffs_i, stream); improc::XYZ2RGB_gpu_16u(src, scn, out, dcn, coeffs_i, stream);
else else
improc::XYZ2RGB_gpu_32f(src, out, dcn, coeffs_f, stream); improc::XYZ2RGB_gpu_32f(src, scn, out, dcn, coeffs_f, stream);
} }
break; break;
......
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