2011-08-07 7 views
2

rgb 이미지를 ycbcr 이미지로 변환하고 그 반대로 수동으로 변환하려고합니다. 그러나 실수가 있으며 찾을 수 없습니다.OpenCV에서 RGB로 YCbCr로 또는 그 반대로 손으로 (Visual C++)

내 이미지가 제대로 보이지 않습니다. http://paste2.org/p/1569904

내가 생각하는이 같은 자사의 캐스팅 오류 또는 뭔가 :

여기
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); 
    } 
} 

구문 강조와 함께 링크입니다 : 다음은 내 코드입니다.

, 내 대답은 어쩌면 바보
+0

이미지 http://i.stack.imgur.com/eos3m.jpg – vo1d

+0

나는 공식을 http://www.equasys.de/colorconversion.html 및 http://opencv.willowgarage.com/에서 시험해 보았습니다. documentation/c/miscellaneous_image_transformations.html – vo1d

답변

3

네, 캐스팅 문제를 당신이 얻을 무엇을 말해합니다.

 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의 처음 세 줄에 같은 변화를 확인해야한다.

또한 반올림 오류가 있습니다. 당신은 할당하기 전에 결과를 반올림합니다 cvShowImage는, RGB BGR을하지 가정 cvMerge(b,g,r,NULL,RGBfromYCbCr); 때문에

 (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);이 있어야한다.

+0

입니다. 슬픈 고양이가 행복하게되기를 바랍니다. – SSteve

+0

대단히 고마워요. 고양이는 매우 행복합니다. 고맙습니다. – vo1d

+1

결과는 다음과 같습니다.) http://dl.dropbox.com/u/724136/cat-happy.jpg – vo1d

0

글쎄 (내가 두 개 이상의 링크를 클릭하거나 이미지를 게시 할 수 있지 않다) 공식 예를 그림에 대한 주석을 참조하지만 당신은 (즉, cvShowImage을 알아야한다 : 은 대단히

PS 감사합니다)는 BGR 이미지로 읽는 것을 해석합니다. 당신의 YCbCr로 변환하고 있는지를 들어,의 YCbCr이 모습을보고 시도하는 경우가있을 것 같은 이상한 모양 :

  • Y는
  • CR 해석
  • 인증 기관은 G 채널로 해석 B 채널로 해석 R 채널로

하면 코드를 통해 실행 테스트하는 나도 몰라, 최선의 최종 테스트에서 이미지 읽을 것 : 당신의 RGBtoYCbCr()의 YCbCrToRGB()를

  • 이미지 => RGBToYCbCr() => YCbCrToRGB() => cvShowImage()

조언의 두 번째 조각, 당신은 BGR 이미지를 작성하는 경우는 RGB로 변환해야하지 있는지 확인 작동 여부를 경우 BGR에 ...

줄리앙

+0

의견을 보내 주셔서 감사합니다. 세 번째 그림은 이미지 => RGBToYCbCr() => YCbCrToRGB() => cvShowImage()입니다.또한 YCbCrToRGB를 시도하고 CvConvert를 사용하여 rgb를 다시 얻습니다. cvShowImage는 Cv로 변환 된 YCbCr 그림을 표시하지만 내 이름은 – vo1d

관련 문제