Priceless

[Vision] 영상 구조와 특징(C++) 본문

ComputerVision

[Vision] 영상 구조와 특징(C++)

Hyun__ 2023. 10. 16. 16:49

영상 데이터 표현 방법

정적 2차원 배열의 생성

가로 크기가 640, 세로 크기가 480인 정적 2차원 배열 생성

unsigned char a[480][640] {};

 

- unsigned char: 1바이트를 사용하여 0~255 사이의 정수로 표현한다

- 2차원 배열 전체 크기만큼 메모리 공간이 연속적으로 할당된다

(640 x 480 = 307200 byte)

 

단점

배열의 크기를 미리 알고 있어야 하기 때문에 다양한 크기의 영상을 다루는 데에 어려움이 있다

또한 stack 영역에 메모리를 할당하므로 대략 1MB까지 할당 가능하다

FHD(1920 x 1080)와 같은 이미지를 나타내기에는 어렵다

 

동적 2차원 배열 할당

가로 크기가 640, 세로 크기가 480인 동적 2차원 배열 생성

int w = 640;
int h = 480;

unsigned char** p; # 2차원 포인터
p = new unsigned char* [h]; # 2차원 포인터 p에 포인터를 h개 만큼 할당
for(int i = 0; i < h; i++){
    p[i] = new unsigned char[w] {}; # 각 p[i]마다 w개 만큼 할당
}

행 단위로만 연속된 메모리 공간이 보장된다

프로그램 동작 중 다양한 크기를 생성할 수 있다

Heap 영역에 메모리가 할당되므로 x86 아키텍처에서 2GB까지 할당 가능하다

 

 

코드 동작

2차원 포인터 변수 p를 선언하면 stack 영역에 로컬 변수로 선언된다

이후 new 연산자를 통해 unsigned char 포인터 타입을 h개 만큼 할당하면

h개 만큼 포인터 변수가 생성되고 그 위치를 포인터 p가 가리킨다

 

w개의 unsigned char 메모리 공간을 h번 할당한다

p[0]는 첫 번째 동적 배열을 가리킨다

기존의 p[n] 배열은 각 p[n][m] 배열의 포인터 공간으로 사용된다

최종적으로 보라색 배열에 값이 저장된다

동적 할당된 데이터 공간은 1byte이며

포인터 공간은 4byte이다

 

메모리 해제

동적 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*x + x);

 

영상 데이터 저장 클래스

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] {}; # 데이터 공간 할당 후 포인터 data를 포인터로 지정
	}
	
    # 소멸자
    ~MyImage () {
		if (data) delete[] data; # 메모리 할당이 있으면 해당 메모리 해제
	}
	
    unsigned char& at(int x, int y) { # 참조로 반환하여 읽어올 뿐만 아니라 새롭게 설정 가능
		return *(data + y * w + x); # at을 통해 반환
	}
public:
	int w, h; # 가로 길이, 세로 길이
	unsigned char* data; # 동적 할당한 메모리 공간의 시작 주소를 가리키는 포인터 변수
};