提交 051adcb7 编写于 作者: V Vladislav Vinogradov

added gpu BGR<->Lab and RGB<->Luv color conversion and gammaCorrection

上级 484e83a9
......@@ -622,6 +622,9 @@ CV_EXPORTS void cvtColor(const GpuMat& src, GpuMat& dst, int code, int dcn = 0,
//! channel order.
CV_EXPORTS void swapChannels(GpuMat& image, const int dstOrder[4], Stream& stream = Stream::Null());
//! Routines for correcting image color gamma
CV_EXPORTS void gammaCorrection(const GpuMat& src, GpuMat& dst, bool forward = true, Stream& stream = Stream::Null());
//! applies fixed threshold to the image
CV_EXPORTS double threshold(const GpuMat& src, GpuMat& dst, double thresh, double maxval, int type, Stream& stream = Stream::Null());
......@@ -1411,7 +1414,7 @@ public:
};
////////////////////////////////// CascadeClassifier_GPU //////////////////////////////////////////
// The cascade classifier class for object detection: supports old haar and new lbp xlm formats and nvbin for haar cascades olny.
// The cascade classifier class for object detection: supports old haar and new lbp xlm formats and nvbin for haar cascades olny.
class CV_EXPORTS CascadeClassifier_GPU
{
public:
......@@ -1421,28 +1424,28 @@ public:
bool empty() const;
bool load(const std::string& filename);
void release();
/* returns number of detected objects */
int detectMultiScale(const GpuMat& image, GpuMat& objectsBuf, double scaleFactor = 1.2, int minNeighbors = 4, Size minSize = Size());
bool findLargestObject;
bool visualizeInPlace;
Size getClassifierSize() const;
private:
struct CascadeClassifierImpl;
CascadeClassifierImpl* impl;
struct HaarCascade;
struct LbpCascade;
friend class CascadeClassifier_GPU_LBP;
public:
int detectMultiScale(const GpuMat& image, GpuMat& objectsBuf, Size maxObjectSize, Size minSize = Size(), double scaleFactor = 1.1, int minNeighbors = 4);
};
////////////////////////////////// SURF //////////////////////////////////////////
void release();
/* returns number of detected objects */
int detectMultiScale(const GpuMat& image, GpuMat& objectsBuf, double scaleFactor = 1.2, int minNeighbors = 4, Size minSize = Size());
bool findLargestObject;
bool visualizeInPlace;
Size getClassifierSize() const;
private:
struct CascadeClassifierImpl;
CascadeClassifierImpl* impl;
struct HaarCascade;
struct LbpCascade;
friend class CascadeClassifier_GPU_LBP;
public:
int detectMultiScale(const GpuMat& image, GpuMat& objectsBuf, Size maxObjectSize, Size minSize = Size(), double scaleFactor = 1.1, int minNeighbors = 4);
};
////////////////////////////////// SURF //////////////////////////////////////////
class CV_EXPORTS SURF_GPU
{
......
......@@ -49,6 +49,7 @@ using namespace cv::gpu;
void cv::gpu::cvtColor(const GpuMat&, GpuMat&, int, int, Stream&) { throw_nogpu(); }
void cv::gpu::swapChannels(GpuMat&, const int[], Stream&) { throw_nogpu(); }
void cv::gpu::gammaCorrection(const GpuMat&, GpuMat&, bool, Stream&) { throw_nogpu(); }
#else /* !defined (HAVE_CUDA) */
......@@ -1142,6 +1143,116 @@ namespace
funcs[dcn == 4][src.channels() == 4][src.depth()](src, dst, StreamAccessor::getStream(stream));
}
void bgr_to_lab(const GpuMat& src, GpuMat& dst, int dcn, Stream& stream)
{
#if (CUDA_VERSION < 5000)
(void)src;
(void)dst;
(void)dcn;
(void)stream;
CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" );
#else
CV_Assert(src.depth() == CV_8U);
CV_Assert(src.channels() == 3);
dcn = src.channels();
dst.create(src.size(), CV_MAKETYPE(src.depth(), dcn));
NppStreamHandler h(StreamAccessor::getStream(stream));
NppiSize oSizeROI;
oSizeROI.width = src.cols;
oSizeROI.height = src.rows;
nppSafeCall( nppiBGRToLab_8u_C3R(src.ptr<Npp8u>(), static_cast<int>(src.step), dst.ptr<Npp8u>(), static_cast<int>(dst.step), oSizeROI) );
#endif
}
void lab_to_bgr(const GpuMat& src, GpuMat& dst, int dcn, Stream& stream)
{
#if (CUDA_VERSION < 5000)
(void)src;
(void)dst;
(void)dcn;
(void)stream;
CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" );
#else
CV_Assert(src.depth() == CV_8U);
CV_Assert(src.channels() == 3);
dcn = src.channels();
dst.create(src.size(), CV_MAKETYPE(src.depth(), dcn));
NppStreamHandler h(StreamAccessor::getStream(stream));
NppiSize oSizeROI;
oSizeROI.width = src.cols;
oSizeROI.height = src.rows;
nppSafeCall( nppiLabToBGR_8u_C3R(src.ptr<Npp8u>(), static_cast<int>(src.step), dst.ptr<Npp8u>(), static_cast<int>(dst.step), oSizeROI) );
#endif
}
void rgb_to_luv(const GpuMat& src, GpuMat& dst, int dcn, Stream& stream)
{
#if (CUDA_VERSION < 5000)
(void)src;
(void)dst;
(void)dcn;
(void)stream;
CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" );
#else
CV_Assert(src.depth() == CV_8U);
CV_Assert(src.channels() == 3 || src.channels() == 4);
dcn = src.channels();
dst.create(src.size(), CV_MAKETYPE(src.depth(), dcn));
NppStreamHandler h(StreamAccessor::getStream(stream));
NppiSize oSizeROI;
oSizeROI.width = src.cols;
oSizeROI.height = src.rows;
if (dcn == 3)
nppSafeCall( nppiRGBToLUV_8u_C3R(src.ptr<Npp8u>(), static_cast<int>(src.step), dst.ptr<Npp8u>(), static_cast<int>(dst.step), oSizeROI) );
else
nppSafeCall( nppiRGBToLUV_8u_AC4R(src.ptr<Npp8u>(), static_cast<int>(src.step), dst.ptr<Npp8u>(), static_cast<int>(dst.step), oSizeROI) );
#endif
}
void luv_to_rgb(const GpuMat& src, GpuMat& dst, int dcn, Stream& stream)
{
#if (CUDA_VERSION < 5000)
(void)src;
(void)dst;
(void)dcn;
(void)stream;
CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" );
#else
CV_Assert(src.depth() == CV_8U);
CV_Assert(src.channels() == 3 || src.channels() == 4);
dcn = src.channels();
dst.create(src.size(), CV_MAKETYPE(src.depth(), dcn));
NppStreamHandler h(StreamAccessor::getStream(stream));
NppiSize oSizeROI;
oSizeROI.width = src.cols;
oSizeROI.height = src.rows;
if (dcn == 3)
nppSafeCall( nppiLUVToRGB_8u_C3R(src.ptr<Npp8u>(), static_cast<int>(src.step), dst.ptr<Npp8u>(), static_cast<int>(dst.step), oSizeROI) );
else
nppSafeCall( nppiLUVToRGB_8u_AC4R(src.ptr<Npp8u>(), static_cast<int>(src.step), dst.ptr<Npp8u>(), static_cast<int>(dst.step), oSizeROI) );
#endif
}
}
void cv::gpu::cvtColor(const GpuMat& src, GpuMat& dst, int code, int dcn, Stream& stream)
......@@ -1203,7 +1314,7 @@ void cv::gpu::cvtColor(const GpuMat& src, GpuMat& dst, int code, int dcn, Stream
0, // =42
0, // =43
0, // CV_BGR2Lab =44
bgr_to_lab, // CV_BGR2Lab =44
0, // CV_RGB2Lab =45
0, // CV_BayerBG2BGR =46
......@@ -1212,7 +1323,7 @@ void cv::gpu::cvtColor(const GpuMat& src, GpuMat& dst, int code, int dcn, Stream
0, // CV_BayerGR2BGR =49
0, // CV_BGR2Luv =50
0, // CV_RGB2Luv =51
rgb_to_luv, // CV_RGB2Luv =51
bgr_to_hls, // CV_BGR2HLS =52
rgb_to_hls, // CV_RGB2HLS =53
......@@ -1220,10 +1331,10 @@ void cv::gpu::cvtColor(const GpuMat& src, GpuMat& dst, int code, int dcn, Stream
hsv_to_bgr, // CV_HSV2BGR =54
hsv_to_rgb, // CV_HSV2RGB =55
0, // CV_Lab2BGR =56
lab_to_bgr, // CV_Lab2BGR =56
0, // CV_Lab2RGB =57
0, // CV_Luv2BGR =58
0, // CV_Luv2RGB =59
luv_to_rgb, // CV_Luv2RGB =59
hls_to_bgr, // CV_HLS2BGR =60
hls_to_rgb, // CV_HLS2RGB =61
......@@ -1292,4 +1403,45 @@ void cv::gpu::swapChannels(GpuMat& image, const int dstOrder[4], Stream& s)
cudaSafeCall( cudaDeviceSynchronize() );
}
void cv::gpu::gammaCorrection(const GpuMat& src, GpuMat& dst, bool forward, Stream& stream)
{
#if (CUDA_VERSION < 5000)
(void)src;
(void)dst;
(void)forward;
(void)stream;
CV_Error( CV_StsNotImplemented, "This function works only with CUDA 5.0 or higher" );
#else
typedef NppStatus (*func_t)(const Npp8u* pSrc, int nSrcStep, Npp8u* pDst, int nDstStep, NppiSize oSizeROI);
typedef NppStatus (*func_inplace_t)(Npp8u* pSrcDst, int nSrcDstStep, NppiSize oSizeROI);
static const func_t funcs[2][5] =
{
{0, 0, 0, nppiGammaInv_8u_C3R, nppiGammaInv_8u_AC4R},
{0, 0, 0, nppiGammaFwd_8u_C3R, nppiGammaFwd_8u_AC4R}
};
static const func_inplace_t funcs_inplace[2][5] =
{
{0, 0, 0, nppiGammaInv_8u_C3IR, nppiGammaInv_8u_AC4IR},
{0, 0, 0, nppiGammaFwd_8u_C3IR, nppiGammaFwd_8u_AC4IR}
};
CV_Assert(src.type() == CV_8UC3 || src.type() == CV_8UC4);
dst.create(src.size(), src.type());
NppStreamHandler h(StreamAccessor::getStream(stream));
NppiSize oSizeROI;
oSizeROI.width = src.cols;
oSizeROI.height = src.rows;
if (dst.data == src.data)
funcs_inplace[forward][src.channels()](dst.ptr<Npp8u>(), static_cast<int>(src.step), oSizeROI);
else
funcs[forward][src.channels()](src.ptr<Npp8u>(), static_cast<int>(src.step), dst.ptr<Npp8u>(), static_cast<int>(dst.step), oSizeROI);
#endif
}
#endif /* !defined (HAVE_CUDA) */
......@@ -1609,6 +1609,52 @@ TEST_P(CvtColor, RGBA2YUV4)
EXPECT_MAT_NEAR(dst_gold, h_dst, 1e-5);
}
TEST_P(CvtColor, BGR2Lab)
{
if (depth != CV_8U)
return;
try
{
cv::Mat src = readImage("stereobm/aloe-L.png");
cv::gpu::GpuMat dst_lab = createMat(src.size(), src.type(), useRoi);
cv::gpu::cvtColor(loadMat(src, useRoi), dst_lab, cv::COLOR_BGR2Lab);
cv::gpu::GpuMat dst_bgr = createMat(src.size(), src.type(), useRoi);
cv::gpu::cvtColor(dst_lab, dst_bgr, cv::COLOR_Lab2BGR);
EXPECT_MAT_NEAR(src, dst_bgr, 10);
}
catch (const cv::Exception& e)
{
ASSERT_EQ(CV_StsBadFlag, e.code);
}
}
TEST_P(CvtColor, BGR2Luv)
{
if (depth != CV_8U)
return;
try
{
cv::Mat src = img;
cv::gpu::GpuMat dst_luv = createMat(src.size(), src.type(), useRoi);
cv::gpu::cvtColor(loadMat(src, useRoi), dst_luv, cv::COLOR_RGB2Luv);
cv::gpu::GpuMat dst_rgb = createMat(src.size(), src.type(), useRoi);
cv::gpu::cvtColor(dst_luv, dst_rgb, cv::COLOR_Luv2RGB);
EXPECT_MAT_NEAR(src, dst_rgb, 10);
}
catch (const cv::Exception& e)
{
ASSERT_EQ(CV_StsBadFlag, e.code);
}
}
INSTANTIATE_TEST_CASE_P(GPU_ImgProc, CvtColor, testing::Combine(
ALL_DEVICES,
DIFFERENT_SIZES,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册