스마일러 프로젝트

네번째 이야기

유승혁 2022. 6. 25. 02:14

 친애하는 백성들이여. 신화같은 나의 전설 스토리를 여기까지 따라오다니 고생 많았도다. 마지막 스마일러 이야기도 시작하지. 집중하도록.

 

 전자, 기계과 친구들과 함께 만들어낸 결과물 사진 뿐만 아니라 참여 후기, 만약 상을 받는 다면 수상 여부 이런 것도 함께 적고 싶지만, 최종 발표가 내일 모레라서 최종 발표 후에 글을 수정하겠어요!

 

 0. 인식 기능 요구사항

일단 다양한 인식 문제가 있었다. 예를 들면 동그란 안경 밑 부분을 자꾸 미소로 착각한다던지, 얼굴이 다중 감지 될 때 같은 문제가 있었을 뿐만 아니라, openCV에서 제공하는 미소감지, 얼굴 감지는 민감도를 조정할 수 있는데 (얼마나 예민하게 얼굴이나 미소를 찾아낼 지) 집에서는 30정도면 인식을 잘 했던게 카페에서 하니깐 50은 해야 인식을 하기 시작했다. 이런 것들을 개선했다.

 

 1. 안경 인식 문제

 근데 이 부분은 간단했다. 직관적으로도 안경만 문제였으니 얼굴 하단부에서만 미소를 인식하게 끔 하면 되었다.

while 1:
    ret, img = cap.read()

    faces = face_cascade.detectMultiScale(gray,
      scaleFactor= 1.2,
      minNeighbors = int(faceFactor),
      minSize = (20, 20))#faceFactor가 바로 얼굴 감지 민감도!
    
    for (fx,fy,fw,fh) in faces:
    	...
        얼굴 감지 관련 처리
        ...
    	smile = smile_cascade.detectMultiScale(roi_gray,scaleFactor= 1.2,
        minNeighbors=int(smileFactor), minSize=(20, 20))#smileFactor가 바로 미소 감지 민감도!
        
        tm = cv2.TickMeter()#시간 측정기(타이머 개념)
        
        for (x, y, w, h) in smile:
            if y < fh/2:#안경 인식 문제 해결 : 얼굴 인식크기의 1/2 아래만 미소 캐치
                continue
        
        ...
        나머지 로직들
        ...

코드 상에서도 간단하게 y < fh/2 로 해결했다. smile의 값은 (x,y,w,h)이고 얼굴 값은 (fx,fy,fw,fh)이다 왜 위와 같은 if문이 나왔느냐면, 맨 처음에는 그냥 [y > fy/2 라면 무시] 이렇게 하면 되는거 아닌가? 얼굴의 절반 아래만 보면 되는거 아냐?

근데 막상 클래스를 까보면서 찾아보니 x,y가 0,0이라면 화면의 좌측 최상단이 아닌 얼굴 범위 안에서 x,y 값이 측정 되었던 것이다! 두둥..즉, 얼굴 안에 있는 너비(fw)와 높이(fh)를 이용해야 한다는 것이당. 그래서 걍 print문으로 각 값 띄어서 비교해서 규칙을 찾아서 저렇게 했다.

 

2. 얼굴 감지 민감도

 맨 처음에 민감도 감지 같은 경우는 조명이나 거리에 따라 바뀔 것이라 생각하고 이제야 진정한 임베디드 시스템을 해볼 때가 되었구나! 우리 전자과 팀원들이 값을 던져 주면 내가 그 사이에서 규칙을 찾는 식으로 해보고 싶었으나.. 팀원들이 별로 원하지 않았다. 다른 방법 찾으라 했다. 너무행

민감도 조정 같은 경우는 다양한 곳에서 값을 확인해본 결과 얼굴 민감도는 10~25 사이, 미소 민감도는 100~200 사이가 적당했다. 그래서 상한 하한을 두어 이분 탐색으로 적당한 민감도 값을 갖게 끔 했다. 

faceFactor = 17 #10~25
fFl = 10
fFh = 25
smileFactor = 150 #100~200
sFl = 50
sFh = 200

while 1:
	...
    if len(faces) == 0:#민감도가 너무 높아서 감지를 못할경우
        faceFactor = (faceFactor+fFl)/2
    for (fx,fy,fw,fh) in faces:
        if  len(faces) >= 2:#인식되는 얼굴이 두 개 이상일 경우
            center = False
            ax, bx = 1,1
            for face in faces:
                if ui.centerFace(fx,fy):#가운데 우선 인식
                    center = True
                    ax = fx
                    bx = fy
                    break
            if center == True:
                fx = ax
                fy = bx
            else:#가운데 얼굴이 없을 경우 민감도를 낮춰 더 잘 감지 되게끔
                faceFactor += (faceFactor+fFh)/2
                continue
            ...
            미소감지
            ...
            break#다른 미소는 버려!
	...

 HW팀에서 만약 사용자가 거울 앞에 나타나면 신호를 주어 콤푸타가 딱 돌아가고 이 파이썬 파일이 실행이 되게 할 계획이니, 켜지고 난 뒤에 얼굴 감지가 잘 안된다면, 민감도를 (현재 민감도+하한)/2 값을 취하게 끔 했다.

 반대로 얼굴이 두 개 이상 감지 된다면, 가운데에 얼굴은 남기고 나머지는 임시 변수 ax,bx와 break를 이용해 버리게끔 했다. 만약 얼굴 감지는 두 개 이상 이지만, 가운데 얼굴이 없다면 민감도를 (현재 민감도+상한)/2 으로 하여 얼굴 감지를 약하게 만들었다.

 

3. 미소 감지 민감도

smileFactor = 150 #100~200
sFl = 50
sFh = 200

while 1:
    
    for (fx,fy,fw,fh) in faces:
        
   	smile = smile_cascade.detectMultiScale( roi_gray,scaleFactor= 1.2,
           minNeighbors=int(smileFactor), minSize=(20, 20))
        
        if len(smile) == 0:
            notSmileTime += 1
            if notSmileTime >= 50:
                smileFactor = (smileFactor+sFl)/2
                notSmileTime = 20

 미소 감지 민감도는 잘 생각해보면 얼굴 감지 이후 대게 일정 시간 이후에는 미소를 지을 것이므로 맨 처음에는 미소 감지가 어느정도 활짝 웃어야 되게끔 설정하더라도 점차 민감도를 낮추어 더 잘 감지할 수 있게끔 했다. 그렇기에 (현재 민감도+하한)/2 값을 취하게 했다. 그러다 보니 맨 처음엔 감지 못하던 미소도 일정 시간이 지나면 미소를 감지하는 모습을 볼 수 있었다.

 

 

 느낀점..

 컴공에 있다보면 여러 개발 프로젝트를 하게 되고 대게 뭐 프론트, 백, 디자이너 이정도 그룹인데, 다른 공대와 함께 하는 경험이 정말,, 신선했다. 뭐랄까 사실 개발자를 하다보면 인터넷 상에서만 볼 수 있는 결과물 들이 많은데 스마트 미러에는 실물로 볼 수 있는 결과물이었어서 재밌었다. 컴공인 우리는 뇌를 만들고 타 공대 학과에서는 근육과 근신경계를 만들어 주는 경험.. 정말 풍성했다.

 뿐만 아니라 우리 주변에 있는 시제품은 얼마나 많은 정제와 검증을 거쳤는지도 느꼈다. 컴공은 사실상 규격이나 이런 제한들에서 자유롭지만, HW 팀에서는 인증 규격을 찾아보고 그 안에서 구현하기 위해 찾아가는 과정이 절반 정도를 차지했었다. 그 모습을 보며 난 컴공이라 다행이라고 생각했다 ^0^

 이 과제를 준 회사 측에서는 나름 귀엽게 봐주셨다. 시제품으로서는 정말 형편 없지만, 우리끼리 충돌하고 배워나가는 과정을 중요시 하셨던거 같다. 뿐만 아니라 계획 단계에서 계획했던 A안이 안될경우 이를 충당해줄 B안을 세워나가야 할 자세도 일깨워 주셨다.

 뿐만 아니라, 라즈베리파이 제고 문제나 디스플레이 같이 대게 HW 문제에서의 어려움을 겪었는데, 이런 부분은 아예 회사에서 쓰던 물품을 주실 정도로 지원을 많이 해주셔서 감사했다.

 

 아쉬웠던 점...

민감도 조정 관련해서 정말 아쉬웠다. 최소한 라즈베리 파이를 이용하니 거리, 조명 센서 같은 걸 이용해 규칙을 찾고 식을 세워서 해결해 나가고 싶었지만, HW 팀에서 짧은 기간에 다른 부분을 구현해야 했다보니 시간이 부족했다.

 추가적으로 요새 머신러닝을 배우고 있는데, 미소랑 얼굴 감지 민감도 설정을 위에서 말한 조명이라던지 거리, 사람의 얼굴 형 등 여러 값을 분석해서 각 값을 기준으로 학습시켜 민감도를 자동 조절하게끔 하고 싶다는 생각까지 했다.  데이터를 모으는 거는 우리 학교 하이테크 엘레베이터에 설치해서 한 두달간 모으면 정말 재미있을 거 같다.

 아무튼 다음에 내가 이 분야에 익숙해 진다면, 혼자서 꼭 해볼 생각이다. 누가 부여한 과제가 아니라 우리 팀끼리 고민해 나가며 문제를 만들어서 풀어 나갔다 보니 확실히 정이 붙었나 보다. 

 

 결과물 사진이나 자세한 후기는 경진대회 이후에 기제하겠습니다!