7. [KhuCv] - FaceTracking, Performance Improvement.

이원규·2023년 2월 14일
0

1. Performance Improvement.

1-1. FaceTracking Improvement 요약.

if(maxSimilarity > 0.945) identified = true;
else if(maxSimilarity > 0.93 && maxTracker->UnTracked > 5) identified = true;

이전 코드(6번 게시물 참조 - 위의 코드처럼)는 수치를 코드에 넣음으로써, 일반적인 경우에 적용하기 힘든 코드였다. 또한 FaceSimilarity가 mobile_net DNN중 사람들간의 얼굴을 구별해주는 DNN이 아니라 사람, 개, 고양이 등 종류를 분류해주는 기능을하는 DNN파일이다. 따라서 해당 FaceSimilariry의 수치를 이용하면 정확도가 많이 떨어져 제대로 매칭되지 않는 경우가 허다했다. 이를 보완하고자, FaceSimilariry 수치는 이용하지 않으면서 가장 유사도가 높은 FaceRect가 매칭되도록 코드를 작성하였다.

전체적으로 첫번째 Tracking은 IOU판별에 의해 이뤄지며, 여러 FaceRect가 Face에 겹칠 경우, Face와 가장 유사도가 높은 FaceRect가 Face에 부여된다.

만약 IOU가 겹치는 FaceRect가 없다면, 일정 거리를 만족하는 FaceRect중 가장 유사도가 높은 것을 Face에 매칭해준다. 여기서 일정거리는 해당 Face와 FaceRect 사이의 거리가 FaceRect의 offset길이와 UnTracked된 횟수 만큼 곱한 값보다 작아야 한다는 조건이다. 이는 멀리 떨어진 FaceRect가 엉뚱한 Face에 매칭되는 것을 막으며, 기준 거리에 UnTracked를 곱해주어 UnTracked된 프레임 수에 따라 거리를 조절하여 FaceRect를 찾아 유사도를 비교하여 매칭시킬 수 있다.


1-2. 최종 코드

- Project.cpp - Github

- Project.h - Github


1-3. 결과 영상

[결과 영상] : Github - KhuCv FaceTracking Project Preview Video.


1-4. 코드 설명

- IOU판별

// IOU가 0.15넘는 FaceRect(Tracker)는 iouVectors에 넣음.
if(m_idTrackers[i].rt.iou(currentRt) > 0.15) {
	iouVectors.push_back(&m_idTrackers[i]);
}

// IOU가 0.15넘는 FaceRect(Tracker)중 가장 유사도가 큰 걸 부여.
if(iouVectors.size() > 0){
	identified = true;
    double maxSim = 0;
    if(iouVectors.size() == 1) maxTracker = iouVectors[0];
    else{
    	for(int i = 0; i < iouVectors.size(); ++i){
            double sim = iouVectors[i]->GetCosineSimilarity(cvFeature);
            if(sim > maxSim) {
                maxSim = sim;
                maxTracker = iouVectors[i];
            }
    	}
    }
}

해당 Face와 IOU가 0.15넘는 FaceRect(Tracker)는 iouVectors에 넣음. 만약 IOU > 0.15를 만족하는 Tracker가 한 개라면 그 FaceRect를 Face에 부여하고, 아니라면 IOU가 0.15넘는 FaceRect(Tracker)중 가장 유사도가 큰 걸 부여.

- Face유사도 판별

// 거리 정의
// distance : 이전 프레임과 현재 프레임의 FaceRect의 거리
// threshold : FaceRect이동속도(offset)에 UnTracked된 횟수 곱한 거리.
double distance = fabs((m_idTrackers[i].rt.center() - currentRt.center()).mag());
double threshold = fabs((m_idTrackers[i].offset).mag() * m_idTrackers[i].UnTracked);

// 유사도 판별
double similarity = m_idTrackers[i].GetCosineSimilarity(cvFeature);

// 거리를 만족하고, Face와 유사도가 제일 높은 FaceRect(maxTracker) 뽑기
else if(distance <= threshold && similarity > maxSimilarity) { // FaceRect주변에서만 조사
    maxSimilarity = similarity;
	maxTracker = &m_idTrackers[i];
}

Face와 FaceRect사이의 거리가 추적한 거리(threshold)보다 작으면 유사도 판별을 진행함. 즉, Face를 추적하고 있는 FaceRect가 Face와 어느 정도 가까이 있을 경우에만 유사도를 측정하여 Face에 FaceRect를 매칭하도록 함.

profile
github: https://github.com/WKlee0607

0개의 댓글