Visual c++ OpenCV手动将RGB转换为YCbCr,反之亦然(Visual C+;+;)

Visual c++ OpenCV手动将RGB转换为YCbCr,反之亦然(Visual C+;+;),visual-c++,casting,opencv,Visual C++,Casting,Opencv,我想手动将我的rgb图像转换为ycbcr图像,反之亦然。但是有个错误,我找不到 我的照片看起来不应该这样。 这是我的密码: void YCbCrToRGB(IplImage* ScrY, IplImage* ScrCb, IplImage* ScrCr, IplImage* DesR, IplImage* DesG, IplImage* DesB){ for(int i=0; i < ScrY->height; i++){ for(int j=0; j &l

我想手动将我的rgb图像转换为ycbcr图像,反之亦然。但是有个错误,我找不到

我的照片看起来不应该这样。 这是我的密码:

void YCbCrToRGB(IplImage* ScrY, IplImage* ScrCb, IplImage* ScrCr, IplImage* DesR, IplImage* DesG, IplImage* DesB){

    for(int i=0; i < ScrY->height; i++){
        for(int j=0; j < ScrY->width; j++){
            double Y = (double)(ScrY->imageData + ScrY->widthStep*i)[j];
            double Cb = (double)(ScrCb->imageData + ScrCb->widthStep*i)[j];
            double Cr = (double)(ScrCr->imageData + ScrCr->widthStep*i)[j];

            Cb = Cb -128;
            Cr = Cr -128;
            int r;
            int g;
            int b;

            (DesR->imageData + DesR->widthStep*i)[j] = (int)(1 * Y + 0 * Cb + 1.4 * Cr);
            (DesG->imageData + DesG->widthStep*i)[j] = (int)(1 * Y - 0.343 * Cb - 0.711 *Cr);
            (DesB->imageData + DesB->widthStep*i)[j] = (int)(1* Y + 1.765 * Cb + 0* Cr);
    }}

void RGBtoYCbCr(IplImage* ScrR, IplImage* ScrG, IplImage* ScrB, IplImage* DesY, IplImage* DesCb, IplImage* DesCr){
    for(int i=0; i < ScrR->height; i++){
        for(int j=0; j < ScrR->width; j++){
            double R = (double)(ScrR->imageData + ScrR->widthStep*i)[j];
            double G = (double)(ScrG->imageData + ScrG->widthStep*i)[j];
            double B = (double)(ScrB->imageData + ScrB->widthStep*i)[j];

            (DesY->imageData + DesY->widthStep*i)[j]   =       0.299    *R + 0.587  *G  + 0.114  *B;
            (DesCb->imageData + DesCb->widthStep*i)[j] =      -0.1687   *R - 0.3313 *G  + 0.5    *B + 128;
            (DesCr->imageData + DesCr->widthStep*i)[j] =       0.5      *R - 0.4187 *G  - 0.0813 *B + 128;          
        }
    }}

int _tmain(int argc, _TCHAR* argv[])
{
    try {
        IplImage* img = cvLoadImage( "C:\\sad-cat.jpg",1 ); 
        cvNamedWindow( "Example1", CV_WINDOW_AUTOSIZE ); 
        cvShowImage( "Example1", img );

        IplImage *r = cvCreateImage(cvGetSize(img), img->depth, 1);
        IplImage *g = cvCreateImage(cvGetSize(img), img->depth, 1);
        IplImage *b = cvCreateImage(cvGetSize(img), img->depth, 1);

        cvSplit(img, b, g, r, NULL);

        IplImage *y  = cvCreateImage(cvGetSize(img), img->depth, 1);
        IplImage *cb = cvCreateImage(cvGetSize(img), img->depth, 1);
        IplImage *cr = cvCreateImage(cvGetSize(img), img->depth, 1);


        RGBtoYCbCr(r,g,b,y,cb,cr);

        IplImage *ycbcr = cvCreateImage(cvGetSize(img), img->depth, 3);
        cvMerge(y,cb,cr,NULL,ycbcr);

        cvNamedWindow( "YCbCr from RGB", CV_WINDOW_AUTOSIZE ); 
        cvShowImage( "YCbCr from RGB", ycbcr );



        YCbCrToRGB(y,cb,cr,r,g,b);

        IplImage *RGBfromYCbCr = cvCreateImage(cvGetSize(img), img->depth, 3);
        cvMerge(r,g,b,NULL,RGBfromYCbCr);

        cvNamedWindow( "RGB from YCbCr", CV_WINDOW_AUTOSIZE ); 
        cvShowImage( "RGB from YCbCr", RGBfromYCbCr );

        cvWaitKey(0);
        return 0;
    }
    catch( exception& e){
        std::cout<<("An error occurred.") << std::endl;
        std::cout << e.what() <<std::endl; // Print the error message. 
         cvWaitKey(0);
    }  
}
无效YCbCrToRGB(IplImage*ScrY,IplImage*ScrCb,IplImage*ScrCr,IplImage*DesR,IplImage*DesG,IplImage*DesB){
对于(int i=0;iheight;i++){
对于(int j=0;jwidth;j++){
双Y=(双)(ScrY->imageData+ScrY->widthStep*i)[j];
双Cb=(双)(ScrCb->imageData+ScrCb->widthStep*i)[j];
双Cr=(双)(ScrCr->imageData+ScrCr->widthStep*i)[j];
Cb=Cb-128;
Cr=Cr-128;
INTR;
int g;
int b;
(DesR->imageData+DesR->widthStep*i)[j]=(int)(1*Y+0*Cb+1.4*Cr);
(设计->图像数据+设计->宽度步长*i)[j]=(int)(1*Y-0.343*Cb-0.711*Cr);
(DesB->imageData+DesB->widthStep*i)[j]=(int)(1*Y+1.765*Cb+0*Cr);
}}
无效RGBtoYCbCr(IplImage*ScrR、IplImage*ScrG、IplImage*ScrB、IplImage*DesY、IplImage*DesCb、IplImage*DesCr){
对于(int i=0;iheight;i++){
对于(int j=0;jwidth;j++){
双R=(双)(ScrR->imageData+ScrR->widthStep*i)[j];
双G=(双)(ScrG->imageData+ScrG->widthStep*i)[j];
双B=(双)(ScrB->imageData+ScrB->widthStep*i)[j];
(DesY->imageData+DesY->widthStep*i)[j]=0.299*R+0.587*G+0.114*B;
(描述->图像数据+描述->宽度步长*i)[j]=-0.1687*R-0.3313*G+0.5*B+128;
(描述->图像数据+描述->宽度步长*i)[j]=0.5*R-0.4187*G-0.0813*B+128;
}
}}
int _tmain(int argc,_TCHAR*argv[]
{
试一试{
IplImage*img=cvLoadImage(“C:\\sad cat.jpg”,1);
cvNamedWindow(“示例1”,CV\u窗口\u自动调整大小);
cvShowImage(“示例1”,img);
IplImage*r=cvCreateImage(cvGetSize(img),img->depth,1);
IplImage*g=cvCreateImage(cvGetSize(img),img->depth,1);
IplImage*b=cvCreateImage(cvGetSize(img),img->depth,1);
cvSplit(img,b,g,r,NULL);
IplImage*y=cvCreateImage(cvGetSize(img),img->depth,1);
IplImage*cb=cvCreateImage(cvGetSize(img),img->depth,1);
IplImage*cr=cvCreateImage(cvGetSize(img),img->depth,1);
RGBtoYCbCr(r,g,b,y,cb,cr);
IplImage*ycbcr=cvCreateImage(cvGetSize(img),img->depth,3);
cvMerge(y、cb、cr、NULL、ycbcr);
cvNamedWindow(“来自RGB的YCbCr”,CV_窗口_自动调整大小);
cvShowImage(“来自RGB的YCbCr”,YCbCr);
YCbCrToRGB(y,cb,cr,r,g,b);
IplImage*RGBfromYCbCr=cvCreateImage(cvGetSize(img),img->depth,3);
cvMerge(r,g,b,NULL,RGBfromYCbCr);
cvNamedWindow(“来自YCbCr的RGB”,CV_窗口_自动调整大小);
cvShowImage(“来自YCbCr的RGB”,来自YCbCr的RGB);
cvWaitKey(0);
返回0;
}
捕获(例外和e){

std::cout好吧,我的答案可能很愚蠢,但你应该知道,cvShowImage()将它读取的内容解释为BGR图像。如果你转换为YCbCr并尝试查看YCbCr的外观,它肯定会看起来很奇怪:

  • Y被解释为B通道
  • Cb解释为G通道
  • Cr解释为R通道
我不知道您在代码上运行了哪个测试,最好的最终测试是读取RGBtoYCbCr()的:YCbCrToRGB()中的图像

  • 您的图像=>RGBToYCbCr()=>YCbCrToRGB()=>cvShowImage()
第二条建议,检查你是否写了BGR图像,如果没有,你需要从RGB转换到BGR

告诉我你得到了什么,它是否有效


朱利安是的,这是一个演员问题

        double Y = (double)(ScrY->imageData + ScrY->widthStep*i)[j];
        double Cb = (double)(ScrCb->imageData + ScrCb->widthStep*i)[j];
        double Cr = (double)(ScrCr->imageData + ScrCr->widthStep*i)[j];
应该是

        double Y = (uchar)(ScrY->imageData + ScrY->widthStep*i)[j];
        double Cb = (uchar)(ScrCb->imageData + ScrCb->widthStep*i)[j];
        double Cr = (uchar)(ScrCr->imageData + ScrCr->widthStep*i)[j];
RGBtoYCbCr
的前三行进行相同的更改

此外,您还存在舍入错误。您应该在分配以下内容之前对结果进行舍入:

        (DesY->imageData + DesY->widthStep*i)[j]   = round(     0.299    *R + 0.587  *G  + 0.114  *B);
        (DesCb->imageData + DesCb->widthStep*i)[j] = round(    -0.1687   *R - 0.3313 *G  + 0.5    *B) + 128;
        (DesCr->imageData + DesCr->widthStep*i)[j] = round(     0.5      *R - 0.4187 *G  - 0.0813 *B) + 128;          

最后,
cvMerge(r,g,b,NULL,RGBfromYCbCr);
应该是
cvMerge(b,g,r,NULL,RGBfromYCbCr);
因为
cvShowImage
假设BGR而不是RGB。

谢谢你的评论,我尝试了来自和来自的公式。第三张图片是你的图片=>RGBToYCbCr()=>ycbcrtogb()=>cvShowImage()。我还尝试使用YCbCrToRGB并使用CvConvert将rgb恢复。cvShowImage显示了使用cv正确转换的YCbCr图片,但不是我的。我希望这会让你的悲伤的猫高兴。非常感谢。猫非常高兴。谢谢。这是一只非常快乐的猫。谢谢你发布这条消息。很高兴有人分享成功的分辨率。