mirror of
https://github.com/opencv/opencv.git
synced 2024-11-25 11:40:44 +08:00
fixed cvtColor (RGB <-> Lab) tests and created another one
This commit is contained in:
parent
5f9aedbe01
commit
2cda65a782
@ -1009,93 +1009,105 @@ double CV_ColorLabTest::get_success_error_level( int /*test_case_idx*/, int i, i
|
||||
|
||||
|
||||
static const double _1_3 = 0.333333333333;
|
||||
const static float _1_3f = static_cast<float>(_1_3);
|
||||
|
||||
void CV_ColorLabTest::convert_row_bgr2abc_32f_c3( const float* src_row, float* dst_row, int n )
|
||||
|
||||
void CV_ColorLabTest::convert_row_bgr2abc_32f_c3(const float* src_row, float* dst_row, int n)
|
||||
{
|
||||
int depth = test_mat[INPUT][0].depth();
|
||||
float Lscale = depth == CV_8U ? 255.f/100.f : depth == CV_16U ? 65535.f/100.f : 1.f;
|
||||
float ab_bias = depth == CV_8U ? 128.f : depth == CV_16U ? 32768.f : 0.f;
|
||||
int j;
|
||||
float M[9];
|
||||
|
||||
for( j = 0; j < 9; j++ )
|
||||
|
||||
for (int j = 0; j < 9; j++ )
|
||||
M[j] = (float)RGB2XYZ[j];
|
||||
|
||||
for( j = 0; j < n*3; j += 3 )
|
||||
|
||||
for (int x = 0; x < n*3; x += 3)
|
||||
{
|
||||
float r = src_row[j+2];
|
||||
float g = src_row[j+1];
|
||||
float b = src_row[j];
|
||||
|
||||
float X = (r*M[0] + g*M[1] + b*M[2])*(1.f/Xn);
|
||||
float Y = r*M[3] + g*M[4] + b*M[5];
|
||||
float Z = (r*M[6] + g*M[7] + b*M[8])*(1.f/Zn);
|
||||
float fX, fY, fZ;
|
||||
|
||||
float L, a;
|
||||
|
||||
if( Y > 0.008856 )
|
||||
float R = src_row[x + 2];
|
||||
float G = src_row[x + 1];
|
||||
float B = src_row[x];
|
||||
|
||||
float X = (R * M[0] + G * M[1] + B * M[2]) / Xn;
|
||||
float Y = R * M[3] + G * M[4] + B * M[5];
|
||||
float Z = (R * M[6] + G * M[7] + B * M[8]) / Zn;
|
||||
float fX = X > 0.008856f ? pow(X, _1_3f) :
|
||||
(7.787f * X + 16.f / 116.f);
|
||||
float fZ = Z > 0.008856f ? pow(Z, _1_3f):
|
||||
(7.787f * Z + 16.f / 116.f);
|
||||
|
||||
float L = 0.0f, fY = 0.0f;
|
||||
if (Y > 0.008856f)
|
||||
{
|
||||
fY = (float)pow((double)Y,_1_3);
|
||||
L = 116.f*fY - 16.f;
|
||||
fY = pow(Y, _1_3f);
|
||||
L = 116.f * fY - 16.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
fY = 7.787f*Y + 16.f/116.f;
|
||||
L = 903.3f*Y;
|
||||
fY = 7.787f * Y + 16.f / 116.f;
|
||||
L = 903.3f * Y;
|
||||
}
|
||||
|
||||
if( X > 0.008856 )
|
||||
fX = (float)pow((double)X,_1_3);
|
||||
else
|
||||
fX = 7.787f*X + 16.f/116.f;
|
||||
|
||||
if( Z > 0.008856 )
|
||||
fZ = (float)pow((double)Z,_1_3);
|
||||
else
|
||||
fZ = 7.787f*Z + 16.f/116.f;
|
||||
|
||||
a = 500.f*(fX - fY);
|
||||
b = 200.f*(fY - fZ);
|
||||
|
||||
dst_row[j] = L*Lscale;
|
||||
dst_row[j+1] = a + ab_bias;
|
||||
dst_row[j+2] = b + ab_bias;
|
||||
|
||||
float a = 500.f * (fX - fY);
|
||||
float b = 200.f * (fY - fZ);
|
||||
|
||||
dst_row[x] = L * Lscale;
|
||||
dst_row[x + 1] = a + ab_bias;
|
||||
dst_row[x + 2] = b + ab_bias;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CV_ColorLabTest::convert_row_abc2bgr_32f_c3( const float* src_row, float* dst_row, int n )
|
||||
{
|
||||
int depth = test_mat[INPUT][0].depth();
|
||||
float Lscale = depth == CV_8U ? 100.f/255.f : depth == CV_16U ? 100.f/65535.f : 1.f;
|
||||
float ab_bias = depth == CV_8U ? 128.f : depth == CV_16U ? 32768.f : 0.f;
|
||||
int j;
|
||||
float M[9];
|
||||
|
||||
for( j = 0; j < 9; j++ )
|
||||
|
||||
for(int j = 0; j < 9; j++ )
|
||||
M[j] = (float)XYZ2RGB[j];
|
||||
|
||||
for( j = 0; j < n*3; j += 3 )
|
||||
|
||||
static const float lthresh = 903.3f * 0.008856f;
|
||||
static const float thresh = 7.787f * 0.008856f + 16.0f / 116.0f;
|
||||
for (int x = 0, end = n * 3; x < end; x += 3)
|
||||
{
|
||||
float L = src_row[j]*Lscale;
|
||||
float a = src_row[j+1] - ab_bias;
|
||||
float b = src_row[j+2] - ab_bias;
|
||||
|
||||
float P = (L + 16.f)*(1.f/116.f);
|
||||
float X = (P + a*0.002f);
|
||||
float Z = (P - b*0.005f);
|
||||
float Y = P*P*P;
|
||||
X = Xn*X*X*X;
|
||||
Z = Zn*Z*Z*Z;
|
||||
|
||||
float r = M[0]*X + M[1]*Y + M[2]*Z;
|
||||
float g = M[3]*X + M[4]*Y + M[5]*Z;
|
||||
b = M[6]*X + M[7]*Y + M[8]*Z;
|
||||
|
||||
dst_row[j] = b;
|
||||
dst_row[j+1] = g;
|
||||
dst_row[j+2] = r;
|
||||
float L = src_row[x] * Lscale;
|
||||
float a = src_row[x + 1] - ab_bias;
|
||||
float b = src_row[x + 2] - ab_bias;
|
||||
|
||||
float FY = 0.0f, Y = 0.0f;
|
||||
if (L <= lthresh)
|
||||
{
|
||||
Y = L / 903.3f;
|
||||
FY = 7.787f * Y + 16.0f / 116.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
FY = (L + 16.0f) / 116.0f;
|
||||
Y = FY * FY * FY;
|
||||
}
|
||||
|
||||
float FX = a / 500.0f + FY;
|
||||
float FZ = FY - b / 200.0f;
|
||||
|
||||
float FXZ[] = { FX, FZ };
|
||||
for (int k = 0; k < 2; ++k)
|
||||
{
|
||||
if (FXZ[k] <= thresh)
|
||||
FXZ[k] = (FXZ[k] - 16.0f / 116.0f) / 7.787f;
|
||||
else
|
||||
FXZ[k] = FXZ[k] * FXZ[k] * FXZ[k];
|
||||
}
|
||||
float X = FXZ[0] * Xn;
|
||||
float Z = FXZ[1] * Zn;
|
||||
|
||||
float R = M[0] * X + M[1] * Y + M[2] * Z;
|
||||
float G = M[3] * X + M[4] * Y + M[5] * Z;
|
||||
float B = M[6] * X + M[7] * Y + M[8] * Z;
|
||||
|
||||
dst_row[x] = B;
|
||||
dst_row[x + 1] = G;
|
||||
dst_row[x + 2] = R;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1869,3 +1881,98 @@ TEST(Imgproc_ColorBayerVNG_Strict, regression)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GetTestMatrix(Mat& src)
|
||||
{
|
||||
Size ssize(1000, 1000);
|
||||
src.create(ssize, CV_32FC3);
|
||||
int szm = ssize.width - 1;
|
||||
float pi2 = 2 * 3.1415f;
|
||||
// Generate a pretty test image
|
||||
for (int i = 0; i < ssize.height; i++)
|
||||
{
|
||||
for (int j = 0; j < ssize.width; j++)
|
||||
{
|
||||
float b = (1 + cos((szm - i) * (szm - j) * pi2 / (10 * float(szm)))) / 2;
|
||||
float g = (1 + cos((szm - i) * j * pi2 / (10 * float(szm)))) / 2;
|
||||
float r = (1 + sin(i * j * pi2 / (10 * float(szm)))) / 2;
|
||||
|
||||
// The following lines aren't necessary, but just to prove that
|
||||
// the BGR values all lie in [0,1]...
|
||||
if (b < 0) b = 0; else if (b > 1) b = 1;
|
||||
if (g < 0) g = 0; else if (g > 1) g = 1;
|
||||
if (r < 0) r = 0; else if (r > 1) r = 1;
|
||||
src.at<cv::Vec3f>(i, j) = cv::Vec3f(b, g, r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void validate_result(const Mat& reference, const Mat& actual, const Mat& src = Mat(), int mode = -1)
|
||||
{
|
||||
cvtest::TS* ts = cvtest::TS::ptr();
|
||||
Size ssize = reference.size();
|
||||
|
||||
int cn = reference.channels();
|
||||
ssize.width *= cn;
|
||||
bool next = true;
|
||||
|
||||
for (int y = 0; y < ssize.height && next; ++y)
|
||||
{
|
||||
const float* rD = reference.ptr<float>(y);
|
||||
const float* D = actual.ptr<float>(y);
|
||||
for (int x = 0; x < ssize.width && next; ++x)
|
||||
if (fabs(rD[x] - D[x]) > 0.0001f)
|
||||
{
|
||||
next = false;
|
||||
ts->printf(cvtest::TS::SUMMARY, "Error in: (%d, %d)\n", x / cn, y);
|
||||
ts->printf(cvtest::TS::SUMMARY, "Reference value: %f\n", rD[x]);
|
||||
ts->printf(cvtest::TS::SUMMARY, "Actual value: %f\n", D[x]);
|
||||
if (!src.empty())
|
||||
ts->printf(cvtest::TS::SUMMARY, "Src value: %f\n", src.ptr<float>(y)[x]);
|
||||
ts->printf(cvtest::TS::SUMMARY, "Size: (%d, %d)\n", reference.rows, reference.cols);
|
||||
|
||||
if (mode >= 0)
|
||||
{
|
||||
cv::Mat lab;
|
||||
cv::cvtColor(src, lab, mode);
|
||||
std::cout << "lab: " << lab(cv::Rect(y, x / cn, 1, 1)) << std::endl;
|
||||
}
|
||||
std::cout << "src: " << src(cv::Rect(y, x / cn, 1, 1)) << std::endl;
|
||||
|
||||
ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
|
||||
ts->set_gtest_status();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Imgproc_ColorLab_Full, accuracy)
|
||||
{
|
||||
Mat src;
|
||||
GetTestMatrix(src);
|
||||
Mat reference(src.size(), CV_32FC3);
|
||||
Size ssize = src.size();
|
||||
CV_Assert(ssize.width == ssize.height);
|
||||
|
||||
RNG& rng = cvtest::TS::ptr()->get_rng();
|
||||
int blueInd = rng.uniform(0., 1.) > 0.5 ? 0 : 2;
|
||||
bool srgb = rng.uniform(0., 1.) > 0.5;
|
||||
|
||||
// Convert test image to LAB
|
||||
cv::Mat lab;
|
||||
int forward_code = blueInd ? srgb ? CV_BGR2Lab : CV_LBGR2Lab : srgb ? CV_RGB2Lab : CV_LRGB2Lab;
|
||||
int inverse_code = blueInd ? srgb ? CV_Lab2BGR : CV_Lab2LBGR : srgb ? CV_Lab2RGB : CV_Lab2LRGB;
|
||||
cv::cvtColor(src, lab, forward_code);
|
||||
// Convert LAB image back to BGR(RGB)
|
||||
cv::Mat recons;
|
||||
cv::cvtColor(lab, recons, inverse_code);
|
||||
|
||||
validate_result(src, recons, src, forward_code);
|
||||
|
||||
// src *= 255.0f;
|
||||
// recons *= 255.0f;
|
||||
|
||||
// imshow("Test", src);
|
||||
// imshow("OpenCV", recons);
|
||||
// waitKey();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user