一、RGB与Ycbcr转换的公式
1.RGB表示三原色:红绿蓝
Y:表示明亮度,也就是灰阶值。“亮度”是透过RGB输入信号来建立的,方法是将RGB信号的特定部分叠加到一起。
Cb:反映的是RGB输入信号蓝色部分与RGB信号亮度值之间的差异。
Cr:反映了RGB输入信号红色部分与RGB信号亮度值之间的差异。
在以下两个公式中RGB和YCbCr各分量的值的范围均为0-255。
2.RGB转换为Ycbcr公式
Y = 0.257*R+0.564*G+0.098*B+16
Cb = -0.148*R-0.291*G+0.439*B+128
Cr = 0.439*R-0.368*G-0.071*B+128
3.Ycbcr转换为RGB公式
R = 1.164*(Y-16)+1.596*(Cr-128)
G = 1.164*(Y-16)-0.392*(Cb-128)-0.813*(Cr-128)
B =1.164*(Y-16)+2.017*(Cb-128)
二、RGB与Ycbcr转换实现
#include "stdafx.h"
#include "highgui.h"
#include "cv.h"
#include "cxcore.h"
#include "stdio.h"
int _tmain(int argc, _TCHAR* argv[])
{
float imgy,imgcb,imgcr;
IplImage* img_rgb=cvLoadImage("lena.jpg");
IplImage* ycbcr=cvCreateImage(cvGetSize(img_rgb),8,3);
IplImage* r_img_rgb=cvCreateImage(cvGetSize(img_rgb),8,1);
IplImage* g_img_rgb=cvCreateImage(cvGetSize(img_rgb),8,1);
IplImage* b_img_rgb=cvCreateImage(cvGetSize(img_rgb),8,1);
IplImage* ycb=cvCreateImage(cvGetSize(img_rgb),8,3);
cvCvtColor(img_rgb,ycb,CV_BGR2YCrCb); //方法一,利用opencv内部函数实现
cvSplit(img_rgb,r_img_rgb,g_img_rgb,b_img_rgb,0);//把RGB三通道分为单通道
IplImage* img_y = cvCreateImage (cvSize (img_rgb->width,img_rgb->height),IPL_DEPTH_8U, 1);
IplImage* img_cb= cvCreateImage (cvSize (img_rgb->width,img_rgb->height),IPL_DEPTH_8U, 1);
IplImage* img_cr= cvCreateImage (cvSize (img_rgb->width,img_rgb->height),IPL_DEPTH_8U, 1);
for(int y=0;y
{
for(int x=0;x
{ //获取每个图像的像素,然后用公式转换
imgy =0.257*cvGetReal2D(r_img_rgb,y,x)+0.504*cvGetReal2D(g_img_rgb,y,x)+0.098*cvGetReal2D(b_img_rgb,y,x)+16;
imgcb=-0.148*cvGetReal2D(r_img_rgb,y,x)-0.291*cvGetReal2D(g_img_rgb,y,x)+0.439*cvGetReal2D(b_img_rgb,y,x)+128;
imgcr=0.439*cvGetReal2D(r_img_rgb,y,x)-0.368*cvGetReal2D(g_img_rgb,y,x)-0.071*cvGetReal2D(b_img_rgb,y,x)+128;
cvSetReal2D(img_y,y,x,imgy);
cvSetReal2D(img_cb,y,x,imgcb);
cvSetReal2D(img_cr,y,x,imgcr);
}
}
cvMerge(img_y,img_cb,img_cr,NULL,ycbcr);//生成Ycbcr颜色空间
//把Ycbcr颜色空间再转换成RGB颜色空间
int imgr,imgg,imgb;
IplImage* r_rgb=cvCreateImage(cvGetSize(ycbcr),8,1);
IplImage* g_rgb=cvCreateImage(cvGetSize(ycbcr),8,1);
IplImage* b_rgb=cvCreateImage(cvGetSize(ycbcr),8,1);
IplImage* rgb=cvCreateImage(cvGetSize(ycbcr),8,3);
for(int y=0;y
{
for(int x=0;x
{
imgr=1.164*(cvGetReal2D(img_y,y,x)-16)+1.596*(cvGetReal2D(img_cr,y,x)-128);
imgg=1.164*(cvGetReal2D(img_y,y,x)-16)-0.392*(cvGetReal2D(img_cb,y,x)-128)-0.813*(cvGetReal2D(img_cr,y,x)-128);
imgb=1.164*(cvGetReal2D(img_y,y,x)-16)+2.017*(cvGetReal2D(img_cb,y,x)-128);
cvSetReal2D(r_rgb,y,x,imgr);
cvSetReal2D(g_rgb,y,x,imgg);
cvSetReal2D( b_rgb,y,x,imgb);
}
}
cvMerge(r_rgb,g_rgb,b_rgb,NULL,rgb);//把Ycbcr转换成RGB空间
cvNamedWindow("ycbcr",CV_WINDOW_AUTOSIZE);
cvNamedWindow("ycb",CV_WINDOW_AUTOSIZE);
cvNamedWindow("y",CV_WINDOW_AUTOSIZE);
cvNamedWindow("cb",CV_WINDOW_AUTOSIZE);
cvNamedWindow("cr",CV_WINDOW_AUTOSIZE);
cvNamedWindow("rgb",CV_WINDOW_AUTOSIZE);
cvShowImage("ycbcr",ycbcr);
cvShowImage("y",img_y);
cvShowImage("cb",img_cb);
cvShowImage("cr",img_cr);
cvShowImage("ycb",ycb);
cvShowImage("rgb",rgb);
cvWaitKey();
cvDestroyWindow("ycbcr");
cvDestroyWindow("cb");
cvDestroyWindow("cr");
cvDestroyWindow("ycb");
cvDestroyWindow("rgb");
cvReleaseImage(&ycbcr);
cvDestroyWindow("y");
cvReleaseImage(&img_y);
cvReleaseImage(&img_cb);
cvReleaseImage(&img_cr);
cvReleaseImage(&ycb);
cvReleaseImage(&rgb);
return 0;
}