-
영상 데이터 구조 및 표현OpenCV/OpenCV_Common 2023. 11. 6. 23:27
영상(Image)?
- 픽셀(pixel)이 바둑판 모양의 격자에 나열되어 있는 형태(2차원 행렬)
- pixel: 영상의 기본 단위, picture element.
1pixel에 R(red), G(green), B(blue) 세가지 색상을 표현할 수 있다.
우리가 흔히 아는 해상도(Resolution)의 640x480은 가로 640pixel, 세로 480pixel이라는 의미이다.
표현하는 pixel의 개수가 많을수록 세밀한 표현이 가능하다.
그레이스케일 영상(Grayscale image)
- 흑백 사진처럼 색상 정보가 없이 오직 발기 정보만으로 구성된 영상.
- 밝기 정보를 256단계로 표현한다.
그레이스케일 영상의 픽셀 값 표현
- 그레이스케일 영상에서 하나의 픽셀은 0 ~ 255 사이의 정수 값을 갖는다.
- 그레이스케일 범위(grayscale level): [0, 255] or [0, 256)
- C, C++에서 unsigned char로 표현한다.(1Byte)
- unsigned char의 범위는 0 ~ 255의 양수표현이 가능하다.
typedef unsigned char BYTE; // Windows typedef unsigned char uint8_t; // Linux typedef unsigned char uchar; // OpenCV
트루컬러 영상(Truecolor image)
- 컬러 사진처럼 다양한 색상을 표현할 수 있는 영상
- Red, Green, Blue색 성분을 각각 256단계로 표현한다.
- 256^3(16,777,216)개의 색상 표현이 가능하다.
트루컬러 영상의 픽셀 값 표현
- R, G, B색 성분의 크기를 각각 0 ~ 255 범위의 정수로 표현
- 0: 해당 색상 성분이 전혀 없는 상태
- 255: 해당 색상 성분이 가득 있는 상태
- C, C++에서는 unsigned char 자료형 3개가 있는 배열 또는 구조체로 표현된다. (3Bytes)
class RGB { unsigned char R; unsigned char G; unsigned char B; };
영상에서 사용되는 좌표계
그레이스케일 영상에서는 1픽셀에 1개의 밝기 정보를 표시.
트루컬러 영상에서는 1픽셀에 R, G, B 3개의 밝기 정보를 표시.
정적 2차원 배열의 생성
unsigned char a[480][640] ();
- unsigned char: 1byte 사용 (0 ~ 255)
- 2차원 배열 전체 크기만큼의 메모리 공간이 연속적으로 할당. (640x480 = 307200byte. 약 0.3MB )
단점
- 배열 크기를 미리 알고 있어야 한다. (다양한 영상을 표현하기에 부적절)
- Stack 영역에 메모리 할당. (대략, 1MB까지 할당이 가능하다.
동적 2차원 배열의 생성
unsigned char** pl p = new unsigned char*[h]; for(int i = 0; i < h; i++{ p[i] = new unsigned char[w] {}; }
동적 2차원 배열의 원소에 접근하기
ex) 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; // 이 부분은 p[0] ~ p[h-1]를 제거하기 위해 사용.
대용량 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);
아래는 간단한 형태의 영상 데이터 저장 클래스이다.
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; };
파일 구조
비트맵(bitmap)
- 비트(bit)들의 집합(map). 픽셀들의 집합이다.
- 영상 전체 크기에 해당하는 픽셀 정보를 그대로 저장한다.
- 장점: 표현이 직관적이고 분석이 용이
- 단점: 메모리 용량을 많이 차지, 영샹의 확대/축소 시 화질 손상이 심함.
- 사진, 포토샵
비트맵의 종류
- 장치 의존 비트맵(DDB)
- 출력 장치들의 설정에 따라 다르게 표현된다.
- 장치 독립 비트맵(DIB)
- 출력 장치가 달라지더라도 항상 동일하게 출력된다.
- BMP 파일은 Windows 환경에서 비트맵을 DIB 형태로 저장한 파일 포맷이다.
번외: 벡터 그래픽스(vector graphics)
- 점과 점을 연결하여 수학적 원리로 그림을 그려서 표현하는 방식.
- 이미지 크기를 확대/축소 시 화질이 손상되지 않음.
- 폰트, 일러스트레이터
BMP 파일의 구조
비트맵 파일 헤더
비트맵 파일에 대한 정보
typedef struct tagBITMAPFILEHEADER{ WORD bfType; // 'B', 'M', 0x42, 0x4D DWORD bfSize; // BMP 파일 크기 WORD bfReserved1; WORD bfReserved2; DWORD bfOffBits; // 비트맵 비트까지의 오프셋 } BITMAPFILEHEADER;
비트맵 정보 헤더
비트맵 영상에 대한 정보
typedef struct tagBITMAPINFOHEADER{ DWORD biSize; // BITMAPINFOHEADER 크기 LONG biWidth; // 비트맵 가로 크기 LONG biHeight; // 비트맵 세로 크기 WORD biPlanes; // 1 WORD biBitCount; // 픽셀 당 비트수 DWORD biCompression; // BI_RGB DWORD biSizeImage; LONG biXpelsPerMeter; LONG biYpelsPerMeter; DWORD biClrUsed; DWORD biClrImportant; } BITMAPINFOHEADER;
색상 테이블/팔레트
비트맵에서 사용되는 색상 정보
typedef struct tagRGBQUAD{ BYTE rgbBlue; BYTE rgbGreen; BYTE rgbRed; BYTE rgbReserved; } RGBQUAD;
- 그레이스케일 비트맵
- (0, 0, 0, 0), (1, 1, 1, 0), 2, 2, 2, 0), ..., (255, 255, 255, 0)
- 전체 4 x 256 = 1024Bytes
- 트루컬러 비트맵
- 색상 테이블이 존재하지 않음.
픽셀 데이터
- 그레이스케일 비트맵: RGBQUAD 배열의 인덱스 저장.
- 트루컬러 비트맵: (BGR) 순서로 픽셀 값 저장.
- 일반적으로 상하가 뒤집힌 상태로 저장. (bottom-up)
- 효율적 데이터 관리를 위해 영상의 가로 크기를 4의 배수로 저장.
각 파일의 형식과 특징
BMP
- 픽셀 데이터를 압축하지 않고 그대로 저장. (파일 용량이 크다.)
- 파일 구조가 단순.
- 별도의 라이브러리 도움 없이 파일 입출력 프로그래밍 가능.
JPG
- 주로 사진과 같은 컬러 영상을 저장.
- 손실 압축. (lossy compression)
- 압축률이 좋아서 파일 용량이 크게 감소. (디지털 카메라 사진 포멧으로 주로 사용)
GIF
- 256 색상 이하의 영상을 저장. (일반 사진을 저장 시 열화가 심함)
- 무손실 압축. (lossless compression)
- 움직이는 GIF 지원.
PNG
- Portable Network Graphics.
- 무손실 압축. (컬러 영상도 무손실 압축)
- 알파 채널(투명도)을 지원.
영상 데이터 크기 분석
- 그레이스케일 영상: (가로 크기) x (세로 크기) Bytes
- 트루컬러 영상: (가로 크기) x (세로 크기) x 3Bytes
ex) 그레이스케일 영상 512 x 512 = 262144 Bytes
ex) 트루컬러 영상 (FHD) 1920 x 1080 x 3 = 6220800 Bytes (약 6MB)
BMP, PNG, JPG의 각 파일에 대해 용량을 비교하면 다음과 같다.
JPG는 압축이 가능한 형식이다.
보면 바다와 숲 이미지의 경우 압축률이 다른데, 바다 그림과 같이 평이한 이미지는 압축률이 좋지만, 숲은 평이한 이미지가 아니기 때문에 압축률이 낮다.
바다 사진의 성분은 저주파 성분이 강함.
숲 사진의 성분은 고주파 성분이 강함.
'OpenCV > OpenCV_Common' 카테고리의 다른 글
OpenCV 개요 및 설치 (0) 2023.11.09 컴퓨터 비전 개요 (0) 2023.11.06