전시작품으로 입선했지만 상위권에 들지는 못했습니다.

내년에 다른 주제로 공모전을 할때는 구체적인 계획과 많은 시간을 투자하여 좋은 결과를 얻을 수 있도록 하겠습니다.

이렇게 좋은 경험을 할 수 있도록 서포트해주신 멘토님께 정말 감사드립니다.

또 저와 함께 일년동안 공모전을 준비한 팀원들에게도 감사합니다.

좋은 경험이 되었던 것 같습니다.

저희는 github에서 오픈소스로 올라온 얼굴인식 소스를 가지고 기능을 추가하여 공모전에 출마했습니다.

오픈소스 : https://github.com/yu4u/age-gender-estimation

수정은 demo.py라는 소스만 수정했고 딥러닝에 필요한 소스들은 그대로 사용했습니다.

문제가 발생하면 삭제될 수 있음을 알려드립니다.

 

  • 수정한 demo.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
import os
import cv2
import dlib
import numpy as np
import argparse
import time
import threading
import random
import socket
import glob
import matplotlib.pyplot as plt
import sys
 
from openpyxl import Workbook
from openpyxl import load_workbook
from PyQt5.QtCore import QTimer
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtWidgets import QApplication, QDialog, QWidget, QVBoxLayout, QHBoxLayout, QBoxLayout
from PyQt5.uic import loadUi
from PyQt5.uic.properties import QtCore
 
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotwidgetfile import matplotwidgetFile
 
from contextlib import contextmanager
from wide_resnet import WideResNet
from keras.utils.data_utils import get_file
 
global myimge
global Agecnt
global Range
global exitflag
global sock
global sock_on
global th_flag
global testflag
global name
global xl_row
 
myimge = cv2.imread("waiting.png")
Agecnt = [000000000]
Agevideo = [r"C:\ProgramData\Age\age-gender-estimation-master\ad\teenF",
            r"C:\ProgramData\Age\age-gender-estimation-master\ad\YouthF",
            r"C:\ProgramData\Age\age-gender-estimation-master\ad\middleF",
            r"C:\ProgramData\Age\age-gender-estimation-master\ad\oldF",
            r"C:\ProgramData\Age\age-gender-estimation-master\ad\teenM",
            r"C:\ProgramData\Age\age-gender-estimation-master\ad\YouthM",
            r"C:\ProgramData\Age\age-gender-estimation-master\ad\middleM",
            r"C:\ProgramData\Age\age-gender-estimation-master\ad\oldM",
            r"C:\ProgramData\Age\age-gender-estimation-master\ad\079war01.mp4",
            r"C:\ProgramData\Age\age-gender-estimation-master\ad\068war02.mp4",
            r"C:\ProgramData\Age\age-gender-estimation-master\ad\109war03.mp4"]
 
Range = ['teenF''YouthF''middleF''oldF''teenM''YouthM''middleM''oldM''warning']
exitflag = 0
sock_on = 1
th_flag = 0
testflag = 0
 
if sock_on == 1:
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1)
    sock.connect(('192.168.43.247'5005))
 
 
class Video(object):
    def __init__(self, path):
        self.path = path
 
    def play(self):
        from os import startfile
        startfile(self.path)
 
 
class Movie_MP4(Video):
    type = "MP4"
 
 
class Life2Coding(QDialog):
 
    def __init__(self):
        super(Life2Coding, self).__init__()
        loadUi('life2coding.ui', self)
 
        self.setGeometry(900301006729)
        # self.timer = QTimer(self)
        self.imgtimer = QTimer(self)
 
        self.startButton.clicked.connect(self.start_webcam)
        self.stopButton.clicked.connect(self.stop_webcam)
        self.warningButton.clicked.connect(self.warning_event)
        self.resetButton.clicked.connect(self.reset)
        self.fireButton.clicked.connect(self.fire)
        self.exitButton.clicked.connect(self.ext)
 
    def start_webcam(self):
        global Agecnt
        global exitflag
        global th_flag
        global name
        global xl_row
        Agecnt = [000000000]
        wb = Workbook()
        xl_row = 0
        ws1 = wb.active  # 현재 열려 있는 Sheet
        now = time.gmtime(time.time())
        now_list = list(now)
        name = str(now_list[0]) + "_" + str(now_list[1]) + "_" + str(now_list[2]) + "-" + str(now_list[3]) + "__" + str(
            now_list[4]) + "__" + str(now_list[5])
 
        ws1.title = name
        wb.save("D:/" + ws1.title + ".xlsx")
 
        Agecnt = [000000000]
        exitflag = 0
 
        self.imgtimer.timeout.connect(self.update_frame)
        # self.timer.timeout.connect(self.graph)
        self.imgtimer.start(1000)
        # self.timer.start(1000)
 
        if (th_flag == 0):
            self.th_main = threading.Thread(target=main, args=())
            # self.th_main.daemon = True
            self.th_main.start()
 
        th_flag = 1
        print("start webcam")
 
    def stop_webcam(self):
        global exitflag
        global th_flag
        exitflag = 1
        # self.timer.stop()
        self.imgtimer.stop()
        self.th_main.join()
        if ad_output.timer.is_alive():
            ad_output.timer.cancel()
        if warning_output.timer_w.is_alive():
            warning_output.timer_w.cancel()
        th_flag = 0
        if sock_on == 1:
            sock.send("qqqqqqqq".encode())
            sock.close()
        print("stop webcam")
 
    def update_frame(self):
        height, width, channel = myimge.shape
        bytesPerLine = 3 * width
        qImg = QImage(myimge.data, width, height, bytesPerLine, QImage.Format_RGB888).rgbSwapped()
        pixmap = QPixmap(qImg)
        self.imgLabel.setPixmap(pixmap)
        self.widget.canvas.ax.clear()
        self.widget.canvas.ax.bar(Range, Agecnt)
        self.widget.canvas.draw()
        print("update_frame")
 
    def graph(self):
        self.widget.canvas.ax.clear()
        self.widget.canvas.ax.bar(Range, Agecnt)
        self.widget.canvas.draw()
 
    def reset(self):
        global Agecnt
        global name
        global xl_row
        wb = load_workbook("D:/" + name + ".xlsx")
        ws = wb.active
        xl_row = xl_row + 1
        for col in range(19):
            ws.cell(row=xl_row, column=col, value=int(Agecnt[col - 1]))
 
        wb.save("D:/" + name + ".xlsx")
 
        Agecnt = [000000000]
        print("reset!")
        # sock.send("reset123".encode())
 
    def warning_event(self):
        Agecnt[8= -1
        warning_output()
        # movie = Movie_MP4(Agevideo[8])
        # movie.play()
 
    def fire(self):
        Agecnt[8= -2
        # movie = Movie_MP4(Agevideo[8])
        # movie.play()
        warning_output()
 
    def ext(self):
        Agecnt[8= -3
        warning_output()
 
 
def ad_output():
    global Agecnt
    if Agecnt[8== 0:
        Max = Agecnt.index(max(Agecnt))
        if not Agecnt[Max] == 0:  # Data 가 있을 경우 해당 나이에 맞는 광고 표출
            path = random.choice(glob.glob(Agevideo[Max] + "\*"))  # 랜덤 파일 추출
            f_name = os.path.split(path)  # 파일명 추출 s[1] -> 파일명
            T = int(f_name[1][0]) * 100 + int(f_name[1][1]) * 10 + int(f_name[1][2])  # 파일명에서 시간 추출
            s_d = os.path.splitext(path)  # mp4 제외 파일명만 추출
            s_d = os.path.split(s_d[0])
 
            if sock_on == 1:
                sock.send(s_d[1].encode())
                print("동영상 제목 전송")
                while 1:
                    receive = sock.recv(8)
                    print(receive)
                    if receive :
                        print("나감")
                        break;
 
            ad_output.timer = threading.Timer(T, ad_output)
            #movie = Movie_MP4(path)
            #movie.play()
            ad_output.timer.start()
            
        else:  # Data 값들이 없을 경우 2초 간격으로 타이머 반복 실행
            ad_output.timer = threading.Timer(2, ad_output)
            ad_output.timer.start()
    else:
        ad_output.timer.cancel()
        print("광고 타이머가 Warning 에 의해 종료되었습니다.")
 
 
def warning_output():
    global Agecnt
    if Agecnt[8!= 0:
        w_index = -1 * Agecnt[8+ 7
        f_name = os.path.split(Agevideo[w_index])  # 파일명 추출 s[1] -> 파일명
        T = int(f_name[1][0]) * 100 + int(f_name[1][1]) * 10 + int(f_name[1][2])  # 파일명에서 시간 추출
 
        s_d = os.path.splitext(Agevideo[w_index])  # mp4 제외 파일명만 추출
        s_d = os.path.split(s_d[0])
        if sock_on == 1:
            sock.send(s_d[1].encode())
            print("Warning 동영상 제목 전송")
 
        warning_output.timer_w = threading.Timer(T, warning_output)
        #movie = Movie_MP4(Agevideo[w_index])
        #movie.play()
        warning_output.timer_w.start()
    else:
        warning_output.timer_w.cancel()
        print("Warning 타이머가 reset에 의해 종료되었습니다.")
 
 
pretrained_model = "https://github.com/yu4u/age-gender-estimation/releases/download/v0.5/weights.18-4.06.hdf5"
modhash = '89f56a39a78454e96379348bddd78c0d'
 
 
def get_args():
    parser = argparse.ArgumentParser(description="This script detects faces from web cam input, "
                                                 "and estimates age and gender for the detected faces.",
                                     formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument("--weight_file", type=str, default=None,
                        help="path to weight file (e.g. weights.18-4.06.hdf5)")
    parser.add_argument("--depth", type=int, default=16,
                        help="depth of network")
    parser.add_argument("--width", type=int, default=8,
                        help="width of network")
    args = parser.parse_args()
    return args
 
 
def draw_label(image, point, label, font=cv2.FONT_HERSHEY_SIMPLEX,
               font_scale=1, thickness=2):
    size = cv2.getTextSize(label, font, font_scale, thickness)[0]
    x, y = point
    cv2.rectangle(image, (x, y - size[1]), (x + size[0], y), (25500), cv2.FILLED)
    cv2.putText(image, label, point, font, font_scale, (255255255), thickness)
 
 
@contextmanager
def video_capture(*args, **kwargs):
    cap = cv2.VideoCapture(*args, **kwargs)
    try:
        yield cap
    finally:
        cap.release()
 
 
def yield_images():
    # capture video
    with video_capture(0) as cap:
        cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
        cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
 
        while True:
            # get video frame
            ret, img = cap.read()
 
            if not ret:
                raise RuntimeError("Failed to capture image")
 
            yield img
 
 
def main():
    global exitflag
    global testflag
    ad_output()
    print("일단 메인문은 들어왔습니다잉")
    args = get_args()
    depth = args.depth
    k = args.width
    weight_file = args.weight_file
    model = 0
    if not weight_file:
        weight_file = get_file("weights.18-4.06.hdf5", pretrained_model, cache_subdir="pretrained_models",
                               file_hash=modhash, cache_dir=os.path.dirname(os.path.abspath(__file__)))
        print("웨이트 파일이 없으므로 받아옵니다.")
        print(weight_file)
    print("웨이트 파일 받습니다.")
    # for face detection
    detector = dlib.get_frontal_face_detector()
    print("얼굴인식 라이브러리 사용")
    # load model and weights
    img_size = 64
    print("이미지 사이즈 = 64")
    model = WideResNet(img_size, depth=depth, k=k)()
    print("wideResNet 설정")
    if testflag == 0:
        model.load_weights(weight_file)
    print("사진 찍기 전!")
    for img in yield_images():
        input_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        img_h, img_w, _ = np.shape(input_img)
 
        # detect faces using dlib detector
        detected = detector(input_img, 1)
        faces = np.empty((len(detected), img_size, img_size, 3))
 
        if len(detected) > 0:
            for i, d in enumerate(detected):
                x1, y1, x2, y2, w, h = d.left(), d.top(), d.right() + 1, d.bottom() + 1, d.width(), d.height()
                xw1 = max(int(x1 - 0.4 * w), 0)
                yw1 = max(int(y1 - 0.4 * h), 0)
                xw2 = min(int(x2 + 0.4 * w), img_w - 1)
                yw2 = min(int(y2 + 0.4 * h), img_h - 1)
                cv2.rectangle(img, (x1, y1), (x2, y2), (25500), 2)
                # cv2.rectangle(img, (xw1, yw1), (xw2, yw2), (255, 0, 0), 2)
                faces[i, :, :, :] = cv2.resize(img[yw1:yw2 + 1, xw1:xw2 + 1, :], (img_size, img_size))
 
            # predict ages and genders of the detected faces
            results = model.predict(faces)
            predicted_genders = results[0]
            ages = np.arange(0101).reshape(1011)
            predicted_ages = results[1].dot(ages).flatten()
 
            # draw results
            for i, d in enumerate(detected):
                label = "{}, {}".format(int(predicted_ages[i]),
                                        "F" if predicted_genders[i][0> 0.5 else "M")
                draw_label(img, (d.left(), d.top()), label)
                age_index = (int)(predicted_ages[i] / 20)
                if predicted_genders[i][0> 0.5:
                    if age_index < 3:
                        Agecnt[age_index] = Agecnt[age_index] + 1
                    else:
                        Agecnt[3= Agecnt[3+ 1
                else:
                    if age_index + 4 < 7:
                        Agecnt[age_index + 4= Agecnt[age_index + 4+ 1
                    else:
                        Agecnt[7= Agecnt[7+ 1
 
        global myimge
        myimge = img
 
        print("main 실행")
 
        # cv2.imshow("result", img)
        # key = cv2.waitKey(30)
        # cv2.waitKey(30)
        if exitflag == 1:
            break
        # while(exitflag):
        # time.sleep(2)
    print("main 끝")
    exitflag = 0
    testflag = 1
 
 
if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = Life2Coding()
    window.setWindowTitle('AD title')
 
    window.show()
    app.exec_()
    # sys.exit(app.exec_())
cs
  •  UI를 사용하고 start, reset을 누를때마다 현재 카운트된 사람들의 기록을 엑셀파일에 저장하게 했기 때문에 UI에 필요한 이미지파일과 저장 파일의 경로가 달라서 오류가 발생할 수 있습니다.
  • 딥러닝과 demo파일을 실행하는데 필요한 import파일들을 먼저 다운받으셔야 합니다.

 

  • 작품 소개

    • 학습시킨 모델을 가진 디바이스가 행인들의 안면을 인식, 성별 및 나이를 판단하여 그에 맞는 광고를 보여 주려고 합니다. 수많은 사람들의 얼굴 데이터를 모아서 딥러닝을 통하여 연령과 성별을 분류해주는 모델을 만듭니다. 만들어진 모델을 라즈베리파이에 넣고 캠을 통한 행인들의 캡처이미지를 입력하여 줍니다. 작동 후 나오게 된 결과 데이터를 통해 분류된 클래스에 따른 광고를 띄워주는 것이 목표입니다.

  • 시스템 구성도

 

  • 시스템 흐름도

  • 프로그램(기능) 목록

  • 기능 흐름도

  • 프로젝트 수행일정

프로젝트 기간 (한이음 사이트 기준)

2018 . 4 . 24 ~ 2018 . 11 . 30

 

구분

추진내용

프로젝트 기간

1

2

3

4

5

6

7

8

9

10

11

12

계획

시나리오 계획, 계획서 작성

 

 

 

 

 

 

 

 

 

 

 

 

분석

OpenCV + 얼굴인식

, 나이 분석(소스,논문)

CNN(input,output)

 

 

 

 

 

 

 

 

 

 

 

 

설계

HW 부품 구입 및 설계

 

 

 

 

 

 

 

 

 

 

 

 

Software 알고리즘 설계

 

 

 

 

 

 

 

 

 

 

 

 

개발

HW 설치 및 동작 확인

 

 

 

 

 

 

 

 

 

 

 

 

OpenCV를 이용하여 얼굴영역 추출

-> 딥러닝을 통한 성별과 나이분석

 

 

 

 

 

 

 

 

 

 

 

 

응급상황 출력 알고리즘 개발

 

 

 

 

 

 

 

 

 

 

 

 

테스트

위 개발 내용을 종합한 프로토타입 테스트 및 보완

 

 

 

 

 

 

 

 

 

 

 

 

종료

프로젝트 종료

 

 

 

 

 

 

 

 

 

 

 

 

  • 작품의 개발배경 및 필요성 
    • 최근 딥러닝을 이용한 ICT디바이스 기술이 발전하면서 없어서는 안 될 기술이 되었습니다. 이러한 트렌드를 맞추고 수많은 정보로 가득 찬 세상에서 수동적인 광고 시스템이 아닌 고객의 니즈를 파악해 능동적으로 적합한 광고 시스템이 필요하다 느꼈습니다

 

  • 작품의 특장점
    • 특징 : 사람의 얼굴을 인식해 나이와 성별을 파악 후 연령대/성별 맞춤광고를 제공합니다.

    • 장점 : 계속 반복되는 광고를 보여주는 것 보다 타겟으로 삼는 사람들에게 맞춰진 광고를 보여줄 수 있으므로 훨씬 더 효율적입니다.

  • 작품의 기대효과 및 활용분야

  •       광고 효율 증가 맞춤형 광고를 통해 단순하게 반복되는 광고보다 효율이 높습니다.

  •        응급처치 시스템 주변에 응급상황 발생 시 응급처치 방법을 제공해 인명을 구조 할 수 있습니다.

  •        전력 절약 고객이 없을 때 모니터 off로 불필요한 전력 소비를 막을 수 있습니다.


+ Recent posts