[OpenCV] Webcam을 이용해서 얼굴을 인식하는 간단한 예제

이전에 OpenCV를 이용해서 간단히 webcam에 접근하는 예제를 포스팅 한 적이 있는데, 기왕 웹캠을 띄웠으니 얼굴 인식도 추가해보기로 했다. 추가적으로 구현하는 것이 아니라 OpenCV에서 제공하는 함수를 가져다 쓰기만 하면 된다.

/*
*   @file ocv_cam_face.cc
*   @brief Face detection using OpenCV with Webcam
*   @author http://thinkpiece.tistory.com
*/

#include "opencv/cv.h"
#include "opencv/highgui.h"
#include <iostream>

int main(int argc, char *argv[])
{

    // -------------------------------------------------------------------------
    // webcam routine
    cv::VideoCapture capture(0);

    if( !capture.isOpened() ) {
        std::cerr << "Could not open camera" << std::endl;
        return 0;
    }

    // create a window
    cv::namedWindow("webcam",1);

    // -------------------------------------------------------------------------
    // face detection configuration
    cv::CascadeClassifier face_classifier;
    face_classifier.load("haarcascade_frontalface_default.xml");

    while (true) {
        bool frame_valid = true;

        cv::Mat frame_original;
        cv::Mat frame;

        try {
            capture >> frame_original; // get a new frame from webcam
            cv::resize(frame_original,frame,cv::Size(frame_original.cols/2,
                frame_original.rows/2),0,0,CV_INTER_NN); // downsample 1/2x
        } catch(cv::Exception& e) {
            std::cerr << "Exception occurred. Ignoring frame... " << e.err
                      << std::endl;
            frame_valid = false;
        }

        if (frame_valid) {
            try {
                // convert captured frame to gray scale & equalize
                cv::Mat grayframe;
                cv::cvtColor(frame, grayframe, CV_BGR2GRAY);
                cv::equalizeHist(grayframe,grayframe);

                // -------------------------------------------------------------
                // face detection routine

                // a vector array to store the face found
                std::vector<cv::Rect> faces;

                face_classifier.detectMultiScale(grayframe, faces, 
                    1.1, // increase search scale by 10% each pass
                    3,   // merge groups of three detections
                    CV_HAAR_FIND_BIGGEST_OBJECT|CV_HAAR_SCALE_IMAGE,
                    cv::Size(30,30));

                // -------------------------------------------------------------
                // draw the results
                for(int i=0; i<faces.size(); i++) {
                    cv::Point lb(faces[i].x + faces[i].width, 
                                 faces[i].y + faces[i].height);
                    cv::Point tr(faces[i].x, faces[i].y);

                    cv::rectangle(frame, lb, tr, cv::Scalar(0,255,0), 3, 4, 0); 
                }

                // print the output
                cv::imshow("webcam", frame);

            } catch(cv::Exception& e) {
                std::cerr << "Exception occurred. Ignoring frame... " << e.err
                          << std::endl;
            }
        }
        if (cv::waitKey(30) >= 0) break;
    }

    // VideoCapture automatically deallocate camera object
    return 0;
}

OpenCV에서는 얼굴 인식을 위한 여러가지 템플릿을 이미 제공하고 있다. OpenCV가 설치된 폴더를 살펴보면 haarcascade classifier를 위한 여러가지 xml파일들을 찾을 수 있을 것이다. 사용자가 직접 얼굴 데이터베이스를 기반으로 학습해놓지 않아도 얼추 잘 된다. 위 예제는 그 파일들 중 haarcascade_frontalface_default.xml을 사용한 예제. 이외에도 alt, alt2, tree 등 몇가지 수식어가 붙은 버전들이 함께 제공된다. 아래는 수행결과.


  • 게스트 썸네일
    지나가는사람
    2014.02.26 13:57 신고

    영상은 뜨는데 인물사진가지고 앞에 비춰봤는데 인식이 안되네요 ... ㅠㅠ

    • 게스트 썸네일
      2014.02.26 22:18 신고

      아무래도 템플릿을 이용하는 매칭이다보니, 인식하고자하는 목표 인물에 따라서는 안될 수도 있습니다. OpenCV에서 몇가지 얼굴 템플릿을 제공하니 바꿔가며 써보세요. 제가 사용한 것은 haarcascade_frontalface_default.xml 입니다.

  • 게스트 썸네일
    ajb
    2014.03.23 21:37 신고

    안녕하세요. 이제막 mfc로 웹캠 영상받고, 얼굴인식하려는사람인데 처음이라..
    haarcascade_frontalface_default.xml 이녀석을 어디서 찾죠 ?ㅠ

    • 게스트 썸네일
      2014.03.24 21:47 신고

      Windows용 OpenCV에서는 경로가 살짝 다르네요.
      opencv 경로에서

      sources/data/haarcascades

      경로로 가시면 22개의 xml파일이 있네요 (2.4.8 기준)

  • 게스트 썸네일
    맛둥도련님
    2014.07.02 18:14 신고

    window용 opencv (2.4.8)사용하는데 경로도 수정하였지만,
    저 역시 웹캠하면만 뜨고 얼굴영역을 못찾네요
    무슨 문제로 안되는 걸까요??

    • 게스트 썸네일
      2014.07.02 23:26 신고

      얼굴 검출이 항상 성공하는 것은 아닙니다. 모든 템플릿이 잘 로딩이 되었다면 영상 환경 탓일 수 있습니다.

      1) 웹캠 화면에서 얼굴이 크게 나오도록 거리 조절을 해보세요.
      2) 조명을 충분히 주세요. 되도록이면 얼굴 전체에 균일한 조명이 비춰지면 좋습니다. 얼굴에 그림자가 많이 끼면 ...
      3) 같은 정면 얼굴이더라도, 템플릿 종류가 다양합니다. 바꿔가면서 확인해보세요.

  • 게스트 썸네일
    희재
    2014.08.04 15:46 신고

    opencv 자료 어디서 참고 하시는지 궁금합니다 서적이나 홈페이면 어느경로를 통해서 습득하셨는지 알수 없을까요?
    제가 졸업작품으로 할 것이 opencv로 이미지 패턴화 작업 및 매칭 관련해서 하려고 합니다. 일단 opencv의 다양한 기법들을 써본 후에 이미지 매칭을 하고 싶은데 제가 생소한 분야여서 그런지 자료를 찾기가 힘드네요....

    • 게스트 썸네일
      2014.08.10 07:44 신고

      opencv를 하나하나 배우기에는 내용이 방대해서 무리가 있으니 하고자 하시는 일을 단계별로 나눈 뒤에 하나하나에 해당하는 예제를 찾아서 이해하시는 게 편할 듯 합니다. cv::Mat 타입에 대해서만 이해하시면 될거에요. OpenCV 공식 홈페이지 튜토리얼을 추천합니다.

  • 게스트 썸네일
    sdfsd
    2015.01.05 03:36 신고

    int main(int,char *[])' 함수에 이미 본문이 있습니다. 이오류 어떻게 해결해야되나요?? 비주얼 스튜디오 2013버전에서 실행했는데 안되네요...

  • 게스트 썸네일
    2015.03.27 19:28

    비밀댓글입니다

    • 게스트 썸네일
      2015.03.27 21:06 신고

      안녕하세요.

      OpenCV 기본 소스를 제가 조금 변경한 것일 뿐이라
      마음대로 가져다 쓰셔도 됩니다.

  • 게스트 썸네일
    세영
    2015.04.05 18:30 신고

    좋은 정보 주셔서 감사합니다!!!
    제가 이번에 졸업작품을 만들예정인데요 opencv를 처음 해보는지라 너무나 어렵네요
    우선 함수로는 대충 이해는 갈거 같은데요 haarcascade_frontalface_default.xml 이런거는 알고리즘인지 궁금하네요
    제가 직접 알고리즘을 짜서 구현해보고 싶은데 현재는 올라와있는 코드를 통해 웹캠만 해본상태인데 어떻게 공부하고 어떤식으로 해결해야할지 도무지 감이 잡히지가 않네요 알고리즘을 공부할려면 어떻게하나요? 제가 너무 질문이 많네요 죄송합니다

    • 게스트 썸네일
      2015.04.07 01:47 신고

      안녕하세요. 얼굴인식은 이미 상용제품에도 활용될 만큼 많이 연구된 기술이기 때문에, 교육자료 또한 굉장히 많습니다.

      http://docs.opencv.org/modules/contrib/doc/facerec/facerec_tutorial.html

      opencv에 face recognition tutorial 이 있는데 여기부터 먼저 읽어나가면서 어떤 식으로 동작하는지 아시는 게 좋을 것 같습니다.

  • 게스트 썸네일
    에러가 나용..
    2015.04.09 02:31 신고

    0x00048016에(ConsoleApplication4.exe의) 처리되지 않은 예외가 있습니다. 0xC0000005: 0x0000001C 위치를 읽는 동안 액세스 위반이 발생했습니다..

    컴파일 단계에선 에러가 없지만 실행하면 에러가 나서 디버깅을 해보면 이런 에러가 뜹니다.
    capture >> frame_original; // get a new frame from webcam
    도저히 왜그러는지 모르겠습니다...

  • 게스트 썸네일
    세영
    2015.04.10 13:02 신고

    경로를 어떻게 지정해야되나여?
    제꺼는 /문서/OPENCV/이런식으로 있는데

    • 게스트 썸네일
      2015.04.14 18:20 신고

      윈도우 쓰신다면.. 아마 기본 문서 폴더가 C:/Users/세영님 아이디/Documents 로 되어있을꺼에요. 문서 폴더에서 우클릭하셔서 정보 보시면 폴더의 절대 경로 나올겁니다.

  • 게스트 썸네일
    2015.05.21 02:57

    비밀댓글입니다

  • 게스트 썸네일
    서희
    2015.11.09 20:39 신고

    이거 리눅스용 소스코드인가요? 윈도우로 하려면 어떻게 해야하나요 ㅠㅠ 어느부분을 바꿔야하는지..

  • 게스트 썸네일
    우걍강
    2016.04.15 02:13 신고

    안녕하세요! 블로그 잘 보았습니다.
    소스에는 아무런 문제가 없는데, 제pc에서 돌리면 detectMultiScale 메소드를 수행한 후에 faces 의 size가 어마어마하게 큰 수가 리턴됩니다.
    그러면서 그 수만큼 돌다가 메모리 엑세스 위반 오류가 듭니다. 캠에 얼굴 딱 1개 있습니다.
    이런 경우 버그라고 볼 수 있을까요?
    혹시나해서 OS도 64bit 에서 32bit로도 바꿨고, opencv버전도 3.1에서 3.0으로 바꿔서 테스트 했는데도 불구하고. 이러네요..
    혹시 tip이 있으시다면 가이드 부탁드립니다!

  • 게스트 썸네일
    학생
    2016.05.27 18:46 신고

    음 사각형으로 얼굴 주위에 표시가 되는것을 그곳만 필터 처리를 할수있을까요?

  • 게스트 썸네일
    학생
    2016.05.27 18:46 신고

    음 사각형으로 얼굴 주위에 표시가 되는것을 그곳만 필터 처리를 할수있을까요?

  • 게스트 썸네일
    2017.03.21 12:30

    비밀댓글입니다

  • 게스트 썸네일
    대학생
    2017.04.01 13:19 신고

    웹캠이 뜨자마자 꺼지는데 왜 그런지 알수있을까요?

    • 게스트 썸네일
      2017.06.05 11:48 신고

      바로 꺼지는건

      if (cv::waitKey(30) >= 0) break;

      이부분을

      if (cv::waitKey(30) == 0) break;

      으로 바꿔보세요 전 그렇게해서 일단 해결했습니다.