카메라 스티커앱을 만드는 원리를 공부하며 정리했던 몇 가지 부분
PNG 파일
- Portable Network Graphics
- 무손실 압축을 사용, 이미지 손실이 없고 고품질 이미지를 생성
- 배경이 투명해서 배경 이미지 위에 png 파일을 얹어 두 이미지를 자연스럽게 합성시킬 수 있음
(배경이 체커판 패턴으로 보임, 이 부분이 투명)
- 다른 이미지를 스티커로 사용하고 싶으면 png 파일을 사용하는 것이 좋음
처리할 이미지 준비할 과정에서
- 랜드마크(landmark), 조정(alignment) : 사진에서의 눈, 코, 입, 귀 같은 얼굴 각각의 위치를 찾아내는 기술
- 조금 더 큰 범위로는 keypoint detection이라고 부름.
- 대부분의 face landmark 데이터셋은 눈, 코, 입과 턱을 포함하고 있음.
- 얼굴의 랜드마크를 찾아냈으면 머리의 위치를 예상하는 것은 쉬움.
- landmark를 찾기 위해서는 얼굴의 bounding box를 먼저 찾아야함.
- matplotlib, dlib 등의 이미지 라이브러리는 모두 이미지 채널을 RGB(빨강, 녹색, 파랑) 순으로 사용함
그런데 opencv는 예외적으로 BGR(파랑, 녹색, 빨강)을 사용함.
그래서 원본사진에서 붉은색은 푸른색으로, 푸른색은 붉은색으로 바뀌어 출력됨.
그래서 openCV에서 다룬 이미지를 다른 이미지 라이브러리를 활용하여 출력하려면 색깔 보정처리를 해야함
얼굴 검출 face detection
- Object detection 기술 이용해서 얼굴 위치 찾기
- dlib의 face detector는 HOG(Histogram of Oriented Gradients)와 SVM(Support Vector Machine)을 사용해서 얼굴을 찾음.
- HOG는 이미지에서 색상의 변화량을 나타냄. 이미지로부터 물체의 특징만 잘잡아냄.
- SVM은 선형분류기임. 한 이미지를 다차원 공간의 한 벡터라고 보면 여러 이미지는 여러 벡터가 되는데, 이 여러 벡터를 잘 구분짓는 방법. 여기서는 얼굴이냐 아니냐를 구분하는 것이 중요.
이미지의 색상만 가지고는 SVM이 큰 힘을 발휘하지 못하지만, 이미지가 HOG를 통해 벡터로 만들어진다면 SVM이 잘 작동함.
- 얼굴위치를 찾는 것은 sliding window 사용 : 작은 영역(window)을 이동해가며 확인하는 방법
큰 이미지의 작은 영역을 잘라 얼굴이 있는지 확인하고, 다시 작은 영역을 옆으로 옮겨 얼굴이 있는지 확인하는 방식. 이미지가 크면 클수록 오래걸리게 됨.
얼굴 랜드마크 face landmark
- 이목구비의 위치를 추론하는 것을 face landmark localization 기술이라고 함.
face landmark는 detection의 결과물인 bounding box로 잘라낸(crop) 얼굴 이미지를 사용함.
- face landmark와 같이 객체 내부의 점을 찾는 기술을 object keypoint estimation이라고 함.
keypoint를 찾는 알고리즘 2가지
1) top-down : bounding box를 찾고 box 내부의 keypoint를 예측
2) bottom-up : 이미지 전체의 keypoint를 먼저 찾고 point 관계를 이용해 군집화해서 box 생성
우리는 1번방식 다룸.
- Dlib landmark localization
잘라진 얼굴 이미지에서 68개의 이목구비 위치를 찾음

OpenCV 관련 함수 함수 몇 가지
cv2.rectangle() 함수 : 사각형 그리는 함수
cv2.rectangle(img, pt1, pt2, color[, thickness[, lineType[, shift]]])
- img : 이미지 파일
- pt1 : 시작점 좌표 (x,y)
- pt2 : 종료점 좌표 (x,y)
- color : 색상 (blue, green, red) 0~255
- thickness : 선 두께 (default 1)
- lineType : 선 종류 (default cv.Line_8)
(LINE_8 : 8 connected line)
(LINE_4 : 4-connecterd line)
(LINE_AA : antialiased line)
- shift : fractional bit (default 0)
cv2.addWeighted() 함수 : 이미지의 투명도를 조정하여 두 개의 이미지가 겹쳐보이게 하는 블렌딩에 관한 함수
img = cv2.addWeighted(img1, alpha, img2, beta, gamma[, dst[, dtype]])
- img1, img2 : 두 개의 이미지 파일
- alpha = 1 - beta
- alpha가 높아질수록 img1은 투명해지고 img2는 불투명해짐
- alpha는 img1의 투명도, beta는 img2의 투명도라고 생각하면 될듯