Yours Ever, Data Chronicles
Python OpenCV (5) - HOG 노이즈 제거하기 (이동평균 이용) 본문
안녕하세요, Everly입니다.
오늘은 [파이썬 데이터 분석 실무 테크닉 100] 의 "이미지 인식 기술" 마지막 포스팅입니다.
바로 전 포스팅에서 HOG의 SVMDetector 모델을 활용하여 동영상으로부터 사람을 인식하여, 사람 수를 세보았는데요!
HOG 모델이 노이즈, 즉 오차가 많은 모델이라 정확한 결과가 나오지 못했습니다.
그래서 이번 장에서는 이런 노이즈를 제거해보고 '이미지 인식 기술' 포스팅을 마무리하겠습니다.
✔Table of Contents
Tech 90. 이동평균을 계산해 HOG 노이즈를 제거하자.
노이즈가 생기는 이유는 이런 이유 때문입니다.
1. 계산해야 할 사람을 계산하지 않아서
2. 계산안해도 될 것을 사람으로 계산해서
그래서 시간의 평균(이동평균)을 계산하는 방법을 통해, 갑자기 사람의 숫자가 늘어나거나 줄어들어서 생기는 오차를 줄일 수 있을 것입니다.
함수 moving_average를 만들어 이동평균을 계산해봅니다.
import numpy as np
def moving_average(x, y):
#people 값을 이동평균화해서 값을 보정함.
y_conv = np.convolve(y, np.ones(5)/float(5), mode = 'valid')
#time의 최소~ 최대를 일정 간격으로 나눈다.
x_dat = np.linspace(np.min(x), np.max(x), np.size(y_conv))
return x_dat, y_conv
이처럼 x와 y를 input으로 받아 이를 x_dat, y_conv로 보정한 값을 output으로 뱉어냅니다.
우리가 넣을 것은 앞서 만들었던 list_df 데이터프레임의 값이겠죠?
x에는 time을, y에는 people을 넣어줍니다.
사실 이 함수를 통해 진짜 바꾸고자 하는 값은 people일 것입니다. 이 값이 너무 들쭉날쭉하면 안 되니까 이동평균을 통해 값을 보정해주는 것이죠.
그럼 people 값은 이렇게 달라질 것입니다.
time 값의 경우는 원래부터 401개의 프레임에서 10의 배수만 뽑았기 때문에 값이 크게 달라지진 않습니다.
어찌됐든 이 함수를 적용하면 그래프가 어떻게 달라지는지 확인해봅시다.
#원래와 어떻게 달라지는지 확인해보자!
## mov01
#원래 그래프
plt.plot(list_df['time'], list_df['people'], label = 'raw')
#달라진 그래프
ma_x , ma_y = moving_average(list_df['time'], list_df['people'])
plt.plot(ma_x, ma_y, label = 'average')
plt.xlabel('time(sec.)')
plt.ylabel('population')
plt.title('mov01 Graph')
plt.ylim(0, 15)
plt.legend()
plt.show()
## mov02
#원래 그래프
plt.plot(list_df2['time'], list_df2['people'], label = 'raw')
#달라진 그래프
ma_x2 , ma_y2 = moving_average(list_df2['time'], list_df2['people'])
plt.plot(ma_x2, ma_y2, label = 'average')
plt.xlabel('time(sec.)')
plt.ylabel('population')
plt.title('mov02 Graph')
plt.ylim(0, 15)
plt.legend()
plt.show()
이렇게 결과를 놓고 보니, 어떠신가요?
파란 선이 원본이고, 주황색 선이 이동평균을 적용했을 때의 모습입니다. 확실히 선이 좀 더 스무스(smooth)해졌죠?
사람 수의 값이 많이 보정되었습니다.
그렇다면 다시 한번 이동평균으로 보정된 mov01과 mov02 그래프의 값을 비교해봅시다.
## 이번엔 mov01과 mov02를 비교해보자.
plt.plot(ma_x, ma_y, label = 'mov01')
plt.plot(ma_x2, ma_y2, label = 'mov02')
plt.xlabel('time(sec.)')
plt.ylabel('population')
plt.title('mov01 vs. mov02 graph using moving average')
plt.ylim(0, 15)
plt.legend()
plt.show()
파란색 선이 mov01, 주황색 선이 mov02의 이동평균 적용 버전입니다.
이 결과를 보면, 직전 포스팅에선 "대충 봤을 때 mov02가 사람이 더 많은 것 같다"는 생각에서,
"정확하게 mov02가 더 사람이 많다" 고 인정할 수 있습니다. (그리고 실제로도 mov02가 사람들이 카메라에 더 몰려 있어서 mov02에서 사람 수가 더 많이 나타나야 하는 것이 정상입니다.)
이렇게 이동평균을 사용하는 것 이외에도, 더 정확하게 비교하기 위해선 이런 방법을 쓸 수 있습니다.
- HOG 크기 변경하기 (파라미터 변경)
- 특정 크기 이상의 사람들만 검출하기
- 특정 크기 이하는 무시하기
보통 사람이 아닌데 사람으로 인식되는 것들은 크기가 작은 것들이 많으니까요.
Summary
이렇게 하여 이미지와 동영상을 파이썬으로 읽어오는 방법, 그리고 사람 얼굴을 모델을 사용해 자동으로 인식하는 방법, 인식된 사람 수를 그래프로 표현하는 방법 등을 공부했습니다.
완벽한 이미지 처리로 보기엔 불충분하지만, 다른 이미지 처리에 관한 책을 통해 더 복잡하고 정교한 모델을 만들 수 있을 것입니다.
이렇게 해서 [파이썬 데이터 분석 실무 테크닉 100]의 9장 내용을 마칩니다.
대망의 마지막 10장은 "자연어 처리(NLP)" 기술에 대해 공부해봅니다. 포스팅 읽어주셔서 감사합니다 :)
'Data Science > Analysis Study' 카테고리의 다른 글
파이썬 자연어 처리(NLP) - konlpy를 활용한 형태소 분석 / 파이썬 데이터 분석 실무 테크닉 100 (0) | 2022.05.17 |
---|---|
파이썬 자연어 처리(NLP) - 텍스트 데이터 전처리 / 파이썬 데이터 분석 실무 테크닉 100 (0) | 2022.05.16 |
Python OpenCV (4) - 동영상에서 사람 얼굴 인식하기, 타임랩스 만들기 (0) | 2022.05.14 |
Python OpenCV (3) - 이미지에서 사람 얼굴 & 방향 인식하기 (python dlib, 안면 인식 기술) (1) | 2022.05.13 |
Python OpenCV (2) - 이미지에서 사람 얼굴 인식하기 (0) | 2022.05.12 |