2015년 7월 25일 토요일

opencv with gstreamer & 얼굴 인식


일전에 라즈베리파이 카메라의 기본동작과 스트리밍에 대하 글을 썼었는데요, 이번에는 한발 더 나아가서 '머신비전' 에 대해 적어 보겠습니다.
'자비스' 를 통해 음성 인식 비서를 얻었다면 이번 공부로 제 얼굴을 인식해서 '친절하게 인사해 주는 자비스'로 업그레이드 시켜 주고 싶습니다.

http://pibot.org/how-to/advanced.html 에서는 정말 간단하게 정리되어 있습니다.
이 자료로 뭔가를 해보기에는 아무래도 부족해서 구글의 힘을 빌어 정리 해야 되겠네요.

라즈베리파이에서 머신비젼을 위해 OpenCV 를 사용하는 방법은 크게 python script 를 사용하거나 gstreamer 를 통해서 스트리밍해서 성능좋은 PC 가 연산을 하게 하는 방법정도가 있습니다.

python 에 친숙하지 않아 그 부분을 건너띄고 gstreamer 를 통해서 스트리밍하는 방법으로 설명을 하면,

1. 라즈베리파이 카메라를 동작시키고 tcp server 를 만듭니다.
$ raspivid -n  -t 0 -b 5000000 -w 1280 -h 720 -fps 30 -o - | gst-launch-1.0 -v fdsrc ! h264parse ! rtph264pay config-interval=1 pt=96 ! gdppay ! tcpserversink host=192.168.0.23 port=5000
2. PC 에서 스티리밍 받은 화면을 보여 주거나 후처리를 해 줍니다.
$ gst-launch-1.0 tcpclientsrc host=192.168.0.23 port=5000 ! gdpdepay ! rtph264depay ! video/x-h264, width=1280, height=720, format=YUY2, framerate=30/1 ! avdec_h264 ! videoconvert ! xvimagesink
3. OpenCV 을 사용하는 예제는 아래와 같습니다.
$ gst-launch-1.0 tcpclientsrc host=192.168.0.23 port=5000 ! gdpdepay ! rtph264depay ! video/x-h264, width=1280, height=720, format=YUY2, framerate=30/1 ! avdec_h264 ! videoconvert ! facedetect ! xvimagesink

gstreamer 에서 사용 가능한 OpenCV 기능들은 아래와 같습니다.
아래 굵은 글씨를 위 빨간 글씨 위치에 바꿔 놓으면 기능을 테스트 할 수 있습니다. 쉽죠?
  cvdilate: cvdilate
  cvequalizehist: cvequalizehist
  cverode: cverode
  cvlaplace: cvlaplace
  cvsmooth: cvsmooth
  cvsobel: cvsobel
  edgedetect: edgedetect
  faceblur: faceblur
  facedetect: facedetect
  motioncells: motioncells
  pyramidsegment: pyramidsegment
  templatematch: templatematch
  opencvtextoverlay: opencvtextoverlay
  handdetect: handdetect
  skindetect: skindetect
  retinex: Retinex image colour enhacement
  segmentation: Foreground/background video sequence segmentation
  grabcut: Grabcut-based image FG/BG segmentation
  disparity: Stereo image disparity (depth) map calculation

그런데 지난번에 소개드린 '자비스' 의 음성인식 처럼, 화자의 얼굴을 인식하는게 실제 사용하는 좋은 기능이 될 수 있어서 찾아보니 OpenCV 에서 이미 사용할 수 있게 되어 있었습니다.

'얼굴 인식' 에 대한 자료와 사용 방법입니다.
출처 : facerec

요약해 보면,
1. 얼굴 인식에 사용할 주인공들의 사진을 찍습니다.
 - 저, 아들, 멍순이 그리고 개구리가 수고 해 줬습니다.
 - 유의 하실 점은 사진은 다다익선, 크기는 인식 때 사용할 webcam 혹은 cam 과 같은 해상도
 - 다 찍은 후 pgm 포맷으로 변환 해 줍니다. (전 gimp 로 변환 했습니다)

2. 찍은 사진을 database 화 해 줍니다.
 - 출처 링크에서 script 를 다운 받아 실행 합니다.
 $ python create_csv.py `pwd` > celebrities.txt
 - 참고로 제 db 파일은 아래와 같습니다.
/home/gouache/raspberry/opencv/faces/john/5.pgm;1
/home/gouache/raspberry/opencv/faces/john/4.pgm;1
/home/gouache/raspberry/opencv/faces/john/2.pgm;1
/home/gouache/raspberry/opencv/faces/john/1.pgm;1
/home/gouache/raspberry/opencv/faces/john/3.pgm;1
/home/gouache/raspberry/opencv/faces/gouache/5.pgm;2
/home/gouache/raspberry/opencv/faces/gouache/4.pgm;2
/home/gouache/raspberry/opencv/faces/gouache/2.pgm;2
/home/gouache/raspberry/opencv/faces/gouache/1.pgm;2
/home/gouache/raspberry/opencv/faces/gouache/3.pgm;2
/home/gouache/raspberry/opencv/faces/frog/5.pgm;3
/home/gouache/raspberry/opencv/faces/frog/4.pgm;3
/home/gouache/raspberry/opencv/faces/frog/2.pgm;3
/home/gouache/raspberry/opencv/faces/frog/1.pgm;3
/home/gouache/raspberry/opencv/faces/frog/3.pgm;3
/home/gouache/raspberry/opencv/faces/dog/5.pgm;4
/home/gouache/raspberry/opencv/faces/dog/4.pgm;4
/home/gouache/raspberry/opencv/faces/dog/2.pgm;4
/home/gouache/raspberry/opencv/faces/dog/1.pgm;4
/home/gouache/raspberry/opencv/faces/dog/3.pgm;4
3. 얼굴 인식 소스를 받아 빌드하고 실행 합니다.
 $ wget http://docs.opencv.org/_downloads/facerec_video.cpp
 $  sudo apt-get install libopencv-dev
 $ g++ -o facerec facerec_video.cpp `pkg-config --cflags --libs opencv`
 $ ./facerec /usr/share/opencv/haarcascades/haarcascade_frontalface_default.xml celebrities.txt 0
4. 결과물을 확인 합니다.
 - 초상권 보호를 위해 모자이크 처리를 했습니다. ㅋㅋㅋ
[4번에 위치한 멍순이. 멍순이도 초상권 보호를 위해 ^^]
[Database 에서 2번인 저를 인식합니다]
[1번에 기록된 아들을 인식]

초반에 시행착오를 많이 했습니다.
사진의 크기를 맞추고 pgm 포맷으로 변환하고 db 를 만드는 작업이 처음하는 사람들에겐 어려울 수 밖에 없겠더군요.

이로써 라즈베리파이로 '눈달린 자비스'를 갖게 되었습니다~~ 

댓글 4개:

김시현 :

안녕하세요
$ raspivid -n -t 0 -b 5000000 -w 1280 -h 720 -fps 30 -o - | gst-launch-1.0 -v fdsrc ! h264parse ! rtph264pay config-interval=1 pt=96 ! gdppay ! tcpserversink host=192.168.0.23 port=5000
여기서부터 막히는데 따로 gst-launch-1.0을 깔아야 하는건가요? 그리고 호스트 주소가 끝이 23 으로 끝나는데 제가 쓰는 파이 ip주소로 할당 해야하는건가요?

brian Park :

네네, $ sudo apt-get install gstreamer1.0-tools 로 설치 하시면 될 것 같네요. gstreamer 관련 plugin 들은 gstreamer1.0-plugins-xxx 들 중에 필요하신 것 설치 하시면 될거에요. IP address 는 지금 생각해 보니 127.0.0.1 로 해도 되지 않을까 싶네요. ㅎㅎ

김시현 :

erroneous pipeline: no element "pt96"
mmal : mmal_vc_component_enable: failed to enable component :ENOSPC
mmal : camera component couldn't be enable 이거는 raspi-config에서 camera enable 해줬는데 따로 뭔 처리를 해야하나요??
mmal :main: Failed to create camera component
mmal :Failed to run camera app. Please check for firmware update
guvcview 있고 업데이트 상태 확인했는데 저런게 뜨는데 혹시 해결 방법을 아시나요??

김시현 :

아... 계속 막히네요... 이번에는 오류없이 커멘드가 실행이 됐는데 Pipeline is PREROLLED... Setting pipeline to PLAYING... New clock: GstSystemClock 여기서 장기간 멈춰있는데 이게 실행이 되고있는건지 궁금합니다.