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
};
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>
__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;
}
}
//////////////////////////////////////// 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)
template <typename T>
__device__ T getAlpha(const typename TypeVec<T, 3>::vec_t& vec)
{
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<uchar, 3>, swapChannels_caller<uchar, 4>};
swapChannels_callers[cn - 3](src, dst, coeffs, stream);
return ColorChannel<T>::max();
}
void swapChannels_gpu_16u(const DevMem2D& src, const DevMem2D& dst, int cn, const int* coeffs, cudaStream_t stream
)
template <typename T>
__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);
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);
return vec.w;
}
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 /////////////////
...
...
@@ -195,7 +130,7 @@ namespace imgproc
dst.x = ((const T*)(&src))[bidx];
dst.y = src.y;
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;
}
...
...
@@ -274,7 +209,7 @@ namespace imgproc
((uchar*)(&dst))[bidx] = (uchar)(src << 3);
dst.y = (uchar)((src >> 2) & ~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;
}
...
...
@@ -290,7 +225,7 @@ namespace imgproc
((uchar*)(&dst))[bidx] = (uchar)(src << 3);
dst.y = (uchar)((src >> 3) & ~3);
((uchar*)(&dst))[bidx ^ 2] = (uchar)((src >> 8) & ~7);
assign
Alpha(dst, (uchar)(255));
set
Alpha(dst, (uchar)(255));
return dst;
}
...
...
@@ -431,7 +366,7 @@ namespace imgproc
dst.x = src;
dst.y = 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;
}
}
...
...
@@ -563,14 +498,14 @@ namespace imgproc
{
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>
{
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
///////////////////////////////////// RGB <-> YCrCb //////////////////////////////////////
//namespace imgproc
//{
// template<typename _Tp> struct RGB2YCrCb_f
// {
// typedef _Tp channel_type;
//
// RGB2YCrCb_f(int _srccn, int _blueIdx, const float* _coeffs) : srccn(_srccn), blueIdx(_blueIdx)
// {
// static const float coeffs0[] = {0.299f, 0.587f, 0.114f, 0.713f, 0.564f};
// memcpy(coeffs, _coeffs ? _coeffs : coeffs0, 5*sizeof(coeffs[0]));
// if(blueIdx==0) std::swap(coeffs[0], coeffs[2]);
// }
//
// void operator()(const _Tp* src, _Tp* dst, int n) const
// {
// int scn = srccn, bidx = blueIdx;
// const _Tp delta = ColorChannel<_Tp>::half();
// float C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], C3 = coeffs[3], C4 = coeffs[4];
// n *= 3;
// for(int i = 0; i < n; i += 3, src += scn)
// {
// _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);
// dst[i] = Y; dst[i+1] = Cr; dst[i+2] = Cb;
// }
// }
// int srccn, blueIdx;
// float coeffs[5];
// };
//
// template<typename _Tp> struct RGB2YCrCb_i
// {
// typedef _Tp channel_type;
//
// RGB2YCrCb_i(int _srccn, int _blueIdx, const int* _coeffs)
// : srccn(_srccn), blueIdx(_blueIdx)
// {
// static const int coeffs0[] = {R2Y, G2Y, B2Y, 11682, 9241};
// memcpy(coeffs, _coeffs ? _coeffs : coeffs0, 5*sizeof(coeffs[0]));
// if(blueIdx==0) std::swap(coeffs[0], coeffs[2]);
// }
// void operator()(const _Tp* src, _Tp* dst, int n) const
// {
// int scn = srccn, bidx = blueIdx;
// int C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], C3 = coeffs[3], C4 = coeffs[4];
// int delta = ColorChannel<_Tp>::half()*(1 << yuv_shift);
// n *= 3;
// for(int i = 0; i < n; i += 3, src += scn)
// {
// 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);
// 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);
// }
// }
// int srccn, blueIdx;
// int coeffs[5];
// };
//
// template<typename _Tp> struct YCrCb2RGB_f
// {
// typedef _Tp channel_type;
//
// YCrCb2RGB_f(int _dstcn, int _blueIdx, const float* _coeffs)
// : dstcn(_dstcn), blueIdx(_blueIdx)
// {
// static const float coeffs0[] = {1.403f, -0.714f, -0.344f, 1.773f};
// memcpy(coeffs, _coeffs ? _coeffs : coeffs0, 4*sizeof(coeffs[0]));
// }
// void operator()(const _Tp* src, _Tp* dst, int n) const
// {
// int dcn = dstcn, bidx = blueIdx;
// const _Tp delta = ColorChannel<_Tp>::half(), alpha = ColorChannel<_Tp>::max();
// float C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], C3 = coeffs[3];
// n *= 3;
// for(int i = 0; i < n; i += 3, dst += dcn)
// {
// _Tp Y = src[i];
// _Tp Cr = src[i+1];
// _Tp Cb = src[i+2];
//
// _Tp b = saturate_cast<_Tp>(Y + (Cb - delta)*C3);
// _Tp g = saturate_cast<_Tp>(Y + (Cb - delta)*C2 + (Cr - delta)*C1);
// _Tp r = saturate_cast<_Tp>(Y + (Cr - delta)*C0);
//
// dst[bidx] = b; dst[1] = g; dst[bidx^2] = r;
// if( dcn == 4 )
// dst[3] = alpha;
// }
// }
// int dstcn, blueIdx;
// float coeffs[4];
// };
//
// template<typename _Tp> struct YCrCb2RGB_i
// {
// typedef _Tp channel_type;
//
// 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]));
// }
//
// void operator()(const _Tp* src, _Tp* dst, int n) const
// {
// int dcn = dstcn, bidx = blueIdx;
// const _Tp delta = ColorChannel<_Tp>::half(), alpha = ColorChannel<_Tp>::max();
// int C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], C3 = coeffs[3];
// n *= 3;
// for(int i = 0; i < n; i += 3, dst += dcn)
// {
// _Tp Y = src[i];
// _Tp Cr = src[i+1];
// _Tp Cb = src[i+2];
//
// int b = Y + CV_DESCALE((Cb - delta)*C3, yuv_shift);
// int g = Y + CV_DESCALE((Cb - delta)*C2 + (Cr - delta)*C1, yuv_shift);
// int r = Y + CV_DESCALE((Cr - delta)*C0, yuv_shift);
//
// dst[bidx] = saturate_cast<_Tp>(b);
// dst[1] = saturate_cast<_Tp>(g);
// dst[bidx^2] = saturate_cast<_Tp>(r);
// if( dcn == 4 )
// dst[3] = alpha;
// }
// }
// int dstcn, blueIdx;
// int coeffs[4];
// };
//}
//
//namespace cv { namespace gpu { namespace impl
//{
//}}}
namespace imgproc
{
__constant__ float cYCrCbCoeffs_f[5];
__constant__ int cYCrCbCoeffs_i[5];
template <typename T> struct RGB2YCrCbConverter
{
typedef typename TypeVec<T, 3>::vec_t dst_t;
static __device__ void cvt(const T* src, dst_t& dst, int bidx)
{
const int delta = ColorChannel<T>::half() * (1 << yuv_shift);
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);
const int Cb = CV_DESCALE((src[bidx] - Y) * cYCrCbCoeffs_i[4] + delta, yuv_shift);
dst.x = saturate_cast<T>(Y);
dst.y = saturate_cast<T>(Cr);
dst.z = saturate_cast<T>(Cb);
}
};
template<> struct RGB2YCrCbConverter<float>
{
typedef typename TypeVec<float, 3>::vec_t dst_t;
static __device__ void cvt(const float* src, dst_t& dst, int bidx)
{
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();
dst.z = (src[bidx] - dst.x) * cYCrCbCoeffs_f[4] + ColorChannel<float>::half();
}
};
template <int SRCCN, typename T>
__global__ void RGB2YCrCb(const uchar* src_, size_t src_step, uchar* dst_, size_t dst_step, int rows, int cols, int bidx)
{
typedef typename TypeVec<T, SRCCN>::vec_t src_t;
typedef typename TypeVec<T, 3>::vec_t dst_t;
const int x = blockDim.x * blockIdx.x + threadIdx.x;
const int y = blockDim.y * blockIdx.y + threadIdx.y;
if (y < rows && x < cols)
{
src_t src = *(const src_t*)(src_ + y * src_step + x * SRCCN);
dst_t dst;
RGB2YCrCbConverter<T>::cvt(((const T*)(&src)), dst, bidx);
*(dst_t*)(dst_ + y * dst_step + x * 3) = dst;
}
}
template <typename T> struct YCrCb2RGBConvertor
{
typedef typename TypeVec<T, 3>::vec_t src_t;
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);
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);
dst[bidx] = saturate_cast<T>(b);
dst[1] = saturate_cast<T>(g);
dst[bidx^2] = saturate_cast<T>(r);
}
};
template <> struct YCrCb2RGBConvertor<float>
{
typedef typename TypeVec<float, 3>::vec_t src_t;
static __device__ void cvt(const src_t& src, float* dst, int bidx)
{
dst[bidx] = src.x + (src.z - ColorChannel<float>::half()) * cYCrCbCoeffs_f[3];
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];
}
};
template <int DSTCN, typename T>
__global__ void YCrCb2RGB(const uchar* src_, size_t src_step, uchar* dst_, size_t dst_step, int rows, int cols, int bidx)
{
typedef typename TypeVec<T, 3>::vec_t src_t;
typedef typename TypeVec<T, DSTCN>::vec_t dst_t;
const int x = blockDim.x * blockIdx.x + threadIdx.x;
const int y = blockDim.y * blockIdx.y + threadIdx.y;
if (y < rows && x < cols)
{
src_t src = *(const src_t*)(src_ + y * src_step + x * 3);
dst_t dst;
YCrCb2RGBConvertor<T>::cvt(src, ((T*)(&dst)), bidx);
setAlpha(dst, ColorChannel<T>::max());
*(dst_t*)(dst_ + y * dst_step + x * DSTCN) = dst;
}
}
}
namespace cv { namespace gpu { namespace improc
{
template <typename T, int SRCCN>
void RGB2YCrCb_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::RGB2YCrCb<SRCCN, T><<<grid, threads, 0, stream>>>(src.ptr, src.step,
dst.ptr, dst.step, src.rows, src.cols, bidx);
if (stream == 0)
cudaSafeCall( cudaThreadSynchronize() );
}
void RGB2YCrCb_gpu_8u(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<uchar, 3>, RGB2YCrCb_caller<uchar, 4>
};
cudaSafeCall( cudaMemcpyToSymbol(imgproc::cYCrCbCoeffs_i, coeffs, 5 * sizeof(int)) );
RGB2YCrCb_callers[srccn-3](src, dst, bidx, stream);
}
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 ///////////////////////////////////////
...
...
modules/gpu/src/imgproc_gpu.cpp
View file @
5d95cd75
...
...
@@ -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_
<
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_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
);
...
...
@@ -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
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
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,
////////////////////////////////////////////////////////////////////////
// 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
{
void
cvtColor_caller
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
int
code
,
int
dcn
,
const
cudaStream_t
&
stream
)
...
...
@@ -328,74 +349,70 @@ namespace
improc
::
Gray2RGB5x5_gpu
(
src
,
out
,
code
==
CV_GRAY2BGR565
?
6
:
5
,
stream
);
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
};
improc
::
swapChannels_gpu_8u
(
out
,
out
,
3
,
coeffs
,
0
);
CV_Assert
(
scn
==
3
||
scn
==
4
);
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
;
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
};
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
;
if
(
dcn
<=
0
)
dcn
=
3
;
//case CV_BGR2YCrCb: case CV_RGB2YCrCb:
//case CV_BGR2YUV: case CV_RGB2YUV:
// {
// CV_Assert( scn == 3 || scn == 4 );
// bidx = code == CV_BGR2YCrCb || code == CV_RGB2YUV ? 0 : 2;
// static const float yuv_f[] = { 0.114f, 0.587f, 0.299f, 0.492f, 0.877f };
// static const int yuv_i[] = { B2Y, G2Y, R2Y, 8061, 14369 };
// const float* coeffs_f = code == CV_BGR2YCrCb || code == CV_RGB2YCrCb ? 0 : yuv_f;
// const int* coeffs_i = code == CV_BGR2YCrCb || code == CV_RGB2YCrCb ? 0 : yuv_i;
//
// dst.create(sz, CV_MAKETYPE(depth, 3));
//
// if( depth == CV_8U )
// CvtColorLoop(src, dst, RGB2YCrCb_i<uchar>(scn, bidx, coeffs_i));
// else if( depth == CV_16U )
// CvtColorLoop(src, dst, RGB2YCrCb_i<ushort>(scn, bidx, coeffs_i));
// else
// CvtColorLoop(src, dst, RGB2YCrCb_f<float>(scn, bidx, coeffs_f));
// }
// break;
//case CV_YCrCb2BGR: case CV_YCrCb2RGB:
//case CV_YUV2BGR: case CV_YUV2RGB:
// {
// 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;
CV_Assert
(
scn
==
3
&&
(
dcn
==
3
||
dcn
==
4
)
);
bidx
=
code
==
CV_YCrCb2BGR
||
code
==
CV_YUV2RGB
?
0
:
2
;
static
const
float
yuv_f
[]
=
{
2.032
f
,
-
0.395
f
,
-
0.581
f
,
1.140
f
};
static
const
int
yuv_i
[]
=
{
33292
,
-
6472
,
-
9519
,
18678
};
static
const
float
YCrCb_f
[]
=
{
1.403
f
,
-
0.714
f
,
-
0.344
f
,
1.773
f
};
static
const
int
YCrCb_i
[]
=
{
22987
,
-
11698
,
-
5636
,
29049
};
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
;
out
.
create
(
sz
,
CV_MAKETYPE
(
depth
,
dcn
));
if
(
depth
==
CV_8U
)
improc
::
YCrCb2RGB_gpu_8u
(
src
,
out
,
dcn
,
bidx
,
coeffs_i
,
stream
);
else
if
(
depth
==
CV_16U
)
improc
::
YCrCb2RGB_gpu_16u
(
src
,
out
,
dcn
,
bidx
,
coeffs_i
,
stream
);
else
improc
::
YCrCb2RGB_gpu_32f
(
src
,
out
,
dcn
,
bidx
,
coeffs_f
,
stream
);
}
break
;
//case CV_BGR2XYZ: case CV_RGB2XYZ:
// CV_Assert( scn == 3 || scn == 4 );
...
...
tests/gpu/src/imgproc_gpu.cpp
View file @
5d95cd75
...
...
@@ -500,12 +500,12 @@ void CV_GpuCvtColorTest::run( int )
//run tests
int
codes
[]
=
{
CV_BGR2RGB
,
CV_RGB2BGRA
,
CV_BGRA2RGB
,
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_GRAY2BGR555
,
CV_BGR5552GRAY
,
CV_GRAY2BGR565
,
CV_BGR5652GRAY
};
const
char
*
codes_str
[]
=
{
"CV_BGR2RGB"
,
"CV_RGB2BGRA"
,
"CV_BGRA2RGB"
,
"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_GRAY2BGR555"
,
"CV_BGR5552GRAY"
,
"CV_GRAY2BGR565"
,
"CV_BGR5652GRAY"
};
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