본문 바로가기
Study/Android

Face detection(얼굴인식) in Android Using Mobile Vision API - 3

by Answer Choi 2018. 6. 5.
반응형

샘플예제 다운로드



앞선 포스팅에서 얼굴의 중요부위(LandMark)에 원을 그렸었습니다.



위 사진을 보고 사람마다 생김새가 다르니


얼굴의 눈과 볼, 입사이의 거리 비율을 적어 비교해 보겠습니다.


수정할 부분은 FaceView.java 파일입니다.


drawFaceAnnotations함수를 보면 얼굴에서 랜드마크에 원을 그립니다.


이부분을 보면 랜드마크의 위치를 알 수 있습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private void drawFaceAnnotations(Canvas canvas, double scale) {
    Paint paint = new Paint();
    paint.setColor(Color.GREEN);
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeWidth(3);
 
    for (int i = 0; i < mFaces.size(); ++i) {
        Face face = mFaces.valueAt(i);
        for (Landmark landmark : face.getLandmarks()) {
           int cx = (int) (landmark.getPosition().x * scale);
           int cy = (int) (landmark.getPosition().y * scale);
            canvas.drawCircle(cx, cy, 10, paint);
        }
    }
}
cs


Line 2~5 : 사진위의 랜드마크에 그림을 그릴 도구를 지정하는 곳입니다.


색은 녹색에 테두리두께는 3으로 하였씁니다.


Line 7~8 : 인식된 얼굴을 하나씩 지정하고


Line 9~12 : 랜드마크마다 찾아서 반지름 10으로 원을 그립니다.


이부분을  아래와 같이 변경합니다.


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
38
39
40
private void drawFaceAnnotations(Canvas canvas, double scale) {
    Paint paint = new Paint();
    paint.setColor(Color.GREEN);
    paint.setStyle(Paint.Style.STROKE);
    paint.setTextSize(40);
    paint.setStrokeWidth(3);
    for (int i = 0; i < mFaces.size(); ++i) {
        Face face = mFaces.valueAt(i);
        int cnt=0;
        int ox=0,oy=0;
        double dis1=0,dis2=0,dis3=0,dis4=0,dis5=0,dis6=0,dis7=0;
        for (Landmark landmark : face.getLandmarks()) {
            int cx = (int) (landmark.getPosition().x * scale);
            int cy = (int) (landmark.getPosition().y * scale);
            if(cnt>0) {
                double dis=getDistance(ox,oy,cx,cy);
                if(cnt==1)
                    dis1=dis;
                else if(cnt==2)
                    dis2=dis;
                else if(cnt==3)
                    dis3=dis;
                else if(cnt==4)
                    dis4=dis;
                else if(cnt==5)
                    dis5=dis;
                else if(cnt==6)
                    dis6=dis;
                else if(cnt==7)
                    dis7=dis;
                if(cnt==1||cnt==4||cnt==6)
                    canvas.drawText((double)Math.round(dis/dis1*100)/100+"",(cx+ox)/2,(cy+oy)/2,paint);
            }
            ox=cx;
            oy=cy;
            cnt++;
            canvas.drawCircle(cx, cy, 10, paint);
        }
    }
}
cs


추가된 부분만 보면


Line 5 : 텍스트를 입력하기 위해 텍스트 size를 넣어줍니다.


Line 9~11 : 각 Landmark의 길이를 재기위한 변수들입니다.


Line 15~30 : 각 랜드마크별로 길이를 저장합니다.


Line 16 : 길이는 두 랜드마크사이의 거리를 측정하기 위해 계산하는 함수를 하나 만들었습니다.


Line 32 : 눈사이 거리를 기준으로 비율을 띄워줍니다.



다른 두개의 사진을 비교해 봅니다.


위 사진은 눈을 기준으로 볼 사이는 0.97, 입 사이는 0.89입니다.


아래 사진은 볼 사이는 1, 입 사이는 0.81입니다.




이번에는 같은 인물의 사진으로 비교해 봤습니다.


왼쪽 위부터 시계방향으로 보면


1번사진 볼 1.1, 입 0.77


2번 사진 볼 1.1, 입 0.72


3번 사진 볼 1.18, 입 0.82


4번 사진 볼 1.13, 입 0.81 


얼굴 각도가 달라서인지 오차가 조금씩 발생합니다.


물론 이자료만으로 동일 인물을 찾아내기에는 역부족입니다만


좀 더 개선된 알고리즘을 적용하면 가능할 수도 있을 것 같습니다.

반응형

인기글