영상처리 관련 개념 및 구현을  틈나는대로 정리하여 블로그에 올릴 계획입니다. 편의상 opencv 라이브러리를 사용하여  이미지를 불러와서 Mat 객체에 저장,  이미지를 화면에 보여주기,  파일로 저장 등의 처리를 했습니다. opencv 설치는 아래 글들을 참고하세요. 


[그래픽스&컴퓨터비전/개발환경] - Visual Studio 2015에서 OpenCV 3.1 연동하기

[그래픽스&컴퓨터비전/개발환경] - OpenCV 3.1을 Ubuntu 16.04에 설치

[그래픽스&컴퓨터비전/개발환경] - OpenCV 3.1을 Ubuntu 14.04에 설치

 


첫번째 내용은 컬러영상을 그레이스케일 영상으로 변환하는 것입니다.  OpenCV에서 보통 이미지를 불러올 때, BGR888 포맷을 사용합니다. 한 픽셀당 Blue 8비트, Green 8비트, Red 8비트 정보가 포함되어 있습니다. RGB라 하지 않고 BGR이라 하는 이유는 메모리상에 저장되는 순서가 Blue, Green, Red 이기 때문입니다. 4개의 픽셀을 예로 들면 다음처럼 저장됩니다.

(0,0)                 (0,1)                (0,2)                 (0,3)

Blue Green Red  Blue Green Red  Blue Green Red  Blue Green Red 


화면에 픽셀이 표시될 때 Blue, Green, Red 값에 따라 다른 색으로 표현됩니다. 각 성분의 값은 0~255까지 가능합니다.  각 성분의 크기가 8비트이기 때문에 2의 8승인 256가지(0~255)를 표현할 수 있기 때문입니다.

Blue 

Green 

Red 

픽셀 색 

 255

255 

255 

흰색 

 0

0

검정색 

 128

128

128 

회색

 255

파란색 

 0

255 

녹색 

 0

255 

빨간색 

 0

255 

255 

노란색 


컬러 영상의 모든 픽셀에 대해 blue, green, red를 더하고서  3으로 나누면 그레이 스케일 영상으로 변환이 됩니다. 

실제로 구현한 코드입니다. 컬러 영상을 저장하고 있는 img_input에서 픽셀 접근하는 부분과 그레이 스케일 영상을 저장하는 img_gray에서 픽셀 접근하는 부분은 자주 사용하게 되니 기억해두면 유용합니다. 

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <opencv2/highgui.hpp>
#include <iostream>
 
using namespace std;
using namespace cv;
 
 
int main()
{
    Mat img_input, img_gray;
        
    //이미지 파일을 읽어와서 img_input에 저장
    img_input = imread("input2.jpg", IMREAD_COLOR);
    if (img_input.empty())
    {
        cout << "파일을 읽어올수 없습니다." << endl;
        exit(1);
    }
 
 
    // 1채널, uchar로 생성
    //opencv에선 unsigned char을 uchar로  재정의해서 사용한다.
    img_gray = Mat(img_input.rows, img_input.cols, CV_8UC1);
 
    for(int y=0; y<img_input.rows; y++)
    { 
        for (int x = 0; x < img_input.cols; x++)
        {
            //img_input으로부터 현재 위치 (y,x) 픽셀의
            //blue, green, red 값을 읽어온다. 
            uchar blue = img_input.at<Vec3b>(y, x)[0];
            uchar green = img_input.at<Vec3b>(y, x)[1];
            uchar red = img_input.at<Vec3b>(y, x)[2];
 
            //blue, green, red를 더한 후, 3으로 나누면 그레이스케일이 된다.
            uchar gray = (blue + green + red) / 3.0;    
 
            //Mat타입 변수 img_gray에 저장한다. 
            img_gray.at<uchar>(y, x) = gray; 
        }
    }
 
 
    //화면에 결과 이미지를 보여준다.
    imshow("입력 영상", img_input);
    imshow("그레이스케일 영상", img_gray);
 
    //아무키를 누르기 전까지 대기
    while (cvWaitKey(0== 0);
 
    //결과를 파일로 저장
    imwrite("img_gray.jpg", img_gray);
}
cs


opencv에서 제공하는 함수를 이용하여 구현한 코드입니다. 

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
31
32
33
34
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
 
using namespace std;
using namespace cv;
 
 
int main()
{
    Mat img_input, img_gray;
        
    //이미지 파일을 읽어와서 img_input에 저장
    img_input = imread("input2.jpg", IMREAD_COLOR);
    if (img_input.empty())
    {
        cout << "파일을 읽어올수 없습니다." << endl;
        exit(1);
    }
 
 
    cvtColor(img_input, img_gray, COLOR_BGR2GRAY);
 
 
    //화면에 결과 이미지를 보여준다.
    imshow("입력 영상", img_input);
    imshow("그레이스케일 영상", img_gray);
 
    //아무키를 누르기 전까지 대기
    while (cvWaitKey(0== 0);
 
    //결과를 파일로 저장
    imwrite("img_gray.jpg", img_gray);
}

 

 

출처 :  http://webnautes.tistory.com/1042?category=710857

블로그 이미지

맨오브파워

한계를 뛰어 넘어서..........

,