Computer Vision2009. 4. 11. 17:41

OpenCV Convert Image


() 글을 읽기 전에
글은 저와 같은 OpenCV초보자를 위해서 정리하는 것입니다.
전문가시라면 굳이 읽을 필요가 없습니다.
공부하면서 정리하는 글이라서 서툰 부분이 많이많이 보입니다.


영상 처리를 하기 위해서는 때때로 컬러 공간을 바꾸어 줘야 할 때가 많습니다.

영상에서 필요한 정보를 찾아서 추출하기 위해서는 RGB공간에서 얻을 수 없는 정보를

다른 컬러 공간에서 얻어낼 수 있기 때문입니다.

예를들어서 사진에서 휘도를 바꾸고 싶을 경우

YCbCr로 바꾼후에 Y를 변경하고 다시 이것을 RGB로 바꾸는 과정을 거치게 됩니다.

이럴 경우 컬러 공간을 변환하는 함수가 있어야 하는데

OpenCV에서는 아래 함수가 그 동작을 도와줍니다.

cvCvtColor( 입력 이미지 , 출력 이미지 , 옵션 ); 


옵션은 아주 많이 있지만 아래에 몇가지 중요한 옵션을 설명하였습니다.


  CV_RGB2GRAY  : 흑백으로 바꾸기

                            수식은 다음과 같다.

RGB[A]->Gray: Y<-0.299*R + 0.587*G + 0.114*B


  CV_RGB2YCrCb : YCrCb로 바꾸기

    Y <- 0.299*R + 0.587*G + 0.114*B

  Cr <- (R-Y)*0.713 + delta

  Cb <- (B-Y)*0.564 + delta


  CV_RGB2HLS    : ( Hue Lightness Saturation ) 으로 변환한다.

   // In case of 8-bit and 16-bit images

  // R, G and B are converted to floating-point format and scaled to fit 0..1 range

  V,,max,, <- max(R,G,B)

  V,,min,, <- min(R,G,B)

  L <- (V,,max,, + V,,min,,)/2

  S <- (V,,max,, - V,,min,,)/(V,,max,, + V,,min,,)  if L < 0.5

        (V,,max,, - V,,min,,)/(2 - (V,,max,, + V,,min,,))  if L = 0.5

           (G - B)*60/S,  if V,,max,,=R

  H <- 180+(B - R)*60/S,  if V,,max,,=G

        240+(R - G)*60/S,  if V,,max,,=B

  if H<0 then H<-H+360

  On output 0=L=1, 0=S=1, 0=H=360.

  The values are then converted to the destination data type:

      8-bit images:

           L <- L*255, S <- S*255, H <- H/2

      16-bit images (currently not supported):

          L <- L*65535, S <- S*65535, H <- H

      32-bit images:

          H, L, S are left as is


  CV_RGB2HSV : RGB 값을 HSV로 바꾼다. HSV란 Hue Saturation Value를 의미한다.


  // In case of 8-bit and 16-bit images

  // R, G and B are converted to floating-point format and scaled to fit 0..1 range

  V <- max(R,G,B)

  S <- (V-min(R,G,B))/V   if V?0, 0 otherwise

           (G - B)*60/S,  if V=R

  H <- 120+(B - R)*60/S,  if V=G

       240+(R - G)*60/S,  if V=B

  if H<0 then H<-H+360

  On output 0=V=1, 0=S=1, 0=H=360.

  The values are then converted to the destination data type:

      8-bit images:

          V <- V*255, S <- S*255, H <- H/2 (to fit to 0..255)

      16-bit images (currently not supported):

          V <- V*65535, S <- S*65535, H <- H

      32-bit images:

          H, S, V are left as is

  CV_RGB2Lab : CIE Lab Color로 변환한다.

  // In case of 8-bit and 16-bit images

  // R, G and B are converted to floating-point format and scaled to fit 0..1 range

  // convert R,G,B to CIE XYZ

  |X|    |0.412453  0.357580  0.180423| |R|

  |Y| <- |0.212671  0.715160  0.072169|*|G|

  |Z|    |0.019334  0.119193  0.950227| |B|

  X <- X/Xn, where Xn = 0.950456

  Z <- Z/Zn, where Zn = 1.088754

  L <- 116*Y^1/3-16      for Y>0.008856

  L <- 903.3*Y           for Y<=0.008856

  a <- 500*(f(X)-f(Y)) + delta

  b <- 200*(f(Y)-f(Z)) + delta

  where f(t)=t^1/3^              for t>0.008856

        f(t)=7.787*t+16/116   for t<=0.008856

  where delta = 128 for 8-bit images,

                0 for floating-point images

  On output 0=L=100, -127=a=127, -127=b=127

  The values are then converted to the destination data type:

      8-bit images:

          L <- L*255/100, a <- a + 128, b <- b + 128

       16-bit images are currently not supported

       32-bit images:

          L, a, b are left as is


  •   CV_RGB2Luv  CIE Luv Color로 변환한다.

  // In case of 8-bit and 16-bit images

  // R, G and B are converted to floating-point format and scaled to fit 0..1 range

  // convert R,G,B to CIE XYZ

  |X|    |0.412453  0.357580  0.180423| |R|

  |Y| <- |0.212671  0.715160  0.072169|*|G|

  |Z|    |0.019334  0.119193  0.950227| |B|

  L <- 116*Y^1/3^      for Y>0.008856

  L <- 903.3*Y      for Y<=0.008856

  u' <- 4*X/(X + 15*Y + 3*Z)

  v' <- 9*Y/(X + 15*Y + 3*Z)

  u <- 13*L*(u' - u,,n,,), where u,,n,,=0.19793943

  v <- 13*L*(v' - v,,n,,), where v,,n,,=0.46831096

  On output 0=L=100, -134=u=220, -140=v=122

  The values are then converted to the destination data type:

      8-bit images:

          L <- L*255/100, u <- (u + 134)*255/354, v <- (v + 140)*255/256

      16-bit images are currently not supported

      32-bit images:

          L, u, v are left as is


코드는 아래와 같습니다.


#include <stdio.h>

#include <unistd.h>

#include <string.h>

#include <errno.h>


#include <opencv/cv.h>

#include <opencv/highgui.h>


int main(int argc , char *argv[]){


  IplImage *imgB ;





  if (argc < 3 )

        {

                printf("usage : colorcvt.elf srcimage dstimage option \n");

                printf("      srcimage : source image file name\n");

                printf("      dstimage : destination image file name\n");

                printf("      option   : 0 : CV_RGB2GRAY \n");

                printf("                 1 : CV_RGB2YCrCb \n");

                printf("                 2 : CV_RGB2HLS \n");

                printf("                 3 : CV_RGB2HSV \n");

                printf("                 4 : CV_RGB2Lab \n");

                printf("                 5 : CV_RGB2Luv \n");

                exit(0);

        }


  // 이미지 읽기

  IplImage *imgA = cvLoadImage( argv[1] , 1);


  // 대상 이미지 확정

  switch( *argv[3] )

  {

   case '0' :

              imgB = cvCreateImage( cvGetSize( imgA), IPL_DEPTH_8U, 1);

              cvCvtColor(imgA , imgB , CV_RGB2GRAY );

              break;

   case '1' :

              imgB = cvCreateImage( cvGetSize( imgA), IPL_DEPTH_8U, 3);

              cvCvtColor(imgA , imgB , CV_RGB2YCrCb  );

              break;

   case '2' :

              imgB = cvCreateImage( cvGetSize( imgA), IPL_DEPTH_8U, 3);

              cvCvtColor(imgA , imgB , CV_RGB2HLS  );

              break;

   case '3' :

              imgB = cvCreateImage( cvGetSize( imgA), IPL_DEPTH_8U, 3);

              cvCvtColor(imgA , imgB , CV_RGB2HSV  );

              break;

   case '4' :

              imgB = cvCreateImage( cvGetSize( imgA), IPL_DEPTH_8U, 3);

              cvCvtColor(imgA , imgB , CV_RGB2Lab  );

              break;

   case '5' :

              imgB = cvCreateImage( cvGetSize( imgA), IPL_DEPTH_8U, 3);

              cvCvtColor(imgA , imgB , CV_RGB2Luv  );

              break;


  }



  cvNamedWindow("Converted Image",0);

  cvShowImage("Converted Image",(CvArr*)imgB);

  cvWaitKey(0);

  cvDestroyWindow("Converted Image");


  cvSaveImage( argv[2] , imgB);

  cvReleaseImage( &imgA );

  cvReleaseImage( &imgB );

  return 0;

}


아래는 각각의 옵션으로 했을때의 그림입니다.

컬러 스페이스가 틀린것을 강제로 출력한 형태이므로 다른 컬러 공간의 그림은 정확하게 표현되지는 않습니다. 그냥 이렇게 되었다는 것만 보면 될 듯 합니다.


원본 이미지


사용자 삽입 이미지


흑백으로 변환 이미지

사용자 삽입 이미지



사용자 삽입 이미지

사용자 삽입 이미지


사용자 삽입 이미지
사용자 삽입 이미지










'Computer Vision' 카테고리의 다른 글

OpenCV - cvSmooth  (2) 2009.04.22
Rob Hess의 SIFT [6]  (0) 2009.04.18
OpenCV - Image Mask  (0) 2009.03.16
OpenCV - Extract  (2) 2009.03.12
OpenCV - Image Rotation & Scale  (0) 2009.03.10
Posted by GUNDAM_IM