|
|
@ -1594,8 +1594,11 @@ struct RGB2Lab_b |
|
|
|
static volatile int _3 = 3; |
|
|
|
static volatile int _3 = 3; |
|
|
|
initLabTabs(); |
|
|
|
initLabTabs(); |
|
|
|
|
|
|
|
|
|
|
|
if(!_coeffs) _coeffs = sRGB2XYZ_D65; |
|
|
|
if (!_coeffs) |
|
|
|
if(!_whitept) _whitept = D65; |
|
|
|
_coeffs = sRGB2XYZ_D65; |
|
|
|
|
|
|
|
if (!_whitept) |
|
|
|
|
|
|
|
_whitept = D65; |
|
|
|
|
|
|
|
|
|
|
|
float scale[] = |
|
|
|
float scale[] = |
|
|
|
{ |
|
|
|
{ |
|
|
|
(1 << lab_shift)/_whitept[0], |
|
|
|
(1 << lab_shift)/_whitept[0], |
|
|
@ -1699,10 +1702,6 @@ struct RGB2Lab_f |
|
|
|
float G = clip(src[1]); |
|
|
|
float G = clip(src[1]); |
|
|
|
float B = clip(src[2]); |
|
|
|
float B = clip(src[2]); |
|
|
|
|
|
|
|
|
|
|
|
// CV_Assert(R >= 0.0f && R <= 1.0f);
|
|
|
|
|
|
|
|
// CV_Assert(G >= 0.0f && G <= 1.0f);
|
|
|
|
|
|
|
|
// CV_Assert(B >= 0.0f && B <= 1.0f);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (gammaTab) |
|
|
|
if (gammaTab) |
|
|
|
{ |
|
|
|
{ |
|
|
|
R = splineInterpolate(R * gscale, gammaTab, GAMMA_TAB_SIZE); |
|
|
|
R = splineInterpolate(R * gscale, gammaTab, GAMMA_TAB_SIZE); |
|
|
@ -1738,7 +1737,7 @@ struct Lab2RGB_f |
|
|
|
|
|
|
|
|
|
|
|
Lab2RGB_f( int _dstcn, int blueIdx, const float* _coeffs, |
|
|
|
Lab2RGB_f( int _dstcn, int blueIdx, const float* _coeffs, |
|
|
|
const float* _whitept, bool _srgb ) |
|
|
|
const float* _whitept, bool _srgb ) |
|
|
|
: dstcn(_dstcn), srgb(_srgb), blueInd(blueIdx) |
|
|
|
: dstcn(_dstcn), srgb(_srgb) |
|
|
|
{ |
|
|
|
{ |
|
|
|
initLabTabs(); |
|
|
|
initLabTabs(); |
|
|
|
|
|
|
|
|
|
|
@ -1796,13 +1795,12 @@ struct Lab2RGB_f |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
float x = fxz[0], z = fxz[1]; |
|
|
|
float x = fxz[0], z = fxz[1]; |
|
|
|
float ro = clip(C0 * x + C1 * y + C2 * z); |
|
|
|
float ro = C0 * x + C1 * y + C2 * z; |
|
|
|
float go = clip(C3 * x + C4 * y + C5 * z); |
|
|
|
float go = C3 * x + C4 * y + C5 * z; |
|
|
|
float bo = clip(C6 * x + C7 * y + C8 * z); |
|
|
|
float bo = C6 * x + C7 * y + C8 * z; |
|
|
|
|
|
|
|
ro = clip(ro); |
|
|
|
// CV_Assert(ro >= 0.0f && ro <= 1.0f);
|
|
|
|
go = clip(go); |
|
|
|
// CV_Assert(go >= 0.0f && go <= 1.0f);
|
|
|
|
bo = clip(bo); |
|
|
|
// CV_Assert(bo >= 0.0f && bo <= 1.0f);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (gammaTab) |
|
|
|
if (gammaTab) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -1820,7 +1818,6 @@ struct Lab2RGB_f |
|
|
|
int dstcn; |
|
|
|
int dstcn; |
|
|
|
float coeffs[9]; |
|
|
|
float coeffs[9]; |
|
|
|
bool srgb; |
|
|
|
bool srgb; |
|
|
|
int blueInd; |
|
|
|
|
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
#undef clip |
|
|
|
#undef clip |
|
|
@ -2700,7 +2697,7 @@ static bool ocl_cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) |
|
|
|
size_t globalsize[] = { src.cols, src.rows }; |
|
|
|
size_t globalsize[] = { src.cols, src.rows }; |
|
|
|
ocl::Kernel k; |
|
|
|
ocl::Kernel k; |
|
|
|
|
|
|
|
|
|
|
|
if(depth != CV_8U && depth != CV_16U && depth != CV_32F) |
|
|
|
if (depth != CV_8U && depth != CV_16U && depth != CV_32F) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
switch (code) |
|
|
|
switch (code) |
|
|
@ -3028,8 +3025,162 @@ static bool ocl_cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) |
|
|
|
format("-D depth=%d -D dcn=4 -D scn=4 -D bidx=3", depth)); |
|
|
|
format("-D depth=%d -D dcn=4 -D scn=4 -D bidx=3", depth)); |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
case CV_BGR2Lab: case CV_RGB2Lab: case CV_LBGR2Lab: case CV_LRGB2Lab: |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
CV_Assert( (scn == 3 || scn == 4) && (depth == CV_8U || depth == CV_32F) ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bidx = code == CV_BGR2Lab || code == CV_LBGR2Lab ? 0 : 2; |
|
|
|
|
|
|
|
bool srgb = code == CV_BGR2Lab || code == CV_RGB2Lab; |
|
|
|
|
|
|
|
dcn = 3; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
k.create("BGR2Lab", ocl::imgproc::cvtcolor_oclsrc, |
|
|
|
|
|
|
|
format("-D depth=%d -D dcn=3 -D scn=%d -D bidx=%d%s", |
|
|
|
|
|
|
|
depth, scn, bidx, srgb ? " -D SRGB" : "")); |
|
|
|
|
|
|
|
if (k.empty()) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
initLabTabs(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_dst.create(dstSz, CV_MAKETYPE(depth, dcn)); |
|
|
|
|
|
|
|
dst = _dst.getUMat(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ocl::KernelArg srcarg = ocl::KernelArg::ReadOnlyNoSize(src), |
|
|
|
|
|
|
|
dstarg = ocl::KernelArg::WriteOnly(dst); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (depth == CV_8U) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
static UMat usRGBGammaTab, ulinearGammaTab, uLabCbrtTab, ucoeffs; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (srgb && usRGBGammaTab.empty()) |
|
|
|
|
|
|
|
Mat(1, 256, CV_16UC1, sRGBGammaTab_b).copyTo(usRGBGammaTab); |
|
|
|
|
|
|
|
else if (ulinearGammaTab.empty()) |
|
|
|
|
|
|
|
Mat(1, 256, CV_16UC1, linearGammaTab_b).copyTo(ulinearGammaTab); |
|
|
|
|
|
|
|
if (uLabCbrtTab.empty()) |
|
|
|
|
|
|
|
Mat(1, LAB_CBRT_TAB_SIZE_B, CV_16UC1, LabCbrtTab_b).copyTo(uLabCbrtTab); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
int coeffs[9]; |
|
|
|
|
|
|
|
const float * const _coeffs = sRGB2XYZ_D65, * const _whitept = D65; |
|
|
|
|
|
|
|
const float scale[] = |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
(1 << lab_shift)/_whitept[0], |
|
|
|
|
|
|
|
(float)(1 << lab_shift), |
|
|
|
|
|
|
|
(1 << lab_shift)/_whitept[2] |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 3; i++ ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
coeffs[i*3+(bidx^2)] = cvRound(_coeffs[i*3]*scale[i]); |
|
|
|
|
|
|
|
coeffs[i*3+1] = cvRound(_coeffs[i*3+1]*scale[i]); |
|
|
|
|
|
|
|
coeffs[i*3+bidx] = cvRound(_coeffs[i*3+2]*scale[i]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CV_Assert( coeffs[i] >= 0 && coeffs[i*3+1] >= 0 && coeffs[i*3+2] >= 0 && |
|
|
|
|
|
|
|
coeffs[i*3] + coeffs[i*3+1] + coeffs[i*3+2] < 2*(1 << lab_shift) ); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Mat(1, 9, CV_32SC1, coeffs).copyTo(ucoeffs); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const int Lscale = (116*255+50)/100; |
|
|
|
|
|
|
|
const int Lshift = -((16*255*(1 << lab_shift2) + 50)/100); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
k.args(srcarg, dstarg, |
|
|
|
|
|
|
|
ocl::KernelArg::PtrReadOnly(srgb ? usRGBGammaTab : ulinearGammaTab), |
|
|
|
|
|
|
|
ocl::KernelArg::PtrReadOnly(uLabCbrtTab), ocl::KernelArg::PtrReadOnly(ucoeffs), |
|
|
|
|
|
|
|
Lscale, Lshift); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
static UMat usRGBGammaTab, ucoeffs; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (srgb && usRGBGammaTab.empty()) |
|
|
|
|
|
|
|
Mat(1, GAMMA_TAB_SIZE * 4, CV_32FC1, sRGBGammaTab).copyTo(usRGBGammaTab); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
float coeffs[9]; |
|
|
|
|
|
|
|
const float * const _coeffs = sRGB2XYZ_D65, * const _whitept = D65; |
|
|
|
|
|
|
|
float scale[] = { 1.0f / _whitept[0], 1.0f, 1.0f / _whitept[2] }; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 3; i++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
int j = i * 3; |
|
|
|
|
|
|
|
coeffs[j + (bidx ^ 2)] = _coeffs[j] * scale[i]; |
|
|
|
|
|
|
|
coeffs[j + 1] = _coeffs[j + 1] * scale[i]; |
|
|
|
|
|
|
|
coeffs[j + bidx] = _coeffs[j + 2] * scale[i]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CV_Assert( coeffs[j] >= 0 && coeffs[j + 1] >= 0 && coeffs[j + 2] >= 0 && |
|
|
|
|
|
|
|
coeffs[j] + coeffs[j + 1] + coeffs[j + 2] < 1.5f*LabCbrtTabScale ); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mat(1, 9, CV_32FC1, coeffs).copyTo(ucoeffs); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
float _1_3 = 1.0f / 3.0f, _a = 16.0f / 116.0f; |
|
|
|
|
|
|
|
ocl::KernelArg ucoeffsarg = ocl::KernelArg::PtrReadOnly(ucoeffs); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (srgb) |
|
|
|
|
|
|
|
k.args(srcarg, dstarg, ocl::KernelArg::PtrReadOnly(usRGBGammaTab), |
|
|
|
|
|
|
|
ucoeffsarg, _1_3, _a); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
k.args(srcarg, dstarg, ucoeffsarg, _1_3, _a); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return k.run(dims, globalsize, NULL, false); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
case CV_Lab2BGR: case CV_Lab2RGB: case CV_Lab2LBGR: case CV_Lab2LRGB: |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if( dcn <= 0 ) |
|
|
|
|
|
|
|
dcn = 3; |
|
|
|
|
|
|
|
CV_Assert( scn == 3 && (dcn == 3 || dcn == 4) && (depth == CV_8U || depth == CV_32F) ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bidx = code == CV_Lab2BGR || code == CV_Lab2LBGR ? 0 : 2; |
|
|
|
|
|
|
|
bool srgb = code == CV_Lab2BGR || code == CV_Lab2RGB; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
k.create("Lab2BGR", ocl::imgproc::cvtcolor_oclsrc, |
|
|
|
|
|
|
|
format("-D depth=%d -D dcn=%d -D scn=3 -D bidx=%d%s", |
|
|
|
|
|
|
|
depth, dcn, bidx, srgb ? " -D SRGB" : "")); |
|
|
|
|
|
|
|
if (k.empty()) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
initLabTabs(); |
|
|
|
|
|
|
|
static UMat ucoeffs, usRGBInvGammaTab; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (srgb && usRGBInvGammaTab.empty()) |
|
|
|
|
|
|
|
Mat(1, GAMMA_TAB_SIZE*4, CV_32FC1, sRGBInvGammaTab).copyTo(usRGBInvGammaTab); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
float coeffs[9]; |
|
|
|
|
|
|
|
const float * const _coeffs = XYZ2sRGB_D65, * const _whitept = D65; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for( int i = 0; i < 3; i++ ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
coeffs[i+(bidx^2)*3] = _coeffs[i]*_whitept[i]; |
|
|
|
|
|
|
|
coeffs[i+3] = _coeffs[i+3]*_whitept[i]; |
|
|
|
|
|
|
|
coeffs[i+bidx*3] = _coeffs[i+6]*_whitept[i]; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mat(1, 9, CV_32FC1, coeffs).copyTo(ucoeffs); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_dst.create(sz, CV_MAKETYPE(depth, dcn)); |
|
|
|
|
|
|
|
dst = _dst.getUMat(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
float lThresh = 0.008856f * 903.3f; |
|
|
|
|
|
|
|
float fThresh = 7.787f * 0.008856f + 16.0f / 116.0f; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ocl::KernelArg srcarg = ocl::KernelArg::ReadOnlyNoSize(src), |
|
|
|
|
|
|
|
dstarg = ocl::KernelArg::WriteOnly(dst), |
|
|
|
|
|
|
|
coeffsarg = ocl::KernelArg::PtrReadOnly(ucoeffs); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (srgb) |
|
|
|
|
|
|
|
k.args(srcarg, dstarg, ocl::KernelArg::PtrReadOnly(usRGBInvGammaTab), |
|
|
|
|
|
|
|
coeffsarg, lThresh, fThresh); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
k.args(srcarg, dstarg, coeffsarg, lThresh, fThresh); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return k.run(dims, globalsize, NULL, false); |
|
|
|
|
|
|
|
} |
|
|
|
default: |
|
|
|
default: |
|
|
|
; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if( !k.empty() ) |
|
|
|
if( !k.empty() ) |
|
|
@ -3037,7 +3188,7 @@ static bool ocl_cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) |
|
|
|
_dst.create(dstSz, CV_MAKETYPE(depth, dcn)); |
|
|
|
_dst.create(dstSz, CV_MAKETYPE(depth, dcn)); |
|
|
|
dst = _dst.getUMat(); |
|
|
|
dst = _dst.getUMat(); |
|
|
|
k.args(ocl::KernelArg::ReadOnlyNoSize(src), ocl::KernelArg::WriteOnly(dst)); |
|
|
|
k.args(ocl::KernelArg::ReadOnlyNoSize(src), ocl::KernelArg::WriteOnly(dst)); |
|
|
|
ok = k.run(dims, globalsize, 0, false); |
|
|
|
ok = k.run(dims, globalsize, NULL, false); |
|
|
|
} |
|
|
|
} |
|
|
|
return ok; |
|
|
|
return ok; |
|
|
|
} |
|
|
|
} |
|
|
@ -3771,9 +3922,9 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) |
|
|
|
dst = _dst.getMat(); |
|
|
|
dst = _dst.getMat(); |
|
|
|
|
|
|
|
|
|
|
|
if( depth == CV_8U ) |
|
|
|
if( depth == CV_8U ) |
|
|
|
{ |
|
|
|
|
|
|
|
CvtColorLoop(src, dst, RGBA2mRGBA<uchar>()); |
|
|
|
CvtColorLoop(src, dst, RGBA2mRGBA<uchar>()); |
|
|
|
} else { |
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
CV_Error( CV_StsBadArg, "Unsupported image depth" ); |
|
|
|
CV_Error( CV_StsBadArg, "Unsupported image depth" ); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -3787,9 +3938,9 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) |
|
|
|
dst = _dst.getMat(); |
|
|
|
dst = _dst.getMat(); |
|
|
|
|
|
|
|
|
|
|
|
if( depth == CV_8U ) |
|
|
|
if( depth == CV_8U ) |
|
|
|
{ |
|
|
|
|
|
|
|
CvtColorLoop(src, dst, mRGBA2RGBA<uchar>()); |
|
|
|
CvtColorLoop(src, dst, mRGBA2RGBA<uchar>()); |
|
|
|
} else { |
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
CV_Error( CV_StsBadArg, "Unsupported image depth" ); |
|
|
|
CV_Error( CV_StsBadArg, "Unsupported image depth" ); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|