Project.h
// Project.h: interface of CProject (main project class you will write)
// Dept. Software Convergence, Kyung Hee University
// Prof. Daeho Lee, [email protected]
//
#pragma once
#include "cv_dnn_ultraface.h"
class CKcPoint {//점 (x,y)
public:
int x, y;
CKcPoint() : x(0), y(0) {}
CKcPoint(int x, int y) : x(x), y(y) {}
CKcPoint operator+(const CKcPoint& p) const {
return { x + p.x, y + p.y };
}
CKcPoint operator-(const CKcPoint& p) const {
return { x - p.x, y - p.y };
}
};
class CKcRect {
public:
int left, top, right, bottom;
CKcRect() {}
CKcRect(int l, int t, int r, int b) : left(l), top(t), right(r), bottom(b) {}
double Iou(const CKcRect& rt) {/*write codes*/ }
CKcRect Intersect(const CKcRect& rt) const {/*write codes*/}
bool IsRect() const {
if (left >= right) return false;
if (top >= bottom) return false;
return true;
}
int Width() const {
return right - left;
}
int Height() const {
return bottom - top;
}
CKcPoint Center() const {
return CKcPoint((right + left) / 2, (bottom + top) / 2);
}
void RefineImage(int nW, int nH) {
if (left < 0) left = 0;
if (top < 0) top = 0;
if (right < 0) right = 0;
if (bottom < 0) bottom = 0;
if (left >= nW) left = nW - 1;
if (top >= nH) top = nH - 1;
if (right >= nW) right = nW - 1;
if (bottom >= nH) bottom = nH - 1;
}
};
class CFaceTracker {
public:
static int cnt;
int id;
CKcRect rt;
int untrackedCnt;
bool remove;
CKcPoint offset;
CFaceTracker() {
id = cnt++;
untrackedCnt = 0;
remove = false;
}
CFaceTracker(int l, int t, int r, int b) : rt(l, t, r, b) {
id = cnt++;
untrackedCnt = 0;
remove = false;
}
CFaceTracker(CKcRect rt) : rt(rt) {
id = cnt++;
untrackedCnt = 0;
remove = false;
}
};
class CProject
{
cv::Mat m_PreviousImage;
public:
char m_ExePath[256];
wchar_t m_ExePathUnicode[256];
CProject();
~CProject();
void GetExecutionPath();
void Run(cv::Mat Input, cv::Mat& Output, bool bFirstRun, bool bVerbose);
UltraFace* m_pUltraface;
std::vector<CFaceTracker> m_FaceTracker;
};
Project.cpp
// Project.cpp: implementation of CProject (main project class you will write)
// Dept. Software Convergence, Kyung Hee University
// Prof. Daeho Lee, [email protected]
//
#include "KhuCvApp.h"
#include "Project.h"
#ifdef _MSC_VER
#ifdef _DEBUG
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
#define new DEBUG_NEW
#endif
#endif
CProject::CProject() {
try {
GetExecutionPath();
m_pUltraface = new UltraFace(m_ExePath, 320, 240);
}catch(cv::Exception& e) {
DlgPrintf(e.what());
}
}
CProject::~CProject() {
delete m_pUltraface;
}
void CProject::GetExecutionPath() {
wxFileName f(wxStandardPaths::Get().GetExecutablePath());
wxString appPath(f.GetPath());
wcscpy(m_ExePathUnicode, appPath);
strcpy(m_ExePath, appPath.c_str());
}
int CFaceTracker::cnt = 0;
void CProject::Run(cv::Mat Input, cv::Mat& Output, bool bFirstRun, bool bVerbose) {
if (bFirstRun) {
CFaceTracker::cnt = 0;
m_FaceTracker.clear();
}
std::vector<FaceInfo> faceList;
m_pUltraface->detect(Input, faceList);
cv::Mat OutImage = Input.clone();
std::vector<bool> bUntrackedList(m_FaceTracker.size());
std::vector<CKcRect> m_prediction(m_FaceTracker.size());
for (int i = 0; i < bUntrackedList.size(); ++i)
bUntrackedList[i] = true;
/*m_FaceTracker에서 offset값을 이용하여 m_prediction 요소를 생성함*/
for (int i = 0; i < m_prediction.size(); i++) {
/*write codes*/
}
/* detect 한 face를 m_prediction이 Iou가 높은 객체를 가지고 있으면 m_FaceTracker를 수정해주고 아닐 경우 m_FaceTracker에 추가함*/
for (auto list : faceList) {
CKcRect rt(list.x1, list.y1, list.x2, list.y2);
bool bTracked = false;
for (int i = 0; i < m_prediction.size(); ++i) {
/*write codes*/
}
if (!bTracked) {
/*write codes*/
}
}
/*m_FaceTracker에서 tracking이 되지 않은 객체에 대해 untrackedCnt값을 증가시켜주고 사각형 정보를 prediction으로 수정해줌
* 만약 untrackedCnt값이 임계치를 넘었을 경우 삭제함
* tracking이 된 객체는 untrackedCnt값을 0으로 초기화함
*/
for (int i = 0; i < bUntrackedList.size(); ++i) {
/*writed codes*/
}
/*remove 값이 true인 객체에 한하여 std::erase_if 함수를 이용하여 m_FaceTracker에서 삭제*/
/*writes codes*/
if (bVerbose) {
cv::Mat OutImage2 = OutImage.clone();
for (auto track : m_FaceTracker) {
std::stringstream ss;
ss << track.id << ",";
ss << track.untrackedCnt;
if (track.untrackedCnt > 0) {
DrawTextOnImage(OutImage, ss.str(), track.rt.left, track.rt.top - 20, 255, 0, 255, 15);
cv::rectangle(OutImage, cv::Point(track.rt.left, track.rt.top), cv::Point(track.rt.right, track.rt.bottom), cv::Scalar(255, 0, 255), 2);
}
else if (track.untrackedCnt == 0)
{
DrawTextOnImage(OutImage, ss.str(), track.rt.left, track.rt.top - 20, 255, 0, 0, 15);
cv::rectangle(OutImage, cv::Point(track.rt.left, track.rt.top), cv::Point(track.rt.right, track.rt.bottom), cv::Scalar(0, 0, 255), 2);
}
}
for (auto list : faceList) {
cv::rectangle(OutImage2, cv::Point(list.x1, list.y1), cv::Point(list.x2, list.y2), cv::Scalar(0, 0, 255), 2);
}
DisplayImage(OutImage, Input.cols, 0, false, true);
DisplayImage(OutImage2, Input.cols, Input.rows, false, true);
}
}