cailean
4 months ago
commit
98afb8ebf6
19 changed files with 1760 additions and 0 deletions
@ -0,0 +1,90 @@ |
|||||
|
#.gitignore is a file which makes git ignore files which should |
||||
|
# not go into version control in the first place |
||||
|
# Questions? See |
||||
|
# http://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository#Ignoring-Files |
||||
|
# http://git-scm.com/docs/gitignore |
||||
|
|
||||
|
########################### |
||||
|
# ignore generated binaries |
||||
|
# but not the data folder |
||||
|
########################### |
||||
|
|
||||
|
/bin/* |
||||
|
|
||||
|
######### |
||||
|
# general |
||||
|
######### |
||||
|
|
||||
|
[Bb]uild/ |
||||
|
[Oo]bj/ |
||||
|
*.o |
||||
|
[Dd]ebug*/ |
||||
|
[Rr]elease*/ |
||||
|
*.mode* |
||||
|
*.app/ |
||||
|
*.pyc |
||||
|
.svn/ |
||||
|
*.log |
||||
|
|
||||
|
######################## |
||||
|
# IDE files which should |
||||
|
# be ignored |
||||
|
######################## |
||||
|
|
||||
|
# XCode |
||||
|
*.pbxuser |
||||
|
*.perspective |
||||
|
*.perspectivev3 |
||||
|
*.mode1v3 |
||||
|
*.mode2v3 |
||||
|
# XCode 4 |
||||
|
*.xccheckout |
||||
|
xcuserdata/ |
||||
|
|
||||
|
# Visual Studio |
||||
|
*.sdf |
||||
|
*.opensdf |
||||
|
*.suo |
||||
|
*.pdb |
||||
|
*.ilk |
||||
|
*.aps |
||||
|
ipch/ |
||||
|
|
||||
|
# Eclipse |
||||
|
.metadata |
||||
|
local.properties |
||||
|
.externalToolBuilders |
||||
|
|
||||
|
# Android Studio |
||||
|
.gradle |
||||
|
/local.properties |
||||
|
/.idea/workspace.xml |
||||
|
/.idea/libraries |
||||
|
|
||||
|
################## |
||||
|
# operating system |
||||
|
################## |
||||
|
|
||||
|
# Linux |
||||
|
*~ |
||||
|
# KDE |
||||
|
.directory |
||||
|
.AppleDouble |
||||
|
|
||||
|
# OSX |
||||
|
.DS_Store |
||||
|
*.swp |
||||
|
*~.nib |
||||
|
# Thumbnails |
||||
|
._* |
||||
|
|
||||
|
# Windows |
||||
|
# Image file caches |
||||
|
Thumbs.db |
||||
|
# Folder config file |
||||
|
Desktop.ini |
||||
|
|
||||
|
# Android |
||||
|
.csettings |
||||
|
|
||||
|
/bin/data/ |
@ -0,0 +1,181 @@ |
|||||
|
{ |
||||
|
"configurations": [ |
||||
|
{ |
||||
|
"name": "Mac", |
||||
|
"includePath": [ |
||||
|
"/usr/include", |
||||
|
"/usr/local/include", |
||||
|
"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/", |
||||
|
"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/4.2.1", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/3d", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/app", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/communication", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/events", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/gl", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/graphics", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/math", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/sound", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/types", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/utils", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/video", |
||||
|
"${workspaceRoot}/../../../libs/boost/include", |
||||
|
"${workspaceRoot}/../../../libs/cairo/include", |
||||
|
"${workspaceRoot}/../../../libs/curl/include", |
||||
|
"${workspaceRoot}/../../../libs/fmod/include", |
||||
|
"${workspaceRoot}/../../../libs/FreeImage/include", |
||||
|
"${workspaceRoot}/../../../libs/freetype/include", |
||||
|
"${workspaceRoot}/../../../libs/glew/include", |
||||
|
"${workspaceRoot}/../../../libs/glfw/include", |
||||
|
"${workspaceRoot}/../../../libs/glm/include", |
||||
|
"${workspaceRoot}/../../../libs/json/include", |
||||
|
"${workspaceRoot}/../../../libs/pugixml/include", |
||||
|
"${workspaceRoot}/../../../libs/rtAudio/include", |
||||
|
"${workspaceRoot}/../../../libs/tess2/include", |
||||
|
"${workspaceRoot}/../../../libs/uriparser/include", |
||||
|
"${workspaceRoot}/../../../libs/utf8/include" |
||||
|
], |
||||
|
"browse": { |
||||
|
"limitSymbolsToIncludedHeaders": true, |
||||
|
"databaseFilename": "${workspaceRoot}/.vscode/browse.db", |
||||
|
"path": [ |
||||
|
"/usr/include", |
||||
|
"/usr/local/include", |
||||
|
"/System/Library/Frameworks", |
||||
|
"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/", |
||||
|
"${workspaceRoot}/../../../libs", |
||||
|
"${workspaceRoot}/../../../addons", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks" |
||||
|
] |
||||
|
}, |
||||
|
"intelliSenseMode": "clang-x64", |
||||
|
"macFrameworkPath": [ |
||||
|
"/System/Library/Frameworks", |
||||
|
"/Library/Frameworks" |
||||
|
], |
||||
|
"compilerPath": "/usr/local/bin/gcc-8", |
||||
|
"cStandard": "c11", |
||||
|
"cppStandard": "c++17" |
||||
|
}, |
||||
|
{ |
||||
|
"name": "Linux", |
||||
|
"includePath": [ |
||||
|
"/usr/include", |
||||
|
"/usr/local/include", |
||||
|
"/usr/include/c++/5", |
||||
|
"/usr/include/c++/5/backward", |
||||
|
"/usr/lib/gcc/x86_64-linux-gnu/5/include", |
||||
|
"/usr/lib/x86_64-linux-gnu/glib-2.0/include", |
||||
|
"/usr/lib/x86_64-linux-gnu/gstreamer-1.0/include", |
||||
|
"/usr/local/include", |
||||
|
"/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed", |
||||
|
"/usr/include/x86_64-linux-gnu", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/3d", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/app", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/communication", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/events", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/gl", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/graphics", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/math", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/sound", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/types", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/utils", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/video", |
||||
|
"${workspaceRoot}/../../../libs/boost/include", |
||||
|
"${workspaceRoot}/../../../libs/cairo/include", |
||||
|
"${workspaceRoot}/../../../libs/curl/include", |
||||
|
"${workspaceRoot}/../../../libs/fmod/include", |
||||
|
"${workspaceRoot}/../../../libs/FreeImage/include", |
||||
|
"${workspaceRoot}/../../../libs/freetype/include", |
||||
|
"${workspaceRoot}/../../../libs/glew/include", |
||||
|
"${workspaceRoot}/../../../libs/glfw/include", |
||||
|
"${workspaceRoot}/../../../libs/glm/include", |
||||
|
"${workspaceRoot}/../../../libs/json/include", |
||||
|
"${workspaceRoot}/../../../libs/pugixml/include", |
||||
|
"${workspaceRoot}/../../../libs/rtAudio/include", |
||||
|
"${workspaceRoot}/../../../libs/tess2/include", |
||||
|
"${workspaceRoot}/../../../libs/uriparser/include", |
||||
|
"${workspaceRoot}/../../../libs/utf8/include", |
||||
|
"${workspaceRoot}/../../../libs/poco/include", |
||||
|
"${workspaceRoot}/../../../libs/kiss/include", |
||||
|
"/usr/include/x86_64-linux-gnu/c++/5", |
||||
|
"/usr/include/pulse", |
||||
|
"/usr/include/cairo", |
||||
|
"/usr/include/gstreamer-1.0", |
||||
|
"/usr/include/glib-2.0", |
||||
|
"${workspaceRoot}", |
||||
|
"/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxOpenCv/src", |
||||
|
"/usr/local/onnxruntime-linux-x64-gpu-1.19.2/include", |
||||
|
"/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxOpenCv/libs/opencv/include/opencv4" |
||||
|
], |
||||
|
"browse": { |
||||
|
"limitSymbolsToIncludedHeaders": true, |
||||
|
"databaseFilename": "", |
||||
|
"path": [ |
||||
|
"/usr/include", |
||||
|
"/usr/local/include", |
||||
|
"${workspaceRoot}/../../../libs", |
||||
|
"${workspaceRoot}/../../../addons", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks", |
||||
|
"/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxOpenCv/src", |
||||
|
"/usr/local/onnxruntime-linux-x64-gpu-1.19.2/include" |
||||
|
] |
||||
|
}, |
||||
|
"intelliSenseMode": "clang-x64", |
||||
|
"compilerPath": "/usr/bin/g++", |
||||
|
"cStandard": "c17", |
||||
|
"cppStandard": "c++17" |
||||
|
}, |
||||
|
{ |
||||
|
"name": "Win32", |
||||
|
"includePath": [ |
||||
|
"C:/msys64/mingw32/include/c++/7.4.0", |
||||
|
"C:/msys64/mingw32/i686-w64-mingw32/include", |
||||
|
"${workspaceRoot}/../../../libs", |
||||
|
"${workspaceRoot}/../../../addons", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/3d", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/app", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/communication", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/events", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/gl", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/graphics", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/math", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/sound", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/types", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/utils", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/video", |
||||
|
"${workspaceRoot}/../../../libs/boost/include", |
||||
|
"${workspaceRoot}/../../../libs/cairo/include", |
||||
|
"${workspaceRoot}/../../../libs/curl/include", |
||||
|
"${workspaceRoot}/../../../libs/fmod/include", |
||||
|
"${workspaceRoot}/../../../libs/FreeImage/include", |
||||
|
"${workspaceRoot}/../../../libs/freetype/include", |
||||
|
"${workspaceRoot}/../../../libs/glew/include", |
||||
|
"${workspaceRoot}/../../../libs/glfw/include", |
||||
|
"${workspaceRoot}/../../../libs/glm/include", |
||||
|
"${workspaceRoot}/../../../libs/json/include", |
||||
|
"${workspaceRoot}/../../../libs/pugixml/include", |
||||
|
"${workspaceRoot}/../../../libs/rtAudio/include", |
||||
|
"${workspaceRoot}/../../../libs/tess2/include", |
||||
|
"${workspaceRoot}/../../../libs/uriparser/include", |
||||
|
"${workspaceRoot}/../../../libs/utf8/include" |
||||
|
], |
||||
|
"browse": { |
||||
|
"limitSymbolsToIncludedHeaders": true, |
||||
|
"databaseFilename": "", |
||||
|
"path": [ |
||||
|
"${workspaceRoot}/../../../libs", |
||||
|
"${workspaceRoot}/../../../addons", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks" |
||||
|
] |
||||
|
}, |
||||
|
"intelliSenseMode": "clang-x64", |
||||
|
"compilerPath": "C:/msys64/mingw32/bin/g++.exe", |
||||
|
"cStandard": "c11", |
||||
|
"cppStandard": "c++17" |
||||
|
} |
||||
|
], |
||||
|
"version": 4 |
||||
|
} |
@ -0,0 +1,72 @@ |
|||||
|
{ |
||||
|
"version": "0.2.0", |
||||
|
"configurations": [ |
||||
|
{ |
||||
|
"name": "C++ Launch", |
||||
|
"type": "cppdbg", |
||||
|
"request": "launch", |
||||
|
"args": [], |
||||
|
"stopAtEntry": false, |
||||
|
"cwd": "${workspaceRoot}", |
||||
|
"environment": [], |
||||
|
"externalConsole": false, |
||||
|
"linux": { |
||||
|
"MIMode": "gdb", |
||||
|
"setupCommands": [ |
||||
|
{ |
||||
|
"description": "Enable pretty-printing for gdb", |
||||
|
"text": "-enable-pretty-printing", |
||||
|
"ignoreFailures": true |
||||
|
} |
||||
|
], |
||||
|
"program": "${workspaceRoot}/bin/${workspaceFolderBasename}_debug" |
||||
|
}, |
||||
|
"osx": { |
||||
|
"MIMode": "lldb", |
||||
|
"program": "${workspaceRoot}/bin/${workspaceFolderBasename}_debug.app/Contents/MacOS/${workspaceFolderBasename}_debug" |
||||
|
}, |
||||
|
"windows": { |
||||
|
"MIMode": "gdb", |
||||
|
"miDebuggerPath": "gdb.exe", |
||||
|
"setupCommands": [ |
||||
|
{ |
||||
|
"description": "Enable pretty-printing for gdb", |
||||
|
"text": "-enable-pretty-printing", |
||||
|
"ignoreFailures": true |
||||
|
} |
||||
|
], |
||||
|
"program": "${workspaceRoot}/bin/${workspaceFolderBasename}_debug" |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"name": "C++ Attach", |
||||
|
"type": "cppdbg", |
||||
|
"request": "attach", |
||||
|
"program": "enter program name, for example ${workspaceRoot}/a.out", |
||||
|
"processId": "${command:pickProcess}", |
||||
|
"linux": { |
||||
|
"MIMode": "gdb", |
||||
|
"setupCommands": [ |
||||
|
{ |
||||
|
"description": "Enable pretty-printing for gdb", |
||||
|
"text": "-enable-pretty-printing", |
||||
|
"ignoreFailures": true |
||||
|
} |
||||
|
] |
||||
|
}, |
||||
|
"osx": { |
||||
|
"MIMode": "lldb" |
||||
|
}, |
||||
|
"windows": { |
||||
|
"MIMode": "gdb", |
||||
|
"setupCommands": [ |
||||
|
{ |
||||
|
"description": "Enable pretty-printing for gdb", |
||||
|
"text": "-enable-pretty-printing", |
||||
|
"ignoreFailures": true |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
] |
||||
|
} |
@ -0,0 +1,133 @@ |
|||||
|
{ |
||||
|
"version": "2.0.0", |
||||
|
"shell":{ |
||||
|
"task": true |
||||
|
}, |
||||
|
"tasks": [ |
||||
|
{ |
||||
|
"type": "shell", |
||||
|
"label": "Build RELEASE", |
||||
|
"presentation": { |
||||
|
"reveal": "always", |
||||
|
"panel": "shared" |
||||
|
}, |
||||
|
"command": "make -j -s 2>&1 && make RunRelease", |
||||
|
"group": { |
||||
|
"kind": "build", |
||||
|
"isDefault": true |
||||
|
}, |
||||
|
"problemMatcher": { |
||||
|
"owner": "cpp", |
||||
|
"fileLocation": ["relative", "${workspaceFolder}"], |
||||
|
"pattern": { |
||||
|
"regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", |
||||
|
"file": 1, |
||||
|
"line": 2, |
||||
|
"column": 3, |
||||
|
"severity": 4, |
||||
|
"message": 5 |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"type": "shell", |
||||
|
"label": "Build DEBUG", |
||||
|
"presentation": { |
||||
|
"reveal": "always", |
||||
|
"panel": "shared" |
||||
|
}, |
||||
|
"command": "make Debug -j -s 2>&1 || exit 1", |
||||
|
"group": { |
||||
|
"kind": "build", |
||||
|
"isDefault": true |
||||
|
}, |
||||
|
"problemMatcher": { |
||||
|
"owner": "cpp", |
||||
|
"fileLocation": ["relative", "${workspaceFolder}"], |
||||
|
"pattern": { |
||||
|
"regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", |
||||
|
"file": 1, |
||||
|
"line": 2, |
||||
|
"column": 3, |
||||
|
"severity": 4, |
||||
|
"message": 5 |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"type": "shell", |
||||
|
"label": "Clean DEBUG", |
||||
|
"presentation": { |
||||
|
"reveal": "always", |
||||
|
"panel": "shared" |
||||
|
}, |
||||
|
"command": "make CleanDebug", |
||||
|
"group": { |
||||
|
"kind": "build", |
||||
|
"isDefault": true |
||||
|
}, |
||||
|
"problemMatcher": { |
||||
|
"owner": "cpp", |
||||
|
"fileLocation": ["relative", "${workspaceFolder}"], |
||||
|
"pattern": { |
||||
|
"regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", |
||||
|
"file": 1, |
||||
|
"line": 2, |
||||
|
"column": 3, |
||||
|
"severity": 4, |
||||
|
"message": 5 |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"type": "shell", |
||||
|
"label": "Clean RELEASE", |
||||
|
"presentation": { |
||||
|
"reveal": "always", |
||||
|
"panel": "shared" |
||||
|
}, |
||||
|
"command": "make CleanRelease", |
||||
|
"group": { |
||||
|
"kind": "build", |
||||
|
"isDefault": true |
||||
|
}, |
||||
|
"problemMatcher": { |
||||
|
"owner": "cpp", |
||||
|
"fileLocation": ["relative", "${workspaceFolder}"], |
||||
|
"pattern": { |
||||
|
"regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", |
||||
|
"file": 1, |
||||
|
"line": 2, |
||||
|
"column": 3, |
||||
|
"severity": 4, |
||||
|
"message": 5 |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"type": "shell", |
||||
|
"label": "Clean ALL", |
||||
|
"presentation": { |
||||
|
"reveal": "always", |
||||
|
"panel": "shared" |
||||
|
}, |
||||
|
"command": "make clean", |
||||
|
"group": { |
||||
|
"kind": "build", |
||||
|
"isDefault": true |
||||
|
}, |
||||
|
"problemMatcher": { |
||||
|
"owner": "cpp", |
||||
|
"fileLocation": ["relative", "${workspaceFolder}"], |
||||
|
"pattern": { |
||||
|
"regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", |
||||
|
"file": 1, |
||||
|
"line": 2, |
||||
|
"column": 3, |
||||
|
"severity": 4, |
||||
|
"message": 5 |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
] |
||||
|
} |
@ -0,0 +1,13 @@ |
|||||
|
# Attempt to load a config.make file.
|
||||
|
# If none is found, project defaults in config.project.make will be used.
|
||||
|
ifneq ($(wildcard config.make),) |
||||
|
include config.make |
||||
|
endif |
||||
|
|
||||
|
# make sure the the OF_ROOT location is defined
|
||||
|
ifndef OF_ROOT |
||||
|
OF_ROOT=$(realpath ../../..) |
||||
|
endif |
||||
|
|
||||
|
# call the project makefile!
|
||||
|
include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk |
@ -0,0 +1,2 @@ |
|||||
|
ofxOpenCv |
||||
|
ofxOpenCv |
@ -0,0 +1,142 @@ |
|||||
|
################################################################################ |
||||
|
# CONFIGURE PROJECT MAKEFILE (optional) |
||||
|
# This file is where we make project specific configurations. |
||||
|
################################################################################ |
||||
|
|
||||
|
################################################################################ |
||||
|
# OF ROOT |
||||
|
# The location of your root openFrameworks installation |
||||
|
# (default) OF_ROOT = ../../.. |
||||
|
################################################################################ |
||||
|
OF_ROOT = ../../.. |
||||
|
|
||||
|
################################################################################ |
||||
|
# PROJECT ROOT |
||||
|
# The location of the project - a starting place for searching for files |
||||
|
# (default) PROJECT_ROOT = . (this directory) |
||||
|
# |
||||
|
################################################################################ |
||||
|
# PROJECT_ROOT = . |
||||
|
|
||||
|
################################################################################ |
||||
|
# PROJECT SPECIFIC CHECKS |
||||
|
# This is a project defined section to create internal makefile flags to |
||||
|
# conditionally enable or disable the addition of various features within |
||||
|
# this makefile. For instance, if you want to make changes based on whether |
||||
|
# GTK is installed, one might test that here and create a variable to check. |
||||
|
################################################################################ |
||||
|
# None |
||||
|
|
||||
|
################################################################################ |
||||
|
# PROJECT EXTERNAL SOURCE PATHS |
||||
|
# These are fully qualified paths that are not within the PROJECT_ROOT folder. |
||||
|
# Like source folders in the PROJECT_ROOT, these paths are subject to |
||||
|
# exlclusion via the PROJECT_EXLCUSIONS list. |
||||
|
# |
||||
|
# (default) PROJECT_EXTERNAL_SOURCE_PATHS = (blank) |
||||
|
# |
||||
|
# Note: Leave a leading space when adding list items with the += operator |
||||
|
################################################################################ |
||||
|
# PROJECT_EXTERNAL_SOURCE_PATHS = |
||||
|
|
||||
|
################################################################################ |
||||
|
# PROJECT EXCLUSIONS |
||||
|
# These makefiles assume that all folders in your current project directory |
||||
|
# and any listed in the PROJECT_EXTERNAL_SOURCH_PATHS are are valid locations |
||||
|
# to look for source code. The any folders or files that match any of the |
||||
|
# items in the PROJECT_EXCLUSIONS list below will be ignored. |
||||
|
# |
||||
|
# Each item in the PROJECT_EXCLUSIONS list will be treated as a complete |
||||
|
# string unless teh user adds a wildcard (%) operator to match subdirectories. |
||||
|
# GNU make only allows one wildcard for matching. The second wildcard (%) is |
||||
|
# treated literally. |
||||
|
# |
||||
|
# (default) PROJECT_EXCLUSIONS = (blank) |
||||
|
# |
||||
|
# Will automatically exclude the following: |
||||
|
# |
||||
|
# $(PROJECT_ROOT)/bin% |
||||
|
# $(PROJECT_ROOT)/obj% |
||||
|
# $(PROJECT_ROOT)/%.xcodeproj |
||||
|
# |
||||
|
# Note: Leave a leading space when adding list items with the += operator |
||||
|
################################################################################ |
||||
|
# PROJECT_EXCLUSIONS = |
||||
|
|
||||
|
################################################################################ |
||||
|
# PROJECT LINKER FLAGS |
||||
|
# These flags will be sent to the linker when compiling the executable. |
||||
|
# |
||||
|
# (default) PROJECT_LDFLAGS = -Wl,-rpath=./libs |
||||
|
# |
||||
|
# Note: Leave a leading space when adding list items with the += operator |
||||
|
################################################################################ |
||||
|
|
||||
|
# Currently, shared libraries that are needed are copied to the |
||||
|
# $(PROJECT_ROOT)/bin/libs directory. The following LDFLAGS tell the linker to |
||||
|
# add a runtime path to search for those shared libraries, since they aren't |
||||
|
# incorporated directly into the final executable application binary. |
||||
|
# TODO: should this be a default setting? |
||||
|
# PROJECT_LDFLAGS=-Wl,-rpath=./libs |
||||
|
|
||||
|
################################################################################ |
||||
|
# PROJECT DEFINES |
||||
|
# Create a space-delimited list of DEFINES. The list will be converted into |
||||
|
# CFLAGS with the "-D" flag later in the makefile. |
||||
|
# |
||||
|
# (default) PROJECT_DEFINES = (blank) |
||||
|
# |
||||
|
# Note: Leave a leading space when adding list items with the += operator |
||||
|
################################################################################ |
||||
|
# PROJECT_DEFINES = |
||||
|
|
||||
|
################################################################################ |
||||
|
# PROJECT CFLAGS |
||||
|
# This is a list of fully qualified CFLAGS required when compiling for this |
||||
|
# project. These CFLAGS will be used IN ADDITION TO the PLATFORM_CFLAGS |
||||
|
# defined in your platform specific core configuration files. These flags are |
||||
|
# presented to the compiler BEFORE the PROJECT_OPTIMIZATION_CFLAGS below. |
||||
|
# |
||||
|
# (default) PROJECT_CFLAGS = (blank) |
||||
|
# |
||||
|
# Note: Before adding PROJECT_CFLAGS, note that the PLATFORM_CFLAGS defined in |
||||
|
# your platform specific configuration file will be applied by default and |
||||
|
# further flags here may not be needed. |
||||
|
# |
||||
|
# Note: Leave a leading space when adding list items with the += operator |
||||
|
################################################################################ |
||||
|
# PROJECT_CFLAGS = |
||||
|
|
||||
|
################################################################################ |
||||
|
# PROJECT OPTIMIZATION CFLAGS |
||||
|
# These are lists of CFLAGS that are target-specific. While any flags could |
||||
|
# be conditionally added, they are usually limited to optimization flags. |
||||
|
# These flags are added BEFORE the PROJECT_CFLAGS. |
||||
|
# |
||||
|
# PROJECT_OPTIMIZATION_CFLAGS_RELEASE flags are only applied to RELEASE targets. |
||||
|
# |
||||
|
# (default) PROJECT_OPTIMIZATION_CFLAGS_RELEASE = (blank) |
||||
|
# |
||||
|
# PROJECT_OPTIMIZATION_CFLAGS_DEBUG flags are only applied to DEBUG targets. |
||||
|
# |
||||
|
# (default) PROJECT_OPTIMIZATION_CFLAGS_DEBUG = (blank) |
||||
|
# |
||||
|
# Note: Before adding PROJECT_OPTIMIZATION_CFLAGS, please note that the |
||||
|
# PLATFORM_OPTIMIZATION_CFLAGS defined in your platform specific configuration |
||||
|
# file will be applied by default and further optimization flags here may not |
||||
|
# be needed. |
||||
|
# |
||||
|
# Note: Leave a leading space when adding list items with the += operator |
||||
|
################################################################################ |
||||
|
# PROJECT_OPTIMIZATION_CFLAGS_RELEASE = |
||||
|
# PROJECT_OPTIMIZATION_CFLAGS_DEBUG = |
||||
|
|
||||
|
################################################################################ |
||||
|
# PROJECT COMPILERS |
||||
|
# Custom compilers can be set for CC and CXX |
||||
|
# (default) PROJECT_CXX = (blank) |
||||
|
# (default) PROJECT_CC = (blank) |
||||
|
# Note: Leave a leading space when adding list items with the += operator |
||||
|
################################################################################ |
||||
|
# PROJECT_CXX = |
||||
|
# PROJECT_CC = |
@ -0,0 +1,107 @@ |
|||||
|
{ |
||||
|
"folders": [ |
||||
|
{ |
||||
|
"path": "." |
||||
|
}, |
||||
|
{ |
||||
|
"path": "${workspaceRoot}/../../../../libs/openFrameworks" |
||||
|
}, |
||||
|
{ |
||||
|
"path": "${workspaceRoot}/../../../../addons" |
||||
|
} |
||||
|
], |
||||
|
"settings": { |
||||
|
"files.associations": { |
||||
|
"cctype": "cpp", |
||||
|
"clocale": "cpp", |
||||
|
"cmath": "cpp", |
||||
|
"csignal": "cpp", |
||||
|
"cstdarg": "cpp", |
||||
|
"cstddef": "cpp", |
||||
|
"cstdio": "cpp", |
||||
|
"cstdlib": "cpp", |
||||
|
"cstring": "cpp", |
||||
|
"ctime": "cpp", |
||||
|
"cwchar": "cpp", |
||||
|
"cwctype": "cpp", |
||||
|
"any": "cpp", |
||||
|
"array": "cpp", |
||||
|
"atomic": "cpp", |
||||
|
"strstream": "cpp", |
||||
|
"bit": "cpp", |
||||
|
"*.tcc": "cpp", |
||||
|
"bitset": "cpp", |
||||
|
"cfenv": "cpp", |
||||
|
"charconv": "cpp", |
||||
|
"chrono": "cpp", |
||||
|
"codecvt": "cpp", |
||||
|
"compare": "cpp", |
||||
|
"complex": "cpp", |
||||
|
"concepts": "cpp", |
||||
|
"condition_variable": "cpp", |
||||
|
"cstdint": "cpp", |
||||
|
"deque": "cpp", |
||||
|
"forward_list": "cpp", |
||||
|
"list": "cpp", |
||||
|
"map": "cpp", |
||||
|
"set": "cpp", |
||||
|
"string": "cpp", |
||||
|
"unordered_map": "cpp", |
||||
|
"unordered_set": "cpp", |
||||
|
"vector": "cpp", |
||||
|
"exception": "cpp", |
||||
|
"expected": "cpp", |
||||
|
"algorithm": "cpp", |
||||
|
"functional": "cpp", |
||||
|
"iterator": "cpp", |
||||
|
"memory": "cpp", |
||||
|
"memory_resource": "cpp", |
||||
|
"numeric": "cpp", |
||||
|
"optional": "cpp", |
||||
|
"random": "cpp", |
||||
|
"ratio": "cpp", |
||||
|
"regex": "cpp", |
||||
|
"source_location": "cpp", |
||||
|
"string_view": "cpp", |
||||
|
"system_error": "cpp", |
||||
|
"tuple": "cpp", |
||||
|
"type_traits": "cpp", |
||||
|
"utility": "cpp", |
||||
|
"fstream": "cpp", |
||||
|
"future": "cpp", |
||||
|
"initializer_list": "cpp", |
||||
|
"iomanip": "cpp", |
||||
|
"iosfwd": "cpp", |
||||
|
"iostream": "cpp", |
||||
|
"istream": "cpp", |
||||
|
"limits": "cpp", |
||||
|
"mutex": "cpp", |
||||
|
"new": "cpp", |
||||
|
"numbers": "cpp", |
||||
|
"ostream": "cpp", |
||||
|
"ranges": "cpp", |
||||
|
"semaphore": "cpp", |
||||
|
"shared_mutex": "cpp", |
||||
|
"span": "cpp", |
||||
|
"sstream": "cpp", |
||||
|
"stdexcept": "cpp", |
||||
|
"stop_token": "cpp", |
||||
|
"streambuf": "cpp", |
||||
|
"thread": "cpp", |
||||
|
"cinttypes": "cpp", |
||||
|
"typeindex": "cpp", |
||||
|
"typeinfo": "cpp", |
||||
|
"valarray": "cpp", |
||||
|
"variant": "cpp", |
||||
|
"format": "cpp", |
||||
|
"stdfloat": "cpp", |
||||
|
"__nullptr": "cpp", |
||||
|
"*.ipp": "cpp", |
||||
|
"__bit_reference": "cpp", |
||||
|
"__hash_table": "cpp", |
||||
|
"__split_buffer": "cpp", |
||||
|
"__tree": "cpp", |
||||
|
"filesystem": "cpp" |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,69 @@ |
|||||
|
import qbs |
||||
|
import qbs.Process |
||||
|
import qbs.File |
||||
|
import qbs.FileInfo |
||||
|
import qbs.TextFile |
||||
|
import "../../../libs/openFrameworksCompiled/project/qtcreator/ofApp.qbs" as ofApp |
||||
|
|
||||
|
Project{ |
||||
|
property string of_root: "../../.." |
||||
|
|
||||
|
ofApp { |
||||
|
name: { return FileInfo.baseName(sourceDirectory) } |
||||
|
|
||||
|
files: [ |
||||
|
'src/main.cpp', |
||||
|
'src/ofApp.cpp', |
||||
|
'src/ofApp.h', |
||||
|
] |
||||
|
|
||||
|
of.addons: [ |
||||
|
'ofxOpenCv', |
||||
|
'ofxOpenCv', |
||||
|
] |
||||
|
|
||||
|
// additional flags for the project. the of module sets some |
||||
|
// flags by default to add the core libraries, search paths... |
||||
|
// this flags can be augmented through the following properties: |
||||
|
of.pkgConfigs: [] // list of additional system pkgs to include |
||||
|
of.includePaths: [] // include search paths |
||||
|
of.cFlags: [] // flags passed to the c compiler |
||||
|
of.cxxFlags: [] // flags passed to the c++ compiler |
||||
|
of.linkerFlags: [] // flags passed to the linker |
||||
|
of.defines: [] // defines are passed as -D to the compiler |
||||
|
// and can be checked with #ifdef or #if in the code |
||||
|
of.frameworks: [] // osx only, additional frameworks to link with the project |
||||
|
of.staticLibraries: [] // static libraries |
||||
|
of.dynamicLibraries: [] // dynamic libraries |
||||
|
|
||||
|
// other flags can be set through the cpp module: http://doc.qt.io/qbs/cpp-module.html |
||||
|
// eg: this will enable ccache when compiling |
||||
|
// |
||||
|
// cpp.compilerWrapper: 'ccache' |
||||
|
|
||||
|
Depends{ |
||||
|
name: "cpp" |
||||
|
} |
||||
|
|
||||
|
// common rules that parse the include search paths, core libraries... |
||||
|
Depends{ |
||||
|
name: "of" |
||||
|
} |
||||
|
|
||||
|
// dependency with the OF library |
||||
|
Depends{ |
||||
|
name: "openFrameworks" |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
property bool makeOF: true // use makfiles to compile the OF library |
||||
|
// will compile OF only once for all your projects |
||||
|
// otherwise compiled per project with qbs |
||||
|
|
||||
|
|
||||
|
property bool precompileOfMain: false // precompile ofMain.h |
||||
|
// faster to recompile when including ofMain.h |
||||
|
// but might use a lot of space per project |
||||
|
|
||||
|
references: [FileInfo.joinPaths(of_root, "/libs/openFrameworksCompiled/project/qtcreator/openFrameworks.qbs")] |
||||
|
} |
@ -0,0 +1 @@ |
|||||
|
## Affection Mapping Beta ## |
@ -0,0 +1,287 @@ |
|||||
|
#include "Onnx.h" |
||||
|
|
||||
|
// Setups the model. CUDA is enabled by default
|
||||
|
void Onnx::Setup(ORTCHAR_T* modelPath, bool isLog, bool useCuda){ |
||||
|
session_options.SetIntraOpNumThreads(1); |
||||
|
session_options.SetIntraOpNumThreads(1); |
||||
|
session_options.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_ALL); |
||||
|
log = isLog; |
||||
|
|
||||
|
// cuda setup
|
||||
|
if(useCuda){ |
||||
|
OrtCUDAProviderOptions opts; |
||||
|
opts.device_id = 0; |
||||
|
opts.cudnn_conv_algo_search = OrtCudnnConvAlgoSearchExhaustive; |
||||
|
opts.do_copy_in_default_stream = 0; |
||||
|
opts.arena_extend_strategy = 0; |
||||
|
session_options.AppendExecutionProvider_CUDA(opts); |
||||
|
} |
||||
|
|
||||
|
ort_session = std::make_shared<Ort::Session>(ort_env, modelPath, session_options); |
||||
|
|
||||
|
Ort::AllocatorWithDefaultOptions allocator; |
||||
|
for (std::size_t i = 0; i < ort_session->GetInputCount(); i++) { |
||||
|
input_node_names.emplace_back(ort_session->GetInputNameAllocated(i, allocator).get()); |
||||
|
input_node_dims = ort_session->GetInputTypeInfo(i).GetTensorTypeAndShapeInfo().GetShape(); |
||||
|
if(log) |
||||
|
std::cout << "\t" << input_node_names.at(i) << " : " << PrintShape(input_node_dims) << std::endl; |
||||
|
} |
||||
|
|
||||
|
// some models might have negative shape values to indicate dynamic shape, e.g., for variable batch size.
|
||||
|
for (auto& s : input_node_dims) { |
||||
|
if (s < 0) { |
||||
|
s = 1; |
||||
|
if(log) |
||||
|
std::cout << "transfromed!" << std::endl; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
if(log) |
||||
|
std::cout << "Output Node Name/Shape (" << output_node_names.size() << "):" << std::endl; |
||||
|
for (std::size_t i = 0; i < ort_session->GetOutputCount(); i++) { |
||||
|
output_node_names.emplace_back(ort_session->GetOutputNameAllocated(i, allocator).get()); |
||||
|
auto output_shapes = ort_session->GetOutputTypeInfo(i).GetTensorTypeAndShapeInfo().GetShape(); |
||||
|
if(log) |
||||
|
std::cout << "\t" << output_node_names.at(i) << " : " << PrintShape(output_shapes) << std::endl; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// Runs the model, given an image
|
||||
|
std::vector<Ort::Value> Onnx::Run(ofImage &img){ |
||||
|
|
||||
|
auto start = std::chrono::high_resolution_clock::now(); |
||||
|
|
||||
|
TransformImage(img); |
||||
|
size_t input_tensor_size = image_array.total(); |
||||
|
std::vector<Ort::Value> input_tensors; |
||||
|
Ort::MemoryInfo mem_info = Ort::MemoryInfo::CreateCpu(OrtAllocatorType::OrtArenaAllocator, OrtMemType::OrtMemTypeDefault); |
||||
|
input_tensors.emplace_back(Ort::Value::CreateTensor<float>(mem_info, (float*)image_array.data, |
||||
|
input_tensor_size, input_node_dims.data(), input_node_dims.size())); |
||||
|
|
||||
|
// double-check the dimensions of the input tensor
|
||||
|
assert(input_tensors[0].IsTensor() && input_tensors[0].GetTensorTypeAndShapeInfo().GetShape() == input_node_dims); |
||||
|
|
||||
|
//std::cout << "\ninput_tensor shape: " << PrintShape(input_tensors[0].GetTensorTypeAndShapeInfo().GetShape()) << std::endl;
|
||||
|
|
||||
|
// pass data through model
|
||||
|
std::vector<const char*> input_names_char(input_node_names.size(), nullptr); |
||||
|
std::transform(std::begin(input_node_names), std::end(input_node_names), std::begin(input_names_char), |
||||
|
[&](const std::string& str) { return str.c_str(); }); |
||||
|
|
||||
|
std::vector<const char*> output_names_char(output_node_names.size(), nullptr); |
||||
|
std::transform(std::begin(output_node_names), std::end(output_node_names), std::begin(output_names_char), |
||||
|
[&](const std::string& str) { return str.c_str(); }); |
||||
|
|
||||
|
std::cout << "Running model... "; |
||||
|
|
||||
|
try { |
||||
|
auto output_tensors = ort_session->Run(Ort::RunOptions{nullptr}, input_names_char.data(), input_tensors.data(), |
||||
|
input_names_char.size(), output_names_char.data(), output_names_char.size()); |
||||
|
|
||||
|
std::cout << "Done!" << std::endl; |
||||
|
|
||||
|
if (timeStamp) { |
||||
|
auto end = std::chrono::high_resolution_clock::now(); |
||||
|
std::chrono::duration<double, std::milli> elapsed = end - start; |
||||
|
std::cout << "Update loop took " << elapsed.count() << " ms" << std::endl; |
||||
|
} |
||||
|
|
||||
|
return output_tensors; |
||||
|
|
||||
|
} catch (const Ort::Exception& exception) { |
||||
|
std::cout << "ERROR running model inference: " << exception.what() << std::endl; |
||||
|
return input_tensors; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
/*
|
||||
|
Runs a model, with a batch of images as input (emotion.onnx) |
||||
|
(1) Creates a 1-dim float array based on the batch * channels * width * height) |
||||
|
(2) Transforms each image into a cv::Mat, and appends it to the array |
||||
|
(3) Sends that information to the model to be processed. |
||||
|
*/ |
||||
|
std::vector<Ort::Value> Onnx::RunBatch(std::vector<ofImage>& images){ |
||||
|
|
||||
|
auto start = std::chrono::high_resolution_clock::now(); |
||||
|
|
||||
|
// Number of images in the batch
|
||||
|
size_t batchSize = images.size(); |
||||
|
|
||||
|
std::vector<int64_t> batch_node_dims = {static_cast<int64_t>(batchSize), 3, 260, 260}; |
||||
|
|
||||
|
std::vector<float> batch_image_array(static_cast<int64_t>(batchSize) * 3 * 260 * 260); |
||||
|
|
||||
|
for(size_t i = 0; i < batchSize; i++){ |
||||
|
TransformImage(images[i]); |
||||
|
// Copy the image data into the batch_image_array
|
||||
|
std::memcpy( |
||||
|
batch_image_array.data() + i * 3 * 260 * 260, // Destination: starting point for this image in the batch array
|
||||
|
image_array.data, // Source: pixel data in the cv::Mat
|
||||
|
3 * 260 * 260 * sizeof(float) // Size: number of bytes to copy (3 channels * 260 * 260 pixels)
|
||||
|
); |
||||
|
} |
||||
|
|
||||
|
size_t input_tensor_size = batch_image_array.size(); |
||||
|
std::vector<Ort::Value> input_tensors; |
||||
|
Ort::MemoryInfo mem_info = Ort::MemoryInfo::CreateCpu(OrtAllocatorType::OrtArenaAllocator, OrtMemType::OrtMemTypeDefault); |
||||
|
input_tensors.emplace_back(Ort::Value::CreateTensor<float>(mem_info, batch_image_array.data(), |
||||
|
input_tensor_size, batch_node_dims.data(), batch_node_dims.size())); |
||||
|
|
||||
|
// double-check the dimensions of the input tensor
|
||||
|
assert(input_tensors[0].IsTensor() && input_tensors[0].GetTensorTypeAndShapeInfo().GetShape() == batch_node_dims); |
||||
|
|
||||
|
std::cout << "\ninput_tensor shape: " << PrintShape(input_tensors[0].GetTensorTypeAndShapeInfo().GetShape()) << std::endl; |
||||
|
|
||||
|
// pass data through model
|
||||
|
std::vector<const char*> input_names_char(input_node_names.size(), nullptr); |
||||
|
std::transform(std::begin(input_node_names), std::end(input_node_names), std::begin(input_names_char), |
||||
|
[&](const std::string& str) { return str.c_str(); }); |
||||
|
|
||||
|
std::vector<const char*> output_names_char(output_node_names.size(), nullptr); |
||||
|
std::transform(std::begin(output_node_names), std::end(output_node_names), std::begin(output_names_char), |
||||
|
[&](const std::string& str) { return str.c_str(); }); |
||||
|
|
||||
|
std::cout << "Running model... "; |
||||
|
|
||||
|
try { |
||||
|
auto output_tensors = ort_session->Run(Ort::RunOptions{nullptr}, input_names_char.data(), input_tensors.data(), |
||||
|
input_names_char.size(), output_names_char.data(), output_names_char.size()); |
||||
|
|
||||
|
std::cout << "Done!" << std::endl; |
||||
|
|
||||
|
if (timeStamp) { |
||||
|
auto end = std::chrono::high_resolution_clock::now(); |
||||
|
std::chrono::duration<double, std::milli> elapsed = end - start; |
||||
|
std::cout << "Update loop took " << elapsed.count() << " ms" << std::endl; |
||||
|
} |
||||
|
|
||||
|
return output_tensors; |
||||
|
|
||||
|
} catch (const Ort::Exception& exception) { |
||||
|
std::cout << "ERROR running model inference: " << exception.what() << std::endl; |
||||
|
return input_tensors; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// Transforms an ofImage into a cv::ImageArray
|
||||
|
void Onnx::TransformImage(ofImage &img){ |
||||
|
// Convert ofImage to cv::Mat
|
||||
|
ofPixels &pixels = img.getPixels(); // Get pixels from ofImage
|
||||
|
int width = img.getWidth(); |
||||
|
int height = img.getHeight(); |
||||
|
int channels = img.getPixels().getNumChannels(); |
||||
|
|
||||
|
// Create a cv::Mat from the pixel data
|
||||
|
cv::Mat cvImg = cv::Mat(height, width, (channels == 3) ? CV_8UC3 : CV_8UC1, pixels.getData()); |
||||
|
|
||||
|
// Convert cv::Mat to cv::InputArray
|
||||
|
cv::InputArray inputArray(cvImg); |
||||
|
|
||||
|
image_array = cv::dnn::blobFromImage(inputArray, 1 / 255.0, cv::Size(input_node_dims[2] , input_node_dims[3] ), (0, 0, 0), false, false); |
||||
|
} |
||||
|
|
||||
|
/* Generates a random 1 dimensional float array, creating values between 0->255.
|
||||
|
Returns a tensor. */ |
||||
|
Ort::Value Onnx::GenerateTensor(){ |
||||
|
std::vector<float> random_input_tensor_values(CalculateProduct(input_node_dims)); |
||||
|
std::generate(random_input_tensor_values.begin(), random_input_tensor_values.end(), [&] { return rand() % 255; }); |
||||
|
return VectorToTensor(random_input_tensor_values, input_node_dims); |
||||
|
} |
||||
|
|
||||
|
// Calculates the product of the vector, how many values.
|
||||
|
int Onnx::CalculateProduct(const std::vector<std::int64_t>& v){ |
||||
|
int total = 1; |
||||
|
for (auto& i : v) total *= i; |
||||
|
return total; |
||||
|
} |
||||
|
|
||||
|
// Creates a tensor from a given vector input.
|
||||
|
Ort::Value Onnx::VectorToTensor(std::vector<float>& data, const std::vector<std::int64_t>& shape){ |
||||
|
Ort::MemoryInfo mem_info = Ort::MemoryInfo::CreateCpu(OrtAllocatorType::OrtArenaAllocator, OrtMemType::OrtMemTypeDefault); |
||||
|
auto tensor = Ort::Value::CreateTensor<float>(mem_info, data.data(), data.size(), shape.data(), shape.size()); |
||||
|
return tensor; |
||||
|
} |
||||
|
|
||||
|
// Prints the shape of the given tensor (ex. input: (1, 1, 512, 512))
|
||||
|
std::string Onnx::PrintShape(const std::vector<std::int64_t>& v){ |
||||
|
std::stringstream ss(""); |
||||
|
for (std::size_t i = 0; i < v.size() - 1; i++) ss << v[i] << "x"; |
||||
|
ss << v[v.size() - 1]; |
||||
|
return ss.str(); |
||||
|
} |
||||
|
|
||||
|
// Function to calculate the minimum value in an array
|
||||
|
float Onnx::ReduceMin(const float* data, size_t size) { |
||||
|
return *std::min_element(data, data + size); |
||||
|
} |
||||
|
|
||||
|
// Function to calculate the maximum value in an array
|
||||
|
float Onnx::ReduceMax(const float* data, size_t size) { |
||||
|
return *std::max_element(data, data + size); |
||||
|
} |
||||
|
|
||||
|
// Function to normalize an array between 0 and 1
|
||||
|
void Onnx::Normalize(float* data, size_t size, float min_value, float max_value) { |
||||
|
for (size_t i = 0; i < size; ++i) { |
||||
|
data[i] = (data[i] - min_value) / (max_value - min_value); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Coverts the output tensor data to a texture of a given ofFbo.
|
||||
|
void Onnx::DataToFbo(const float* data, size_t width, size_t height, ofFbo& fbo){ |
||||
|
// Convert data into opencv mat
|
||||
|
cv::Mat inputMat(height, width, CV_32FC1, const_cast<float*>(data)); |
||||
|
|
||||
|
// Convert to 8-bit grayscale Mat
|
||||
|
cv::Mat inputMat8U; |
||||
|
inputMat.convertTo(inputMat8U, CV_8UC1, 255.0); // Convert float to 8-bit grayscale
|
||||
|
|
||||
|
// Resize the image using OpenCV
|
||||
|
cv::Mat resizedMat; |
||||
|
cv::resize(inputMat8U, resizedMat, cv::Size(fbo.getWidth(), fbo.getHeight()), 0, 0, cv::INTER_LINEAR); |
||||
|
|
||||
|
// Convert OpenCV Mat to ofPixels
|
||||
|
ofPixels pixels; |
||||
|
pixels.allocate(fbo.getWidth(), fbo.getHeight(), OF_PIXELS_GRAY); |
||||
|
|
||||
|
// Copy data from resizedMat to ofPixels
|
||||
|
for (size_t y = 0; y < fbo.getHeight(); ++y) { |
||||
|
for (size_t x = 0; x < fbo.getWidth(); ++x) { |
||||
|
unsigned char value = resizedMat.at<uchar>(y, x); |
||||
|
pixels.setColor(x, y, ofColor(value)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Update FBO with new pixels
|
||||
|
fbo.begin(); |
||||
|
ofTexture& texture = fbo.getTexture(); |
||||
|
texture.loadData(pixels); |
||||
|
fbo.end(); |
||||
|
|
||||
|
|
||||
|
} |
||||
|
|
||||
|
void Onnx::Softmax(float* data, size_t size) { |
||||
|
std::vector<float> logits(data, data + size); |
||||
|
std::vector<float> expValues(size); |
||||
|
float maxLogit = *std::max_element(logits.begin(), logits.end()); |
||||
|
|
||||
|
// Calculate exp(logit - maxLogit) for numerical stability
|
||||
|
std::transform(logits.begin(), logits.end(), expValues.begin(), |
||||
|
[maxLogit](float logit) { return std::exp(logit - maxLogit); }); |
||||
|
|
||||
|
float sumExp = std::accumulate(expValues.begin(), expValues.end(), 0.0f); |
||||
|
|
||||
|
// Normalize to get probabilities
|
||||
|
std::transform(expValues.begin(), expValues.end(), data, |
||||
|
[sumExp](float expValue) { return expValue / sumExp; }); |
||||
|
} |
||||
|
|
||||
|
|
@ -0,0 +1,57 @@ |
|||||
|
#ifndef ONNX |
||||
|
#define ONNX |
||||
|
|
||||
|
#include <onnxruntime_cxx_api.h> |
||||
|
#include <algorithm> // std::generate |
||||
|
#include <cassert> |
||||
|
#include <cstddef> |
||||
|
#include <cstdint> |
||||
|
#include <iostream> |
||||
|
#include <sstream> |
||||
|
#include <string> |
||||
|
#include <vector> |
||||
|
#include <cstdlib> // For std::rand and std::srand |
||||
|
#include "ofMain.h" |
||||
|
#include "ofxOpenCv.h" |
||||
|
#include <numeric> |
||||
|
#include <cmath> |
||||
|
|
||||
|
class Onnx { |
||||
|
|
||||
|
public: |
||||
|
Onnx() {} |
||||
|
void Setup(ORTCHAR_T* modelPath, bool isLog, bool useCuda); |
||||
|
std::vector<Ort::Value> Run(ofImage &img); |
||||
|
std::vector<Ort::Value> RunBatch(std::vector<ofImage> &images); |
||||
|
std::string PrintShape(const std::vector<std::int64_t>& v); |
||||
|
Ort::Value VectorToTensor(std::vector<float>& data, const std::vector<std::int64_t>& shape); |
||||
|
Ort::Value GenerateTensor(); |
||||
|
int CalculateProduct(const std::vector<std::int64_t>& v); |
||||
|
void TransformImage(ofImage &img); |
||||
|
float ReduceMin(const float* data, size_t size); |
||||
|
float ReduceMax(const float* data, size_t size); |
||||
|
void Normalize(float* data, size_t size, float min_value, float max_value); |
||||
|
void DataToFbo(const float* data, size_t width, size_t height, ofFbo& fbo); |
||||
|
void Softmax(float* data, size_t size); |
||||
|
bool timeStamp = true; |
||||
|
bool log = false; |
||||
|
|
||||
|
protected: |
||||
|
Ort::Env ort_env; |
||||
|
Ort::SessionOptions session_options; |
||||
|
cv::Mat image_array; |
||||
|
std::shared_ptr<Ort::Session> ort_session; |
||||
|
std::vector<std::string> input_node_names; |
||||
|
std::vector<int64_t> input_node_dims; // 1 input only.
|
||||
|
std::size_t input_tensor_size = 1; |
||||
|
std::vector<float> input_values_handler; |
||||
|
Ort::MemoryInfo memory_info_handler = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault); |
||||
|
std::vector<std::string> output_node_names; |
||||
|
std::vector<std::vector<int64_t>> output_node_dims; // >=1 outputs
|
||||
|
std::vector<Ort::Value> output_values; |
||||
|
Ort::Value dummy_tensor{ nullptr }; |
||||
|
std::vector<ofImage> imageBatch; |
||||
|
int num_outputs = 1; |
||||
|
}; |
||||
|
|
||||
|
#endif |
@ -0,0 +1,55 @@ |
|||||
|
#include "Player.h" |
||||
|
|
||||
|
Player::Player(){ |
||||
|
hasVideo = false; |
||||
|
} |
||||
|
|
||||
|
/* Basic ofVideoPlayer setup */ |
||||
|
void Player::Setup(){ |
||||
|
videoPlayer.setLoopState(OF_LOOP_NONE); |
||||
|
videoPlayer.setVolume(0); |
||||
|
} |
||||
|
|
||||
|
/* Updated the video player:
|
||||
|
(1) Allocates the required W x H for the model input |
||||
|
(2) Updates the video texture, and sets the current frame value */ |
||||
|
void Player::Update(ofImage &img){ |
||||
|
|
||||
|
if(!img.isAllocated() || img.getWidth() != videoPlayer.getWidth() || img.getHeight() != videoPlayer.getHeight()){ |
||||
|
img.allocate(videoPlayer.getWidth(), videoPlayer.getHeight(), OF_IMAGE_COLOR); |
||||
|
std::cout << "allocating new ofImage" << std::endl; |
||||
|
} |
||||
|
|
||||
|
if(videoPlayer.isLoaded()){ |
||||
|
hasVideo = true; |
||||
|
playerCurrentFrame = videoPlayer.getCurrentFrame(); |
||||
|
videoPlayer.update(); |
||||
|
videoPlayer.play(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void Player::Draw(){ |
||||
|
if(videoPlayer.isLoaded()){ |
||||
|
videoPlayer.draw(0, 0); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
ofPixels Player::GetVideoPixels(){ |
||||
|
return videoPlayer.getPixels(); |
||||
|
} |
||||
|
|
||||
|
/* Loads the video from path:
|
||||
|
(1) Sets the frame |
||||
|
(2) Allocates the fbo dims for final render */ |
||||
|
void Player::SetVideo(std::string path, ofFbo &fbo){ |
||||
|
videoPlayer.load(path); |
||||
|
videoPlayer.setFrame(800); |
||||
|
fbo.allocate(videoPlayer.getWidth(), videoPlayer.getHeight(), GL_RGB); |
||||
|
} |
||||
|
|
||||
|
// Sets a random frame in the active video
|
||||
|
void Player::SetRandomFrame(){ |
||||
|
int randomFrame = ofRandom(0, videoPlayer.getTotalNumFrames()); |
||||
|
std::cout << "setting frame: " << randomFrame << std::endl; |
||||
|
videoPlayer.setFrame(randomFrame); |
||||
|
} |
@ -0,0 +1,39 @@ |
|||||
|
#ifndef _PLAYER |
||||
|
#define _PLAYER |
||||
|
|
||||
|
#include "ofMain.h" |
||||
|
|
||||
|
class Player { |
||||
|
|
||||
|
public: |
||||
|
|
||||
|
void Setup(); |
||||
|
void Update(ofImage &img); |
||||
|
void Draw(); |
||||
|
void SetVideo(std::string path, ofFbo &fbo); |
||||
|
ofPixels GetVideoPixels(); |
||||
|
void SetVideoPosition(); |
||||
|
void SetRandomFrame(); |
||||
|
void SetupGUI(); |
||||
|
void UpdateGUI(); |
||||
|
void UpdateVector(); |
||||
|
void CheckNewFrame(); |
||||
|
void GetCurrentFrame(); |
||||
|
|
||||
|
ofVideoPlayer videoPlayer; |
||||
|
|
||||
|
int playerCurrentFrame; |
||||
|
int playerTotalFrameNum; |
||||
|
int playerVideoIndex; |
||||
|
std::string videoPath; |
||||
|
bool hasVideo; |
||||
|
|
||||
|
glm::vec2 centerPosition; |
||||
|
|
||||
|
ofFbo fbo; |
||||
|
|
||||
|
Player(); |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
#endif |
@ -0,0 +1,155 @@ |
|||||
|
#include "Yolo.h" |
||||
|
|
||||
|
// Takes output tensor data, processes that data, and returns an array of BoxfWithLandmarks (detected_faces)
|
||||
|
void Yolo::ParseOutput(float* &output_tensors, std::vector<types::BoxfWithLandmarks> &sorted_faces, unsigned int num_anchors) { |
||||
|
|
||||
|
std::vector<types::BoxfWithLandmarks> detected_faces; |
||||
|
|
||||
|
for (unsigned int i = 0; i < num_anchors; ++i) { |
||||
|
const float *row_ptr = output_tensors + i * 16; // Each row contains 16 values
|
||||
|
float obj_conf = row_ptr[4]; // Objectness confidence
|
||||
|
|
||||
|
if (obj_conf < 0.5) continue; // Filter out low-confidence detections
|
||||
|
|
||||
|
// Extract bounding box, confidence, and landmarks
|
||||
|
float cx = row_ptr[0]; |
||||
|
float cy = row_ptr[1]; |
||||
|
float w = row_ptr[2]; |
||||
|
float h = row_ptr[3]; |
||||
|
float cls_conf = row_ptr[15]; // Face confidence score
|
||||
|
|
||||
|
if (cls_conf < 0.5) continue; // Filter by class confidence
|
||||
|
|
||||
|
types::BoxfWithLandmarks face; |
||||
|
face.box.x1 = cx - w / 2; |
||||
|
face.box.y1 = cy - h / 2; |
||||
|
face.box.x2 = cx + w / 2; |
||||
|
face.box.y2 = cy + h / 2; |
||||
|
face.box.score = cls_conf; |
||||
|
face.box.label_text = "face"; |
||||
|
|
||||
|
// Extract landmarks
|
||||
|
for (int j = 0; j < 10; j += 2) { |
||||
|
face.landmarks.points.push_back(cv::Point2f(row_ptr[5 + j], row_ptr[5 + j + 1])); |
||||
|
} |
||||
|
|
||||
|
detected_faces.push_back(face); // Store the detected face with landmarks
|
||||
|
} |
||||
|
|
||||
|
// Apply NMS to detected faces list to remove any overlapping bounding boxes.
|
||||
|
NonMaximumSuppression(detected_faces, sorted_faces, 0.5); |
||||
|
|
||||
|
// Sort faces based on confidence value
|
||||
|
SortDetectedFaces(sorted_faces); |
||||
|
} |
||||
|
|
||||
|
// Simple helper for drawing boxes given x1, y1, x2, y2 coordinates.
|
||||
|
void Yolo::DrawBox(std::vector<types::BoxfWithLandmarks> &detected_faces){ |
||||
|
for (const auto &face : detected_faces) { |
||||
|
ofNoFill(); |
||||
|
ofDrawRectangle(face.box.x1, face.box.y1, face.box.x2 - face.box.x1, face.box.y2 - face.box.y1); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Simple helper to draw boxes at the center of the detected face.
|
||||
|
void Yolo::DrawCenter(std::vector<types::BoxfWithLandmarks> &detected_faces){ |
||||
|
ofNoFill(); |
||||
|
ofDrawCircle(detected_faces[0].box.center, 5); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// Applies NMS to an array of BoxfWithLandmarks.face.boxes, to remove any overlapping bounding boxes.
|
||||
|
void Yolo::NonMaximumSuppression(std::vector<types::BoxfWithLandmarks> &input_faces, std::vector<types::BoxfWithLandmarks> &output_faces, float iou_threshold) |
||||
|
{ |
||||
|
// Sort the boxes by their confidence scores (highest to lowest)
|
||||
|
std::sort(input_faces.begin(), input_faces.end(), |
||||
|
[](const types::BoxfWithLandmarks &a, const types::BoxfWithLandmarks &b) { |
||||
|
return a.box.score > b.box.score; |
||||
|
}); |
||||
|
|
||||
|
std::vector<int> suppressed(input_faces.size(), 0); // Suppression mask
|
||||
|
|
||||
|
// Iterate through the boxes
|
||||
|
for (size_t i = 0; i < input_faces.size(); ++i) { |
||||
|
if (suppressed[i]) continue; // Skip already suppressed boxes
|
||||
|
|
||||
|
// Add this box to the output
|
||||
|
output_faces.push_back(input_faces[i]); |
||||
|
|
||||
|
for (size_t j = i + 1; j < input_faces.size(); ++j) { |
||||
|
if (suppressed[j]) continue; |
||||
|
|
||||
|
// Calculate IoU between box i and box j
|
||||
|
float iou = input_faces[i].box.iou_of(input_faces[j].box); |
||||
|
|
||||
|
// Suppress box j if IoU is greater than the threshold
|
||||
|
if (iou > iou_threshold) { |
||||
|
suppressed[j] = 1; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Scales the coordinates of detected faces from the model output dimensions -> the original input image dimensions.
|
||||
|
void Yolo::ConvertBoxCoordsToOriginalSize(std::vector<types::BoxfWithLandmarks> &detected_faces, size_t original_width, size_t original_height){ |
||||
|
float width_scale = static_cast<float>(original_width) / modelSize; |
||||
|
float height_scale = static_cast<float>(original_height) / modelSize; |
||||
|
|
||||
|
for (auto &face : detected_faces) { |
||||
|
// Convert bounding box coordinates
|
||||
|
face.box.x1 *= width_scale; |
||||
|
face.box.y1 *= height_scale; |
||||
|
face.box.x2 *= width_scale; |
||||
|
face.box.y2 *= height_scale; |
||||
|
face.box.UpdateCenter(); |
||||
|
|
||||
|
// Convert landmarks
|
||||
|
for (size_t j = 0; j < face.landmarks.points.size(); ++j) { |
||||
|
face.landmarks.points[j].x *= width_scale; |
||||
|
face.landmarks.points[j].y *= height_scale; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void Yolo::CropFaceToImage(ofImage &inputImage, types::BoxfWithLandmarks &face, ofxCvColorImage &colorImage){ |
||||
|
|
||||
|
colorImage.resetROI(); |
||||
|
|
||||
|
// Calculate the coordinates and dimensions of the face box
|
||||
|
float x1 = face.box.x1; |
||||
|
float y1 = face.box.y1; |
||||
|
float x2 = face.box.x2; |
||||
|
float y2 = face.box.y2; |
||||
|
|
||||
|
// Ensure coordinates are within the input image bounds
|
||||
|
x1 = ofClamp(x1, 0.0f, (float)inputImage.getWidth()); |
||||
|
y1 = ofClamp(y1, 0.0f, (float)inputImage.getHeight()); |
||||
|
x2 = ofClamp(x2, 0.0f, (float)inputImage.getWidth()); |
||||
|
y2 = ofClamp(y2, 0.0f, (float)inputImage.getHeight()); |
||||
|
|
||||
|
// Calculate width and height of the cropped area
|
||||
|
float cropWidth = x2 - x1; |
||||
|
float cropHeight = y2 - y1; |
||||
|
|
||||
|
// Create cropped section, defined by the box coords
|
||||
|
ofFbo tempFbo; |
||||
|
tempFbo.allocate(cropWidth, cropHeight, GL_RGB); |
||||
|
|
||||
|
tempFbo.begin(); |
||||
|
ofClear(0); |
||||
|
inputImage.getTexture().drawSubsection(0, 0, cropWidth, cropHeight, x1, y1); |
||||
|
tempFbo.end(); |
||||
|
|
||||
|
ofFloatPixels pix; |
||||
|
tempFbo.readToPixels(pix); |
||||
|
colorImage.setFromPixels(pix); |
||||
|
|
||||
|
colorImage.resize(260, 260); |
||||
|
} |
||||
|
|
||||
|
void Yolo::SortDetectedFaces(std::vector<types::BoxfWithLandmarks> &detectedFaces){ |
||||
|
std::sort(detectedFaces.begin(), detectedFaces.end(), |
||||
|
[](const types::BoxfWithLandmarks &a, const types::BoxfWithLandmarks &b) { |
||||
|
return a.box.score > b.box.score; // Sort in descending order
|
||||
|
}); |
||||
|
} |
@ -0,0 +1,81 @@ |
|||||
|
#ifndef YOLO |
||||
|
#define YOLO |
||||
|
|
||||
|
#include "ofMain.h" |
||||
|
#include "ofxOpenCv.h" |
||||
|
#include <onnxruntime_cxx_api.h> |
||||
|
#include <algorithm> |
||||
|
|
||||
|
struct Emotef{ |
||||
|
float emotions[7]; |
||||
|
}; |
||||
|
|
||||
|
namespace types { |
||||
|
|
||||
|
/*
|
||||
|
Struct for storing information about detetced faces. |
||||
|
*/ |
||||
|
struct Boxf { |
||||
|
float x1, y1, x2, y2; // Coordinates of the bounding box
|
||||
|
float score; // Confidence score
|
||||
|
glm::vec2 center; |
||||
|
int label; // Class label (e.g., "face")
|
||||
|
std::string label_text; |
||||
|
Emotef emotional_state; |
||||
|
|
||||
|
// Calculate Intersection over Union (IoU) with another box
|
||||
|
float iou_of(const Boxf &other) const { |
||||
|
float intersection_x1 = std::max(x1, other.x1); |
||||
|
float intersection_y1 = std::max(y1, other.y1); |
||||
|
float intersection_x2 = std::min(x2, other.x2); |
||||
|
float intersection_y2 = std::min(y2, other.y2); |
||||
|
|
||||
|
float intersection_area = std::max(0.0f, intersection_x2 - intersection_x1) * |
||||
|
std::max(0.0f, intersection_y2 - intersection_y1); |
||||
|
|
||||
|
float this_area = (x2 - x1) * (y2 - y1); |
||||
|
float other_area = (other.x2 - other.x1) * (other.y2 - other.y1); |
||||
|
|
||||
|
float union_area = this_area + other_area - intersection_area; |
||||
|
|
||||
|
return intersection_area / union_area; |
||||
|
} |
||||
|
|
||||
|
void UpdateCenter(){ |
||||
|
center.x = (x1 + x2) / 2; |
||||
|
center.y = (y1 + y2) / 2; |
||||
|
} |
||||
|
|
||||
|
void SetEmotionState(float* emotional_data){ |
||||
|
std::copy(emotional_data, emotional_data + 7, emotional_state.emotions); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
struct Landmarks { |
||||
|
std::vector<cv::Point2f> points; // Facial landmarks points (e.g., eyes, nose, mouth)
|
||||
|
bool flag = false; // Indicator if landmarks are available
|
||||
|
}; |
||||
|
|
||||
|
struct BoxfWithLandmarks { |
||||
|
Boxf box; // Bounding box for the face
|
||||
|
Landmarks landmarks; // Landmark points for the face
|
||||
|
bool flag = false; // Indicator if this detection is valid
|
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
class Yolo{ |
||||
|
public: |
||||
|
Yolo(){}; |
||||
|
void ParseOutput(float* &out_ptr, std::vector<types::BoxfWithLandmarks> &sorted_faces, unsigned int num_anchors); |
||||
|
void DrawBox(std::vector<types::BoxfWithLandmarks> &detected_faces); |
||||
|
void DrawCenter(std::vector<types::BoxfWithLandmarks> &detected_faces); |
||||
|
void NonMaximumSuppression(std::vector<types::BoxfWithLandmarks> &input_faces, std::vector<types::BoxfWithLandmarks> &output_faces, float iou_threshold); |
||||
|
void ConvertBoxCoordsToOriginalSize(std::vector<types::BoxfWithLandmarks> &detected_faces, size_t original_width, size_t original_height); |
||||
|
void CropFaceToImage(ofImage &inputImage, types::BoxfWithLandmarks &face, ofxCvColorImage &colorImage); |
||||
|
void SortDetectedFaces(std::vector<types::BoxfWithLandmarks> &detectedFaces); |
||||
|
private: |
||||
|
// Input dimenions of the model -- used for coordinate scaling.
|
||||
|
size_t modelSize = 640; |
||||
|
}; |
||||
|
|
||||
|
#endif |
@ -0,0 +1,17 @@ |
|||||
|
#include "ofMain.h" |
||||
|
#include "ofApp.h" |
||||
|
|
||||
|
//========================================================================
|
||||
|
int main( ){ |
||||
|
|
||||
|
//Use ofGLFWWindowSettings for more options like multi-monitor fullscreen
|
||||
|
ofGLWindowSettings settings; |
||||
|
settings.setSize(1280, 720); |
||||
|
settings.windowMode = OF_WINDOW; //can also be OF_FULLSCREEN
|
||||
|
|
||||
|
auto window = ofCreateWindow(settings); |
||||
|
|
||||
|
ofRunApp(window, make_shared<ofApp>()); |
||||
|
ofRunMainLoop(); |
||||
|
|
||||
|
} |
@ -0,0 +1,210 @@ |
|||||
|
#include "ofApp.h" |
||||
|
|
||||
|
//--------------------------------------------------------------
|
||||
|
void ofApp::setup(){ |
||||
|
ofSetFrameRate(24); |
||||
|
ofSetVerticalSync(true); |
||||
|
|
||||
|
player.Setup(); |
||||
|
player.SetVideo("videos/demo.mp4", fbo); |
||||
|
|
||||
|
emoteImage.allocate(260, 260); |
||||
|
tempImage.allocate(emoteImage.getWidth(), emoteImage.getHeight(), OF_IMAGE_COLOR); |
||||
|
|
||||
|
ORTCHAR_T* modelPath = "/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/apps/myApps/onnx-test/bin/data/depth_anything_v2_vitb.onnx"; |
||||
|
ORTCHAR_T* modelPath2 = "/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/apps/myApps/onnx-test/bin/data/yolov5s-face.onnx"; |
||||
|
ORTCHAR_T* modelPath3 = "/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/apps/myApps/onnx-test/bin/data/rgb_emotion.onnx"; |
||||
|
|
||||
|
/* Setup Models (modelPath, log, useCuda) */ |
||||
|
yolo.Setup(modelPath2, false, true); |
||||
|
depth.Setup(modelPath, false, true); |
||||
|
emotion.Setup(modelPath3, false, true); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
//--------------------------------------------------------------
|
||||
|
void ofApp::update(){ |
||||
|
/* Check to see if the application has moved to the first frame
|
||||
|
As the models need to load first, as the first inference is quite slow */ |
||||
|
if(ofGetFrameNum() > 0) |
||||
|
firstRun = false; |
||||
|
|
||||
|
/* Clear detetced face list */ |
||||
|
detected_faces.clear(); |
||||
|
|
||||
|
/* Setup model input using ofImage */ |
||||
|
player.Update(img); |
||||
|
img.setFromPixels(player.GetVideoPixels()); |
||||
|
|
||||
|
/* Run Models */ |
||||
|
try{ |
||||
|
auto output_tensors = depth.Run(img); |
||||
|
float* output_ptr = output_tensors.front().GetTensorMutableData<float>(); |
||||
|
size_t num_elements = output_tensors.front().GetTensorTypeAndShapeInfo().GetElementCount(); |
||||
|
|
||||
|
float min_value = depth.ReduceMin(output_ptr, num_elements); |
||||
|
float max_value = depth.ReduceMax(output_ptr, num_elements); |
||||
|
|
||||
|
depth.Normalize(output_ptr, num_elements, min_value, max_value); |
||||
|
|
||||
|
depth.DataToFbo(output_ptr, 518, 518, fbo); |
||||
|
|
||||
|
auto output_tensors_face = yolo.Run(img); |
||||
|
|
||||
|
auto output_faces = output_tensors_face.front().GetTensorTypeAndShapeInfo().GetShape(); |
||||
|
|
||||
|
unsigned int num_anchors = output_faces[1]; // Number of anchors
|
||||
|
|
||||
|
float* output_face_ptr = output_tensors_face.front().GetTensorMutableData<float>(); |
||||
|
|
||||
|
faceDetector.ParseOutput(output_face_ptr, detected_faces, num_anchors); |
||||
|
|
||||
|
faceDetector.ConvertBoxCoordsToOriginalSize(detected_faces, fbo.getWidth(), fbo.getHeight()); |
||||
|
|
||||
|
/* As no input is generated for the emotion recognition model, run a dummy vector through the model
|
||||
|
So it can load */ |
||||
|
if(firstRun){ |
||||
|
|
||||
|
/*
|
||||
|
Create a dummy initial input of batch_size = 5, as |
||||
|
when initialising the model, it will attempt to create a space in memory for this array. |
||||
|
If the batch_size does change it will completely slow down inference, due to how the cudnn_search_algo is set. |
||||
|
None of the other search alogithms bar EXHAUSTIVE will work.. no idead why. |
||||
|
*/ |
||||
|
for(int i = 0; i < emotionImageMaxBatchSize; i++){ |
||||
|
tempImage.setFromPixels(emoteImage.getPixels()); |
||||
|
croppedFaces.push_back(tempImage); |
||||
|
} |
||||
|
|
||||
|
// Run model to warmup
|
||||
|
auto emotion_output_tensor = emotion.RunBatch(croppedFaces); |
||||
|
|
||||
|
} else { |
||||
|
inferEmotionalState(); |
||||
|
} |
||||
|
|
||||
|
/* Run emotion inference */ |
||||
|
//inferEmotionalState();
|
||||
|
|
||||
|
} catch (exception e){ |
||||
|
|
||||
|
std::cout << "Model did not run" << std::endl; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
//--------------------------------------------------------------
|
||||
|
void ofApp::draw(){ |
||||
|
fbo.draw(0, 0); |
||||
|
|
||||
|
if(!firstRun){ |
||||
|
faceDetector.DrawBox(detected_faces); |
||||
|
faceDetector.DrawCenter(detected_faces); |
||||
|
} |
||||
|
|
||||
|
// emoteImage.draw(640, 0);
|
||||
|
// for(auto& face : detected_faces){
|
||||
|
// ofDrawBitmapString(std::to_string(face.box.emotional_state.emotions[0]), 700, 300);
|
||||
|
// }
|
||||
|
|
||||
|
} |
||||
|
|
||||
|
//--------------------------------------------------------------
|
||||
|
void ofApp::inferEmotionalState(){ |
||||
|
|
||||
|
/*
|
||||
|
Max faces to process with the model (5) |
||||
|
*/ |
||||
|
int max_faces_to_process = std::min(emotionImageMaxBatchSize, static_cast<int>(detected_faces.size())); |
||||
|
|
||||
|
/*
|
||||
|
For the detetced faces, set the cropped image to a location in the image batch array |
||||
|
*/ |
||||
|
for (size_t i = 0; i < max_faces_to_process; i++){ |
||||
|
auto& face = detected_faces[i]; |
||||
|
faceDetector.CropFaceToImage(img, face, emoteImage); |
||||
|
tempImage.setFromPixels(emoteImage.getPixels()); |
||||
|
croppedFaces[i] = tempImage; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
auto emotion_output_tensor = emotion.RunBatch(croppedFaces); |
||||
|
|
||||
|
auto& output_tensor = emotion_output_tensor.front(); |
||||
|
auto output_shap = output_tensor.GetTensorTypeAndShapeInfo().GetShape(); |
||||
|
size_t batch_size = output_shap[0]; // Number of images in the batch
|
||||
|
size_t num_classes = output_shap[1]; // Number of emotion classes
|
||||
|
std::cout << batch_size << " : " << num_classes << std::endl; |
||||
|
|
||||
|
// for(int i = 0; i < max_faces_to_process; ++i){
|
||||
|
// auto& face = detected_faces[i];
|
||||
|
// faceDetector.CropFaceToImage(img, face, emoteImage);
|
||||
|
// tempImage.setFromPixels(emoteImage.getPixels());
|
||||
|
// auto emotion_output_tensor = emotion.Run(tempImage);
|
||||
|
// float* emotional_data = emotion_output_tensor.front().GetTensorMutableData<float>();
|
||||
|
// emotion.Softmax(emotional_data, 7);
|
||||
|
// face.box.SetEmotionState(emotional_data);
|
||||
|
// }
|
||||
|
|
||||
|
std::cout << croppedFaces.size() << std::endl; |
||||
|
} |
||||
|
|
||||
|
//--------------------------------------------------------------
|
||||
|
void ofApp::keyPressed(int key){ |
||||
|
if (key=OF_KEY_LEFT){ |
||||
|
player.SetRandomFrame(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
//--------------------------------------------------------------
|
||||
|
void ofApp::keyReleased(int key){ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
//--------------------------------------------------------------
|
||||
|
void ofApp::mouseMoved(int x, int y ){ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
//--------------------------------------------------------------
|
||||
|
void ofApp::mouseDragged(int x, int y, int button){ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
//--------------------------------------------------------------
|
||||
|
void ofApp::mousePressed(int x, int y, int button){ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
//--------------------------------------------------------------
|
||||
|
void ofApp::mouseReleased(int x, int y, int button){ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
//--------------------------------------------------------------
|
||||
|
void ofApp::mouseEntered(int x, int y){ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
//--------------------------------------------------------------
|
||||
|
void ofApp::mouseExited(int x, int y){ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
//--------------------------------------------------------------
|
||||
|
void ofApp::windowResized(int w, int h){ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
//--------------------------------------------------------------
|
||||
|
void ofApp::gotMessage(ofMessage msg){ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
//--------------------------------------------------------------
|
||||
|
void ofApp::dragEvent(ofDragInfo dragInfo){ |
||||
|
|
||||
|
} |
@ -0,0 +1,49 @@ |
|||||
|
#pragma once |
||||
|
|
||||
|
#include "ofMain.h" |
||||
|
#include <onnxruntime_cxx_api.h> |
||||
|
#include "ofxOpenCv.h" |
||||
|
#include "Onnx.h" |
||||
|
#include "Yolo.h" |
||||
|
#include <vector> |
||||
|
#include "Player.h" |
||||
|
|
||||
|
class ofApp : public ofBaseApp{ |
||||
|
|
||||
|
public: |
||||
|
void setup(); |
||||
|
void update(); |
||||
|
void draw(); |
||||
|
|
||||
|
void keyPressed(int key); |
||||
|
void keyReleased(int key); |
||||
|
void mouseMoved(int x, int y ); |
||||
|
void mouseDragged(int x, int y, int button); |
||||
|
void mousePressed(int x, int y, int button); |
||||
|
void mouseReleased(int x, int y, int button); |
||||
|
void mouseEntered(int x, int y); |
||||
|
void mouseExited(int x, int y); |
||||
|
void windowResized(int w, int h); |
||||
|
void dragEvent(ofDragInfo dragInfo); |
||||
|
void gotMessage(ofMessage msg); |
||||
|
void inferEmotionalState(); |
||||
|
|
||||
|
ofImage img; |
||||
|
ofFbo fbo; |
||||
|
cv::Mat cvImg; |
||||
|
ofVideoGrabber webcam; |
||||
|
Player player; |
||||
|
bool firstRun = true; |
||||
|
|
||||
|
Onnx depth; |
||||
|
Onnx yolo; |
||||
|
Onnx emotion; |
||||
|
ofxCvColorImage emoteImage; |
||||
|
ofImage tempImage; |
||||
|
std::vector<ofImage> croppedFaces; |
||||
|
int emotionImageMaxBatchSize = 5; |
||||
|
|
||||
|
Emotef emo; |
||||
|
Yolo faceDetector; |
||||
|
std::vector<types::BoxfWithLandmarks> detected_faces; |
||||
|
}; |
Loading…
Reference in new issue