RGB与Ycbcr空间的互相转换

一、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<img_rgb->height;y++) //方法二,利用公式
{
        for(int x=0;x<img_rgb->width;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<ycbcr->height;y++)
{
for(int x=0;x<ycbcr->width;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;
}

ycbcr图
RGB与Ycbcr空间的互相转换_第1张图片



你可能感兴趣的:(opencv,颜色空间)