OpenCV의 영상 데이터 구조체인 IplImage는 imageData라는 배열에 영상의 픽셀 정보를 저장한다. IplImage로부터 픽셀 값을 읽어오는 방법은 두가지로 분류된다.
1. 직접 imageData라는 배열에 접근해서 가져오는 방법
2. cvGet* 함수를 이용하는 방법
1. 픽셀에 직접 접근하는 방법
픽셀에 직접 접근하는 경우는 imageData에서 픽셀의 인덱스를 계산하여 값을 얻어온다. 인덱스를 계산할 때는 보통 widthStep을 이용한다. 왜냐하면 IplImage에서 row하나가 저장되는 메모리의 폭을 나타내게된다. 그러나 영상의 폭이 홀수로 끝나는 경우는 영상의 한 row가 저장되는 메모리 폭이 width와 다를 수 있기 때문에 x 좌표가 하나씩 밀리는 현상이 나타날 수 있다. 그렇기 때문에 width 보다는 widthStep을 이용하는 것이 안전하다.
IplImage* img = cvLoadImage("lena.png", 1); IplImage *red = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 3); IplImage *green = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 3); IplImage *blue = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 3); int i, j, nIdx; for (i = 0; i < img->height; i++) { for (j = 0; j < img->width; j++) { nIdx = i*img->widthStep + j*img->nChannels; red->imageData[nIdx + 2] = img->imageData[nIdx + 2]; green->imageData[nIdx + 1] = img->imageData[nIdx + 1]; blue->imageData[nIdx + 0] = img->imageData[nIdx + 0]; } }
이러한 예제코드에서 볼 수 있듯
channel RGB 영상의 경우
int index = 3*x + y*widthStep;
unsigned char B = image->imageData[index];
unsigned char G = image->imageData[index+1];
unsigned char R = image->imageData[index+2];
이러한 형식으로 픽셀에 직접 접근 할 수 있다.
channel gray 영상의 경우에는
int index = x + y *image->widthStep;
unsigned char value = image->imageData[index];
이러한 형식으로 픽셀에 직접 접근 할 수 있다.
2. cvGet* 함수를 이용하는 방법
이 방법은 OpenCV가 제공해주는 cvGet 함수를 이용하는 것이다. 1채널 Gray 영상에는 cvGetReal2D() 함수를 사용하고 double 값을 이용한다. 다채널 영상(ex 3채널..)에서는 cvGet2D() 함수를 사용하고, CvScalar 구조체를 사용하여 각 채널별로 값을 저장해서 리턴한다. 특히, 함수의 인자가 알던 순서와는 다르게 반대이기 때문에 x, y 순서에 주의해야한다.
channel RGB 영상의 경우
double value = cvGetReal2D(iamge, y, x);
channel gray 영상의 경우
CvScalar value = cvGet2D(iamge, y, x);
double B = value.val[0];
double G = value.val[1];
double R = value.val[2];
cvGet* 함수를 쓰는 것 보다 imageData에 직접 접근하는 방법이 성능이 빠르다고 한다. 하지만 인덱스 계산할 필요 없이 픽셀 좌표만으로 데이터를 가져오는데는 함수를 이용하는 것이 더 편리한 것은 자명한 사실이다.
'Programming > OpenCV' 카테고리의 다른 글
OpenCV 히스토그램 구현하기 (0) | 2016.01.18 |
---|---|
OpenCV 픽셀 값 접근하기 - cvMat 데이터 구조 (4) | 2016.01.06 |
OpenCV 트랙바 처리된 이진화 영상처리 in C++ (0) | 2016.01.05 |
OpenCV에서 IplImage와 Mat의 차이 그리고 호환 (2) | 2016.01.05 |
OpenCV 히스토그램 그리기 in C++ (2) | 2016.01.05 |