1
+ # 최신화 : 2022/11/4(금)
1
2
# 중간발표 완성버전
2
3
# 웹캠으로 이미지 딴거를
3
4
# 이미지에 이미지(웹캠) 넣기 - 성공
4
- import cv2
5
- import dlib
5
+ import cv2 # 이미지 처리 라이브러리
6
+ import dlib # 이미지 처리 라이브러리
6
7
import sys
7
8
import numpy as np
8
9
9
10
11
+ # 이미지 크기를 조정해준다 0.7은 10분의 7로 줄여주기 위한 변수. cv2.resize에서 쓰인다.
10
12
# scaler = 0.2
11
13
scaler = 0.7
12
14
15
+ # 얼굴 디텍터 모듈 초기화
13
16
detector = dlib .get_frontal_face_detector ()
17
+ # 얼굴 특징점 모듈 초기화 shape_predictor_68_face_landmarks.dat 이 파일이 있어야 실행가능
18
+ # shape_predictor_68_face_landmarks.dat 는 머신러닝으로 학습된 모델
14
19
predictor = dlib .shape_predictor ("shape_predictor_68_face_landmarks.dat" )
15
20
16
21
22
+ # 웹캠이 켜진다.
17
23
cap = cv2 .VideoCapture (0 )
18
24
19
25
width = cap .get (cv2 .CAP_PROP_FRAME_WIDTH )
44
50
cv2 .destroyAllWindows ()
45
51
46
52
47
- # cv2.imshow('test', img)
48
- # cv2.waitKey(0)
49
-
50
-
51
- # load overlay image
53
+ # 파일 이미지를 BGRA 타입으로 읽기
54
+ # load overlay image , PNG 파일을 넣어야한다. cv2.IMREAD_UNCHANGED 이걸 해야 BGR값과 A(알파채널)값을 읽을 수 있다.
52
55
overlay = cv2 .imread ('test.png' , cv2 .IMREAD_UNCHANGED )
53
- #overlay = cv2.imread('test.png', 1)
54
56
55
57
#
56
58
#
57
59
#
58
- # overlay function
59
60
60
61
62
+ # overlay function, 이미지(웹캠)을 이미지에 띄우는 것은 구글링을 통해 찾았다함.
61
63
def overlay_transparent (background_img , img_to_overlay_t , x , y , overlay_size = None ):
62
64
bg_img = background_img .copy ()
63
65
# convert 3 channels to 4 channels
@@ -81,7 +83,8 @@ def overlay_transparent(background_img, img_to_overlay_t, x, y, overlay_size=Non
81
83
mask = cv2 .bitwise_not (mask ))
82
84
img2_fg = cv2 .bitwise_and (img_to_overlay_t , img_to_overlay_t , mask = mask )
83
85
84
- bg_img [int (y - h / 2 ):int (y + h / 2 ), int (x - w / 2 ):int (x + w / 2 )] = cv2 .add (img1_bg , img2_fg )
86
+ bg_img [int (y - h / 2 ):int (y + h / 2 ), int (x - w / 2 )
87
+ :int (x + w / 2 )] = cv2 .add (img1_bg , img2_fg )
85
88
86
89
# convert 4 channels to 4 channels
87
90
bg_img = cv2 .cvtColor (bg_img , cv2 .COLOR_BGRA2BGR )
@@ -93,25 +96,30 @@ def overlay_transparent(background_img, img_to_overlay_t, x, y, overlay_size=Non
93
96
94
97
95
98
while True :
99
+ ''' #여기는 영상을 읽기 위한 부분
96
100
# read frame buffer from video
97
101
# 비디오의 한 프레임씩 읽는다. 제대로 프레임을 읽으면 ret값이 True, 실패하면 False가 나타난다. img에 읽은 프레임이 나온다.
98
102
# ret, img = cap.read()
99
103
# if not ret:
100
104
# break
105
+ # '''
101
106
102
107
# cv2.imread(fileName, flag) : fileName은 이미지 파일의 경로를 의미하고 flag는 이미지 파일을 읽을 때 옵션이다.
103
108
img = cv2 .imread ('boy2.png' , 1 )
104
- # cv2.imshow('test', img)
105
109
110
+ # img에 (int(img.shape[1] * scaler), int(img.shape[0] * scaler)) 크기로 조절
106
111
img = cv2 .resize (
107
112
img , (int (img .shape [1 ] * scaler ), int (img .shape [0 ] * scaler )))
108
113
ori = img .copy ()
109
114
110
- # detect faces
115
+ # detect faces, img에서 모든 얼굴 찾기
111
116
faces = detector (img )
117
+ # 찾은 모든 얼굴에서 첫번째 얼굴만 가져오기
112
118
face = faces [0 ]
113
119
120
+ # img의 face 영역 안의 얼굴 특징점 찾기
114
121
dlib_shape = predictor (img , face )
122
+ # dlib 객체를 numpy 객체로 변환(연산을 쉽게 하기 위해)
115
123
shape_2d = np .array ([[p .x , p .y ] for p in dlib_shape .parts ()])
116
124
117
125
# compute center of face
@@ -123,22 +131,29 @@ def overlay_transparent(background_img, img_to_overlay_t, x, y, overlay_size=Non
123
131
124
132
center_x , center_y = np .mean (shape_2d , axis = 0 ).astype (np .int )
125
133
134
+ # 복사한 이미지를 센터x, 센터y 중심으로 넣고 overlay_size 만큼 resize해서
135
+ # 원본 이미지에 넣어준다. 크기는 얼굴 크기만큼 resize해주는 것이다.
126
136
result = overlay_transparent (
127
137
ori , overlay , center_x , center_y - 10 , overlay_size = (face_size , face_size ))
128
138
129
- # visualize
139
+ # visualize , 직사각형 그리기
130
140
img = cv2 .rectangle (img , pt1 = (face .left (), face .top ()),
131
141
pt2 = (face .right (), face .bottom ()),
132
142
color = (255 , 255 , 255 ), thickness = 2 , lineType = cv2 .LINE_AA )
133
143
144
+ # 얼굴 특징점 그리기, 68개의 점을 찾아줌
134
145
for s in shape_2d :
146
+ # 얼굴에 원그리기
135
147
cv2 .circle (img , center = tuple (s ), radius = 1 , color = (
136
148
255 , 255 , 255 ), thickness = 2 , lineType = cv2 .LINE_AA )
137
149
150
+ # 얼굴 왼쪽 위 파란점
138
151
cv2 .circle (img , center = tuple (top_left ), radius = 1 , color = (
139
152
255 , 0 , 0 ), thickness = 2 , lineType = cv2 .LINE_AA )
153
+ # 얼굴 오른쪽 아래 파란점
140
154
cv2 .circle (img , center = tuple (bottom_right ), radius = 1 ,
141
155
color = (255 , 0 , 0 ), thickness = 2 , lineType = cv2 .LINE_AA )
156
+ # 모든 특징점의 평균을 구해서 얼굴의 중심을 구하기
142
157
cv2 .circle (img , center = tuple ((center_x , center_y )), radius = 1 ,
143
158
color = (0 , 0 , 255 ), thickness = 2 , lineType = cv2 .LINE_AA )
144
159
@@ -147,4 +162,4 @@ def overlay_transparent(background_img, img_to_overlay_t, x, y, overlay_size=Non
147
162
cv2 .imshow ('result' , result )
148
163
149
164
# 0넣으면 x클릭해야 꺼짐 1넣으면 ctrl+c해도 꺼짐
150
- cv2 .waitKey (1 )
165
+ cv2 .waitKey (1 ) # 1밀리세컨드만큼 대기. 이걸 넣어야 동영상이 제대로 보임
0 commit comments