[ROS] 얼굴인식(face recognition): Raspberry Pi + face_recognition

지난 글에서는 얼굴 탐지에 대한 기능을 구현해 보았습니다: [ROS] 얼굴탐지(face detection)

얼굴 탐지는 카메라(이미지)에서 얼굴에 해당하는 부분을 사각형 부분으로 탐지하는 기술을 말합니다.

이번 글에서는 같은 환경에서 누구인지 판별할 수 있는 얼굴 인식(face recognition) 기능을 구현해 보도록 하겠습니다.

Step 1. Main Structure

얼굴 인식 기능은 연산 처리가 많기 때문에 computing resources를 많이 사용하는 기능입니다.

그래서 이번에는 cloud server에서 얼굴 인식 알고리즘을 실행시키고, raspberry pi에서는 이미지 전송 및 결과 tag만 전송받도록 해 보겠습니다.

 

 

Step 2. Server Side

face detection과 마찬가지로 face recognition도 다양한 서비스에서 다양한 알고리즘으로 제공하고 있습니다.

그 중에서 “face_recognition”을 사용해 보겠습니다.

github에 source, 설치법 및 사용법이 나와 있습니다.

README를 읽다 보니, docker 이미지로도 제공해 주고 있군요! 이번에는 docker 이미지를 활용해 보겠습니다.

 

저는 개인적으로 Amazon AWS Instance를 사용하고 있습니다. 하지만 t2.micro라서 높은 성능을 기대하기는 힘들 듯 합니다.

aws에 docker를 설치합니다. 설치법은 공식 홈페이지에 친절히 나와 있습니다. 

docker 이미지를 설치합니다.

docker pull aaftio/face_recognition

 

수행 명령어는 다음과 같습니다.

“docker run –volume [마운트할 폴더 경로] aaftio/face_recognition face_recognition [라벨링된 이미지 폴더] [확인하려는 이미지 경로] | cut -d ‘,’ -f2″

 

먼저, docker는 가상화 이미지이기 때문에 실제 시스템의 폴더를 공유하기 위해서 “–volume” 옵션을 사용합니다.

[라벨링된 이미지 폴더]에는 인식하려는 사람의 얼굴이 있는 이미지를 넣어둡니다.

예를 들어, 제 얼굴이 있는 사진을 찍어서 “napier.jpg” 로 넣어 두었습니다.

[확인하려는 이미지 경로]는 라즈베리파이에서 전송되는 이미지 경로를 지정합니다.

docker run --volume /var/www/face_recognition:/folders aaftio/face_recognition face_recognition /folders/people/ /tfolders/check/check.jpg | cut -d ',' -f2

 

그 후 해당 docker를 외부에서 실행 가능하도록 API를 만듭니다.

저는 php로 만들어 보았습니다.

Step 3. Client Side

라즈베리파이에서는 카메라에서 이미지를 얻어와 Server Side의  API를 호출하고, 전송되는 결과 tag를 처리하면 됩니다.

먼저 uvc_camera에서 topic으로 전송되는 영상을 opencv를 이용하여 파일로 저장합니다.

void imageCallback(const sensor_msgs::ImageConstPtr& msg)
{
  try {
    cv_bridge::CvImagePtr cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::iamge_encodings::RGB8);
    cv::imwrite("face.png", cv_ptr->image);
  } catch(cv_bridge::Exception e) {
    ROS_ERROR("cv_bridge exception: %s", e.what());
  }
}

int main(int argc, char **argv)
{
  ros::NodeHAndle nh;
  image_transport::ImageTransport it(nh);
  image_transport::Subscriber sub = it(subscribe("/image_raw", 1, imageCallback);
  ros::spin();
}

 

그 후 Server Side의 API를 통해 이미지를 전송한 후, 해당 결과 tag를 받으면 됩니다.