Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv
Commits
5d95cd75
Commit
5d95cd75
authored
Sep 28, 2010
by
Vladislav Vinogradov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added gpu::cvtColor for RGB <-> YCrCb and RGB <-> YUV
parent
5285722c
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
316 additions
and
286 deletions
+316
-286
color.cu
modules/gpu/src/cuda/color.cu
+232
-219
imgproc_gpu.cpp
modules/gpu/src/imgproc_gpu.cpp
+82
-65
imgproc_gpu.cpp
tests/gpu/src/imgproc_gpu.cpp
+2
-2
No files found.
modules/gpu/src/cuda/color.cu
View file @
5d95cd75
...
@@ -89,90 +89,25 @@ namespace imgproc
...
@@ -89,90 +89,25 @@ namespace imgproc
};
};
template <typename T>
template <typename T>
__device__ void
assign
Alpha(typename TypeVec<T, 3>::vec_t& vec, T val)
__device__ void
set
Alpha(typename TypeVec<T, 3>::vec_t& vec, T val)
{
{
}
}
template <typename T>
template <typename T>
__device__ void
assign
Alpha(typename TypeVec<T, 4>::vec_t& vec, T val)
__device__ void
set
Alpha(typename TypeVec<T, 4>::vec_t& vec, T val)
{
{
vec.w = val;
vec.w = val;
}
}
}
template <typename T>
__device__ T getAlpha(const typename TypeVec<T, 3>::vec_t& vec)
//////////////////////////////////////// SwapChannels /////////////////////////////////////
namespace imgproc
{
__constant__ int ccoeffs[4];
template <int CN, typename T>
__global__ void swapChannels(const uchar* src_, size_t src_step, uchar* dst_, size_t dst_step, int rows, int cols)
{
typedef typename TypeVec<T, CN>::vec_t vec_t;
const int x = blockDim.x * blockIdx.x + threadIdx.x;
const int y = blockDim.y * blockIdx.y + threadIdx.y;
if (y < rows && x < cols)
{
vec_t src = *(const vec_t*)(src_ + y * src_step + x * CN);
vec_t dst;
const T* src_ptr = (const T*)(&src);
T* dst_ptr = (T*)(&dst);
for (int i = 0; i < CN; ++i)
dst_ptr[i] = src_ptr[ccoeffs[i]];
*(vec_t*)(dst_ + y * dst_step + x * CN) = dst;
}
}
}
namespace cv { namespace gpu { namespace improc
{
template <typename T, int CN>
void swapChannels_caller(const DevMem2D& src, const DevMem2D& dst, const int* coeffs, cudaStream_t stream)
{
dim3 threads(32, 8, 1);
dim3 grid(1, 1, 1);
grid.x = divUp(src.cols, threads.x);
grid.y = divUp(src.rows, threads.y);
cudaSafeCall( cudaMemcpyToSymbol(imgproc::ccoeffs, coeffs, CN * sizeof(int)) );
imgproc::swapChannels<CN, T><<<grid, threads, 0, stream>>>(src.ptr, src.step,
dst.ptr, dst.step, src.rows, src.cols);
if (stream == 0)
cudaSafeCall( cudaThreadSynchronize() );
}
void swapChannels_gpu_8u(const DevMem2D& src, const DevMem2D& dst, int cn, const int* coeffs, cudaStream_t stream)
{
{
typedef void (*swapChannels_caller_t)(const DevMem2D& src, const DevMem2D& dst, const int* coeffs, cudaStream_t stream);
return ColorChannel<T>::max();
static const swapChannels_caller_t swapChannels_callers[] = {swapChannels_caller<uchar, 3>, swapChannels_caller<uchar, 4>};
swapChannels_callers[cn - 3](src, dst, coeffs, stream);
}
}
template <typename T>
void swapChannels_gpu_16u(const DevMem2D& src, const DevMem2D& dst, int cn, const int* coeffs, cudaStream_t stream
)
__device__ T getAlpha(const typename TypeVec<T, 4>::vec_t& vec
)
{
{
typedef void (*swapChannels_caller_t)(const DevMem2D& src, const DevMem2D& dst, const int* coeffs, cudaStream_t stream);
return vec.w;
static const swapChannels_caller_t swapChannels_callers[] = {swapChannels_caller<unsigned short, 3>, swapChannels_caller<unsigned short, 4>};
swapChannels_callers[cn - 3](src, dst, coeffs, stream);
}
}
}
void swapChannels_gpu_32f(const DevMem2D& src, const DevMem2D& dst, int cn, const int* coeffs, cudaStream_t stream)
{
typedef void (*swapChannels_caller_t)(const DevMem2D& src, const DevMem2D& dst, const int* coeffs, cudaStream_t stream);
static const swapChannels_caller_t swapChannels_callers[] = {swapChannels_caller<float, 3>, swapChannels_caller<float, 4>};
swapChannels_callers[cn - 3](src, dst, coeffs, stream);
}
}}}
////////////////// Various 3/4-channel to 3/4-channel RGB transformations /////////////////
////////////////// Various 3/4-channel to 3/4-channel RGB transformations /////////////////
...
@@ -195,7 +130,7 @@ namespace imgproc
...
@@ -195,7 +130,7 @@ namespace imgproc
dst.x = ((const T*)(&src))[bidx];
dst.x = ((const T*)(&src))[bidx];
dst.y = src.y;
dst.y = src.y;
dst.z = ((const T*)(&src))[bidx ^ 2];
dst.z = ((const T*)(&src))[bidx ^ 2];
assignAlpha(dst, ColorChannel<T>::max(
));
setAlpha(dst, getAlpha<T>(src
));
*(dst_t*)(dst_ + y * dst_step + x * DSTCN) = dst;
*(dst_t*)(dst_ + y * dst_step + x * DSTCN) = dst;
}
}
...
@@ -274,7 +209,7 @@ namespace imgproc
...
@@ -274,7 +209,7 @@ namespace imgproc
((uchar*)(&dst))[bidx] = (uchar)(src << 3);
((uchar*)(&dst))[bidx] = (uchar)(src << 3);
dst.y = (uchar)((src >> 2) & ~7);
dst.y = (uchar)((src >> 2) & ~7);
((uchar*)(&dst))[bidx ^ 2] = (uchar)((src >> 7) & ~7);
((uchar*)(&dst))[bidx ^ 2] = (uchar)((src >> 7) & ~7);
assign
Alpha(dst, (uchar)(src & 0x8000 ? 255 : 0));
set
Alpha(dst, (uchar)(src & 0x8000 ? 255 : 0));
return dst;
return dst;
}
}
...
@@ -290,7 +225,7 @@ namespace imgproc
...
@@ -290,7 +225,7 @@ namespace imgproc
((uchar*)(&dst))[bidx] = (uchar)(src << 3);
((uchar*)(&dst))[bidx] = (uchar)(src << 3);
dst.y = (uchar)((src >> 3) & ~3);
dst.y = (uchar)((src >> 3) & ~3);
((uchar*)(&dst))[bidx ^ 2] = (uchar)((src >> 8) & ~7);
((uchar*)(&dst))[bidx ^ 2] = (uchar)((src >> 8) & ~7);
assign
Alpha(dst, (uchar)(255));
set
Alpha(dst, (uchar)(255));
return dst;
return dst;
}
}
...
@@ -431,7 +366,7 @@ namespace imgproc
...
@@ -431,7 +366,7 @@ namespace imgproc
dst.x = src;
dst.x = src;
dst.y = src;
dst.y = src;
dst.z = src;
dst.z = src;
assign
Alpha(dst, ColorChannel<T>::max());
set
Alpha(dst, ColorChannel<T>::max());
*(dst_t*)(dst_ + y * dst_step + x * DSTCN) = dst;
*(dst_t*)(dst_ + y * dst_step + x * DSTCN) = dst;
}
}
}
}
...
@@ -563,14 +498,14 @@ namespace imgproc
...
@@ -563,14 +498,14 @@ namespace imgproc
{
{
static __device__ unsigned char cvt(unsigned int t)
static __device__ unsigned char cvt(unsigned int t)
{
{
return (unsigned char)CV_DESCALE(((t << 3) & 0xf8)
*B2Y + ((t >> 3) & 0xfc)*G2Y + ((t >> 8) & 0xf8)*
R2Y, yuv_shift);
return (unsigned char)CV_DESCALE(((t << 3) & 0xf8)
* B2Y + ((t >> 3) & 0xfc) * G2Y + ((t >> 8) & 0xf8) *
R2Y, yuv_shift);
}
}
};
};
template<> struct RGB5x52GrayConverter<5>
template<> struct RGB5x52GrayConverter<5>
{
{
static __device__ unsigned char cvt(unsigned int t)
static __device__ unsigned char cvt(unsigned int t)
{
{
return (unsigned char)CV_DESCALE(((t << 3) & 0xf8)
*B2Y + ((t >> 2) & 0xf8)*G2Y + ((t >> 7) & 0xf8)*
R2Y, yuv_shift);
return (unsigned char)CV_DESCALE(((t << 3) & 0xf8)
* B2Y + ((t >> 2) & 0xf8) * G2Y + ((t >> 7) & 0xf8) *
R2Y, yuv_shift);
}
}
};
};
...
@@ -836,145 +771,223 @@ namespace cv { namespace gpu { namespace improc
...
@@ -836,145 +771,223 @@ namespace cv { namespace gpu { namespace improc
///////////////////////////////////// RGB <-> YCrCb //////////////////////////////////////
///////////////////////////////////// RGB <-> YCrCb //////////////////////////////////////
//namespace imgproc
namespace imgproc
//{
{
// template<typename _Tp> struct RGB2YCrCb_f
__constant__ float cYCrCbCoeffs_f[5];
// {
__constant__ int cYCrCbCoeffs_i[5];
// typedef _Tp channel_type;
//
template <typename T> struct RGB2YCrCbConverter
// RGB2YCrCb_f(int _srccn, int _blueIdx, const float* _coeffs) : srccn(_srccn), blueIdx(_blueIdx)
{
// {
typedef typename TypeVec<T, 3>::vec_t dst_t;
// static const float coeffs0[] = {0.299f, 0.587f, 0.114f, 0.713f, 0.564f};
// memcpy(coeffs, _coeffs ? _coeffs : coeffs0, 5*sizeof(coeffs[0]));
static __device__ void cvt(const T* src, dst_t& dst, int bidx)
// if(blueIdx==0) std::swap(coeffs[0], coeffs[2]);
{
// }
const int delta = ColorChannel<T>::half() * (1 << yuv_shift);
//
// void operator()(const _Tp* src, _Tp* dst, int n) const
const int Y = CV_DESCALE(src[0] * cYCrCbCoeffs_i[0] + src[1] * cYCrCbCoeffs_i[1] + src[2] * cYCrCbCoeffs_i[2], yuv_shift);
// {
const int Cr = CV_DESCALE((src[bidx^2] - Y) * cYCrCbCoeffs_i[3] + delta, yuv_shift);
// int scn = srccn, bidx = blueIdx;
const int Cb = CV_DESCALE((src[bidx] - Y) * cYCrCbCoeffs_i[4] + delta, yuv_shift);
// const _Tp delta = ColorChannel<_Tp>::half();
// float C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], C3 = coeffs[3], C4 = coeffs[4];
dst.x = saturate_cast<T>(Y);
// n *= 3;
dst.y = saturate_cast<T>(Cr);
// for(int i = 0; i < n; i += 3, src += scn)
dst.z = saturate_cast<T>(Cb);
// {
}
// _Tp Y = saturate_cast<_Tp>(src[0]*C0 + src[1]*C1 + src[2]*C2);
};
// _Tp Cr = saturate_cast<_Tp>((src[bidx^2] - Y)*C3 + delta);
// _Tp Cb = saturate_cast<_Tp>((src[bidx] - Y)*C4 + delta);
template<> struct RGB2YCrCbConverter<float>
// dst[i] = Y; dst[i+1] = Cr; dst[i+2] = Cb;
{
// }
typedef typename TypeVec<float, 3>::vec_t dst_t;
// }
// int srccn, blueIdx;
static __device__ void cvt(const float* src, dst_t& dst, int bidx)
// float coeffs[5];
{
// };
dst.x = src[0] * cYCrCbCoeffs_f[0] + src[1] * cYCrCbCoeffs_f[1] + src[2] * cYCrCbCoeffs_f[2];
//
dst.y = (src[bidx^2] - dst.x) * cYCrCbCoeffs_f[3] + ColorChannel<float>::half();
// template<typename _Tp> struct RGB2YCrCb_i
dst.z = (src[bidx] - dst.x) * cYCrCbCoeffs_f[4] + ColorChannel<float>::half();
// {
}
// typedef _Tp channel_type;
};
//
// RGB2YCrCb_i(int _srccn, int _blueIdx, const int* _coeffs)
template <int SRCCN, typename T>
// : srccn(_srccn), blueIdx(_blueIdx)
__global__ void RGB2YCrCb(const uchar* src_, size_t src_step, uchar* dst_, size_t dst_step, int rows, int cols, int bidx)
// {
{
// static const int coeffs0[] = {R2Y, G2Y, B2Y, 11682, 9241};
typedef typename TypeVec<T, SRCCN>::vec_t src_t;
// memcpy(coeffs, _coeffs ? _coeffs : coeffs0, 5*sizeof(coeffs[0]));
typedef typename TypeVec<T, 3>::vec_t dst_t;
// if(blueIdx==0) std::swap(coeffs[0], coeffs[2]);
// }
const int x = blockDim.x * blockIdx.x + threadIdx.x;
// void operator()(const _Tp* src, _Tp* dst, int n) const
const int y = blockDim.y * blockIdx.y + threadIdx.y;
// {
// int scn = srccn, bidx = blueIdx;
if (y < rows && x < cols)
// int C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], C3 = coeffs[3], C4 = coeffs[4];
{
// int delta = ColorChannel<_Tp>::half()*(1 << yuv_shift);
src_t src = *(const src_t*)(src_ + y * src_step + x * SRCCN);
// n *= 3;
dst_t dst;
// for(int i = 0; i < n; i += 3, src += scn)
// {
RGB2YCrCbConverter<T>::cvt(((const T*)(&src)), dst, bidx);
// int Y = CV_DESCALE(src[0]*C0 + src[1]*C1 + src[2]*C2, yuv_shift);
// int Cr = CV_DESCALE((src[bidx^2] - Y)*C3 + delta, yuv_shift);
*(dst_t*)(dst_ + y * dst_step + x * 3) = dst;
// int Cb = CV_DESCALE((src[bidx] - Y)*C4 + delta, yuv_shift);
}
// dst[i] = saturate_cast<_Tp>(Y);
}
// dst[i+1] = saturate_cast<_Tp>(Cr);
// dst[i+2] = saturate_cast<_Tp>(Cb);
template <typename T> struct YCrCb2RGBConvertor
// }
{
// }
typedef typename TypeVec<T, 3>::vec_t src_t;
// int srccn, blueIdx;
// int coeffs[5];
static __device__ void cvt(const src_t& src, T* dst, int bidx)
// };
{
//
const int b = src.x + CV_DESCALE((src.z - ColorChannel<T>::half()) * cYCrCbCoeffs_i[3], yuv_shift);
// template<typename _Tp> struct YCrCb2RGB_f
const int g = src.x + CV_DESCALE((src.z - ColorChannel<T>::half()) * cYCrCbCoeffs_i[2] + (src.y - ColorChannel<T>::half()) * cYCrCbCoeffs_i[1], yuv_shift);
// {
const int r = src.x + CV_DESCALE((src.y - ColorChannel<T>::half()) * cYCrCbCoeffs_i[0], yuv_shift);
// typedef _Tp channel_type;
//
dst[bidx] = saturate_cast<T>(b);
// YCrCb2RGB_f(int _dstcn, int _blueIdx, const float* _coeffs)
dst[1] = saturate_cast<T>(g);
// : dstcn(_dstcn), blueIdx(_blueIdx)
dst[bidx^2] = saturate_cast<T>(r);
// {
}
// static const float coeffs0[] = {1.403f, -0.714f, -0.344f, 1.773f};
};
// memcpy(coeffs, _coeffs ? _coeffs : coeffs0, 4*sizeof(coeffs[0]));
// }
template <> struct YCrCb2RGBConvertor<float>
// void operator()(const _Tp* src, _Tp* dst, int n) const
{
// {
typedef typename TypeVec<float, 3>::vec_t src_t;
// int dcn = dstcn, bidx = blueIdx;
// const _Tp delta = ColorChannel<_Tp>::half(), alpha = ColorChannel<_Tp>::max();
static __device__ void cvt(const src_t& src, float* dst, int bidx)
// float C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], C3 = coeffs[3];
{
// n *= 3;
dst[bidx] = src.x + (src.z - ColorChannel<float>::half()) * cYCrCbCoeffs_f[3];
// for(int i = 0; i < n; i += 3, dst += dcn)
dst[1] = src.x + (src.z - ColorChannel<float>::half()) * cYCrCbCoeffs_f[2] + (src.y - ColorChannel<float>::half()) * cYCrCbCoeffs_f[1];
// {
dst[bidx^2] = src.x + (src.y - ColorChannel<float>::half()) * cYCrCbCoeffs_f[0];
// _Tp Y = src[i];
}
// _Tp Cr = src[i+1];
};
// _Tp Cb = src[i+2];
//
template <int DSTCN, typename T>
// _Tp b = saturate_cast<_Tp>(Y + (Cb - delta)*C3);
__global__ void YCrCb2RGB(const uchar* src_, size_t src_step, uchar* dst_, size_t dst_step, int rows, int cols, int bidx)
// _Tp g = saturate_cast<_Tp>(Y + (Cb - delta)*C2 + (Cr - delta)*C1);
{
// _Tp r = saturate_cast<_Tp>(Y + (Cr - delta)*C0);
typedef typename TypeVec<T, 3>::vec_t src_t;
//
typedef typename TypeVec<T, DSTCN>::vec_t dst_t;
// dst[bidx] = b; dst[1] = g; dst[bidx^2] = r;
// if( dcn == 4 )
const int x = blockDim.x * blockIdx.x + threadIdx.x;
// dst[3] = alpha;
const int y = blockDim.y * blockIdx.y + threadIdx.y;
// }
// }
if (y < rows && x < cols)
// int dstcn, blueIdx;
{
// float coeffs[4];
src_t src = *(const src_t*)(src_ + y * src_step + x * 3);
// };
dst_t dst;
//
// template<typename _Tp> struct YCrCb2RGB_i
YCrCb2RGBConvertor<T>::cvt(src, ((T*)(&dst)), bidx);
// {
setAlpha(dst, ColorChannel<T>::max());
// typedef _Tp channel_type;
//
*(dst_t*)(dst_ + y * dst_step + x * DSTCN) = dst;
// YCrCb2RGB_i(int _dstcn, int _blueIdx, const int* _coeffs)
}
// : dstcn(_dstcn), blueIdx(_blueIdx)
}
// {
}
// static const int coeffs0[] = {22987, -11698, -5636, 29049};
// memcpy(coeffs, _coeffs ? _coeffs : coeffs0, 4*sizeof(coeffs[0]));
namespace cv { namespace gpu { namespace improc
// }
{
//
template <typename T, int SRCCN>
// void operator()(const _Tp* src, _Tp* dst, int n) const
void RGB2YCrCb_caller(const DevMem2D& src, const DevMem2D& dst, int bidx, cudaStream_t stream)
// {
{
// int dcn = dstcn, bidx = blueIdx;
dim3 threads(32, 8, 1);
// const _Tp delta = ColorChannel<_Tp>::half(), alpha = ColorChannel<_Tp>::max();
dim3 grid(1, 1, 1);
// int C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], C3 = coeffs[3];
// n *= 3;
grid.x = divUp(src.cols, threads.x);
// for(int i = 0; i < n; i += 3, dst += dcn)
grid.y = divUp(src.rows, threads.y);
// {
// _Tp Y = src[i];
imgproc::RGB2YCrCb<SRCCN, T><<<grid, threads, 0, stream>>>(src.ptr, src.step,
// _Tp Cr = src[i+1];
dst.ptr, dst.step, src.rows, src.cols, bidx);
// _Tp Cb = src[i+2];
//
if (stream == 0)
// int b = Y + CV_DESCALE((Cb - delta)*C3, yuv_shift);
cudaSafeCall( cudaThreadSynchronize() );
// int g = Y + CV_DESCALE((Cb - delta)*C2 + (Cr - delta)*C1, yuv_shift);
}
// int r = Y + CV_DESCALE((Cr - delta)*C0, yuv_shift);
//
void RGB2YCrCb_gpu_8u(const DevMem2D& src, int srccn, const DevMem2D& dst, int bidx, const int* coeffs, cudaStream_t stream)
// dst[bidx] = saturate_cast<_Tp>(b);
{
// dst[1] = saturate_cast<_Tp>(g);
typedef void (*RGB2YCrCb_caller_t)(const DevMem2D& src, const DevMem2D& dst, int bidx, cudaStream_t stream);
// dst[bidx^2] = saturate_cast<_Tp>(r);
static const RGB2YCrCb_caller_t RGB2YCrCb_callers[2] =
// if( dcn == 4 )
{
// dst[3] = alpha;
RGB2YCrCb_caller<uchar, 3>, RGB2YCrCb_caller<uchar, 4>
// }
};
// }
// int dstcn, blueIdx;
cudaSafeCall( cudaMemcpyToSymbol(imgproc::cYCrCbCoeffs_i, coeffs, 5 * sizeof(int)) );
// int coeffs[4];
// };
RGB2YCrCb_callers[srccn-3](src, dst, bidx, stream);
//}
}
//
//namespace cv { namespace gpu { namespace impl
void RGB2YCrCb_gpu_16u(const DevMem2D& src, int srccn, const DevMem2D& dst, int bidx, const int* coeffs, cudaStream_t stream)
//{
{
//}}}
typedef void (*RGB2YCrCb_caller_t)(const DevMem2D& src, const DevMem2D& dst, int bidx, cudaStream_t stream);
static const RGB2YCrCb_caller_t RGB2YCrCb_callers[2] =
{
RGB2YCrCb_caller<unsigned short, 3>, RGB2YCrCb_caller<unsigned short, 4>
};
cudaSafeCall( cudaMemcpyToSymbol(imgproc::cYCrCbCoeffs_i, coeffs, 5 * sizeof(int)) );
RGB2YCrCb_callers[srccn-3](src, dst, bidx, stream);
}
void RGB2YCrCb_gpu_32f(const DevMem2D& src, int srccn, const DevMem2D& dst, int bidx, const float* coeffs, cudaStream_t stream)
{
typedef void (*RGB2YCrCb_caller_t)(const DevMem2D& src, const DevMem2D& dst, int bidx, cudaStream_t stream);
static const RGB2YCrCb_caller_t RGB2YCrCb_callers[2] =
{
RGB2YCrCb_caller<float, 3>, RGB2YCrCb_caller<float, 4>
};
cudaSafeCall( cudaMemcpyToSymbol(imgproc::cYCrCbCoeffs_f, coeffs, 5 * sizeof(float)) );
RGB2YCrCb_callers[srccn-3](src, dst, bidx, stream);
}
template <typename T, int DSTCN>
void YCrCb2RGB_caller(const DevMem2D& src, const DevMem2D& dst, int bidx, cudaStream_t stream)
{
dim3 threads(32, 8, 1);
dim3 grid(1, 1, 1);
grid.x = divUp(src.cols, threads.x);
grid.y = divUp(src.rows, threads.y);
imgproc::YCrCb2RGB<DSTCN, T><<<grid, threads, 0, stream>>>(src.ptr, src.step,
dst.ptr, dst.step, src.rows, src.cols, bidx);
if (stream == 0)
cudaSafeCall( cudaThreadSynchronize() );
}
void YCrCb2RGB_gpu_8u(const DevMem2D& src, const DevMem2D& dst, int dstcn, int bidx, const int* coeffs, cudaStream_t stream)
{
typedef void (*YCrCb2RGB_caller_t)(const DevMem2D& src, const DevMem2D& dst, int bidx, cudaStream_t stream);
static const YCrCb2RGB_caller_t YCrCb2RGB_callers[2] =
{
YCrCb2RGB_caller<uchar, 3>, YCrCb2RGB_caller<uchar, 4>
};
cudaSafeCall( cudaMemcpyToSymbol(imgproc::cYCrCbCoeffs_i, coeffs, 4 * sizeof(int)) );
YCrCb2RGB_callers[dstcn-3](src, dst, bidx, stream);
}
void YCrCb2RGB_gpu_16u(const DevMem2D& src, const DevMem2D& dst, int dstcn, int bidx, const int* coeffs, cudaStream_t stream)
{
typedef void (*YCrCb2RGB_caller_t)(const DevMem2D& src, const DevMem2D& dst, int bidx, cudaStream_t stream);
static const YCrCb2RGB_caller_t YCrCb2RGB_callers[2] =
{
YCrCb2RGB_caller<unsigned short, 3>, YCrCb2RGB_caller<unsigned short, 4>
};
cudaSafeCall( cudaMemcpyToSymbol(imgproc::cYCrCbCoeffs_i, coeffs, 4 * sizeof(int)) );
YCrCb2RGB_callers[dstcn-3](src, dst, bidx, stream);
}
void YCrCb2RGB_gpu_32f(const DevMem2D& src, const DevMem2D& dst, int dstcn, int bidx, const float* coeffs, cudaStream_t stream)
{
typedef void (*YCrCb2RGB_caller_t)(const DevMem2D& src, const DevMem2D& dst, int bidx, cudaStream_t stream);
static const YCrCb2RGB_caller_t YCrCb2RGB_callers[2] =
{
YCrCb2RGB_caller<float, 3>, YCrCb2RGB_caller<float, 4>
};
cudaSafeCall( cudaMemcpyToSymbol(imgproc::cYCrCbCoeffs_f, coeffs, 4 * sizeof(float)) );
YCrCb2RGB_callers[dstcn-3](src, dst, bidx, stream);
}
}}}
////////////////////////////////////// RGB <-> XYZ ///////////////////////////////////////
////////////////////////////////////// RGB <-> XYZ ///////////////////////////////////////
...
...
modules/gpu/src/imgproc_gpu.cpp
View file @
5d95cd75
...
@@ -81,10 +81,6 @@ namespace cv { namespace gpu
...
@@ -81,10 +81,6 @@ namespace cv { namespace gpu
void
reprojectImageTo3D_gpu
(
const
DevMem2D
&
disp
,
const
DevMem2Df
&
xyzw
,
const
float
*
q
,
const
cudaStream_t
&
stream
);
void
reprojectImageTo3D_gpu
(
const
DevMem2D
&
disp
,
const
DevMem2Df
&
xyzw
,
const
float
*
q
,
const
cudaStream_t
&
stream
);
void
reprojectImageTo3D_gpu
(
const
DevMem2D_
<
short
>&
disp
,
const
DevMem2Df
&
xyzw
,
const
float
*
q
,
const
cudaStream_t
&
stream
);
void
reprojectImageTo3D_gpu
(
const
DevMem2D_
<
short
>&
disp
,
const
DevMem2Df
&
xyzw
,
const
float
*
q
,
const
cudaStream_t
&
stream
);
void
swapChannels_gpu_8u
(
const
DevMem2D
&
src
,
const
DevMem2D
&
dst
,
int
cn
,
const
int
*
coeffs
,
cudaStream_t
stream
);
void
swapChannels_gpu_16u
(
const
DevMem2D
&
src
,
const
DevMem2D
&
dst
,
int
cn
,
const
int
*
coeffs
,
cudaStream_t
stream
);
void
swapChannels_gpu_32f
(
const
DevMem2D
&
src
,
const
DevMem2D
&
dst
,
int
cn
,
const
int
*
coeffs
,
cudaStream_t
stream
);
void
RGB2RGB_gpu_8u
(
const
DevMem2D
&
src
,
int
srccn
,
const
DevMem2D
&
dst
,
int
dstcn
,
int
bidx
,
cudaStream_t
stream
);
void
RGB2RGB_gpu_8u
(
const
DevMem2D
&
src
,
int
srccn
,
const
DevMem2D
&
dst
,
int
dstcn
,
int
bidx
,
cudaStream_t
stream
);
void
RGB2RGB_gpu_16u
(
const
DevMem2D
&
src
,
int
srccn
,
const
DevMem2D
&
dst
,
int
dstcn
,
int
bidx
,
cudaStream_t
stream
);
void
RGB2RGB_gpu_16u
(
const
DevMem2D
&
src
,
int
srccn
,
const
DevMem2D
&
dst
,
int
dstcn
,
int
bidx
,
cudaStream_t
stream
);
void
RGB2RGB_gpu_32f
(
const
DevMem2D
&
src
,
int
srccn
,
const
DevMem2D
&
dst
,
int
dstcn
,
int
bidx
,
cudaStream_t
stream
);
void
RGB2RGB_gpu_32f
(
const
DevMem2D
&
src
,
int
srccn
,
const
DevMem2D
&
dst
,
int
dstcn
,
int
bidx
,
cudaStream_t
stream
);
...
@@ -101,6 +97,14 @@ namespace cv { namespace gpu
...
@@ -101,6 +97,14 @@ namespace cv { namespace gpu
void
RGB2Gray_gpu
(
const
DevMem2D_
<
ushort
>&
src
,
int
srccn
,
const
DevMem2D_
<
ushort
>&
dst
,
int
bidx
,
cudaStream_t
stream
);
void
RGB2Gray_gpu
(
const
DevMem2D_
<
ushort
>&
src
,
int
srccn
,
const
DevMem2D_
<
ushort
>&
dst
,
int
bidx
,
cudaStream_t
stream
);
void
RGB2Gray_gpu
(
const
DevMem2Df
&
src
,
int
srccn
,
const
DevMem2Df
&
dst
,
int
bidx
,
cudaStream_t
stream
);
void
RGB2Gray_gpu
(
const
DevMem2Df
&
src
,
int
srccn
,
const
DevMem2Df
&
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_16u
(
const
DevMem2D
&
src
,
int
srccn
,
const
DevMem2D
&
dst
,
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
YCrCb2RGB_gpu_8u
(
const
DevMem2D
&
src
,
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_32f
(
const
DevMem2D
&
src
,
const
DevMem2D
&
dst
,
int
dstcn
,
int
bidx
,
const
float
*
coeffs
,
cudaStream_t
stream
);
}
}
}}
}}
...
@@ -222,6 +226,23 @@ void cv::gpu::reprojectImageTo3D(const GpuMat& disp, GpuMat& xyzw, const Mat& Q,
...
@@ -222,6 +226,23 @@ void cv::gpu::reprojectImageTo3D(const GpuMat& disp, GpuMat& xyzw, const Mat& Q,
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// cvtColor
// cvtColor
namespace
{
#undef R2Y
#undef G2Y
#undef B2Y
enum
{
yuv_shift
=
14
,
xyz_shift
=
12
,
R2Y
=
4899
,
G2Y
=
9617
,
B2Y
=
1868
,
BLOCK_SIZE
=
256
};
}
namespace
namespace
{
{
void
cvtColor_caller
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
int
code
,
int
dcn
,
const
cudaStream_t
&
stream
)
void
cvtColor_caller
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
int
code
,
int
dcn
,
const
cudaStream_t
&
stream
)
...
@@ -328,74 +349,70 @@ namespace
...
@@ -328,74 +349,70 @@ namespace
improc
::
Gray2RGB5x5_gpu
(
src
,
out
,
code
==
CV_GRAY2BGR565
?
6
:
5
,
stream
);
improc
::
Gray2RGB5x5_gpu
(
src
,
out
,
code
==
CV_GRAY2BGR565
?
6
:
5
,
stream
);
break
;
break
;
case
CV_RGB2YCrCb
:
CV_Assert
(
scn
==
3
&&
depth
==
CV_8U
);
out
.
create
(
sz
,
CV_MAKETYPE
(
depth
,
3
));
nppSafeCall
(
nppiRGBToYCbCr_8u_C3R
(
src
.
ptr
<
Npp8u
>
(),
src
.
step
,
out
.
ptr
<
Npp8u
>
(),
out
.
step
,
nppsz
)
);
case
CV_BGR2YCrCb
:
case
CV_RGB2YCrCb
:
case
CV_BGR2YUV
:
case
CV_RGB2YUV
:
{
{
static
int
coeffs
[]
=
{
0
,
2
,
1
};
CV_Assert
(
scn
==
3
||
scn
==
4
);
improc
::
swapChannels_gpu_8u
(
out
,
out
,
3
,
coeffs
,
0
);
bidx
=
code
==
CV_BGR2YCrCb
||
code
==
CV_RGB2YUV
?
0
:
2
;
static
const
float
yuv_f
[]
=
{
0.114
f
,
0.587
f
,
0.299
f
,
0.492
f
,
0.877
f
};
static
const
int
yuv_i
[]
=
{
B2Y
,
G2Y
,
R2Y
,
8061
,
14369
};
static
const
float
YCrCb_f
[]
=
{
0.299
f
,
0.587
f
,
0.114
f
,
0.713
f
,
0.564
f
};
static
const
int
YCrCb_i
[]
=
{
R2Y
,
G2Y
,
B2Y
,
11682
,
9241
};
float
coeffs_f
[
5
];
int
coeffs_i
[
5
];
::
memcpy
(
coeffs_f
,
code
==
CV_BGR2YCrCb
||
code
==
CV_RGB2YCrCb
?
YCrCb_f
:
yuv_f
,
5
*
sizeof
(
float
));
::
memcpy
(
coeffs_i
,
code
==
CV_BGR2YCrCb
||
code
==
CV_RGB2YCrCb
?
YCrCb_i
:
yuv_i
,
5
*
sizeof
(
int
));
if
(
bidx
==
0
)
{
std
::
swap
(
coeffs_f
[
0
],
coeffs_f
[
2
]);
std
::
swap
(
coeffs_i
[
0
],
coeffs_i
[
2
]);
}
out
.
create
(
sz
,
CV_MAKETYPE
(
depth
,
3
));
if
(
depth
==
CV_8U
)
improc
::
RGB2YCrCb_gpu_8u
(
src
,
scn
,
out
,
bidx
,
coeffs_i
,
stream
);
else
if
(
depth
==
CV_16U
)
improc
::
RGB2YCrCb_gpu_16u
(
src
,
scn
,
out
,
bidx
,
coeffs_i
,
stream
);
else
improc
::
RGB2YCrCb_gpu_32f
(
src
,
scn
,
out
,
bidx
,
coeffs_f
,
stream
);
}
}
break
;
break
;
case
CV_YCrCb2RGB
:
CV_Assert
(
scn
==
3
&&
depth
==
CV_8U
);
out
.
create
(
sz
,
CV_MAKETYPE
(
depth
,
3
));
case
CV_YCrCb2BGR
:
case
CV_YCrCb2RGB
:
case
CV_YUV2BGR
:
case
CV_YUV2RGB
:
{
{
static
int
coeffs
[]
=
{
0
,
2
,
1
};
if
(
dcn
<=
0
)
dcn
=
3
;
GpuMat
src1
(
src
.
size
(),
src
.
type
());
improc
::
swapChannels_gpu_8u
(
src
,
src1
,
3
,
coeffs
,
0
);
nppSafeCall
(
nppiYCbCrToRGB_8u_C3R
(
src1
.
ptr
<
Npp8u
>
(),
src1
.
step
,
out
.
ptr
<
Npp8u
>
(),
out
.
step
,
nppsz
)
);
}
break
;
//case CV_BGR2YCrCb: case CV_RGB2YCrCb:
CV_Assert
(
scn
==
3
&&
(
dcn
==
3
||
dcn
==
4
)
);
//case CV_BGR2YUV: case CV_RGB2YUV:
// {
bidx
=
code
==
CV_YCrCb2BGR
||
code
==
CV_YUV2RGB
?
0
:
2
;
// CV_Assert( scn == 3 || scn == 4 );
// bidx = code == CV_BGR2YCrCb || code == CV_RGB2YUV ? 0 : 2;
static
const
float
yuv_f
[]
=
{
2.032
f
,
-
0.395
f
,
-
0.581
f
,
1.140
f
};
// static const float yuv_f[] = { 0.114f, 0.587f, 0.299f, 0.492f, 0.877f };
static
const
int
yuv_i
[]
=
{
33292
,
-
6472
,
-
9519
,
18678
};
// static const int yuv_i[] = { B2Y, G2Y, R2Y, 8061, 14369 };
// const float* coeffs_f = code == CV_BGR2YCrCb || code == CV_RGB2YCrCb ? 0 : yuv_f;
static
const
float
YCrCb_f
[]
=
{
1.403
f
,
-
0.714
f
,
-
0.344
f
,
1.773
f
};
// const int* coeffs_i = code == CV_BGR2YCrCb || code == CV_RGB2YCrCb ? 0 : yuv_i;
static
const
int
YCrCb_i
[]
=
{
22987
,
-
11698
,
-
5636
,
29049
};
//
// dst.create(sz, CV_MAKETYPE(depth, 3));
const
float
*
coeffs_f
=
code
==
CV_YCrCb2BGR
||
code
==
CV_YCrCb2RGB
?
YCrCb_f
:
yuv_f
;
//
const
int
*
coeffs_i
=
code
==
CV_YCrCb2BGR
||
code
==
CV_YCrCb2RGB
?
YCrCb_i
:
yuv_i
;
// if( depth == CV_8U )
// CvtColorLoop(src, dst, RGB2YCrCb_i<uchar>(scn, bidx, coeffs_i));
out
.
create
(
sz
,
CV_MAKETYPE
(
depth
,
dcn
));
// else if( depth == CV_16U )
// CvtColorLoop(src, dst, RGB2YCrCb_i<ushort>(scn, bidx, coeffs_i));
if
(
depth
==
CV_8U
)
// else
improc
::
YCrCb2RGB_gpu_8u
(
src
,
out
,
dcn
,
bidx
,
coeffs_i
,
stream
);
// CvtColorLoop(src, dst, RGB2YCrCb_f<float>(scn, bidx, coeffs_f));
else
if
(
depth
==
CV_16U
)
// }
improc
::
YCrCb2RGB_gpu_16u
(
src
,
out
,
dcn
,
bidx
,
coeffs_i
,
stream
);
// break;
else
improc
::
YCrCb2RGB_gpu_32f
(
src
,
out
,
dcn
,
bidx
,
coeffs_f
,
stream
);
//case CV_YCrCb2BGR: case CV_YCrCb2RGB:
}
//case CV_YUV2BGR: case CV_YUV2RGB:
break
;
// {
// if( dcn <= 0 ) dcn = 3;
// CV_Assert( scn == 3 && (dcn == 3 || dcn == 4) );
// bidx = code == CV_YCrCb2BGR || code == CV_YUV2RGB ? 0 : 2;
// static const float yuv_f[] = { 2.032f, -0.395f, -0.581f, 1.140f };
// static const int yuv_i[] = { 33292, -6472, -9519, 18678 };
// const float* coeffs_f = code == CV_YCrCb2BGR || code == CV_YCrCb2RGB ? 0 : yuv_f;
// const int* coeffs_i = code == CV_YCrCb2BGR || code == CV_YCrCb2RGB ? 0 : yuv_i;
//
// dst.create(sz, CV_MAKETYPE(depth, dcn));
//
// if( depth == CV_8U )
// CvtColorLoop(src, dst, YCrCb2RGB_i<uchar>(dcn, bidx, coeffs_i));
// else if( depth == CV_16U )
// CvtColorLoop(src, dst, YCrCb2RGB_i<ushort>(dcn, bidx, coeffs_i));
// else
// CvtColorLoop(src, dst, YCrCb2RGB_f<float>(dcn, bidx, coeffs_f));
// }
// break;
//case CV_BGR2XYZ: case CV_RGB2XYZ:
//case CV_BGR2XYZ: case CV_RGB2XYZ:
// CV_Assert( scn == 3 || scn == 4 );
// CV_Assert( scn == 3 || scn == 4 );
...
...
tests/gpu/src/imgproc_gpu.cpp
View file @
5d95cd75
...
@@ -500,12 +500,12 @@ void CV_GpuCvtColorTest::run( int )
...
@@ -500,12 +500,12 @@ void CV_GpuCvtColorTest::run( int )
//run tests
//run tests
int
codes
[]
=
{
CV_BGR2RGB
,
CV_RGB2BGRA
,
CV_BGRA2RGB
,
int
codes
[]
=
{
CV_BGR2RGB
,
CV_RGB2BGRA
,
CV_BGRA2RGB
,
CV_RGB2BGR555
,
CV_BGR5552BGR
,
CV_BGR2BGR565
,
CV_BGR5652RGB
,
CV_RGB2BGR555
,
CV_BGR5552BGR
,
CV_BGR2BGR565
,
CV_BGR5652RGB
,
/* CV_RGB2YCrCb, CV_YCrCb2RGB,*/
CV_RGB2YCrCb
,
CV_YCrCb2BGR
,
CV_BGR2YUV
,
CV_YUV2RGB
,
CV_RGB2GRAY
,
CV_GRAY2BGRA
,
CV_BGRA2GRAY
,
CV_RGB2GRAY
,
CV_GRAY2BGRA
,
CV_BGRA2GRAY
,
CV_GRAY2BGR555
,
CV_BGR5552GRAY
,
CV_GRAY2BGR565
,
CV_BGR5652GRAY
};
CV_GRAY2BGR555
,
CV_BGR5552GRAY
,
CV_GRAY2BGR565
,
CV_BGR5652GRAY
};
const
char
*
codes_str
[]
=
{
"CV_BGR2RGB"
,
"CV_RGB2BGRA"
,
"CV_BGRA2RGB"
,
const
char
*
codes_str
[]
=
{
"CV_BGR2RGB"
,
"CV_RGB2BGRA"
,
"CV_BGRA2RGB"
,
"CV_RGB2BGR555"
,
"CV_BGR5552BGR"
,
"CV_BGR2BGR565"
,
"CV_BGR5652RGB"
,
"CV_RGB2BGR555"
,
"CV_BGR5552BGR"
,
"CV_BGR2BGR565"
,
"CV_BGR5652RGB"
,
/* "CV_RGB2YCrCb", "CV_YCrCb2RGB",*/
"CV_RGB2YCrCb"
,
"CV_YCrCb2BGR"
,
"CV_BGR2YUV"
,
"CV_YUV2RGB"
,
"CV_RGB2GRAY"
,
"CV_GRAY2BGRA"
,
"CV_BGRA2GRAY"
,
"CV_RGB2GRAY"
,
"CV_GRAY2BGRA"
,
"CV_BGRA2GRAY"
,
"CV_GRAY2BGR555"
,
"CV_BGR5552GRAY"
,
"CV_GRAY2BGR565"
,
"CV_BGR5652GRAY"
};
"CV_GRAY2BGR555"
,
"CV_BGR5552GRAY"
,
"CV_GRAY2BGR565"
,
"CV_BGR5652GRAY"
};
int
codes_num
=
sizeof
(
codes
)
/
sizeof
(
int
);
int
codes_num
=
sizeof
(
codes
)
/
sizeof
(
int
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment