先说结论, 不同色彩空间的转换矩阵不能混用, 否则一定会出现负数或者超过1 的情况
测试代码:
constant.h
const float rgb2yuv_2020[] = {
0.2627, 0.6780, 0.0593,
-0.1396, -0.3604, 0.5000,
0.5000, -0.4598, -0.0402
};
const float rgb2yuv_2020_invert[] = {
1, 0, 1.4746,
1, -0.1646, -0.5714,
1, 1.8814, 0
};
//
//"BT601 625 D65"
//Input :
// r = (0.64, 0.33)
// g = (0.29, 0.60)
// b = (0.15, 0.06)
// w = (0.3127, 0.3290)
//
// Output :
// RGB2YUV Matrix :
//0.2220, 0.7067, 0.0713
//- 0.1195, -0.3805, 0.5000
//0.5000, -0.4542, -0.0458
//
//YUV2RGB Matrix :
//1, 0, 1.5560
//1, -0.1875, -0.4888
//1, 1.8573, 0
//
//"BT601 525 D65"
//Input :
// r = (0.63, 0.34)
// g = (0.31, 0.595)
// b = (0.155, 0.070)
// w = (0.3127, 0.3290)
//
// Output :
// RGB2YUV Matrix :
//0.2124, 0.7011, 0.0866
//- 0.1163, -0.3837, 0.5000
//0.5000, -0.4450, -0.0550
//
//YUV2RGB Matrix :
//1, 0, 1.5752
//1, -0.2256, -0.4772
//1, 1.8269, 0
const float rgb2yuv_709[] = {
0.2126, 0.7152, 0.0722,
-0.1146, -0.3854, 0.5000,
0.5000, -0.4542, -0.0458
};
const float rgb2yuv_709_invert[] = {
1, 0, 1.5747,
1, -0.1873, -0.4682,
1, 1.8556, 0
};
const float rgb2yuv_ntsc[] = {
0.2989, 0.5866, 0.1145,
-0.1688, -0.3312, 0.5000,
0.5000, -0.4184, -0.0816
};
const float rgb2yuv_ntsc_invert[] = {
1, 0, 1.4022,
1, -0.3456, -0.7145,
1, 1.7710, 0
};
inline void mul32f_3x3(const float* matrix, float* in, float* out)
{
out[0] = matrix[0] * in[0] + matrix[1] * in[1] + matrix[2] * in[2];
out[1] = matrix[3] * in[0] + matrix[4] * in[1] + matrix[5] * in[2];
out[2] = matrix[6] * in[0] + matrix[7] * in[1] + matrix[8] * in[2];
}
main.cpp
#include "constant.h"
#include <stdio.h>
int check_rgb_to_rgb( const float * rgb2yuv_coeffs, const float* yuv2rgb_coeffs, float* rgb)
{
float rgbout[3];
int res = 0;
const float delta = 0.001f;
mul32f_3x3(rgb2yuv_coeffs, rgb, rgbout);
mul32f_3x3(yuv2rgb_coeffs, rgbout, rgb);
if (rgb[0] < -delta || rgb[1] < -delta || rgb[2] < -delta) {
res = -1;
}
if (rgb[0] > 1 + delta || rgb[1] > 1 + delta || rgb[2] > 1 + delta) {
res = -2;
}
if(res!=0)
printf("SRC :%.4f %.4f %.4f DST:%.4f %.4f %.4f \n",
rgb[0], rgb[1], rgb[2], rgbout[0], rgbout[1], rgbout[2]);
return res;
}
const float* rgb2yuv_coeffs[] = {
rgb2yuv_709,
rgb2yuv_2020,
rgb2yuv_ntsc
};
const float* rgb2yuv_coeffs_invert[] = {
rgb2yuv_709_invert,
rgb2yuv_2020_invert,
rgb2yuv_ntsc_invert
};
bool check(int rgb2yuv_id, int rgb2yuv_id_invert)
{
for (int i = 0; i < 256; ++i) {
for (int j = 0; j < 256; ++j) {
for (int k = 0; k < 256; ++k) {
float in[] = { i / 255.0f, j / 255.0f, k / 255.0f };
int is_bad_coeffs = check_rgb_to_rgb(rgb2yuv_coeffs[rgb2yuv_id], rgb2yuv_coeffs_invert[rgb2yuv_id_invert], in);
if (is_bad_coeffs) {
return false;
}
}
}
}
return true;
}
int main()
{
int errflag = 0;
float nb_colorspace = sizeof(rgb2yuv_coeffs) / sizeof(rgb2yuv_coeffs[0]);
for (int ci = 0; ci != nb_colorspace; ++ci) {
for (int co = 0; co != nb_colorspace; ++co) {
bool res = check(ci, co);
printf("Check res:%d rgb2yuv:%d yuv2rgb:%d \n", res, ci, co);
}
}
}
网友评论