티스토리 뷰

이번 글에서는 OpenCV에서 RGB 컬러를 Grayscale로 변환하는 방법에 대하여 알아보도록 하겠다. 

우선 이론적으로 살펴보면, 가장 널리 사용되는 방법 중 하나가
Luma Coding(
https://en.wikipedia.org/wiki/Grayscale)을 이용한 방법인데, 수식은 다음과 같다:



여기서, R', G', B'은 Red, Green, Blue 채널에 대한 비디오 시스템의 Gamma-compressed 값이다.

이들로부터 계산된 Y'은 비선형 Luma 컴포넌트(Nonlinear Luma Component)이며, Grayscale된 값이다.

이 수식을 기반으로 RGB 컬러를 Grayscale로 변환하는 OpenCV Source Code는 다음과 같다.



[Source Code 1]

#include <iostream>

#include <opencv2/opencv.hpp>


#include <stdlib.h>

#include <stdio.h>


using namespace std;

using namespace cv;


/* @ function main */

int main( int argc, char** argv )

{

  /// Load an image

  cv::Mat image = cv::imread( {YOUR_IMAGE_PATH}, 1 );

  cv::Mat image_gray;


  /// Copy image

  image.copyTo( image_gray );


  int nRows = image.rows;

  int nCols = image.cols;


  /// Convert to gray

  float fGray = 0.0f;

  float chBlue, chGreen, chRed;


  for( int j = 0 ; j < nRows ; j++ ) {


    for( int i = 0 ; i < nCols ; i++ ) {


      chBlue  = (float)( image.at<cv::Vec3b>(j,i)[0] );

      chGreen = (float)( image.at<cv::Vec3b>(j,i)[1] );

      chRed = (float)( image.at<cv::Vec3b>(j,i)[2] );


      fGray = 0.2126f * chRed + 0.7152f * chGreen + 0.0722f * chBlue;


      if( fGray < 0.0 ) fGray = 0.0f;

      if( fGray > 255.0 ) fGray = 255.0f;


      image_gray.at<cv::Vec3b>(j,i)[0] = (int)fGray;

      image_gray.at<cv::Vec3b>(j,i)[1] = (int)fGray;

      image_gray.at<cv::Vec3b>(j,i)[2] = (int)fGray;


    }


  }


  /// Creates window

  cv::namedWindow( "Image Original", CV_WINDOW_AUTOSIZE );

  cv::namedWindow( "Image Grayed", CV_WINDOW_AUTOSIZE );


  /// Show stuff

  cv::imshow( "Image Original", image );

  cv::imshow( "Image Grayed", image_gray );


  /// Wait until user press some key

  cv::waitKey();


  return 0;


}

 



결과를 살펴보면 다음과 같다.


[Result]

위의 코드는 순전히 이론을 바탕으로 정말 충실하게 픽셀 하나하나 끄집어내어 계산한 것이다. 하지만 매우 효율면에서 떨어질뿐더러 OpenCV가 위의 연산을 수행하는 함수를 제공하지 않을리 없다.

OpenCV의 cvtColor() 함수는 상당히 다양한 Color Space 간 변환을 해주는 함수이며, 계산 속도도 매우 빠르다. 이 함수의 프로토타입은 다음과 같다:

void cvtColor( InputArray src, OutputArray dst, int code, int dstCn=0 )

src: input image

dst: output image (destination image)

code: color space conversion code

dstCn: number of channels in the destination image


이 함수를 이용하여 RGB를 Grayscale로 변환하는 코드를 작성하면 다음과 같다.



[Source Code 2]

#include <iostream>

#include <opencv2/opencv.hpp>


#include <stdlib.h>

#include <stdio.h>


using namespace std;

using namespace cv;


/* @ function main */

int main( int argc, char** argv )

{

  cv::Mat image, image_gray;


  /// Load an image

  image = cv::imread( {YOUR_IMAGE_PATH}, 1 );


  if( !image.data ) { return -1; }


  /// Convert it to gray

  cv::cvtColor( image, image_gray, CV_RGB2GRAY );


  /// Create window

  cv::namedWindow( "Image Original", CV_WINDOW_AUTOSIZE );

  cv::namedWindow( "Image Grayed", CV_WINDOW_AUTOSIZE );

  

  /// Show stuff

  cv::imshow( "Image Original", image );

  cv::imshow( "Image Grayed", image_gray );

  

  /// Wait until user press some key

  cv::waitKey();


  return 0;


}




당연한 얘기겠지만 소스가 매우 간결해졌다. 결과는 다음과 같다.


[Result]



깔끔하게 정리가 잘 된 글을 발견하여 퍼왔다.

출처 : http://cinema4dr12.tistory.com/entry/OpenCV-RGB-Color%EB%A5%BC-Grayscale%EB%A1%9C-%EB%B3%80%ED%99%98%ED%95%98%EA%B8%B0

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함