Head pose estimation
This commit is contained in:
1 parent
7f5aea5047
commit
d9bf46043e
160 files changed
+4724
-3380
No files matched your search
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
@@ -22,33 +22,35 @@
|
||||
<ProjectGuid>{1CC98EEE-BBCB-4D79-B6D7-8511789172C5}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>DoubleHitBallswin</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
|
||||
<ProjectName>TorchFaceTracker</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
@@ -110,13 +112,13 @@
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>TARGET_WIN32;DEBUG;_WIN32_WINNT=0x0501;EIGEN_DONT_ALIGN_STATICALLY;_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>../../../game;../../../../tes-engine;../../../../eigen;../../../../boost_1_63_0/;../../../../boost_1_63_0/bin.v2/libs/system/build/msvc-14.0/debug/address-model-64/link-static/threading-multi;../../../../boost_1_63_0/bin.v2/libs/date_time/build/msvc-14.0/debug/address-model-64/link-static/threading-multi/;../../../../boost_1_63_0/bin.v2/libs/regex/build/msvc-14.0/debug/address-model-64/link-static/threading-multi;../../../../boost_1_63_0/bin.v2/libs/thread/build/msvc-14.0/debug/address-model-64/link-static/threading-multi;../../../../boost_1_63_0/bin.v2/libs/chrono/build/msvc-14.0/debug/address-model-64/link-static/threading-multi;../../../../boost_1_63_0/bin.v2/libs/signals/build/msvc-14.0/debug/address-model-64/link-static/threading-multi;../../../../libs/boost-gil-extension;../../../../libs/jpeg-9;../../../../libs/jpeg-9/vc10;../../../../libs/lpng1510</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../../../luajit-vlad/luajit-vlad;..\..\..\..\..\Torch7\distro\install\include;C:\Work\TorchProjects\dlib;D:\Work\TorchProjects\dlib\dlib\..;..\..\..\..\..\Torch7\distro\exe\luajit-2.1\src;..\..\..\..\..\opencv3.4\build\include;D:\Work\Torch7\distro\install\include;../../../game;../../../../tes-engine;../../../../eigen;../../../../boost_1_67_0/;../../../../libs/boost-gil-extension;../../../../libs/jpeg-9;../../../../libs/jpeg-9/vc10;../../../../libs/lpng1510</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>4503</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>../../../game;../../../../tes-engine;../../../../eigen;../../../../boost_1_63_0/;../../../../boost_1_63_0/bin.v2/libs/system/build/msvc-14.0/debug/address-model-64/link-static/threading-multi;../../../../boost_1_63_0/bin.v2/libs/date_time/build/msvc-14.0/debug/address-model-64/link-static/threading-multi/;../../../../boost_1_63_0/bin.v2/libs/regex/build/msvc-14.0/debug/address-model-64/link-static/threading-multi;../../../../boost_1_63_0/bin.v2/libs/thread/build/msvc-14.0/debug/address-model-64/link-static/threading-multi;../../../../boost_1_63_0/bin.v2/libs/chrono/build/msvc-14.0/debug/address-model-64/link-static/threading-multi;../../../../boost_1_63_0/bin.v2/libs/filesystem/build/msvc-14.0/debug/address-model-64/link-static/threading-multi;../../../../boost_1_63_0/bin.v2/libs/signals/build/msvc-14.0/debug/address-model-64/link-static/threading-multi;../../../../libs/boost-gil-extension;../../../../libs/jpeg-9;../../../../libs/jpeg-9/vc10;../../../../libs/lpng1510;../x64/Debug</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>../../../game;../../../../tes-engine;../../../../eigen;../../../../boost_1_67_0/stage/lib;../../../../libs/jpeg-9;../../../../libs/jpeg-9/vc10;../../../../libs/lpng1510;../x64/Debug</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>libjpeg.lib;libpng.lib;Engine.lib;opengl32.lib;glu32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
@@ -150,7 +152,7 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;TARGET_WIN32;_WIN32_WINNT=0x0501;WIN32_LEAN_AND_MEAN;EIGEN_DONT_ALIGN_STATICALLY;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>../../../game;../../../../tes-engine;../../../../eigen;../../../../boost_1_63_0/;../../../../boost_1_63_0/bin.v2/libs/system/build/msvc-14.0/release/address-model-64/link-static/threading-multi;../../../../boost_1_63_0/bin.v2/libs/date_time/build/msvc-14.0/release/address-model-64/link-static/threading-multi/;../../../../boost_1_63_0/bin.v2/libs/regex/build/msvc-14.0/release/address-model-64/link-static/threading-multi;../../../../boost_1_63_0/bin.v2/libs/thread/build/msvc-14.0/release/address-model-64/link-static/threading-multi;../../../../boost_1_63_0/bin.v2/libs/chrono/build/msvc-14.0/release/address-model-64/link-static/threading-multi;../../../../boost_1_63_0/bin.v2/libs/signals/build/msvc-14.0/release/address-model-64/link-static/threading-multi;../../../../libs/boost-gil-extension;../../../../libs/jpeg-9;../../../../libs/jpeg-9/vc10;../../../../libs/lpng1510</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../../../luajit-vlad/luajit-vlad;..\..\..\..\..\Torch7\distro\install\include;C:\Work\TorchProjects\dlib;D:\Work\TorchProjects\dlib\dlib\..;..\..\..\..\..\Torch7\distro\exe\luajit-2.1\src;..\..\..\..\..\opencv3.4\build\include;D:\Work\Torch7\distro\install\include;../../../game;../../../../tes-engine;../../../../eigen;../../../../boost_1_67_0/;../../../../libs/boost-gil-extension;../../../../libs/jpeg-9;../../../../libs/jpeg-9/vc10;../../../../libs/lpng1510</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>4503</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
@@ -158,26 +160,21 @@
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>../../../game;../../../../tes-engine;../../../../eigen;../../../../boost_1_63_0/;../../../../boost_1_63_0/bin.v2/libs/system/build/msvc-14.0/release/address-model-64/link-static/threading-multi;../../../../boost_1_63_0/bin.v2/libs/date_time/build/msvc-14.0/release/address-model-64/link-static/threading-multi/;../../../../boost_1_63_0/bin.v2/libs/regex/build/msvc-14.0/release/address-model-64/link-static/threading-multi;../../../../boost_1_63_0/bin.v2/libs/thread/build/msvc-14.0/release/address-model-64/link-static/threading-multi;../../../../boost_1_63_0/bin.v2/libs/chrono/build/msvc-14.0/release/address-model-64/link-static/threading-multi;../../../../boost_1_63_0/bin.v2/libs/signals/build/msvc-14.0/release/address-model-64/link-static/threading-multi;../../../../libs/boost-gil-extension;../../../../libs/jpeg-9;../../../../libs/jpeg-9/vc10;../../../../libs/lpng1510;../x64/Release</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>libjpeg.lib;libpng.lib;Engine.lib;opengl32.lib;glu32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\..\..\opencv3.4-build\lib\$(Configuration);..\..\..\..\..\opencv3.4-build\3rdparty\lib\$(Configuration);..\..\..\..\..\opencv3.4-build\3rdparty\ippicv\ippicv_win\lib\intel64;../../../game;../../../../tes-engine;../../../../eigen;../../../../boost_1_67_0/stage/lib;../../../../libs/jpeg-9;../../../../libs/jpeg-9/vc10;../x64/Release;C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v9.1/lib/x64;C:/Program Files/NVIDIA GPU Computing</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>ippiw.lib;ippicvmt.lib;cudart.lib;nppc.lib;nppial.lib;nppicc.lib;nppicom.lib;nppidei.lib;nppif.lib;nppig.lib;nppim.lib;nppist.lib;nppisu.lib;nppitc.lib;npps.lib;cufft.lib;opencv_dnn341.lib;opencv_highgui341.lib;opencv_videoio341.lib;opencv_imgcodecs341.lib;opencv_imgproc341.lib;opencv_core341.lib;opencv_calib3d341.lib;opencv_cudev341.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib;Engine.lib;opengl32.lib;glu32.lib;libjpeg-static.lib;libpng-static.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\game\creditscode.cpp" />
|
||||
<ClCompile Include="..\..\..\game\gamecode.cpp" />
|
||||
<ClCompile Include="..\..\..\game\loadingcode.cpp" />
|
||||
<ClCompile Include="..\..\..\game\main_code.cpp" />
|
||||
<ClCompile Include="..\..\..\game\menucode.cpp" />
|
||||
<ClCompile Include="FaceLandmarkDetector.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="ValueSmoother.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\game\creditscode.h" />
|
||||
<ClInclude Include="..\..\..\game\gamecode.h" />
|
||||
<ClInclude Include="..\..\..\game\game_area_interface.h" />
|
||||
<ClInclude Include="..\..\..\game\loadingcode.h" />
|
||||
<ClInclude Include="..\..\..\game\main_code.h" />
|
||||
<ClInclude Include="..\..\..\game\menucode.h" />
|
||||
<ClInclude Include="FaceLandmarkDetector.h" />
|
||||
<ClInclude Include="main.h" />
|
||||
<ClInclude Include="ValueSmoother.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
||||
@@ -21,16 +21,10 @@
|
||||
<ClCompile Include="..\..\..\game\main_code.cpp">
|
||||
<Filter>Файлы исходного кода</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\game\menucode.cpp">
|
||||
<ClCompile Include="FaceLandmarkDetector.cpp">
|
||||
<Filter>Файлы исходного кода</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\game\creditscode.cpp">
|
||||
<Filter>Файлы исходного кода</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\game\gamecode.cpp">
|
||||
<Filter>Файлы исходного кода</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\game\loadingcode.cpp">
|
||||
<ClCompile Include="ValueSmoother.cpp">
|
||||
<Filter>Файлы исходного кода</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
@@ -41,19 +35,10 @@
|
||||
<ClInclude Include="..\..\..\game\main_code.h">
|
||||
<Filter>Заголовочные файлы</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\game\menucode.h">
|
||||
<ClInclude Include="FaceLandmarkDetector.h">
|
||||
<Filter>Заголовочные файлы</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\game\creditscode.h">
|
||||
<Filter>Заголовочные файлы</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\game\game_area_interface.h">
|
||||
<Filter>Заголовочные файлы</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\game\gamecode.h">
|
||||
<Filter>Заголовочные файлы</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\game\loadingcode.h">
|
||||
<ClInclude Include="ValueSmoother.h">
|
||||
<Filter>Заголовочные файлы</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
</Project>
|
||||
@@ -0,0 +1,506 @@
|
||||
#include "FaceLandmarkDetector.h"
|
||||
|
||||
|
||||
|
||||
static const size_t faceTrackerWidth = 300;
|
||||
static const size_t faceTrackerHeight = 300;
|
||||
|
||||
static const double faceTrackerScaleFactor = 1.0;
|
||||
static const cv::Scalar faceTrackerMeanVal(104.0, 177.0, 123.0);
|
||||
|
||||
|
||||
float calcSquaredDistanceBetweenFaces(const cv::Rect& face1, const cv::Rect& face2)
|
||||
{
|
||||
|
||||
|
||||
cv::Point2f oldCenter(face1.x + face1.width*0.5f, face1.y + face1.height*0.5f);
|
||||
cv::Point2f newCenter(face2.x + face2.width*0.5f, face2.y + face2.height*0.5f);
|
||||
|
||||
float distanceX = newCenter.x - oldCenter.x;
|
||||
float distanceY = newCenter.y - oldCenter.y;
|
||||
|
||||
float squareDistance = distanceX * distanceX + distanceY * distanceY;
|
||||
|
||||
return squareDistance;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
FaceLandmarkDetector::FaceLandmarkDetector()
|
||||
{
|
||||
|
||||
|
||||
static const cv::String faceTrackerConfiguration = "deploy.prototxt";
|
||||
static const cv::String faceTrackerBinary = "res10_300x300_ssd_iter_140000.caffemodel";
|
||||
|
||||
|
||||
#ifdef USE_3D_LANDMARKS
|
||||
static const cv::String landmarkTrackerConfiguration = "fa_deploy.prototxt";
|
||||
static const cv::String landmarkTrackerBinary = "fa__iter_1400000.caffemodel";
|
||||
|
||||
#else
|
||||
static const cv::String landmarkTrackerConfiguration = "landmark_deploy.prototxt";
|
||||
static const cv::String landmarkTrackerBinary = "VanFace.caffemodel";
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
faceNet = cv::dnn::readNetFromCaffe(faceTrackerConfiguration, faceTrackerBinary);
|
||||
|
||||
for (size_t i = 0; i < MAX_FACE_COUNT; i++)
|
||||
{
|
||||
landmarkNetArr[i] = cv::dnn::readNetFromCaffe(landmarkTrackerConfiguration, landmarkTrackerBinary);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
FaceLandmarkDetector::~FaceLandmarkDetector()
|
||||
{
|
||||
StopTrackProcess();
|
||||
}
|
||||
|
||||
|
||||
void FaceLandmarkDetector::StartTrackProcess()
|
||||
{
|
||||
if (started)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//Some init setup
|
||||
|
||||
syncStop = false;
|
||||
|
||||
for (size_t i = 0; i < MAX_FACE_COUNT; i++)
|
||||
{
|
||||
syncFaceRectArr[i].valid = false;
|
||||
syncFaceLandmarkArr[i].valid = false;
|
||||
}
|
||||
|
||||
syncLastFrame = cv::Mat();
|
||||
|
||||
|
||||
//Start threads
|
||||
|
||||
findFaceThread = std::thread([this]() { this->FindFaceThreadProc(); });
|
||||
|
||||
for (size_t i = 0; i < MAX_FACE_COUNT; i++)
|
||||
{
|
||||
landmarkThreadArr[i] = std::thread([this, i]() { this->FindLandmarkThreadProc(i); });
|
||||
}
|
||||
|
||||
started = true;
|
||||
|
||||
}
|
||||
|
||||
void FaceLandmarkDetector::StopTrackProcess()
|
||||
{
|
||||
if (!started)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//Do not remove braces
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(syncMutex);
|
||||
|
||||
syncStop = true;
|
||||
|
||||
syncFaceRectCond.notify_all();
|
||||
}
|
||||
|
||||
|
||||
findFaceThread.join();
|
||||
|
||||
for (size_t i = 0; i < MAX_FACE_COUNT; i++)
|
||||
{
|
||||
landmarkThreadArr[i].join();
|
||||
}
|
||||
|
||||
started = false;
|
||||
|
||||
}
|
||||
|
||||
std::array<FaceLandmarkStruct, MAX_FACE_COUNT> FaceLandmarkDetector::GetFaceLandmarks(cv::Mat frame, int frameIndex)
|
||||
{
|
||||
|
||||
std::array<FaceLandmarkStruct, MAX_FACE_COUNT> result;
|
||||
//Sync area
|
||||
|
||||
std::unique_lock<std::mutex> lock(syncMutex);
|
||||
|
||||
// OUT to face rect thread >>>>
|
||||
syncLastFrame = frame;
|
||||
|
||||
syncLastFrameIndex = frameIndex;
|
||||
|
||||
// IN from landmark threads <<<<
|
||||
result = syncFaceLandmarkArr;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void FaceLandmarkDetector::FindFaceThreadProc()
|
||||
{
|
||||
cv::Mat localFrame;
|
||||
std::array<FaceIntermediateStruct, MAX_FACE_COUNT> localFaceRectArr;
|
||||
|
||||
bool localStop = false;
|
||||
|
||||
int localFrameIndex = 0;
|
||||
|
||||
|
||||
while (!syncStop)
|
||||
{
|
||||
|
||||
if (!localFrame.empty())
|
||||
{
|
||||
std::vector<cv::Rect> faces = InnerFindFaces(localFrame);
|
||||
|
||||
std::vector<cv::Mat> faceFrames;
|
||||
|
||||
//Get rid of faces that are too big
|
||||
for (size_t i = 0; i < faces.size(); )
|
||||
{
|
||||
if (faces[i].x < 0 || faces[i].y < 0 || (faces[i].x + faces[i].width >= localFrame.cols) || (faces[i].y + faces[i].height >= localFrame.rows))
|
||||
{
|
||||
faces.erase(faces.begin() + i);
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
//Cut faces from frame
|
||||
for (size_t i = 0; i <faces.size(); i++)
|
||||
{
|
||||
faceFrames.push_back(InnerCutFaceFrame(localFrame, faces[i]));
|
||||
}
|
||||
|
||||
InnerSeparateFacesToBuckets(faces, faceFrames, localFaceRectArr);
|
||||
|
||||
|
||||
for (size_t i = 0; i <localFaceRectArr.size(); i++)
|
||||
{
|
||||
if (localFaceRectArr[i].valid)
|
||||
{
|
||||
localFaceRectArr[i].frameIndex = localFrameIndex;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Sync area
|
||||
|
||||
std::unique_lock<std::mutex> lock(syncMutex);
|
||||
|
||||
// OUT to landmark Threads >>>>
|
||||
syncFaceRectArr = localFaceRectArr;
|
||||
|
||||
syncFaceRectCond.notify_all();
|
||||
|
||||
|
||||
// IN from main thread <<<<
|
||||
localFrame = syncLastFrame;
|
||||
|
||||
localFrameIndex = syncLastFrameIndex;
|
||||
|
||||
localStop = syncStop;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void FaceLandmarkDetector::FindLandmarkThreadProc(size_t threadIndex)
|
||||
{
|
||||
|
||||
FaceIntermediateStruct localInputFace;
|
||||
|
||||
FaceLandmarkStruct localOutputLandmarks;
|
||||
|
||||
bool localStop = false;
|
||||
|
||||
while (!localStop)
|
||||
{
|
||||
if (localInputFace.valid)
|
||||
{
|
||||
#ifdef USE_3D_LANDMARKS
|
||||
cv::Mat landmarkInputBlob = cv::dnn::blobFromImage(localInputFace.faceFrame, 1.0, cv::Size(40, 40), cv::Scalar(), false, false);
|
||||
#else
|
||||
cv::Mat landmarkInputBlob = cv::dnn::blobFromImage(localInputFace.faceFrame, 1.0, cv::Size(60, 60), cv::Scalar(), false, false);
|
||||
#endif
|
||||
|
||||
landmarkInputBlob.reshape(0, std::vector<int>{ 1, 1, localInputFace.faceFrame.rows, localInputFace.faceFrame.cols });
|
||||
|
||||
landmarkNetArr[threadIndex].setInput(landmarkInputBlob);
|
||||
#ifdef USE_3D_LANDMARKS
|
||||
cv::Mat featureBlob = landmarkNetArr[threadIndex].forward("Dense2");
|
||||
#else
|
||||
cv::Mat featureBlob = landmarkNetArr[threadIndex].forward("Dense3");
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < featureBlob.cols / 2; i++)
|
||||
{
|
||||
cv::Point landmarkPoint;
|
||||
|
||||
landmarkPoint.x = int(featureBlob.at<float>(0, 2 * i) * (localInputFace.faceRect.width) + localInputFace.faceRect.x);
|
||||
landmarkPoint.y = int(featureBlob.at<float>(0, 2 * i + 1) * (localInputFace.faceRect.height) + localInputFace.faceRect.y);
|
||||
localOutputLandmarks.landmarkArr[i] = landmarkPoint;
|
||||
|
||||
}
|
||||
|
||||
localOutputLandmarks.faceRect = localInputFace.faceRect;
|
||||
localOutputLandmarks.frameIndex = localInputFace.frameIndex;
|
||||
localOutputLandmarks.valid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
localOutputLandmarks.valid = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Sync area
|
||||
|
||||
std::unique_lock<std::mutex> lock(syncMutex);
|
||||
|
||||
// OUT to main thread >>>>
|
||||
syncFaceLandmarkArr[threadIndex] = localOutputLandmarks;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool doLoop = true;
|
||||
|
||||
while (doLoop)
|
||||
{
|
||||
|
||||
//IN from face rect thread <<<<
|
||||
|
||||
localInputFace = syncFaceRectArr[threadIndex];
|
||||
|
||||
|
||||
localStop = syncStop;
|
||||
|
||||
//Time to quit
|
||||
if (localStop)
|
||||
{
|
||||
doLoop = false;
|
||||
}
|
||||
|
||||
if (!localInputFace.valid)
|
||||
{
|
||||
|
||||
syncFaceLandmarkArr[threadIndex].valid = false;
|
||||
|
||||
syncFaceRectCond.wait(lock);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
doLoop = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::vector<cv::Rect> FaceLandmarkDetector::InnerFindFaces(cv::Mat frame)
|
||||
{
|
||||
if (frame.channels() == 4)
|
||||
{
|
||||
cvtColor(frame, frame, cv::COLOR_BGRA2BGR);
|
||||
}
|
||||
|
||||
cv::Mat inputBlob = cv::dnn::blobFromImage(frame, faceTrackerScaleFactor, cv::Size(faceTrackerWidth, faceTrackerHeight), faceTrackerMeanVal, false, false);
|
||||
|
||||
faceNet.setInput(inputBlob, "data");
|
||||
|
||||
cv::Mat detection = faceNet.forward("detection_out");
|
||||
|
||||
cv::Mat detectionMat(detection.size[2], detection.size[3], CV_32F, detection.ptr<float>());
|
||||
|
||||
float confidenceThreshold = 0.5f;
|
||||
|
||||
std::vector<cv::Rect> faces;
|
||||
|
||||
for (int i = 0; i < detectionMat.rows; i++)
|
||||
{
|
||||
float confidence = detectionMat.at<float>(i, 2);
|
||||
|
||||
if (confidence > confidenceThreshold)
|
||||
{
|
||||
int xLeftBottom = static_cast<int>(detectionMat.at<float>(i, 3) * frame.cols);
|
||||
int yLeftBottom = static_cast<int>(detectionMat.at<float>(i, 4) * frame.rows);
|
||||
int xRightTop = static_cast<int>(detectionMat.at<float>(i, 5) * frame.cols);
|
||||
int yRightTop = static_cast<int>(detectionMat.at<float>(i, 6) * frame.rows);
|
||||
|
||||
cv::Rect object((int)xLeftBottom, (int)yLeftBottom,
|
||||
(int)(xRightTop - xLeftBottom),
|
||||
(int)(yRightTop - yLeftBottom));
|
||||
|
||||
|
||||
object.x = object.x - object.width*0.1f;
|
||||
object.y = object.y - object.height*0.1f;
|
||||
object.width = object.width*1.2f;
|
||||
object.height = object.height*1.2f;
|
||||
|
||||
|
||||
|
||||
faces.push_back(object);
|
||||
}
|
||||
}
|
||||
|
||||
return faces;
|
||||
|
||||
}
|
||||
|
||||
cv::Mat FaceLandmarkDetector::InnerCutFaceFrame(cv::Mat frame, cv::Rect faceRect)
|
||||
{
|
||||
|
||||
|
||||
cv::Mat srcROI(frame, faceRect);
|
||||
|
||||
cv::Mat img2;
|
||||
cvtColor(srcROI, img2, CV_RGB2GRAY);
|
||||
|
||||
img2.convertTo(img2, CV_32FC1);
|
||||
#ifdef USE_3D_LANDMARKS
|
||||
cv::Size dsize = cv::Size(40, 40);
|
||||
#else
|
||||
cv::Size dsize = cv::Size(60, 60);
|
||||
#endif
|
||||
|
||||
cv::Mat img3 = cv::Mat(dsize, CV_32FC1);
|
||||
cv::resize(img2, img3, dsize, 0, 0, cv::INTER_CUBIC);
|
||||
|
||||
cv::Mat tmp_m, tmp_sd;
|
||||
double m = 0, sd = 0;
|
||||
meanStdDev(img3, tmp_m, tmp_sd);
|
||||
m = tmp_m.at<double>(0, 0);
|
||||
sd = tmp_sd.at<double>(0, 0);
|
||||
|
||||
img3 = (img3 - m) / (0.000001 + sd);
|
||||
|
||||
return img3;
|
||||
}
|
||||
|
||||
void FaceLandmarkDetector::InnerSeparateFacesToBuckets(std::vector<cv::Rect>& faceArr, std::vector<cv::Mat>& faceFrameArr, std::array<FaceIntermediateStruct, MAX_FACE_COUNT>& inOutBucketArr)
|
||||
{
|
||||
static std::array<std::vector<std::pair<cv::Rect, cv::Mat>>, MAX_FACE_COUNT> facesBelongsToSpace;
|
||||
|
||||
|
||||
for (size_t i = 0; i < MAX_FACE_COUNT; i++)
|
||||
{
|
||||
facesBelongsToSpace[i].clear();
|
||||
}
|
||||
|
||||
|
||||
//Distribute current faces to nearest old positions
|
||||
for (size_t i = 0; i < faceArr.size(); )
|
||||
{
|
||||
float lastDistance = 1000000.f;
|
||||
int lastIndex = -1;
|
||||
|
||||
for (size_t j = 0; j < MAX_FACE_COUNT; j++)
|
||||
{
|
||||
if (inOutBucketArr[j].valid)
|
||||
{
|
||||
float newDistance = calcSquaredDistanceBetweenFaces(inOutBucketArr[j].faceRect, faceArr[i]);
|
||||
if (newDistance < lastDistance)
|
||||
{
|
||||
lastDistance = newDistance;
|
||||
lastIndex = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lastIndex != -1)
|
||||
{
|
||||
facesBelongsToSpace[lastIndex].push_back(std::make_pair(faceArr[i], faceFrameArr[i]));
|
||||
faceArr.erase(faceArr.begin() + i);
|
||||
faceFrameArr.erase(faceFrameArr.begin() + i);
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
//Mark "free spots" to those that don't have any face belong to
|
||||
for (size_t j = 0; j < MAX_FACE_COUNT; j++)
|
||||
{
|
||||
if (inOutBucketArr[j].valid)
|
||||
{
|
||||
if (facesBelongsToSpace[j].size() == 0)
|
||||
{
|
||||
inOutBucketArr[j].valid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Find nearest face in each space - others return back to pool
|
||||
for (size_t j = 0; j < MAX_FACE_COUNT; j++)
|
||||
{
|
||||
if (inOutBucketArr[j].valid)
|
||||
{
|
||||
float lastDistance = calcSquaredDistanceBetweenFaces(inOutBucketArr[j].faceRect, facesBelongsToSpace[j][0].first);
|
||||
int lastIndex = 0;
|
||||
|
||||
for (size_t i = 1; i < facesBelongsToSpace[j].size(); i++)
|
||||
{
|
||||
float newDistance = calcSquaredDistanceBetweenFaces(inOutBucketArr[j].faceRect, facesBelongsToSpace[j][i].first);
|
||||
if (newDistance < lastDistance)
|
||||
{
|
||||
lastDistance = newDistance;
|
||||
lastIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
inOutBucketArr[j].faceRect = facesBelongsToSpace[j][lastIndex].first;
|
||||
inOutBucketArr[j].faceFrame = facesBelongsToSpace[j][lastIndex].second;
|
||||
|
||||
|
||||
facesBelongsToSpace[j].erase(facesBelongsToSpace[j].begin() + lastIndex);
|
||||
|
||||
for (size_t k = 0; k < facesBelongsToSpace[j].size(); k++)
|
||||
{
|
||||
faceArr.push_back(facesBelongsToSpace[j][k].first);
|
||||
faceFrameArr.push_back(facesBelongsToSpace[j][k].second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Distribute faces from pool to empty slots
|
||||
for (size_t j = 0; j < MAX_FACE_COUNT; j++)
|
||||
{
|
||||
if (!inOutBucketArr[j].valid)
|
||||
{
|
||||
|
||||
if (faceArr.size() > 0)
|
||||
{
|
||||
inOutBucketArr[j].valid = true;
|
||||
|
||||
inOutBucketArr[j].faceRect = faceArr[0];
|
||||
inOutBucketArr[j].faceFrame = faceFrameArr[0];
|
||||
|
||||
|
||||
faceArr.erase(faceArr.begin());
|
||||
faceFrameArr.erase(faceFrameArr.begin());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
#pragma once
|
||||
|
||||
#include <opencv2/core.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <opencv2/calib3d.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
|
||||
#include <opencv2/dnn.hpp>
|
||||
|
||||
#include <thread>
|
||||
|
||||
|
||||
#include <queue>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
|
||||
#define USE_3D_LANDMARKS
|
||||
|
||||
|
||||
//#include "boost/thread.hpp"
|
||||
|
||||
constexpr size_t LANDMARK_POINT_COUNT = 68;
|
||||
|
||||
constexpr size_t MAX_FACE_COUNT = 5;
|
||||
|
||||
|
||||
struct FaceIntermediateStruct
|
||||
{
|
||||
bool valid = false;
|
||||
|
||||
cv::Rect faceRect;
|
||||
cv::Mat faceFrame;
|
||||
|
||||
int frameIndex;
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct FaceLandmarkStruct
|
||||
{
|
||||
bool valid = false;
|
||||
|
||||
cv::Rect faceRect;
|
||||
std::array<cv::Point2f, LANDMARK_POINT_COUNT> landmarkArr;
|
||||
|
||||
int frameIndex;
|
||||
};
|
||||
|
||||
|
||||
class FaceLandmarkDetector
|
||||
{
|
||||
public:
|
||||
FaceLandmarkDetector();
|
||||
~FaceLandmarkDetector();
|
||||
|
||||
void StartTrackProcess();
|
||||
|
||||
void StopTrackProcess();
|
||||
|
||||
std::array<FaceLandmarkStruct, MAX_FACE_COUNT> GetFaceLandmarks(cv::Mat frame, int frameIndex);
|
||||
|
||||
protected:
|
||||
cv::dnn::Net faceNet;
|
||||
|
||||
std::array<cv::dnn::Net, MAX_FACE_COUNT> landmarkNetArr;
|
||||
|
||||
bool started = false;
|
||||
|
||||
|
||||
//Sync variables - shared between threads:
|
||||
|
||||
cv::Mat syncLastFrame;
|
||||
|
||||
int syncLastFrameIndex;
|
||||
|
||||
std::array<FaceIntermediateStruct, MAX_FACE_COUNT> syncFaceRectArr;
|
||||
|
||||
std::array<FaceLandmarkStruct, MAX_FACE_COUNT> syncFaceLandmarkArr;
|
||||
|
||||
std::mutex syncMutex;
|
||||
|
||||
bool syncStop = false;
|
||||
|
||||
std::condition_variable syncFaceRectCond;
|
||||
|
||||
std::thread findFaceThread;
|
||||
void FindFaceThreadProc();
|
||||
|
||||
std::array<std::thread, MAX_FACE_COUNT> landmarkThreadArr;
|
||||
void FindLandmarkThreadProc(size_t threadIndex);
|
||||
|
||||
|
||||
|
||||
std::vector<cv::Rect> InnerFindFaces(cv::Mat frame);
|
||||
|
||||
cv::Mat InnerCutFaceFrame(cv::Mat frame, cv::Rect faceRect);
|
||||
|
||||
void InnerSeparateFacesToBuckets(std::vector<cv::Rect>& faceArr, std::vector<cv::Mat>& faceFrameArr, std::array<FaceIntermediateStruct, MAX_FACE_COUNT>& inOutBucketArr);
|
||||
|
||||
|
||||
};
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
#include "ValueSmoother.h"
|
||||
|
||||
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
|
||||
using namespace std;
|
||||
|
||||
using namespace std::chrono;
|
||||
|
||||
|
||||
float snapCurve(float x)
|
||||
{
|
||||
float y = 1.0 / (x + 1.0);
|
||||
y = (1.0 - y) * 2.0;
|
||||
if (y > 1.0) {
|
||||
return 1.0;
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ValueSmoother::reset()
|
||||
{
|
||||
inited = false;
|
||||
}
|
||||
|
||||
|
||||
float ValueSmoother::responsiveAnalogReadSimple(float newValue)
|
||||
{
|
||||
if (!inited)
|
||||
{
|
||||
inited = true;
|
||||
smoothValue = newValue;
|
||||
return smoothValue;
|
||||
}
|
||||
auto diff = abs(newValue - smoothValue);
|
||||
float snap = snapCurve(diff * SNAP_MULTIPLIER_SIMPLE);
|
||||
|
||||
smoothValue += (newValue - smoothValue) * snap;
|
||||
return smoothValue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void ExtendedValueSmoother::reset()
|
||||
{
|
||||
inited = false;
|
||||
}
|
||||
|
||||
float ExtendedValueSmoother::responsiveAnalogRead(float newValue)
|
||||
{
|
||||
using namespace std::chrono;
|
||||
|
||||
auto ms = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
|
||||
|
||||
|
||||
auto diff = abs(newValue - smoothValue);
|
||||
|
||||
// measure the difference between the new value and current value over time
|
||||
// to get a more reasonable indication of how far off the current smooth value is
|
||||
// compared to the actual measurements
|
||||
errorEMA += ((newValue - smoothValue) - errorEMA) * 0.4;
|
||||
|
||||
// if sleep has been enabled, keep track of when we're asleep or not by marking the time of last activity and testing to see how much time has passed since then
|
||||
if (SLEEP_ENABLE) {
|
||||
// recalculate sleeping status
|
||||
// (asleep if last activity was over SLEEP_DELAY_MS ago)
|
||||
sleeping = abs(errorEMA) < ACTIVITY_THRESHOLD;
|
||||
}
|
||||
|
||||
|
||||
if (SLEEP_ENABLE && sleeping) {
|
||||
return smoothValue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
auto snap = snapCurve(diff * SNAP_MULTIPLIER);
|
||||
|
||||
// when sleep is enabled, the emphasis is stopping on a responsiveValue quickly, and it's less about easing into position. If sleep is enabled, add a small amount to snap so it'll tend to snap into a more accurate position before sleeping starts.
|
||||
if (SLEEP_ENABLE) {
|
||||
snap = snap * 0.5 + 0.5;
|
||||
}
|
||||
|
||||
// calculate the exponential moving average based on the snap
|
||||
smoothValue += (newValue - smoothValue) * snap;
|
||||
|
||||
return smoothValue;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
class ValueSmoother {
|
||||
public:
|
||||
|
||||
|
||||
void reset();
|
||||
|
||||
float responsiveAnalogReadSimple(float newValue);
|
||||
|
||||
protected:
|
||||
bool inited = false;
|
||||
|
||||
//float SNAP_MULTIPLIER_SIMPLE = 1.0 / 60;
|
||||
|
||||
float SNAP_MULTIPLIER_SIMPLE = 0.3;
|
||||
|
||||
float smoothValue = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct ExtendedValueSmoother {
|
||||
public:
|
||||
void reset();
|
||||
|
||||
float responsiveAnalogRead(float newValue);
|
||||
|
||||
protected:
|
||||
|
||||
bool inited = false;
|
||||
|
||||
float SNAP_MULTIPLIER = 1.0 / 200;
|
||||
|
||||
float smoothValue = 0;
|
||||
|
||||
bool SLEEP_ENABLE = true;
|
||||
|
||||
float ACTIVITY_THRESHOLD = 16.0;
|
||||
|
||||
float errorEMA = 0;
|
||||
|
||||
long long lastActivityMS = 0;
|
||||
|
||||
bool sleeping = false;
|
||||
|
||||
};
|
||||
Binary file not shown.
+1789
File diff suppressed because it is too large.
Load diff
Binary file not shown.
@@ -0,0 +1,293 @@
|
||||
name: "CNNFacepoint"
|
||||
layer {
|
||||
name: "data"
|
||||
type: "Input"
|
||||
top: "data"
|
||||
input_param {
|
||||
shape: {dim: 1 dim: 1 dim: 40 dim: 40}
|
||||
}
|
||||
}
|
||||
|
||||
layer {
|
||||
name: "Conv1"
|
||||
type: "Convolution"
|
||||
bottom: "data"
|
||||
top: "Conv1"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 16
|
||||
pad: 2
|
||||
kernel_size: 5
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "xavier"
|
||||
std: 0.1
|
||||
}
|
||||
bias_filler {
|
||||
type: "constant"
|
||||
value: 0.2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
layer {
|
||||
name: "ActivationTangH1"
|
||||
bottom: "Conv1"
|
||||
top: "ActivationTangH1"
|
||||
type: "TanH"
|
||||
}
|
||||
|
||||
layer {
|
||||
name: "ActivationAbs1"
|
||||
bottom: "ActivationTangH1"
|
||||
top: "Abs1"
|
||||
type: "AbsVal"
|
||||
}
|
||||
|
||||
layer {
|
||||
name: "Pool1"
|
||||
type: "Pooling"
|
||||
bottom: "Abs1"
|
||||
top: "Pool1"
|
||||
pooling_param {
|
||||
pool: MAX
|
||||
kernel_size: 2
|
||||
stride: 2
|
||||
}
|
||||
}
|
||||
|
||||
layer {
|
||||
name: "Conv2"
|
||||
type: "Convolution"
|
||||
bottom: "Pool1"
|
||||
top: "Conv2"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 48
|
||||
pad: 1
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "xavier"
|
||||
std: 0.1
|
||||
}
|
||||
bias_filler {
|
||||
type: "constant"
|
||||
value: 0.2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
layer {
|
||||
name: "ActivationTangH2"
|
||||
bottom: "Conv2"
|
||||
top: "ActivationTangH2"
|
||||
type: "TanH"
|
||||
}
|
||||
|
||||
layer {
|
||||
name: "ActivationAbs2"
|
||||
bottom: "ActivationTangH2"
|
||||
top: "Abs2"
|
||||
type: "AbsVal"
|
||||
}
|
||||
|
||||
|
||||
layer {
|
||||
name: "Pool2"
|
||||
type: "Pooling"
|
||||
bottom: "Abs2"
|
||||
top: "Pool2"
|
||||
pooling_param {
|
||||
pool: MAX
|
||||
kernel_size: 2
|
||||
stride: 2
|
||||
}
|
||||
}
|
||||
|
||||
# layer 3
|
||||
layer {
|
||||
name: "Conv3"
|
||||
type: "Convolution"
|
||||
bottom: "Pool2"
|
||||
top: "Conv3"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 64
|
||||
pad: 0
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "xavier"
|
||||
std: 0.1
|
||||
}
|
||||
bias_filler {
|
||||
type: "constant"
|
||||
value: 0.2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
layer {
|
||||
name: "ActivationTangH3"
|
||||
bottom: "Conv3"
|
||||
top: "ActivationTangH3"
|
||||
type: "TanH"
|
||||
}
|
||||
|
||||
layer {
|
||||
name: "ActivationAbs3"
|
||||
bottom: "ActivationTangH3"
|
||||
top: "Abs3"
|
||||
type: "AbsVal"
|
||||
}
|
||||
|
||||
layer {
|
||||
name: "Pool3"
|
||||
type: "Pooling"
|
||||
bottom: "Abs3"
|
||||
top: "Pool3"
|
||||
pooling_param {
|
||||
pool: MAX
|
||||
kernel_size: 3
|
||||
stride: 2
|
||||
}
|
||||
}
|
||||
|
||||
# layer 4
|
||||
layer {
|
||||
name: "Conv4"
|
||||
type: "Convolution"
|
||||
bottom: "Pool3"
|
||||
top: "Conv4"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 64
|
||||
pad: 0
|
||||
kernel_size: 2
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "xavier"
|
||||
std: 0.1
|
||||
}
|
||||
bias_filler {
|
||||
type: "constant"
|
||||
value: 0.2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
layer {
|
||||
name: "ActivationTangH4"
|
||||
bottom: "Conv4"
|
||||
top: "ActivationTangH4"
|
||||
type: "TanH"
|
||||
}
|
||||
|
||||
layer {
|
||||
name: "ActivationAbs4"
|
||||
bottom: "ActivationTangH4"
|
||||
top: "Abs4"
|
||||
type: "AbsVal"
|
||||
}
|
||||
|
||||
|
||||
########################################
|
||||
|
||||
layer {
|
||||
name: "Dense1"
|
||||
type: "InnerProduct"
|
||||
bottom: "Abs4"
|
||||
top: "Dense1"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
inner_product_param {
|
||||
num_output: 100
|
||||
weight_filler {
|
||||
type: "xavier"
|
||||
}
|
||||
bias_filler {
|
||||
type: "constant"
|
||||
value: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
layer {
|
||||
name: "ActivationTangH5"
|
||||
bottom: "Dense1"
|
||||
top: "ActivationTangH5"
|
||||
type: "TanH"
|
||||
}
|
||||
|
||||
layer {
|
||||
name: "ActivationAbs5"
|
||||
bottom: "ActivationTangH5"
|
||||
top: "Abs5"
|
||||
type: "AbsVal"
|
||||
}
|
||||
|
||||
|
||||
layer {
|
||||
name: "Dense2"
|
||||
type: "InnerProduct"
|
||||
bottom: "Abs5"
|
||||
top: "Dense2"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
inner_product_param {
|
||||
num_output: 136
|
||||
weight_filler {
|
||||
type: "xavier"
|
||||
}
|
||||
bias_filler {
|
||||
type: "constant"
|
||||
value: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,292 @@
|
||||
name: "landmark"
|
||||
input: "data"
|
||||
input_shape {
|
||||
dim: 1
|
||||
dim: 1
|
||||
dim: 60
|
||||
dim: 60
|
||||
}
|
||||
########################################
|
||||
# the actual net
|
||||
# layer 1
|
||||
layer {
|
||||
name: "Conv1"
|
||||
type: "Convolution"
|
||||
bottom: "data"
|
||||
top: "Conv1"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 20
|
||||
pad: 2
|
||||
kernel_size: 5
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "xavier"
|
||||
std: 0.1
|
||||
}
|
||||
bias_filler {
|
||||
type: "constant"
|
||||
value: 0.2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
layer {
|
||||
name: "ActivationTangH1"
|
||||
bottom: "Conv1"
|
||||
top: "ActivationTangH1"
|
||||
type: "TanH"
|
||||
}
|
||||
|
||||
layer {
|
||||
name: "ActivationAbs1"
|
||||
bottom: "ActivationTangH1"
|
||||
top: "Abs1"
|
||||
type: "AbsVal"
|
||||
}
|
||||
|
||||
layer {
|
||||
name: "Pool1"
|
||||
type: "Pooling"
|
||||
bottom: "Abs1"
|
||||
top: "Pool1"
|
||||
pooling_param {
|
||||
pool: MAX
|
||||
kernel_size: 2
|
||||
stride: 2
|
||||
}
|
||||
}
|
||||
|
||||
layer {
|
||||
name: "Conv2"
|
||||
type: "Convolution"
|
||||
bottom: "Pool1"
|
||||
top: "Conv2"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 48
|
||||
pad: 2
|
||||
kernel_size: 5
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "xavier"
|
||||
std: 0.1
|
||||
}
|
||||
bias_filler {
|
||||
type: "constant"
|
||||
value: 0.2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
layer {
|
||||
name: "ActivationTangH2"
|
||||
bottom: "Conv2"
|
||||
top: "ActivationTangH2"
|
||||
type: "TanH"
|
||||
}
|
||||
|
||||
layer {
|
||||
name: "ActivationAbs2"
|
||||
bottom: "ActivationTangH2"
|
||||
top: "Abs2"
|
||||
type: "AbsVal"
|
||||
}
|
||||
|
||||
|
||||
layer {
|
||||
name: "Pool2"
|
||||
type: "Pooling"
|
||||
bottom: "Abs2"
|
||||
top: "Pool2"
|
||||
pooling_param {
|
||||
pool: MAX
|
||||
kernel_size: 2
|
||||
stride: 2
|
||||
}
|
||||
}
|
||||
|
||||
# layer 3
|
||||
layer {
|
||||
name: "Conv3"
|
||||
type: "Convolution"
|
||||
bottom: "Pool2"
|
||||
top: "Conv3"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 64
|
||||
pad: 0
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "xavier"
|
||||
std: 0.1
|
||||
}
|
||||
bias_filler {
|
||||
type: "constant"
|
||||
value: 0.2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
layer {
|
||||
name: "ActivationTangH3"
|
||||
bottom: "Conv3"
|
||||
top: "ActivationTangH3"
|
||||
type: "TanH"
|
||||
}
|
||||
|
||||
layer {
|
||||
name: "ActivationAbs3"
|
||||
bottom: "ActivationTangH3"
|
||||
top: "Abs3"
|
||||
type: "AbsVal"
|
||||
}
|
||||
|
||||
layer {
|
||||
name: "Pool3"
|
||||
type: "Pooling"
|
||||
bottom: "Abs3"
|
||||
top: "Pool3"
|
||||
pooling_param {
|
||||
pool: MAX
|
||||
kernel_size: 3
|
||||
stride: 2
|
||||
}
|
||||
}
|
||||
|
||||
# layer 4
|
||||
layer {
|
||||
name: "Conv4"
|
||||
type: "Convolution"
|
||||
bottom: "Pool3"
|
||||
top: "Conv4"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 80
|
||||
pad: 0
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "xavier"
|
||||
std: 0.1
|
||||
}
|
||||
bias_filler {
|
||||
type: "constant"
|
||||
value: 0.2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
layer {
|
||||
name: "ActivationTangH4"
|
||||
bottom: "Conv4"
|
||||
top: "ActivationTangH4"
|
||||
type: "TanH"
|
||||
}
|
||||
|
||||
layer {
|
||||
name: "ActivationAbs4"
|
||||
bottom: "ActivationTangH4"
|
||||
top: "Abs4"
|
||||
type: "AbsVal"
|
||||
}
|
||||
|
||||
|
||||
########################################
|
||||
|
||||
layer {
|
||||
name: "Dense1"
|
||||
type: "InnerProduct"
|
||||
bottom: "Abs4"
|
||||
top: "Dense1"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
inner_product_param {
|
||||
num_output: 512
|
||||
weight_filler {
|
||||
type: "xavier"
|
||||
}
|
||||
bias_filler {
|
||||
type: "constant"
|
||||
value: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
layer {
|
||||
name: "ActivationTangH5"
|
||||
bottom: "Dense1"
|
||||
top: "ActivationTangH5"
|
||||
type: "TanH"
|
||||
}
|
||||
|
||||
layer {
|
||||
name: "ActivationAbs5"
|
||||
bottom: "ActivationTangH5"
|
||||
top: "Abs5"
|
||||
type: "AbsVal"
|
||||
}
|
||||
|
||||
|
||||
layer {
|
||||
name: "Dense3"
|
||||
type: "InnerProduct"
|
||||
bottom: "Abs5"
|
||||
top: "Dense3"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
inner_product_param {
|
||||
num_output: 136
|
||||
weight_filler {
|
||||
type: "xavier"
|
||||
}
|
||||
bias_filler {
|
||||
type: "constant"
|
||||
value: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,14 +4,17 @@
|
||||
|
||||
TMyApplication* App = NULL;
|
||||
|
||||
|
||||
|
||||
|
||||
int APIENTRY WinMain(HINSTANCE hCurrentInst, HINSTANCE hPreviousInst,
|
||||
LPSTR lpszCmdLine, int nCmdShow)
|
||||
{
|
||||
|
||||
int width = 480;
|
||||
int height = 320;
|
||||
|
||||
int width = 1280;
|
||||
int height = 720;
|
||||
|
||||
|
||||
if (CreateEngine(width, height))
|
||||
{
|
||||
|
||||
@@ -30,5 +33,6 @@ int APIENTRY WinMain(HINSTANCE hCurrentInst, HINSTANCE hPreviousInst,
|
||||
DestroyEngine();
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 134 KiB |
BIN
Binary file not shown.
File renamed without changes.
Reference in new issue
Block a user