YUV to Mat 출력하기

Posted in Programming by

YUV format

Y : 휘도 성분 / Cb, Cr : 색차 성분

HVS (Human Visual System)에 의하면 인간은 색상보다 명암에 민감함으로 색차 성분을 줄여도 그 변화를 느끼지 못한다. 따라서 색차 성분을 줄인 정도에 따라 4:4:4, 4:2:2, 4:2:0 format으로 분류 된다.

그림1

 

Source Code

아래 예제 코드는 YUV 4:2:0 Format을 RGB로 변환 하여 출력하는 openCV 코드이다.

#include <cv.h>
#include <highgui.h>
#include <iostream>
#include <fstream>

using namespace cv;
using namespace std;

const int frame_width         = 1024;
const int frame_height        = 768;
const int pixels_num_in_frame = frame_width*frame_height;


int main( int argc, char** argv )
{
  Mat mat_y, mat_u, mat_v, mat_ext_u, mat_ext_v, mat_yuv;
  ifstream src_file("ChinaSpeed_1024x768_30.yuv", std::ifstream::binary); 
  
	// memory allocation
  mat_y.create(frame_height, frame_width, CV_8UC1);
  mat_u.create(frame_height>>1, frame_width>>1, CV_8UC1);
  mat_v.create(frame_height>>1, frame_width>>1, CV_8UC1);
  mat_yuv.create(frame_height, frame_width, CV_8UC3);
	
  vector<char> vc_y(pixels_num_in_frame);
  vector<char> vc_u(pixels_num_in_frame>>2);
  vector<char> vc_v(pixels_num_in_frame>>2);


  // copy YUV data from file
  src_file.read( &vc_y[0], pixels_num_in_frame);
  src_file.read( &vc_u[0], pixels_num_in_frame>>2);
  src_file.read( &vc_v[0], pixels_num_in_frame>>2);


  // copy YUV vector data to Matix
  for(int y=0; y<frame_height; y++)
  {
    for(int x=0; x<frame_width; x++)
    {
      mat_y.at<uchar>(y, x) = vc_y[y*frame_width+x];
    }
  }

  for(int y=0; y<frame_height>>1; y++)
  {
    for(int x=0; x<frame_width>>1; x++)
    {
      mat_u.at<uchar>(y, x) = vc_u[y*(frame_width>>1)+x];
      mat_v.at<uchar>(y, x) = vc_v[y*(frame_width>>1)+x];
    }
  }

  // up-scale of chroma components
  resize(mat_u, mat_ext_u, mat_y.size(), 0, 0, 0);
  resize(mat_v, mat_ext_v, mat_y.size(), 0, 0, 0);

  // merge 3 components 
  for(int y=0; y<frame_height; y++)
  {
    for(int x=0; x<frame_width; x++)
    {
      mat_yuv.at<Vec3b>(y, x)[0] = mat_y.at<uchar>(y, x);
      mat_yuv.at<Vec3b>(y, x)[1] = mat_ext_u.at<uchar>(y, x);
      mat_yuv.at<Vec3b>(y, x)[2] = mat_ext_v.at<uchar>(y, x);
    }
  }

  // convert color format for display
  cvtColor(mat_yuv, mat_yuv, CV_YCrCb2RGB);

	// display
  namedWindow( "Current Sequence", 2 );
  imshow("Current Sequence" , mat_yuv );
  waitKey();
}

 

※ 실습 환경

openCV2.3

visual studio 10.0