04-28 14:02
Notice
Recent Posts
Recent Comments
관리 메뉴

Scientific Computing & Data Science

[OpenCV] Face Detection & Put Mask on Face 본문

Programming/OpenCV

[OpenCV] Face Detection & Put Mask on Face

cinema4dr12 2015. 9. 26. 18:50

이번 포스팅에서는 안면 인식과 인식된 안면에 이미지를 정합하는 예제에 대하여 다루도록 하겠습니다.


아래 파일을 다운로드 하세요:

masks.zip

haarcascade_frontalface_alt2.zip


다음과 같이 코드는 크게 3개의 함수로 구성됩니다:

  • main 함수

  • 안면인식에 대한 함수: detectFace

  • Mask 이미지를 정합하는 함수: putMask

Implementation

1. Face Detection


안면 인식을 위한 cascade 파일을 불러옵니다:


1
2
/// Load Face cascade (.xml file)
cv::CascadeClassifier face_cascade( "{OpenCV_DATA_PATH}/haarcascade_frontalface_alt2.xml" );
cs


참고로 Haar Cascade에 대해서는 다음 링크를 참고합니다:

(1) 이론: http://docs.opencv.org/master/d7/d8b/tutorial_py_face_detection.html#gsc.tab=0

(2) Haar Cascade 생성하기: http://note.sonots.com/SciSoftware/haartraining.html


다음은 안면을 인식하는 코드입니다:


1
2
3
/// Detect faces
std::vector<Rect> faces;
face_cascade.detectMultiScale( image, faces, 1.220|CV_HAAR_SCALE_IMAGE, cv::Size( (int)min_face_size, (int)min_face_size ), cv::Size( (int)max_face_size, (int)max_face_size ) );
cs


detectMultiScale 함수의 prototype은 다음과 같습니다:


1
2
3
4
5
6
7
CV_WRAP void detectMultiScale( InputArray image,
                          CV_OUT std::vector<Rect>& objects,
                          double scaleFactor = 1.1,
                          int minNeighbors = 3,
                          int flags = 0,
                          Size minSize = Size(),
                          Size maxSize = Size() );
cs


Detected Face에 원(circle)을 그립니다. 이때 첫번째로 인식된 얼굴만 추적하도록 합니다.


1
2
3
4
5
6
7
8
9
/// Draw circles on the detected faces
forint i = 0 ; i < faces.size() ; i++ )
{
    /// Lets only track the first face, i.e. face[0]
    min_face_size = faces[0].width * 0.7;
    max_face_size = faces[0].width * 1.5;
    cv::Point center( faces[i].x + faces[i].width * 0.5, faces[i].y + faces[i].height * 0.5 );
    image = putMask( image, center, cv::Size( faces[i].width, faces[i].height ) );
}
cs


2. Putting Mask on Face

Example Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/*/////////////////////////////////////
@ function: putMask
*//////////////////////////////////////
cv::Mat putMask( cv::Mat src, cv::Point center, cv::Size face_size )
{
    cv::Mat mask1, src1;
    cv::resize( mask, mask1, face_size );
 
    /// ROI selection
    cv::Rect roi( center.x - face_size.width / 2, center.y - face_size.width / 2, face_size.width, face_size.width );
    src(roi).copyTo(src1);
 
    /// to make the white region transparent
    cv::Mat mask2, m, m1;
    cv::cvtColor( mask1, mask2, CV_BGR2GRAY );
    cv::threshold( mask2, mask2, 230255, CV_THRESH_BINARY_INV ); 
 
    vector<cv::Mat> maskChannels( 3 ), result_mask( 3 );
    cv::split( mask1, maskChannels );
    cv::bitwise_and( maskChannels[0], mask2, result_mask[0] );
    cv::bitwise_and( maskChannels[1], mask2, result_mask[1] );
    cv::bitwise_and( maskChannels[2], mask2, result_mask[2] );
    cv::merge( result_mask, m );
 
    mask2 = 255 - mask2;
    vector<cv::Mat> srcChannels( 3 );
    cv::split(src1, srcChannels);
    cv::bitwise_and( srcChannels[0], mask2, result_mask[0] );
    cv::bitwise_and( srcChannels[1], mask2, result_mask[1] );
    cv::bitwise_and( srcChannels[2], mask2, result_mask[2] );
    cv::merge( result_mask, m1 );
 
    cv::addWeighted( m, 1, m1, 10, m1);
    m1.copyTo( src( roi ) );
 
    return src;
}
cs

Result


'Programming > OpenCV' 카테고리의 다른 글

[OpenCV] Custom Color Map  (0) 2015.09.28
[OpenCV] Color Map  (0) 2015.09.27
[OpenCV] 이미지 윈도우 상에서 마우스 이벤트 감지하기  (0) 2015.09.23
[OpenCV] Bitwise Operation  (0) 2015.09.20
[OpenCV] 2D Convolution / New Filter  (0) 2015.09.16
Comments