[2023-05-02] 3. 딥러닝과 OpenCV DNN 모듈
딥러닝
머신러닝 vs 딥러닝
- 어떤 영상을 주고 어떠한 영상들인지 정보만 주면 알아서 유용한 특징들을 선별해서 분류를 진행함 (End to End)
컴퓨터 비전 분야에서의 딥러닝 활용
- Image Recognition
- Object Detection
- Object Segmentation
퍼셉트론
- 다수의 입력으로부터 가중합을 계산하고, 이를 이용하여 하나의 출력을 만들어내는 구조
- 퍼셉트론, 다층 퍼셉트론, 심층 신경망
- 다층 퍼셉트론 : 은닉층(hidden layer) 1개 이상
- 심층 신경망 : 은닉층(hidden layer) 2개 이상
컨볼루션 신경망 (CNN, Convolutional Neural Network)
- 영상 인식 등의 딥러닝 분야에 특화된 네트워크 구조
필시체 숫자 인식을 위한 LeNet-5
- CNN 원조
- 28 x 28 필기체 숫자 영상을 32 x 32로 확장하여 만든 입력 데이터를 사용
- 전체 7개 레이어 : Conv - Pool - Conv - Pool - FC - FC - FC
AlexNet
VGG16
GoogLeNET
OpenCV DNN 모듈
- 미리 학습된 딥러닝 모델을 이용하여 실행(forward pass, inference)하는 기능
- 학습은 지원하지 않음
- OpenCV 3.3 버전부터 기본 기능으로 제공
-
OpenCV 4.3 버전부터 GPU(CUDA) 지원 (소스 코드 직접 빌드 필요)
- 지원하는 딥러닝 프레임워크
Net 클래스
네트워크 불러오기
void readNet(const String& model, const String& config = "", const String& framework ="");
- model : 훈련된 가중치를 저장하고 있는 이진 파일의 이름
- config : 네트워크 구성을 저장하고 있는 테스트 파일 이름
- framework : 명시적인 딥러닝 프레임워크 이름
- 반환값 : dnn : Net 객체
네트워크 입력 블롭 만들기
-
blob : 딥러닝에서 주로 사용하는 다차원 행렬)
-
Mat 클래스 객체에서 Blob으로 변환을 해서 입력을 줘야 함
Mat blobFromImage(InputArray image, double scalefactor=1.0, const Size& size = Size() )
- image : 입력 영상
- scalefactor : 입력 영상 픽셀 값에 곱할 값
- Normalized를 요구하는 딥러닝 모델을 사용할 경우 1/255. 를 입력해서 각각의 픽셀에 1/255를 곱하여 입력 영상의 각각의 픽셀 값이 0 ~1 사이가 되도록 Normalized 작업을 해야 함
- size : 딥러닝 영상에서 사용하는 입력 크기가 정해져 있는데, 그 크기로 Resize를 하기 위한 출력 영상의 크기
- mean : 입력 영상 각 채널에서 뺄 평균 값
- swapRB : R 과 B 채널을 서로 바꿀 것 인지를 결정하는 플래그
- crop : 크롭 수행 여부
- ddepth : 출력 블롭의 깊이 CV_32F 또는 CV_8U
- 반환값 : 영상으로부터 구한 블롭 객체. 4차원 NCHW(batch N, channels C, depth D, height H, width W) Mat 행렬
네트워크 입력 설정하기
void Net::setInput(InputArray blob, const String& name ="", double scalefactor = 1.0, const Scalar& mean = Scalar());
- blob : blobFromImage 함수를 통해 반환한 블롭 객체
- name : 입력 레이어 이름
- scalefactor : 추가적으로 픽셀 값에 곱할 값
- mean : 추가적으로 픽셀 값에서 뺄 평균 값
네트워크 순방향 실행(추론)
- 실제로 네트워크를 실행
Mat Net::forward(const String& outputName = String());
- outputName : 출력 레이어 이름
- 반환값 : 지정한 레이어의 출력 블롭