컴퓨터 비전에 대한 기초 지식과 컴퓨터 비전을 활용하기 위한 OpenCV에 대한 기본적인 내용들을 위주로 학습을 진행했다.
컴퓨터 비전은 정지 영상 또는 동영상으로부터 의미 있는 정보를 추출하는 방법을 연구하는 학문을 말한다.
컴퓨터 비전은 신호처리, 광학, 머신러닝, 컴퓨터 과학... 등 다양한 학문을 기초로 필요로 한다. 최근에는 컴퓨터 비전이 수학적 분야로 많이 인식되고 있다.
컴퓨터 비전은 다양한 일상에 활용되고 있다. 기본적으로 스마트폰에서 사용되는 HDR 영상은 밝기에 따른 여러 이미지를 촬영한 뒤 합성한 것이다. 48MP의 카메라 데이터를 별도로 찍어 낮은 해상도의 이미지의 디테일을 살리는 작업에도 활용된다. 이 밖에도 얼굴 검출, 얼굴 인식 등 일상 속 다양한 환경에서 컴퓨터 비전이 사용되고 있음을 볼 수 있다.
영상에는 R, G, B 세 가지 성분을 사용하게 되는데, C/C++에서는 각각의 요소를 unsigned char 자료형을 사용해 표현한다.
class RGB{
unsigned char R;
unsigned char G;
unsigned char B;
};
컴퓨터에서 영상을 사용할 때에는 x-by-h image 형태를 사용하게 된다.

이미지 데이터는 2차원 배열의 형태이므로, 정적 또는 동적으로 저장해 사용할 수 있다.
unsigned char a[480][640] {};
하지만 이처럼 2차원 정적으로 저장하게 되면, Stack 영역을 활용하게 되기에 1MB까지의 데이터만 저장할 수 있게 된다.
따라서, 보통은 동적 2차원 배열로 선언해 이미지를 저장하게 된다. 이 경우 Heap 영역에 할당하게 되며 x86 시스템의 경우 2GB까지, x64 시스템의 경우 8TB까지 저장이 가능하다.
int w = 640;
int h = 480;
unsigned char** p;
p = new unsigned char*[h];
for(int i = 0; i < h; i++){
p[i] = new unsigned char[w] {};
}
다음과 같이 이미지를 2차원이 아닌 1차원 대용량 배열에 저장하는 방식으로도 사용이 가능하다.
int w = 10, h = 10;
unsigned char* data = new unsigned char[w * h] {};
이미지는 다양한 형태로 저장할 수 있다. 컴퓨터를 사용하며 bmp, jpg 등 다양한 이미지 파일을 봤을 것이다.
- BMP 파일: 픽셀 데이터를 압축하지 않고 그대로 저장하는 형태로, 파일 용량이 큰 편이다.
- JPG 파일: 사진과 같은 컬러 영상을 저장하는 형태로, 손실 압축 통해 파일 용량이 크게 감소된다.
- GIF 파일: 256 색상 이하의 영상을 저장하며, 무손실 압축을 지원한다. 움직이는 GIF 파일을 지원한다.
- PNG 파일: 무손실 압축을 지원하는 파일 형태로, 알파 채널(투명도)를 지원한다.
이미지를 저장하는 전통적인 방식은 비트맵 방식인 BMP 파일 형태이다. BMP 파일은 다음과 같은 구조로 저장되어 있다.

비트맵 파일 헤더에는 파일에 대한 정보를 담고 있고, 비트맵 정보 헤더에는 사용하는 색상의 정보, 이미지의 구조 등의 데이터가 저장되어 있다. 이 중 가장 중요한 것은 다음과 같다.
- 그레이 스케일은 RGBQUAD 배열의 인덱스로 저장된다.
- 트루컬러는 BGR 순서로 픽셀 값이 저장된다.
- 일반적으로 상하가 뒤집힌 Bottom-up 형태로 저장된다.
- 효율적인 데이터 관리를 위해 영상의 가로 크기를 4배수로 저장한다.
OpenCV는 오픈소스 기반의 컴퓨터 비전과 머신러닝용 라이브러리이다. 많은 컴퓨터비전에서 OpenCV를 사용하고 있다. OpenCV는 BSD/Apache2 License를 사용하고 있기 때문에, 교육은 물론 회사에서도 무료로 사용할 수 있다. 또한, C/C++은 물론 Java, Python 등등 많은 언어를 지원하며, Windows, MAC에 상관없이 사용이 가능한 장점을 갖고 있다. 또한, 최적화가 좋은 것이 OpenCV를 사용하는 큰 이유 중 하나이다.(CUDA, OpenCL, Multi-Core 환경을 지원)
OpenCV는 다양한 모듈들을 지원하고 있다. 이미지 처리 과정에 따라 사용되는 모듈들은 다음과 같다. 프로그래밍 절차에 따라 다르지만, 다음 모듈들은 대부분 사용되는 모듈들이라 할 수 있다.

윈도우에서 Visual Studio를 사용해 개발환경을 구성했다. 우선 OpenCV 홈페이지에서 OpenCV를 다운받는다. OpenCV 4.5.5를 사용했으며, 압축을 풀 수 있는 프로그램으로 실행되는데 C드라이브에 opencv라는 폴더로 압축을 풀었다.
먼저 쉽게 사용하기 위해 opencv의 위치를 환경변수에 등록한다. 고급시스템 설정 -> 환경변수 -> 사용자 변수에 새로만들기로 OPENCV_DIR이라는 변수명으로 C:\opencv\build를 지정해준다.

Visual Studio에서 빈프로젝트로 프로젝트를 생성한 뒤, main.cpp를 추가해 다음 소스코드를 입력한다.
#include <iostream>
#include "opencv2/opencv.hpp"
using namespace std;
int main() {
cout << "Hello, OpenCV" << CV_VERSION << endl;
}
빌드를 정상적으로 하기 위해 상단의 디버스 -> '프로젝트이름' 디버그 속성으로 들어와 다음 항목들을 설정한다.
상태추정이라는 학문 분야로 로봇틱스에서 많이 사용되는 분야이다. 로봇의 위치를 추정하기 위해 필요한 학문 중 하나이다. 로봇의 위치는 여러 센서를 통해 수집할 수 있으나, 노이즈들로 인해 정확한 위치를 추정하는 데 어려움이 있다. 따라서, 로봇의 움직임을 추정할 때 완벽한 값이 아닌 State Estimation을 진행한다. 즉 확률과 통계에 대한 이해가 필요하다.
확률에서 기본적인 이론은 다음과 같다.
즉 Discrete random variable에서는 이라 할 수 있으며, 으로 구성된다. 이며, 부터 에 대한 총 합을 이라 할 수 있다.
위의 경우는 (이산 확률 변수)로 연속적이지 않은 구간에 대한 값이며, 이 때의 확률을 구하는 함수를 이라 한다.
연속된 구간에서는 (연속 확률 변수)로 구간에 대해 적분한 값인 으로 구할 수 있게 되는데, 이를 이라 한다.
두 개의 변수 와 가 있을 때, 형태로 함수가 구성되게 된다. 이 때, 와 가 (독립적이지 않음)하다고 할때, 가 된다.
상황에 대한 확률은 다음과 같이 구할 수 있다. 만일 가 주어진 상황에서 의 확률 분포를 구할 떄에는 로 함수를 표현하며 다음과 같이 계산할 수 있다.
만일, 와 가 하다면, 가 된다.
SLAM에서는 다음과 같은 식이 중요한 요소 중 하나이다.
SLAM에서 가 로봇의 위치, 가 센서라 가정한다면, 센서 값이 주어졌을 때, 로봇의 위치를 추론하겠다는 의미를 갖는다. 반대로 로봇의 위치 데이터를 기반으로 센서 값이 올바른지 추정할수도 있는 환경이 구성된다.
확률과 통계가 나와 조금 어지럽다.
아직은 궁금한 점이 없었다.
학부 때 '윈도우즈 프로그래밍'이라는 교과목을 수강한 적이 있다. 그 때 사용한 교재가 황선규 강사님의 'Visual C++ 영상처리 프로그래밍'이라는 도서였다. 황선규 강사님의 교육을 직접 들을 수 있었기에 좋은 경험이었다. 학부 때 공부한 내용이 머리 속에 아직 남아있어 이해하는데 어렵지는 않았고, 복기하듯이 강의를 둘러볼 수 있었다.
수학에 대한 기초가 어느정도 필요한듯 하다. 그 중 확률과 통계 선형대 수학에 대해서는 추가적으로 공부를 하면 좋을것 같다.
📌 프로그래머스 데브코스 6기 자율주행 인지과정(Perception) 수강 내용을 바탕으로 정리한 TIL 입니다.
📅 Today: 2023.10.16.