YUV与RGB转换公式
1、RGB转YUV
float R = (float)r;float G = (float)g;
float B = (float)b;
float Y = 0.299*R + 0.587*G + 0.114*B;
float U = -0.169*R - 0.331*G + 0.5 *B + 128.0;
float V = 0.5 *R - 0.419*G - 0.081*B + 128.0;
void Draw_Point_YUV420SP(cv::Mat &image, const cv::Point &pt, const Eigen::Vector3f &RGB)
{
Eigen::Vector3f YUV(0,0,0);
const Eigen::Vector3f yuv_offset(0.0, 128.0, 128.0);
int W = image.cols;
int H = image.rows*2/3;
if(pt.x<0||pt.x>=W || pt.y<0 || pt.y>=H)
return;
Eigen::Matrix3f rgb2yuv;
rgb2yuv<<0.299,0.587,0.114,-0.169,- 0.331,0.5,0.5,-0.419,-0.081;
YUV = rgb2yuv*RGB;
YUV += yuv_offset;
YUV[0] = std::min(float(255.0), std::max(float(0.0), YUV[0]));
YUV[1] = std::min(float(255.0), std::max(float(0.0), YUV[1]));
YUV[2] = std::min(float(255.0), std::max(float(0.0), YUV[2]));
unsigned char y=static_cast<unsigned char>(YUV[0]);
unsigned char u=static_cast<unsigned char>(YUV[1]);
unsigned char v=static_cast<unsigned char>(YUV[2]);
unsigned char *pY = image.data;
unsigned char *pUV = image.data + W*H;
//计算YUV索引
pY[pt.y*W+pt.x] = y;
int uv_id = (pt.y/2)*W + pt.x - pt.x%2; // UV的列和Y的列相同
pUV[uv_id] = u;
pUV[uv_id+1] = v;
return;
}
2: YUV转RGB
YUV420SP
const unsigned char *pY = buf.data();
const unsigned char *pUV = pY + width*height;
cv::Mat img = cv::Mat::zeros(height, width, CV_8UC3);
for(int v=0; v<height; v++){
for(int u=0; u<width; u++){
auto &BGR = img.at<cv::Vec3b>(v, u);
float Y = static_cast<float>(pY[v*width+u]);
int vu_id = (v/2)*width + u - u%2;
float U = static_cast<float>(pUV[vu_id]);
float V = static_cast<float>(pUV[vu_id+1]);
float r = Y + 1.403*(V - 128);
float g = Y - 0.343*(U - 128) - 0.714*(V - 128);
float b = Y + 1.77*(U - 128);
r = r<0.0?0.0:r;
r = r>255.0?255:r;
g = g<0.0?0.0:g;
g = g>255.0?255:g;
b = b<0.0?0.0:b;
b = b>255.0?255:b;
BGR[0] = static_cast<unsigned char>(b);
BGR[1] = static_cast<unsigned char>(g);
BGR[2] = static_cast<unsigned char>(r);
}
}
cv::imwrite("out.png", img);
评论已关闭