티스토리 뷰
이번 글에서는 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
'영상처리_머신러닝을 통한 스마트카 > open_cv' 카테고리의 다른 글
컬러 모델 Gray, RGB, HSI, CMY, CMYK, YUV(YCbCr) : 색상을 좌표상의 한 점으로 표현하자 (3) | 2016.12.27 |
---|