[2023-04-17] 4. 영상 데이터 구조와 표현 방법
영상 데이터 구조와 표현 방법
영상(image)이란?
- 픽셀이 바둑판 모양의 격자에 나열되어있는 형태 (2차원 행렬)
- 픽셀은 영상의 기본 단위로 Picture Element의 줄임말로 화소라고도 부름
그레이스케일 영상(Grayscale Image)
- 흑백 사진 처럼 색상 정보가 없이 오직 밝기 정보만으로 구성된 영상
- 밝기 정보를 256단계로 표현 [0,255]
- C/C++ 에서 unsigned char로 표현함 : 1Byte
typedef unsigned char BYTE; // Windows
typedef unsigned char uint8_t; // Linux
typedef unsigned char uchar; // OpenCV
트루컬러 영상(Truecolor Image)
- 컬러 사진 처럼 다양한 색상을 표현할 수 있는 영상
- RGB 색 성분으로 256단계로 표현 256 * 256 * 256 = 16,777,216 색상 표현 가능
- unsigned char 자료형 3개 있는 배열 또는 구조체로 표현 : 3Byte
class RGB
{
unsigned char R;
unsigned char G;
unsigned char B;
};
영상에서 사용되는 좌표계
- 그레이스케일 영상에서 픽셀 값 분포
- 트루컬러 영상에서 픽셀 값 분포
영상 데이터 표현 방법
정적 2차원 배열의 생성
unsigned char a[480][640] {};
- unsigned char : 1Byte 사용
- 2차원 배열 전체의 크기 만큼 메모리공간이 연속적으로 할당되므로 640 * 480 = 307200 Byte
- 배열의 크기를 미리 알고 있어야 함
- 다양한 크기의 영상을 표현하기에 부적절함
동적 2차원 배열의 생성
int w = 640;
int h = 480;
unsigned char** p; //
p = new signed char*[h];
for (int i = 0; i<h; i++) {
p[i] = new unsigned char[w] {};
}
- 행 단위로만 연속된 메모리 공간이 보장됨
- 프로그램 동작 중 다양한 크기의 영상을 생성할 수 있음
- new 연산자를 사용하면, Heap 영역에 메모리를 할당 : x86의 경우 2GB 까지 할당 가능하며 x64의 경우 8TB 까지 가능
- 동적 2차원 배열의 원소에 접근하는 방법
- 2차원 배열 p의 모든 원소 값을 10씩 증가하기
for (int y=0; y<h; y++){
for (int x = 0; x<w; x++) {
p[y][x] = p[y][x] + 10;
}
}
- 동적 2차원 배열의 메모리 해제
- 동적 2차원 배열 생성의 역순으로 해제하며 delete 구문에서 괄호 연산자 [] 를 반드시 사용해야 함
for(int y =0; y<h; y++)
delete[] p[i]; // 각각의 행에 대한 메모리 공간을 먼저 해제
delete[] p; // 각각의 행을 가리키기 위한 포인터 변수 공간을 다음으로 해제
대용량 1차원 메모리 할당 후 영상 데이터 저장하기
- 2차원 배열이 아닌 1차원 배열에 영상의 픽셀 값을 차례대로 이어 붙여서 저장하여 사용
int w = 10, h = 10;
unsigned char * data = new unsigned char[w*h] {};
...
delete [] data;
- 특정 좌표(x,y) 위치의 픽셀 값 참조하기
unsigned char& p1 = *(data + y*w + x); // w는 영상의 가로 크기 , (x,y)는 좌표, data는 시작 좌표
- 간단한 형태의 영상 데이터 저장 클래스
class MyImage
{
public :
MyImage() : w(0), h(0), data(0) {}
MyImage(int _w, int _h) : w(_w), h(_h) {
data = new unsigned char[w*h] {} ;
}
~MyImage(){
if(data) delete[] data;
}
unsigned char& at(int x, int y) {
return *(data + y * w + x);
}
public :
int w, h;
unsigned char* data;
};