OpenCV DNN ( Deep Neural Network ) 모듈
- 미리 학습된 딥러닝 모델을 이용하여 실행 ( forward pass, inference ) 하는 기능 ( 학습기능 X )
TensorFlow나 torch에서 학습된 Weight 파일을 가져와서 테스트 데이터로 실행을 할 수 있는 기능제공
- OpenCV는 C언어 C++로도 실행을 할 수 있는데 Python 에서 학습을 하고 학습된 결과를 C언어로 구성되어있는
프로그램을 만들때 OpenCV 모듈을 가져와서 사용하게 되면 편하게 exe파일을 만들 수 있음
- 학습은 지원하지 않음
- OpenCV 3.3버젼부터 기본 기능으로 제공 ( pip install 가능 )
- OpenCV 4.3 버전부터 GPU ( CUDA ) 지원 ( 소스코드 직접 빌드 필요 )
- 참고 : Deep Learning in OpenCV · opencv/opencv Wiki · GitHub
GitHub - opencv/opencv: Open Source Computer Vision Library
Open Source Computer Vision Library. Contribute to opencv/opencv development by creating an account on GitHub.
github.com
위 지원되는 프레임 워크가 의미하는 것은
DNN 모듈이 테스트 해본 딥러닝 학습 FrameWork ( 라이브러리 ) 프로그램을 지원
* ONNX 는 Open Network Exchange , Caffe 나 Tensor Flow 에서 학습을 하게되면 학습된 Weight를 저장하는
포맷이 조금씩 달라지는데 해당 포맷들을 하나로 통일시켜놓은 새로운 포맷
지원되는 레이어는 많이 사용되고있는 네트워크 구조를 의미한다.
따라서 DNN 모듈은 다른 곳에서 학습되어있는 포맷을 실행시킬 수 있는 모듈이기 때문에
학습되어있는 Weight 포맷을 다운 받을 수 있는 링크도 포함되어있다.
그리고 물체 감지라고 하는 분류창에서는 Image 처리에서 사용하는 Detection의 의미와 비슷한데
딥러닝에서의 Detection은 어떤 객체가 어느정도의 크기를 갖고있는지에 따른 Bounding Box를 찾고
해당 Bounding Box가 어떤 객체인지 Identification 까지 하는 기능을 갖고있는 포맷이다.
Semantic Segmentation
- 단순히 바운딩박스를 그리는 것이 아니고 해당 물체의 윤곽까지 잡아주는 포맷
Pose estimation
- 사람의 관절 위치를 알아낼 수 있는 포맷 , 따라서 어떤 자세를 취하고 있는지 알 수 있음
Image Processing
- 이미지를 흑백으로 줬을 때 자동으로 컬러를 넣는 포맷 ( Colorization ( Caffe ) )
- 사진을 줬을 때 유명화가가 쓴 화풍 형태의 이미지로 변환해주는 포맷 ( Fast-Neural-Style ( Torch ) )
Person Identification
- 얼굴 인식과 관련된 Deep Learning FrameWork
해서 결론은 위 사이트에서 프레임워크를 다운받아서 사용할 수 있다.
그리고 실제로 이미 학습되어있는 파일을 가져와서 OpenCV에서 사용하는 방법에 대해서 설명한다.
OpenCV DNN API
네트워크 불러오기
cv2.dnn.readNet ( model, config=None, framework = None ) -> retval
- mode : 훈련된 가중치를 저장하고있는 이진 파일 이름 ( 문자열 )
- config : 네트워크 구성을 저장하고 있는 텍스트 파일 이름 ( 문자열 )
아래 표를 보면 알 수 있지만 있는경우도있지만 없는 경우도 있음
- framework : 명시적인 딥러닝 프레임워크 이름
- retval : cv2.dnn_Net 클래스 객체
텐서플로우같은 경우는 .pbtxt 가 필요없는 경우도 있고
어떤 방식으로 pb파일을 만들었는지에따라 다른데 요즘에는 필요없는 경우가 많음
그리고 framework 문자열은 거의 사용되지 않고, model 과 config만 잘 주게되면
readNet 함수는 dnn_Net이라는 클래스 객체를 반환해준다.
예를들어 GooLeNet 을 불러왔으면 GoogLeNet에 대한 전체의 네트워크 구조가 메모리상에 가상으로 생성이된다.
그리고 해당 네크워크에 입력을 주기 위해서 클래스 객체를 만들어야하는데 ndarray의 2차원 영상을 그대로 주는 것이
아니고 2차원이 아닌 4차원형태의 행렬 형식을 따르고있다.
따라서 아래 네트워크 블롭을 만들어서 네트워크에 입력으로 준다.
네트워크 입력 블롭 ( blob ) 만들기
cv2.dnn.blobFromImage( image, scalefactor=None, size=None, mean=None, swapRB=None, crop=None, ddepth=None ) -> retval
- image : 입력 영상
- scalefacotr : 입력 영상 픽셀 값에 곱할 값. 기본값은 1.
딥러닝 학습시 픽셀값이 0~255의 범위로 본 것인지 , 또는 0~1까지 평준화해서 실수값형태로 본것인지..
따라서 일반적인 영상을 학습했을때는 1을 넣어주면 되고 평준화했을때는 1/255의 값을 넣어준다.
사용하고자하는 모델 타입이 어떤 타입인지를 정확히 알아야한다.
- size : 출력 영상의 크기. 기본값은 ( 0,0 )
- mean : 입력 영상 각 채널에서 뺄 평균 값. 기본값은 ( 0, 0, 0, 0 )
- swapRB : R과 B채널을 서로 바꿀 것인지를 결정하는 플래그. 기본값은 False
학습된 영상이 BGR인지 RGB인지를 알아야한다.
- crop : 크롭 수행 여부. 기본값은 false.
- ddepth : 출력 블롭의 깊이. CV_32F 또는 CV2_8U. 기본값은 CV_32F.
- retval : 영상으로부터 구한 블롭 객체
numpy.ndarray.shape = (N,C,H,W). dtype = numpy.float32. ( ddepth 깊이값 )
N : 이미지개수 , C : 차원수 , H : 이미지 높이, W : 이미지 너비 ( 위 3번째 size의 Width, Height )
위에서 구한 네트워크 입력 블럽을 아래 함수를 사용하여 네트워크에 입력시킨다.
네트워크 입력 설정하기
cv2.dnn_Net.setInput ( blob, name = None, scalefactor = None, mean = None ) -> None
- blob : 블롭 객체
- name : 입력 레이어 이름 ( 보통 Skip , 첫번째 레이어 사용 )
- scalefactor : 추가적으로 픽셀 값에 곱할 값
- mean : 추가적으로 픽셀 값에서 뺄 평균 값
* scalefactor , mean은 앞 입력 네트워크 블럽을 만들때 넣어주는게 좋다.
* SetInput 은 네트워크 앞에 블럽을 위치시키는 것이고 실행시키기 위해서는 아래 네트워크 순방향 실행을 해줘야함.
네트워크 순방향 실행( 추론 )
cv2.dnn_Net.forward ( outputName = None ) => retval
cv2.dnn_Net.forward ( outputName = None, outputBlobs = None ) => outputBlobs
- outputName : 출력 레이어 이름
- retval : 지정한 레이어의 출력 블럽. 네트워크마다 다르게 결정됨
- outputNames : 출력 레이어 이름 리스트
- outputBlobs : 지정한 레이어의 출력 블롭 리스트
한장의 이미지에 대해서
블롭만들기 , 입력설정, 순방향 실행을 연달아서 호출하는 형태로 모두 사용해야한다.
'Program > 딥러닝' 카테고리의 다른 글
[Open CV] 딥러닝 _ GoogLeNet 영상 인식 (0) | 2022.07.22 |
---|---|
[Open CV] 딥러닝 _ MNIST 학습 모델 사용하기 (0) | 2022.07.21 |
[Open CV] 딥러닝 _ 딥러닝 학습과 모델 파일 저장 (0) | 2022.07.18 |
[Open CV] 딥러닝 _ CNN 이해하기 (0) | 2022.07.17 |
[Open CV] 딥러닝 _ 딥러닝이해하기 (0) | 2022.07.16 |