├── .gitignore
├── README.md
├── license.md
└── native-activity
├── .classpath
├── .cproject
├── .externalToolBuilders
└── testbuilder.launch
├── .project
├── .settings
└── org.eclipse.jdt.core.prefs
├── AndroidManifest.xml
├── README.md~
├── assets
├── face.con
├── face.tracker
├── face.tri
├── face2.tracker
└── haarcascade_eye.xml
├── bin
├── AndroidManifest.xml
├── FaceTrackerJS.apk
├── R.txt
├── classes.dex
├── classes
│ ├── comsc
│ │ └── cardiff
│ │ │ └── ajdroid
│ │ │ └── FaceTracker
│ │ │ ├── BuildConfig.class
│ │ │ ├── R$attr.class
│ │ │ ├── R$drawable.class
│ │ │ ├── R$id.class
│ │ │ ├── R$string.class
│ │ │ ├── R$styleable.class
│ │ │ └── R.class
│ └── org
│ │ └── opencv
│ │ ├── R$attr.class
│ │ ├── R$id.class
│ │ ├── R$styleable.class
│ │ ├── R.class
│ │ └── samples
│ │ └── NativeActivity
│ │ ├── CvNativeActivity$1.class
│ │ └── CvNativeActivity.class
├── dexedLibs
│ └── opencv library - 2.4.8.2-94d917d6d803c7f29e6dbeaeb95cc035.jar
├── res
│ └── crunch
│ │ └── drawable
│ │ └── icon.png
└── resources.ap_
├── gen
├── comsc
│ └── cardiff
│ │ └── ajdroid
│ │ └── FaceTracker
│ │ ├── BuildConfig.java
│ │ └── R.java
└── org
│ └── opencv
│ └── R.java
├── jni
├── Android.mk
├── Application.mk
├── FaceTracker
│ ├── CLM.h
│ ├── FCheck.h
│ ├── FDet.h
│ ├── IO.h
│ ├── PAW.h
│ ├── PDM.h
│ ├── Patch.h
│ ├── Tracker.h
│ └── lib
│ │ ├── CLM.cpp
│ │ ├── FCheck.cpp
│ │ ├── FDet.cpp
│ │ ├── IO.cpp
│ │ ├── PAW.cpp
│ │ ├── PDM.cpp
│ │ ├── Patch.cpp
│ │ └── Tracker.cpp
├── Tracker.h
├── libFaceTracker.a
├── libFaceTracker.so
├── model
│ ├── face.con
│ ├── face.tracker
│ ├── face.tri
│ └── face2.tracker
├── native.cpp
├── nativeact.h
└── vecthelp.h
├── libs
└── armeabi-v7a
│ ├── gdb.setup
│ ├── gdbserver
│ ├── libnative_activity.so
│ ├── libnative_camera_r2.2.0.so
│ ├── libnative_camera_r2.3.3.so
│ ├── libnative_camera_r3.0.1.so
│ ├── libnative_camera_r4.0.0.so
│ ├── libnative_camera_r4.0.3.so
│ ├── libnative_camera_r4.1.1.so
│ ├── libnative_camera_r4.2.0.so
│ ├── libnative_camera_r4.3.0.so
│ ├── libnative_camera_r4.4.0.so
│ └── libopencv_java.so
├── lint.xml
├── obj
└── local
│ └── armeabi-v7a
│ ├── libandroid_native_app_glue.a
│ ├── libnative_activity.so
│ ├── libnative_camera_r2.2.0.so
│ ├── libnative_camera_r2.3.3.so
│ ├── libnative_camera_r3.0.1.so
│ ├── libnative_camera_r4.0.0.so
│ ├── libnative_camera_r4.0.3.so
│ ├── libnative_camera_r4.1.1.so
│ ├── libnative_camera_r4.2.0.so
│ ├── libnative_camera_r4.3.0.so
│ ├── libnative_camera_r4.4.0.so
│ ├── libopencv_java.so
│ └── objs
│ ├── android_native_app_glue
│ ├── android_native_app_glue.o
│ └── android_native_app_glue.o.d
│ └── native_activity
│ ├── native.o
│ └── native.o.d
├── project.properties
├── res
├── drawable
│ └── icon.png
└── values
│ └── strings.xml
└── src
└── org
└── opencv
└── samples
└── NativeActivity
└── CvNativeActivity.java
/.gitignore:
--------------------------------------------------------------------------------
1 | obj/
2 | bin/
3 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # FaceTrackerApp
2 |
3 | An Android port of : [Jason Saragih](http://jsaragih.org/) and [Kyle McDonald](http://kylemcdonald.net/)'s [FaceTracker](https://github.com/kylemcdonald/FaceTracker). Capable of tracking facial landmark points.
4 |
5 | ## Requirements
6 |
7 | + Android phone with OS version \< 5.0.0 (OpenCV's native camera does not support greater version)
8 | + Installation of latest [OpenCV Manager](https://play.google.com/store/apps/details?id=org.opencv.engine&hl=en) app
9 | + armv7 processor with NEON architecture for best performance. Protip: If you don't know if your phone has this, install OpenCV Manager and it will tell you when you open it.
10 |
11 | ## apk file
12 |
13 | Find it at `native-activity/bin/FaceTrackerJS.apk`
14 |
15 | ## License
16 |
17 | Available free for non-commercial use, and may be redistributed under these conditions. Please see license.md for complete details. For commercial use, [request a quote](http://facetracker.net/quote/).
18 |
19 |
--------------------------------------------------------------------------------
/license.md:
--------------------------------------------------------------------------------
1 | Summary: FaceTracker is available for non-commercial use only. For commercial use, [request a quote](http://facetracker.net/quote/). The complete license follows.
2 |
3 | Copyright (C) 2010, Jason Mora Saragih, all rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 |
7 | The software is provided under the terms of this license strictly for academic, non-commercial, not-for-profit purposes.
8 | Redistributions of source code must retain the above copyright notice, this list of conditions (license) and the following disclaimer.
9 | Redistributions in binary form must reproduce the above copyright notice, this list of conditions (license) and the following disclaimer in the documentation and/or other materials provided with the distribution.
10 | The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
11 | As this software depends on other libraries, the user must adhere to and keep in place any licensing terms of those libraries.
12 | Any publications arising from the use of this software, including but not limited to academic journal and conference publications, technical reports and manuals, must cite the following work: J. M. Saragih, S. Lucey, and J. F. Cohn. Face Alignment through Subspace Constrained Mean-Shifts. International Conference of Computer Vision (ICCV), September, 2009.
13 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14 |
--------------------------------------------------------------------------------
/native-activity/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/native-activity/.cproject:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
26 |
27 |
28 |
29 |
30 |
31 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/native-activity/.externalToolBuilders/testbuilder.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/native-activity/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | FaceTrackerJS
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
10 |
11 |
12 | ?name?
13 |
14 |
15 |
16 | org.eclipse.cdt.make.core.append_environment
17 | true
18 |
19 |
20 | org.eclipse.cdt.make.core.autoBuildTarget
21 |
22 |
23 |
24 | org.eclipse.cdt.make.core.buildArguments
25 |
26 |
27 |
28 | org.eclipse.cdt.make.core.buildCommand
29 | "${NDKROOT}/ndk-build.cmd"
30 |
31 |
32 | org.eclipse.cdt.make.core.cleanBuildTarget
33 | clean
34 |
35 |
36 | org.eclipse.cdt.make.core.contents
37 | org.eclipse.cdt.make.core.activeConfigSettings
38 |
39 |
40 | org.eclipse.cdt.make.core.enableAutoBuild
41 | true
42 |
43 |
44 | org.eclipse.cdt.make.core.enableCleanBuild
45 | false
46 |
47 |
48 | org.eclipse.cdt.make.core.enableFullBuild
49 | true
50 |
51 |
52 | org.eclipse.cdt.make.core.fullBuildTarget
53 |
54 |
55 |
56 | org.eclipse.cdt.make.core.stopOnError
57 | true
58 |
59 |
60 | org.eclipse.cdt.make.core.useDefaultBuildCmd
61 | false
62 |
63 |
64 |
65 |
66 | com.android.ide.eclipse.adt.ResourceManagerBuilder
67 |
68 |
69 |
70 |
71 | com.android.ide.eclipse.adt.PreCompilerBuilder
72 |
73 |
74 |
75 |
76 | org.eclipse.jdt.core.javabuilder
77 |
78 |
79 |
80 |
81 | com.android.ide.eclipse.adt.ApkBuilder
82 |
83 |
84 |
85 |
86 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
87 | full,incremental,
88 |
89 |
90 |
91 |
92 | org.eclipse.ui.externaltools.ExternalToolBuilder
93 | auto,full,incremental,
94 |
95 |
96 | LaunchConfigHandle
97 | <project>/.externalToolBuilders/testbuilder.launch
98 |
99 |
100 |
101 |
102 |
103 | com.android.ide.eclipse.adt.AndroidNature
104 | org.eclipse.jdt.core.javanature
105 | org.eclipse.cdt.core.cnature
106 | org.eclipse.cdt.core.ccnature
107 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
108 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
109 |
110 |
111 |
--------------------------------------------------------------------------------
/native-activity/.settings/org.eclipse.jdt.core.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
3 | org.eclipse.jdt.core.compiler.compliance=1.6
4 | org.eclipse.jdt.core.compiler.source=1.6
5 |
--------------------------------------------------------------------------------
/native-activity/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
23 |
24 |
29 |
30 |
31 |
32 |
33 |
34 |
38 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/native-activity/README.md~:
--------------------------------------------------------------------------------
1 | # FaceTrackerApp
2 |
3 | An android port of : [FaceTracker](https://github.com/kylemcdonald/FaceTracker)
4 |
5 | ## Requirements
6 |
7 | + Android phone with OS version \< 5.0.0 (OpenCV's native camera does not support greater version)
8 | + Installation of latest [OpenCV Manager](https://play.google.com/store/apps/details?id=org.opencv.engine&hl=en) app
9 |
10 |
--------------------------------------------------------------------------------
/native-activity/assets/face.con:
--------------------------------------------------------------------------------
1 | n_connections: 61
2 | {
3 | 0 1
4 | 1 2
5 | 2 3
6 | 3 4
7 | 4 5
8 | 5 6
9 | 6 7
10 | 7 8
11 | 8 9
12 | 9 10
13 | 10 11
14 | 11 12
15 | 12 13
16 | 13 14
17 | 14 15
18 | 15 16
19 | 17 18
20 | 18 19
21 | 19 20
22 | 20 21
23 | 22 23
24 | 23 24
25 | 24 25
26 | 25 26
27 | 27 28
28 | 28 29
29 | 29 30
30 | 31 32
31 | 32 33
32 | 33 34
33 | 34 35
34 | 36 37
35 | 37 38
36 | 38 39
37 | 39 40
38 | 40 41
39 | 41 36
40 | 42 43
41 | 43 44
42 | 44 45
43 | 45 46
44 | 46 47
45 | 47 42
46 | 48 49
47 | 49 50
48 | 50 51
49 | 51 52
50 | 52 53
51 | 53 54
52 | 54 55
53 | 55 56
54 | 56 57
55 | 57 58
56 | 58 59
57 | 59 48
58 | 60 65
59 | 60 61
60 | 61 62
61 | 62 63
62 | 63 64
63 | 64 65
64 | }
65 |
--------------------------------------------------------------------------------
/native-activity/assets/face.tri:
--------------------------------------------------------------------------------
1 | n_tri: 91
2 | {
3 | 20 21 23
4 | 21 22 23
5 | 0 1 36
6 | 15 16 45
7 | 0 17 36
8 | 16 26 45
9 | 17 18 37
10 | 25 26 44
11 | 17 36 37
12 | 26 44 45
13 | 18 19 38
14 | 24 25 43
15 | 18 37 38
16 | 25 43 44
17 | 19 20 38
18 | 23 24 43
19 | 20 21 39
20 | 22 23 42
21 | 20 38 39
22 | 23 42 43
23 | 21 22 27
24 | 21 27 39
25 | 22 27 42
26 | 27 28 42
27 | 27 28 39
28 | 28 42 47
29 | 28 39 40
30 | 1 36 41
31 | 15 45 46
32 | 1 2 41
33 | 14 15 46
34 | 28 29 40
35 | 28 29 47
36 | 2 40 41
37 | 14 46 47
38 | 2 29 40
39 | 14 29 47
40 | 2 3 29
41 | 13 14 29
42 | 29 30 31
43 | 29 30 35
44 | 3 29 31
45 | 13 29 35
46 | 30 32 33
47 | 30 33 34
48 | 30 31 32
49 | 30 34 35
50 | 3 4 31
51 | 12 13 35
52 | 4 5 48
53 | 11 12 54
54 | 5 6 48
55 | 10 11 54
56 | 6 48 59
57 | 10 54 55
58 | 6 7 59
59 | 9 10 55
60 | 7 58 59
61 | 9 55 56
62 | 8 57 58
63 | 8 56 57
64 | 7 8 58
65 | 8 9 56
66 | 4 31 48
67 | 12 35 54
68 | 31 48 49
69 | 35 53 54
70 | 31 49 50
71 | 35 52 53
72 | 31 32 50
73 | 34 35 52
74 | 32 33 50
75 | 33 34 52
76 | 33 50 51
77 | 33 51 52
78 | 48 49 60
79 | 49 60 50
80 | 50 60 61
81 | 50 51 61
82 | 51 52 61
83 | 61 62 52
84 | 52 53 62
85 | 53 54 62
86 | 54 55 63
87 | 55 56 63
88 | 56 63 64
89 | 56 57 64
90 | 64 65 57
91 | 57 58 65
92 | 58 59 65
93 | 48 59 65
94 | }
95 |
--------------------------------------------------------------------------------
/native-activity/bin/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
23 |
24 |
29 |
30 |
31 |
32 |
33 |
34 |
38 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/native-activity/bin/FaceTrackerJS.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ajdroid/facetrackerapp/ac0d9c8d2dd1fd64cebb2b4b6120452cfc36a38a/native-activity/bin/FaceTrackerJS.apk
--------------------------------------------------------------------------------
/native-activity/bin/R.txt:
--------------------------------------------------------------------------------
1 | int attr camera_id 0x7f010001
2 | int attr show_fps 0x7f010000
3 | int drawable icon 0x7f020000
4 | int id any 0x7f040000
5 | int id back 0x7f040001
6 | int id front 0x7f040002
7 | int string app_name 0x7f030000
8 | int[] styleable CameraBridgeViewBase { 0x7f010000, 0x7f010001 }
9 | int styleable CameraBridgeViewBase_camera_id 1
10 | int styleable CameraBridgeViewBase_show_fps 0
11 |
--------------------------------------------------------------------------------
/native-activity/bin/classes.dex:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ajdroid/facetrackerapp/ac0d9c8d2dd1fd64cebb2b4b6120452cfc36a38a/native-activity/bin/classes.dex
--------------------------------------------------------------------------------
/native-activity/bin/classes/comsc/cardiff/ajdroid/FaceTracker/BuildConfig.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ajdroid/facetrackerapp/ac0d9c8d2dd1fd64cebb2b4b6120452cfc36a38a/native-activity/bin/classes/comsc/cardiff/ajdroid/FaceTracker/BuildConfig.class
--------------------------------------------------------------------------------
/native-activity/bin/classes/comsc/cardiff/ajdroid/FaceTracker/R$attr.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ajdroid/facetrackerapp/ac0d9c8d2dd1fd64cebb2b4b6120452cfc36a38a/native-activity/bin/classes/comsc/cardiff/ajdroid/FaceTracker/R$attr.class
--------------------------------------------------------------------------------
/native-activity/bin/classes/comsc/cardiff/ajdroid/FaceTracker/R$drawable.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ajdroid/facetrackerapp/ac0d9c8d2dd1fd64cebb2b4b6120452cfc36a38a/native-activity/bin/classes/comsc/cardiff/ajdroid/FaceTracker/R$drawable.class
--------------------------------------------------------------------------------
/native-activity/bin/classes/comsc/cardiff/ajdroid/FaceTracker/R$id.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ajdroid/facetrackerapp/ac0d9c8d2dd1fd64cebb2b4b6120452cfc36a38a/native-activity/bin/classes/comsc/cardiff/ajdroid/FaceTracker/R$id.class
--------------------------------------------------------------------------------
/native-activity/bin/classes/comsc/cardiff/ajdroid/FaceTracker/R$string.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ajdroid/facetrackerapp/ac0d9c8d2dd1fd64cebb2b4b6120452cfc36a38a/native-activity/bin/classes/comsc/cardiff/ajdroid/FaceTracker/R$string.class
--------------------------------------------------------------------------------
/native-activity/bin/classes/comsc/cardiff/ajdroid/FaceTracker/R$styleable.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ajdroid/facetrackerapp/ac0d9c8d2dd1fd64cebb2b4b6120452cfc36a38a/native-activity/bin/classes/comsc/cardiff/ajdroid/FaceTracker/R$styleable.class
--------------------------------------------------------------------------------
/native-activity/bin/classes/comsc/cardiff/ajdroid/FaceTracker/R.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ajdroid/facetrackerapp/ac0d9c8d2dd1fd64cebb2b4b6120452cfc36a38a/native-activity/bin/classes/comsc/cardiff/ajdroid/FaceTracker/R.class
--------------------------------------------------------------------------------
/native-activity/bin/classes/org/opencv/R$attr.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ajdroid/facetrackerapp/ac0d9c8d2dd1fd64cebb2b4b6120452cfc36a38a/native-activity/bin/classes/org/opencv/R$attr.class
--------------------------------------------------------------------------------
/native-activity/bin/classes/org/opencv/R$id.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ajdroid/facetrackerapp/ac0d9c8d2dd1fd64cebb2b4b6120452cfc36a38a/native-activity/bin/classes/org/opencv/R$id.class
--------------------------------------------------------------------------------
/native-activity/bin/classes/org/opencv/R$styleable.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ajdroid/facetrackerapp/ac0d9c8d2dd1fd64cebb2b4b6120452cfc36a38a/native-activity/bin/classes/org/opencv/R$styleable.class
--------------------------------------------------------------------------------
/native-activity/bin/classes/org/opencv/R.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ajdroid/facetrackerapp/ac0d9c8d2dd1fd64cebb2b4b6120452cfc36a38a/native-activity/bin/classes/org/opencv/R.class
--------------------------------------------------------------------------------
/native-activity/bin/classes/org/opencv/samples/NativeActivity/CvNativeActivity$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ajdroid/facetrackerapp/ac0d9c8d2dd1fd64cebb2b4b6120452cfc36a38a/native-activity/bin/classes/org/opencv/samples/NativeActivity/CvNativeActivity$1.class
--------------------------------------------------------------------------------
/native-activity/bin/classes/org/opencv/samples/NativeActivity/CvNativeActivity.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ajdroid/facetrackerapp/ac0d9c8d2dd1fd64cebb2b4b6120452cfc36a38a/native-activity/bin/classes/org/opencv/samples/NativeActivity/CvNativeActivity.class
--------------------------------------------------------------------------------
/native-activity/bin/dexedLibs/opencv library - 2.4.8.2-94d917d6d803c7f29e6dbeaeb95cc035.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ajdroid/facetrackerapp/ac0d9c8d2dd1fd64cebb2b4b6120452cfc36a38a/native-activity/bin/dexedLibs/opencv library - 2.4.8.2-94d917d6d803c7f29e6dbeaeb95cc035.jar
--------------------------------------------------------------------------------
/native-activity/bin/res/crunch/drawable/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ajdroid/facetrackerapp/ac0d9c8d2dd1fd64cebb2b4b6120452cfc36a38a/native-activity/bin/res/crunch/drawable/icon.png
--------------------------------------------------------------------------------
/native-activity/bin/resources.ap_:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ajdroid/facetrackerapp/ac0d9c8d2dd1fd64cebb2b4b6120452cfc36a38a/native-activity/bin/resources.ap_
--------------------------------------------------------------------------------
/native-activity/gen/comsc/cardiff/ajdroid/FaceTracker/BuildConfig.java:
--------------------------------------------------------------------------------
1 | /** Automatically generated file. DO NOT MODIFY */
2 | package comsc.cardiff.ajdroid.FaceTracker;
3 |
4 | public final class BuildConfig {
5 | public final static boolean DEBUG = true;
6 | }
--------------------------------------------------------------------------------
/native-activity/gen/comsc/cardiff/ajdroid/FaceTracker/R.java:
--------------------------------------------------------------------------------
1 | /* AUTO-GENERATED FILE. DO NOT MODIFY.
2 | *
3 | * This class was automatically generated by the
4 | * aapt tool from the resource data it found. It
5 | * should not be modified by hand.
6 | */
7 |
8 | package comsc.cardiff.ajdroid.FaceTracker;
9 |
10 | public final class R {
11 | public static final class attr {
12 | /**
May be an integer value, such as "100".
13 |
This may also be a reference to a resource (in the form
14 | "@[package:]type:name") or
15 | theme attribute (in the form
16 | "?[package:][type:]name")
17 | containing a value of this type.
18 |
May be one of the following constant values.
19 |
20 |
21 |
22 |
23 |
Constant
Value
Description
24 |
any
-1
25 |
back
99
26 |
front
98
27 |
28 | */
29 | public static final int camera_id=0x7f010001;
30 | /**
Must be a boolean value, either "true" or "false".
31 |
This may also be a reference to a resource (in the form
32 | "@[package:]type:name") or
33 | theme attribute (in the form
34 | "?[package:][type:]name")
35 | containing a value of this type.
36 | */
37 | public static final int show_fps=0x7f010000;
38 | }
39 | public static final class drawable {
40 | public static final int icon=0x7f020000;
41 | }
42 | public static final class id {
43 | public static final int any=0x7f040000;
44 | public static final int back=0x7f040001;
45 | public static final int front=0x7f040002;
46 | }
47 | public static final class string {
48 | public static final int app_name=0x7f030000;
49 | }
50 | public static final class styleable {
51 | /** Attributes that can be used with a CameraBridgeViewBase.
52 |
This symbol is the offset where the {@link comsc.cardiff.ajdroid.FaceTracker.R.attr#camera_id}
68 | attribute's value can be found in the {@link #CameraBridgeViewBase} array.
69 |
70 |
71 |
May be an integer value, such as "100".
72 |
This may also be a reference to a resource (in the form
73 | "@[package:]type:name") or
74 | theme attribute (in the form
75 | "?[package:][type:]name")
76 | containing a value of this type.
77 |
May be one of the following constant values.
78 |
79 |
80 |
81 |
82 |
Constant
Value
Description
83 |
any
-1
84 |
back
99
85 |
front
98
86 |
87 | @attr name comsc.cardiff.ajdroid.FaceTracker:camera_id
88 | */
89 | public static final int CameraBridgeViewBase_camera_id = 1;
90 | /**
91 |
This symbol is the offset where the {@link comsc.cardiff.ajdroid.FaceTracker.R.attr#show_fps}
92 | attribute's value can be found in the {@link #CameraBridgeViewBase} array.
93 |
94 |
95 |
Must be a boolean value, either "true" or "false".
96 |
This may also be a reference to a resource (in the form
97 | "@[package:]type:name") or
98 | theme attribute (in the form
99 | "?[package:][type:]name")
100 | containing a value of this type.
101 | @attr name comsc.cardiff.ajdroid.FaceTracker:show_fps
102 | */
103 | public static final int CameraBridgeViewBase_show_fps = 0;
104 | };
105 | }
106 |
--------------------------------------------------------------------------------
/native-activity/gen/org/opencv/R.java:
--------------------------------------------------------------------------------
1 | /* AUTO-GENERATED FILE. DO NOT MODIFY.
2 | *
3 | * This class was automatically generated by the
4 | * aapt tool from the resource data it found. It
5 | * should not be modified by hand.
6 | */
7 | package org.opencv;
8 |
9 | public final class R {
10 | public static final class attr {
11 | public static final int camera_id = 0x7f010001;
12 | public static final int show_fps = 0x7f010000;
13 | }
14 | public static final class id {
15 | public static final int any = 0x7f040000;
16 | public static final int back = 0x7f040001;
17 | public static final int front = 0x7f040002;
18 | }
19 | public static final class styleable {
20 | public static final int[] CameraBridgeViewBase = { 0x7f010000, 0x7f010001 };
21 | public static final int CameraBridgeViewBase_camera_id = 1;
22 | public static final int CameraBridgeViewBase_show_fps = 0;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/native-activity/jni/Android.mk:
--------------------------------------------------------------------------------
1 |
2 | LOCAL_PATH := $(call my-dir)
3 | MY_PATH := $(LOCAL_PATH)
4 |
5 | ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
6 |
7 | include $(CLEAR_VARS)
8 | LOCAL_MODULE := FaceTracker
9 | LOCAL_SRC_FILES := libFaceTracker.a #$(wildcard /FaceTracker/lib/*.cc)
10 | #LOCAL_C_INCLUDES := $(LOCAL_PATH)/FaceTracker
11 | LOCAL_LDLIBS = -lz -lm
12 | LOCAL_CFLAGS = -Wall -pedantic -g -O3 -ffast-math -funroll-loops -march=armv7-a -mfloat-abi=softfp -mfpu=neon
13 | include $(PREBUILT_STATIC_LIBRARY)
14 |
15 | include $(CLEAR_VARS)
16 |
17 | OPENCV_INSTALL_MODULES:=on
18 | OPENCV_CAMERA_MODULES:=on
19 |
20 |
21 | include ../../sdk/native/jni/OpenCV.mk
22 |
23 | LOCAL_MODULE := native_activity
24 | LOCAL_SRC_FILES := native.cpp
25 | LOCAL_C_FLAGS+= -DNDEBUG -Wall -pedantic -g -O3 -ffast-math -funroll-loops -march=armv7-a -mfloat-abi=softfp -mfpu=neon
26 | #LOCAL_C_INCLUDES+= $(NDK_APP_PROJECT_PATH)/stasm4.1.0/stasm
27 | #LOCAL_SRC_FILES += $(NDK_APP_PROJECT_PATH)/libstasm.a
28 | #LOCAL_SRC_FILES += $(wildcard $(NDK_APP_PROJECT_PATH)/stasm/*.cpp)
29 | LOCAL_LDLIBS += -lm -llog -landroid
30 | #LOCAL_SHARED_LIBRARIES += libandroid
31 | LOCAL_STATIC_LIBRARIES += android_native_app_glue
32 | LOCAL_STATIC_LIBRARIES += FaceTracker
33 | LOCAL_ARM_NEON := true
34 | LOCAL_ARM_MODE := arm
35 | include $(BUILD_SHARED_LIBRARY)
36 | $(call import-module,android/native_app_glue)
37 | endif
38 |
39 |
40 |
--------------------------------------------------------------------------------
/native-activity/jni/Application.mk:
--------------------------------------------------------------------------------
1 | APP_PLATFORM := android-17
2 | APP_ABI := armeabi-v7a
3 | APP_STL := gnustl_static
4 | APP_CPPFLAGS := -frtti -fexceptions -std=c++11
5 | APP_OPTIM := release
6 |
--------------------------------------------------------------------------------
/native-activity/jni/FaceTracker/CLM.h:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | // Copyright (C) 2010, Jason Mora Saragih, all rights reserved.
3 | //
4 | // This file is part of FaceTracker.
5 | //
6 | // Redistribution and use in source and binary forms, with or without
7 | // modification, are permitted provided that the following conditions are met:
8 | //
9 | // * The software is provided under the terms of this licence stricly for
10 | // academic, non-commercial, not-for-profit purposes.
11 | // * Redistributions of source code must retain the above copyright notice,
12 | // this list of conditions (licence) and the following disclaimer.
13 | // * Redistributions in binary form must reproduce the above copyright
14 | // notice, this list of conditions (licence) and the following disclaimer
15 | // in the documentation and/or other materials provided with the
16 | // distribution.
17 | // * The name of the author may not be used to endorse or promote products
18 | // derived from this software without specific prior written permission.
19 | // * As this software depends on other libraries, the user must adhere to
20 | // and keep in place any licencing terms of those libraries.
21 | // * Any publications arising from the use of this software, including but
22 | // not limited to academic journal and conference publications, technical
23 | // reports and manuals, must cite the following work:
24 | //
25 | // J. M. Saragih, S. Lucey, and J. F. Cohn. Face Alignment through
26 | // Subspace Constrained Mean-Shifts. International Conference of Computer
27 | // Vision (ICCV), September, 2009.
28 | //
29 | // THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
30 | // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
32 | // EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
36 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
38 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 | ///////////////////////////////////////////////////////////////////////////////
40 | #ifndef __CLM_h_
41 | #define __CLM_h_
42 | #include
43 | #include
44 | #include
45 | namespace FACETRACKER
46 | {
47 | //===========================================================================
48 | /**
49 | A Constrained Local Model
50 | */
51 | class CLM{
52 | public:
53 | PDM _pdm; /**< 3D Shape model */
54 | cv::Mat _plocal;/**< local parameters */
55 | cv::Mat _pglobl;/**< global parameters */
56 | cv::Mat _refs; /**< Reference shape */
57 | std::vector _cent; /**< Centers/view (Euler) */
58 | std::vector _visi; /**< Visibility for each view */
59 | std::vector > _patch; /**< Patches/point/view */
60 |
61 | CLM(){;}
62 | CLM(const char* fname){this->Load(fname);}
63 | CLM(PDM &s,cv::Mat &r, std::vector &c,
64 | std::vector &v,std::vector > &p){
65 | this->Init(s,r,c,v,p);
66 | }
67 | CLM& operator=(CLM const&rhs);
68 | inline int nViews(){return _patch.size();}
69 | int GetViewIdx();
70 | void Load(const char* fname);
71 | void Save(const char* fname);
72 | void Write(std::ofstream &s);
73 | void Read(std::ifstream &s,bool readType = true);
74 | void Init(PDM &s,cv::Mat &r, std::vector &c,
75 | std::vector &v,std::vector > &p);
76 | void Fit(cv::Mat im, std::vector &wSize,
77 | int nIter = 10,double clamp = 3.0,double fTol = 0.0);
78 | private:
79 | cv::Mat cshape_,bshape_,oshape_,ms_,u_,g_,J_,H_;
80 | std::vector prob_,pmem_,wmem_;
81 | void Optimize(int idx,int wSize,int nIter,
82 | double fTol,double clamp,bool rigid);
83 | };
84 | //===========================================================================
85 | }
86 | #endif
87 |
--------------------------------------------------------------------------------
/native-activity/jni/FaceTracker/FCheck.h:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | // Copyright (C) 2010, Jason Mora Saragih, all rights reserved.
3 | //
4 | // This file is part of FaceTracker.
5 | //
6 | // Redistribution and use in source and binary forms, with or without
7 | // modification, are permitted provided that the following conditions are met:
8 | //
9 | // * The software is provided under the terms of this licence stricly for
10 | // academic, non-commercial, not-for-profit purposes.
11 | // * Redistributions of source code must retain the above copyright notice,
12 | // this list of conditions (licence) and the following disclaimer.
13 | // * Redistributions in binary form must reproduce the above copyright
14 | // notice, this list of conditions (licence) and the following disclaimer
15 | // in the documentation and/or other materials provided with the
16 | // distribution.
17 | // * The name of the author may not be used to endorse or promote products
18 | // derived from this software without specific prior written permission.
19 | // * As this software depends on other libraries, the user must adhere to
20 | // and keep in place any licencing terms of those libraries.
21 | // * Any publications arising from the use of this software, including but
22 | // not limited to academic journal and conference publications, technical
23 | // reports and manuals, must cite the following work:
24 | //
25 | // J. M. Saragih, S. Lucey, and J. F. Cohn. Face Alignment through
26 | // Subspace Constrained Mean-Shifts. International Conference of Computer
27 | // Vision (ICCV), September, 2009.
28 | //
29 | // THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
30 | // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
32 | // EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
36 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
38 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 | ///////////////////////////////////////////////////////////////////////////////
40 | #ifndef __FCheck_h_
41 | #define __FCheck_h_
42 | #include
43 | #include
44 | namespace FACETRACKER
45 | {
46 | //===========================================================================
47 | /**
48 | Checks for Tracking Failure
49 | */
50 | class FCheck{
51 | public:
52 | PAW _paw; /**< Piecewise affine warp */
53 | double _b; /**< SVM bias */
54 | cv::Mat _w; /**< SVM gain */
55 |
56 | FCheck(){;}
57 | FCheck(const char* fname){this->Load(fname);}
58 | FCheck(double b, cv::Mat &w, PAW &paw){this->Init(b,w,paw);}
59 | FCheck& operator=(FCheck const&rhs);
60 | void Init(double b, cv::Mat &w, PAW &paw);
61 | void Load(const char* fname);
62 | void Save(const char* fname);
63 | void Write(std::ofstream &s);
64 | void Read(std::ifstream &s,bool readType = true);
65 | bool Check(cv::Mat &im,cv::Mat &s);
66 |
67 | private:
68 | cv::Mat crop_,vec_;
69 | };
70 | //===========================================================================
71 | /**
72 | Checks for Multiview Tracking Failure
73 | */
74 | class MFCheck{
75 | public:
76 | std::vector _fcheck; /**< FCheck for each view */
77 |
78 | MFCheck(){;}
79 | MFCheck(const char* fname){this->Load(fname);}
80 | MFCheck(std::vector &fcheck){this->Init(fcheck);}
81 | MFCheck& operator=(MFCheck const&rhs){
82 | this->_fcheck = rhs._fcheck; return *this;
83 | }
84 | void Init(std::vector &fcheck){_fcheck = fcheck;}
85 | void Load(const char* fname);
86 | void Save(const char* fname);
87 | void Write(std::ofstream &s);
88 | void Read(std::ifstream &s,bool readType = true);
89 | bool Check(int idx,cv::Mat &im,cv::Mat &s);
90 | };
91 | //===========================================================================
92 | }
93 | #endif
94 |
--------------------------------------------------------------------------------
/native-activity/jni/FaceTracker/FDet.h:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | // Copyright (C) 2010, Jason Mora Saragih, all rights reserved.
3 | //
4 | // This file is part of FaceTracker.
5 | //
6 | // Redistribution and use in source and binary forms, with or without
7 | // modification, are permitted provided that the following conditions are met:
8 | //
9 | // * The software is provided under the terms of this licence stricly for
10 | // academic, non-commercial, not-for-profit purposes.
11 | // * Redistributions of source code must retain the above copyright notice,
12 | // this list of conditions (licence) and the following disclaimer.
13 | // * Redistributions in binary form must reproduce the above copyright
14 | // notice, this list of conditions (licence) and the following disclaimer
15 | // in the documentation and/or other materials provided with the
16 | // distribution.
17 | // * The name of the author may not be used to endorse or promote products
18 | // derived from this software without specific prior written permission.
19 | // * As this software depends on other libraries, the user must adhere to
20 | // and keep in place any licencing terms of those libraries.
21 | // * Any publications arising from the use of this software, including but
22 | // not limited to academic journal and conference publications, technical
23 | // reports and manuals, must cite the following work:
24 | //
25 | // J. M. Saragih, S. Lucey, and J. F. Cohn. Face Alignment through
26 | // Subspace Constrained Mean-Shifts. International Conference of Computer
27 | // Vision (ICCV), September, 2009.
28 | //
29 | // THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
30 | // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
32 | // EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
36 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
38 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 | ///////////////////////////////////////////////////////////////////////////////
40 | #ifndef __FDet_h_
41 | #define __FDet_h_
42 | #include
43 | namespace FACETRACKER
44 | {
45 | //===========================================================================
46 | /**
47 | A wrapper for OpenCV's face detector
48 | */
49 | class FDet{
50 | public:
51 | int _min_neighbours; /**< see OpenCV documentation */
52 | int _min_size; /**< ... */
53 | double _img_scale; /**< ... */
54 | double _scale_factor; /**< ... */
55 | CvHaarClassifierCascade* _cascade; /**< ... */
56 |
57 | FDet(){storage_=NULL;_cascade=NULL;}
58 | FDet(const char* fname){this->Load(fname);}
59 | FDet(const char* cascFile,
60 | const double img_scale = 1.3,
61 | const double scale_factor = 1.1,
62 | const int min_neighbours = 2,
63 | const int min_size = 30){
64 | this->Init(cascFile,img_scale,scale_factor,min_neighbours,min_size);
65 | }
66 | ~FDet();
67 | FDet& operator=(FDet const&rhs);
68 | void Init(const char* fname,
69 | const double img_scale = 1.3,
70 | const double scale_factor = 1.1,
71 | const int min_neighbours = 2,
72 | const int min_size = 30);
73 | cv::Rect Detect(cv::Mat im);
74 | void Load(const char* fname);
75 | void Save(const char* fname);
76 | void Write(std::ofstream &s);
77 | void Read(std::ifstream &s,bool readType = true);
78 |
79 | private:
80 | cv::Mat small_img_; CvMemStorage* storage_;
81 | };
82 | //===========================================================================
83 | }
84 | #endif
85 |
--------------------------------------------------------------------------------
/native-activity/jni/FaceTracker/IO.h:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | // Copyright (C) 2010, Jason Mora Saragih, all rights reserved.
3 | //
4 | // This file is part of FaceTracker.
5 | //
6 | // Redistribution and use in source and binary forms, with or without
7 | // modification, are permitted provided that the following conditions are met:
8 | //
9 | // * The software is provided under the terms of this licence stricly for
10 | // academic, non-commercial, not-for-profit purposes.
11 | // * Redistributions of source code must retain the above copyright notice,
12 | // this list of conditions (licence) and the following disclaimer.
13 | // * Redistributions in binary form must reproduce the above copyright
14 | // notice, this list of conditions (licence) and the following disclaimer
15 | // in the documentation and/or other materials provided with the
16 | // distribution.
17 | // * The name of the author may not be used to endorse or promote products
18 | // derived from this software without specific prior written permission.
19 | // * As this software depends on other libraries, the user must adhere to
20 | // and keep in place any licencing terms of those libraries.
21 | // * Any publications arising from the use of this software, including but
22 | // not limited to academic journal and conference publications, technical
23 | // reports and manuals, must cite the following work:
24 | //
25 | // J. M. Saragih, S. Lucey, and J. F. Cohn. Face Alignment through
26 | // Subspace Constrained Mean-Shifts. International Conference of Computer
27 | // Vision (ICCV), September, 2009.
28 | //
29 | // THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
30 | // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
32 | // EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
36 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
38 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 | ///////////////////////////////////////////////////////////////////////////////
40 | #ifndef __IO_h_
41 | #define __IO_h_
42 | #include
43 | #include
44 | namespace FACETRACKER
45 | {
46 | //===========================================================================
47 | /**
48 | Input-output Operations
49 | */
50 | class IO{
51 | public:
52 | enum{PDM = 0,PAW,PATCH,MPATCH,CLM,FDET,FCHECK,MFCHECK,TRACKER};
53 | static void ReadMat(std::ifstream& s,cv::Mat &M);
54 | static void WriteMat(std::ofstream& s,cv::Mat &M);
55 | static cv::Mat LoadCon(const char* fname);
56 | static cv::Mat LoadTri(const char* fname);
57 | };
58 | //===========================================================================
59 | }
60 | #endif
61 |
--------------------------------------------------------------------------------
/native-activity/jni/FaceTracker/PAW.h:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | // Copyright (C) 2010, Jason Mora Saragih, all rights reserved.
3 | //
4 | // This file is part of FaceTracker.
5 | //
6 | // Redistribution and use in source and binary forms, with or without
7 | // modification, are permitted provided that the following conditions are met:
8 | //
9 | // * The software is provided under the terms of this licence stricly for
10 | // academic, non-commercial, not-for-profit purposes.
11 | // * Redistributions of source code must retain the above copyright notice,
12 | // this list of conditions (licence) and the following disclaimer.
13 | // * Redistributions in binary form must reproduce the above copyright
14 | // notice, this list of conditions (licence) and the following disclaimer
15 | // in the documentation and/or other materials provided with the
16 | // distribution.
17 | // * The name of the author may not be used to endorse or promote products
18 | // derived from this software without specific prior written permission.
19 | // * As this software depends on other libraries, the user must adhere to
20 | // and keep in place any licencing terms of those libraries.
21 | // * Any publications arising from the use of this software, including but
22 | // not limited to academic journal and conference publications, technical
23 | // reports and manuals, must cite the following work:
24 | //
25 | // J. M. Saragih, S. Lucey, and J. F. Cohn. Face Alignment through
26 | // Subspace Constrained Mean-Shifts. International Conference of Computer
27 | // Vision (ICCV), September, 2009.
28 | //
29 | // THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
30 | // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
32 | // EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
36 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
38 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 | ///////////////////////////////////////////////////////////////////////////////
40 | #ifndef __PAW_h_
41 | #define __PAW_h_
42 | #include
43 | namespace FACETRACKER
44 | {
45 | //===========================================================================
46 | /**
47 | A Piecewise Affine Warp
48 | */
49 | class PAW{
50 | public:
51 | int _nPix; /**< Number of pixels */
52 | double _xmin; /**< Minimum x-coord for src */
53 | double _ymin; /**< Minimum y-coord for src */
54 | cv::Mat _src; /**< Source points */
55 | cv::Mat _dst; /**< destination points */
56 | cv::Mat _tri; /**< Triangulation */
57 | cv::Mat _tridx; /**< Triangle for each valid pixel */
58 | cv::Mat _mask; /**< Valid region mask */
59 | cv::Mat _coeff; /**< affine coeffs for all triangles */
60 | cv::Mat _alpha; /**< matrix of (c,x,y) coeffs for alpha */
61 | cv::Mat _beta; /**< matrix of (c,x,y) coeffs for alpha */
62 | cv::Mat _mapx; /**< x-destination of warped points */
63 | cv::Mat _mapy; /**< y-destination of warped points */
64 |
65 | PAW(){;}
66 | PAW(const char* fname){this->Load(fname);}
67 | PAW(cv::Mat &src,cv::Mat &tri){this->Init(src,tri);}
68 | PAW& operator=(PAW const&rhs);
69 | inline int nPoints(){return _src.rows/2;}
70 | inline int nTri(){return _tri.rows;}
71 | inline int Width(){return _mask.cols;}
72 | inline int Height(){return _mask.rows;}
73 | void Load(const char* fname);
74 | void Save(const char* fname);
75 | void Write(std::ofstream &s);
76 | void Read(std::ifstream &s,bool readType = true);
77 | void Init(cv::Mat &src,cv::Mat &tri);
78 | void Crop(cv::Mat &src, cv::Mat &dst,cv::Mat &s);
79 |
80 | private:
81 | void CalcCoeff();
82 | void WarpRegion(cv::Mat &mapx,cv::Mat &mapy);
83 | };
84 | //===========================================================================
85 | }
86 | #endif
87 |
--------------------------------------------------------------------------------
/native-activity/jni/FaceTracker/PDM.h:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | // Copyright (C) 2010, Jason Mora Saragih, all rights reserved.
3 | //
4 | // This file is part of FaceTracker.
5 | //
6 | // Redistribution and use in source and binary forms, with or without
7 | // modification, are permitted provided that the following conditions are met:
8 | //
9 | // * The software is provided under the terms of this licence stricly for
10 | // academic, non-commercial, not-for-profit purposes.
11 | // * Redistributions of source code must retain the above copyright notice,
12 | // this list of conditions (licence) and the following disclaimer.
13 | // * Redistributions in binary form must reproduce the above copyright
14 | // notice, this list of conditions (licence) and the following disclaimer
15 | // in the documentation and/or other materials provided with the
16 | // distribution.
17 | // * The name of the author may not be used to endorse or promote products
18 | // derived from this software without specific prior written permission.
19 | // * As this software depends on other libraries, the user must adhere to
20 | // and keep in place any licencing terms of those libraries.
21 | // * Any publications arising from the use of this software, including but
22 | // not limited to academic journal and conference publications, technical
23 | // reports and manuals, must cite the following work:
24 | //
25 | // J. M. Saragih, S. Lucey, and J. F. Cohn. Face Alignment through
26 | // Subspace Constrained Mean-Shifts. International Conference of Computer
27 | // Vision (ICCV), September, 2009.
28 | //
29 | // THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
30 | // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
32 | // EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
36 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
38 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 | ///////////////////////////////////////////////////////////////////////////////
40 | #ifndef __PDM_h_
41 | #define __PDM_h_
42 | #include
43 | namespace FACETRACKER
44 | {
45 | //===========================================================================
46 | /**
47 | A 3D Point Distribution Model
48 | */
49 | class PDM{
50 | public:
51 | cv::Mat _V; /**< basis of variation */
52 | cv::Mat _E; /**< vector of eigenvalues (row vector) */
53 | cv::Mat _M; /**< mean 3D shape vector [x1,..,xn,y1,...yn] */
54 |
55 | PDM(){;}
56 | PDM(const char* fname){this->Load(fname);}
57 | PDM(cv::Mat &M,cv::Mat &V,cv::Mat &E){this->Init(M,V,E);}
58 | PDM& operator=(PDM const&rhs);
59 | inline int nPoints(){return _M.rows/3;}
60 | inline int nModes(){return _V.cols;}
61 | inline double Var(int i){assert(i<_E.cols); return _E.at(0,i);}
62 | void Load(const char* fname);
63 | void Save(const char* fname);
64 | void Write(std::ofstream &s);
65 | void Read(std::ifstream &s,bool readType = true);
66 | void Clamp(cv::Mat &p,double c);
67 | void Init(cv::Mat &M,cv::Mat &V,cv::Mat &E);
68 | void Identity(cv::Mat &plocal,cv::Mat &pglobl);
69 | void CalcShape3D(cv::Mat &s,cv::Mat &plocal);
70 | void CalcShape2D(cv::Mat &s,cv::Mat &plocal,cv::Mat &pglobl);
71 | void CalcParams(cv::Mat &s,cv::Mat &plocal,cv::Mat &pglobl);
72 | void CalcRigidJacob(cv::Mat &plocal,cv::Mat &pglobl,cv::Mat &Jacob);
73 | void CalcJacob(cv::Mat &plocal,cv::Mat &pglobl,cv::Mat &Jacob);
74 | void CalcReferenceUpdate(cv::Mat &dp,cv::Mat &plocal,cv::Mat &pglobl);
75 | void ApplySimT(double a,double b,double tx,double ty,cv::Mat &pglobl);
76 |
77 | private:
78 | cv::Mat S_,R_,s_,P_,Px_,Py_,Pz_,R1_,R2_,R3_;
79 | };
80 | //===========================================================================
81 | }
82 | #endif
83 |
--------------------------------------------------------------------------------
/native-activity/jni/FaceTracker/Patch.h:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | // Copyright (C) 2010, Jason Mora Saragih, all rights reserved.
3 | //
4 | // This file is part of FaceTracker.
5 | //
6 | // Redistribution and use in source and binary forms, with or without
7 | // modification, are permitted provided that the following conditions are met:
8 | //
9 | // * The software is provided under the terms of this licence stricly for
10 | // academic, non-commercial, not-for-profit purposes.
11 | // * Redistributions of source code must retain the above copyright notice,
12 | // this list of conditions (licence) and the following disclaimer.
13 | // * Redistributions in binary form must reproduce the above copyright
14 | // notice, this list of conditions (licence) and the following disclaimer
15 | // in the documentation and/or other materials provided with the
16 | // distribution.
17 | // * The name of the author may not be used to endorse or promote products
18 | // derived from this software without specific prior written permission.
19 | // * As this software depends on other libraries, the user must adhere to
20 | // and keep in place any licencing terms of those libraries.
21 | // * Any publications arising from the use of this software, including but
22 | // not limited to academic journal and conference publications, technical
23 | // reports and manuals, must cite the following work:
24 | //
25 | // J. M. Saragih, S. Lucey, and J. F. Cohn. Face Alignment through
26 | // Subspace Constrained Mean-Shifts. International Conference of Computer
27 | // Vision (ICCV), September, 2009.
28 | //
29 | // THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
30 | // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
32 | // EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
36 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
38 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 | ///////////////////////////////////////////////////////////////////////////////
40 | #ifndef __Patch_h_
41 | #define __Patch_h_
42 | #include
43 | namespace FACETRACKER
44 | {
45 | //===========================================================================
46 | /**
47 | A Patch Expert
48 | */
49 | class Patch{
50 | public:
51 | int _t; /**< Type of patch (0=raw,1=grad,2=lbp) */
52 | double _a; /**< scaling */
53 | double _b; /**< bias */
54 | cv::Mat _W; /**< Gain */
55 |
56 | Patch(){;}
57 | Patch(const char* fname){this->Load(fname);}
58 | Patch(int t,double a,double b,cv::Mat &W){this->Init(t,a,b,W);}
59 | Patch& operator=(Patch const&rhs);
60 | inline int w(){return _W.cols;}
61 | inline int h(){return _W.rows;}
62 | void Load(const char* fname);
63 | void Save(const char* fname);
64 | void Write(std::ofstream &s);
65 | void Read(std::ifstream &s,bool readType = true);
66 | void Init(int t, double a, double b, cv::Mat &W);
67 | void Response(cv::Mat &im,cv::Mat &resp);
68 |
69 | private:
70 | cv::Mat im_,res_;
71 | };
72 | //===========================================================================
73 | /**
74 | A Multi-patch Expert
75 | */
76 | class MPatch{
77 | public:
78 | int _w,_h; /**< Width and height of patch */
79 | std::vector _p; /**< List of patches */
80 |
81 | MPatch(){;}
82 | MPatch(const char* fname){this->Load(fname);}
83 | MPatch(std::vector &p){this->Init(p);}
84 | MPatch& operator=(MPatch const&rhs);
85 | inline int nPatch(){return _p.size();}
86 | void Load(const char* fname);
87 | void Save(const char* fname);
88 | void Write(std::ofstream &s);
89 | void Read(std::ifstream &s,bool readType = true);
90 | void Init(std::vector &p);
91 | void Response(cv::Mat &im,cv::Mat &resp);
92 |
93 | private:
94 | cv::Mat res_;
95 | };
96 | //===========================================================================
97 | }
98 | #endif
99 |
--------------------------------------------------------------------------------
/native-activity/jni/FaceTracker/Tracker.h:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | // Copyright (C) 2010, Jason Mora Saragih, all rights reserved.
3 | //
4 | // This file is part of FaceTracker.
5 | //
6 | // Redistribution and use in source and binary forms, with or without
7 | // modification, are permitted provided that the following conditions are met:
8 | //
9 | // * The software is provided under the terms of this licence stricly for
10 | // academic, non-commercial, not-for-profit purposes.
11 | // * Redistributions of source code must retain the above copyright notice,
12 | // this list of conditions (licence) and the following disclaimer.
13 | // * Redistributions in binary form must reproduce the above copyright
14 | // notice, this list of conditions (licence) and the following disclaimer
15 | // in the documentation and/or other materials provided with the
16 | // distribution.
17 | // * The name of the author may not be used to endorse or promote products
18 | // derived from this software without specific prior written permission.
19 | // * As this software depends on other libraries, the user must adhere to
20 | // and keep in place any licencing terms of those libraries.
21 | // * Any publications arising from the use of this software, including but
22 | // not limited to academic journal and conference publications, technical
23 | // reports and manuals, must cite the following work:
24 | //
25 | // J. M. Saragih, S. Lucey, and J. F. Cohn. Face Alignment through
26 | // Subspace Constrained Mean-Shifts. International Conference of Computer
27 | // Vision (ICCV), September, 2009.
28 | //
29 | // THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
30 | // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
32 | // EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
36 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
38 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 | ///////////////////////////////////////////////////////////////////////////////
40 | #ifndef __Tracker_h_
41 | #define __Tracker_h_
42 | #include
43 | #include
44 | #include
45 | namespace FACETRACKER
46 | {
47 | //===========================================================================
48 | /**
49 | Face Tracker
50 | */
51 | class Tracker{
52 | public:
53 | CLM _clm; /**< Constrained Local Model */
54 | FDet _fdet; /**< Face Detector */
55 | int64 _frame; /**< Frame number since last detection */
56 | MFCheck _fcheck; /**< Failure checker */
57 | cv::Mat _shape; /**< Current shape */
58 | cv::Mat _rshape; /**< Reference shape */
59 | cv::Rect _rect; /**< Detected rectangle */
60 | cv::Scalar _simil; /**< Initialization similarity */
61 |
62 | /** NULL constructor */
63 | Tracker(){;}
64 |
65 | /** Constructor from model file */
66 | Tracker(const char* fname){this->Load(fname);}
67 |
68 | /** Constructor from components */
69 | Tracker(CLM &clm,FDet &fdet,MFCheck &fcheck,
70 | cv::Mat &rshape,cv::Scalar &simil){
71 | this->Init(clm,fdet,fcheck,rshape,simil);
72 | }
73 | /**
74 | Track model in current frame
75 | @param im Image containing face
76 | @param wSize List of search window sizes (set from large to small)
77 | @param fpd Number of frames between detections (-1: never)
78 | @param nIter Maximum number of optimization steps to perform.
79 | @param clamp Shape model parameter clamping factor (in standard dev's)
80 | @param fTol Convergence tolerance of optimization
81 | @param fcheck Check if tracking succeeded?
82 | @return -1 on failure, 0 otherwise.
83 | */
84 | int Track(cv::Mat im,std::vector &wSize,
85 | const int fpd =-1,
86 | const int nIter = 10,
87 | const double clamp = 3.0,
88 | const double fTol = 0.01,
89 | const bool fcheck = true);
90 |
91 | /** Reset frame number (will perform detection in next image) */
92 | inline void FrameReset(){_frame = -1;}
93 |
94 | /** Load tracker from model file */
95 | void Load(const char* fname);
96 |
97 | /** Save tracker to model file */
98 | void Save(const char* fname);
99 |
100 | /** Write tracker to file stream */
101 | void Write(std::ofstream &s);
102 |
103 | /** Read tracking from file stream */
104 | void Read(std::ifstream &s,bool readType = true);
105 |
106 | private:
107 | cv::Mat gray_,temp_,ncc_,small_;
108 | void Init(CLM &clm,FDet &fdet,MFCheck &fcheck,
109 | cv::Mat &rshape,cv::Scalar &simil);
110 | void InitShape(cv::Rect &r,cv::Mat &shape);
111 | cv::Rect ReDetect(cv::Mat &im);
112 | cv::Rect UpdateTemplate(cv::Mat &im,cv::Mat &s,bool rsize);
113 | };
114 | //===========================================================================
115 | }
116 | #endif
117 |
--------------------------------------------------------------------------------
/native-activity/jni/FaceTracker/lib/CLM.cpp:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | // Copyright (C) 2010, Jason Mora Saragih, all rights reserved.
3 | //
4 | // This file is part of FaceTracker.
5 | //
6 | // Redistribution and use in source and binary forms, with or without
7 | // modification, are permitted provided that the following conditions are met:
8 | //
9 | // * The software is provided under the terms of this licence stricly for
10 | // academic, non-commercial, not-for-profit purposes.
11 | // * Redistributions of source code must retain the above copyright notice,
12 | // this list of conditions (licence) and the following disclaimer.
13 | // * Redistributions in binary form must reproduce the above copyright
14 | // notice, this list of conditions (licence) and the following disclaimer
15 | // in the documentation and/or other materials provided with the
16 | // distribution.
17 | // * The name of the author may not be used to endorse or promote products
18 | // derived from this software without specific prior written permission.
19 | // * As this software depends on other libraries, the user must adhere to
20 | // and keep in place any licencing terms of those libraries.
21 | // * Any publications arising from the use of this software, including but
22 | // not limited to academic journal and conference publications, technical
23 | // reports and manuals, must cite the following work:
24 | //
25 | // J. M. Saragih, S. Lucey, and J. F. Cohn. Face Alignment through
26 | // Subspace Constrained Mean-Shifts. International Conference of Computer
27 | // Vision (ICCV), September, 2009.
28 | //
29 | // THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
30 | // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
32 | // EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
36 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
38 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 | ///////////////////////////////////////////////////////////////////////////////
40 | #include
41 | #define it at
42 | #define db at
43 | #define SQR(x) x*x
44 | using namespace FACETRACKER;
45 | using namespace std;
46 | //=============================================================================
47 | void CalcSimT(cv::Mat &src,cv::Mat &dst,
48 | double &a,double &b,double &tx,double &ty)
49 | {
50 | assert((src.type() == CV_64F) && (dst.type() == CV_64F) &&
51 | (src.rows == dst.rows) && (src.cols == dst.cols) && (src.cols == 1));
52 | int i,n = src.rows/2;
53 | cv::Mat H(4,4,CV_64F,cv::Scalar(0));
54 | cv::Mat g(4,1,CV_64F,cv::Scalar(0));
55 | cv::Mat p(4,1,CV_64F);
56 | cv::MatIterator_ ptr1x = src.begin();
57 | cv::MatIterator_ ptr1y = src.begin()+n;
58 | cv::MatIterator_ ptr2x = dst.begin();
59 | cv::MatIterator_ ptr2y = dst.begin()+n;
60 | for(i = 0; i < n; i++,++ptr1x,++ptr1y,++ptr2x,++ptr2y){
61 | H.db(0,0) += SQR(*ptr1x) + SQR(*ptr1y);
62 | H.db(0,2) += *ptr1x; H.db(0,3) += *ptr1y;
63 | g.db(0,0) += (*ptr1x)*(*ptr2x) + (*ptr1y)*(*ptr2y);
64 | g.db(1,0) += (*ptr1x)*(*ptr2y) - (*ptr1y)*(*ptr2x);
65 | g.db(2,0) += *ptr2x; g.db(3,0) += *ptr2y;
66 | }
67 | H.db(1,1) = H.db(0,0); H.db(1,2) = H.db(2,1) = -1.0*(H.db(3,0) = H.db(0,3));
68 | H.db(1,3) = H.db(3,1) = H.db(2,0) = H.db(0,2); H.db(2,2) = H.db(3,3) = n;
69 | cv::solve(H,g,p,CV_CHOLESKY);
70 | a = p.db(0,0); b = p.db(1,0); tx = p.db(2,0); ty = p.db(3,0); return;
71 | }
72 | //=============================================================================
73 | void invSimT(double a1,double b1,double tx1,double ty1,
74 | double& a2,double& b2,double& tx2,double& ty2)
75 | {
76 | cv::Mat M = (cv::Mat_(2,2) << a1, -b1, b1, a1);
77 | cv::Mat N = M.inv(CV_SVD); a2 = N.db(0,0); b2 = N.db(1,0);
78 | tx2 = -1.0*(N.db(0,0)*tx1 + N.db(0,1)*ty1);
79 | ty2 = -1.0*(N.db(1,0)*tx1 + N.db(1,1)*ty1); return;
80 | }
81 | //=============================================================================
82 | void SimT(cv::Mat &s,double a,double b,double tx,double ty)
83 | {
84 | assert((s.type() == CV_64F) && (s.cols == 1));
85 | int i,n = s.rows/2; double x,y;
86 | cv::MatIterator_ xp = s.begin(),yp = s.begin()+n;
87 | for(i = 0; i < n; i++,++xp,++yp){
88 | x = *xp; y = *yp; *xp = a*x - b*y + tx; *yp = b*x + a*y + ty;
89 | }return;
90 | }
91 | //=============================================================================
92 | //=============================================================================
93 | //=============================================================================
94 | //=============================================================================
95 | //=============================================================================
96 | //=============================================================================
97 | //=============================================================================
98 | CLM& CLM::operator= (CLM const& rhs)
99 | {
100 | this->_pdm = rhs._pdm;
101 | this->_plocal = rhs._plocal.clone();
102 | this->_pglobl = rhs._pglobl.clone();
103 | this->_refs = rhs._refs.clone();
104 | this->_cent.resize(rhs._cent.size());
105 | this->_visi.resize(rhs._visi.size());
106 | this->_patch.resize(rhs._patch.size());
107 | for(int i = 0; i < (int)rhs._cent.size(); i++){
108 | this->_cent[i] = rhs._cent[i].clone();
109 | this->_visi[i] = rhs._visi[i].clone();
110 | this->_patch[i].resize(rhs._patch[i].size());
111 | for(int j = 0; j < (int)rhs._patch[i].size(); j++)
112 | this->_patch[i][j] = rhs._patch[i][j];
113 | }
114 | this->cshape_ = rhs.cshape_.clone();
115 | this->bshape_ = rhs.bshape_.clone();
116 | this->oshape_ = rhs.oshape_.clone();
117 | this->ms_ = rhs.cshape_.clone();
118 | this->u_ = rhs.u_.clone();
119 | this->g_ = rhs.g_.clone();
120 | this->J_ = rhs.J_.clone();
121 | this->H_ = rhs.H_.clone();
122 | this->prob_.resize(rhs.prob_.size());
123 | this->pmem_.resize(rhs.pmem_.size());
124 | this->wmem_.resize(rhs.pmem_.size());
125 | for(int i = 0; i < (int)rhs.prob_.size(); i++){
126 | this->prob_[i] = rhs.prob_[i].clone();
127 | this->pmem_[i] = rhs.pmem_[i].clone();
128 | this->wmem_[i] = rhs.wmem_[i].clone();
129 | }return *this;
130 | }
131 | //=============================================================================
132 | void CLM::Init(PDM &s,cv::Mat &r, vector &c,
133 | vector &v,vector > &p)
134 | {
135 | int n = p.size(); assert(((int)c.size() == n) && ((int)v.size() == n));
136 | assert((r.type() == CV_64F) && (r.rows == 2*s.nPoints()) && (r.cols == 1));
137 | for(int i = 0; i < n; i++){
138 | assert((int)p[i].size() == s.nPoints());
139 | assert((c[i].type() == CV_64F) && (c[i].rows == 3) && (c[i].cols == 1));
140 | assert((v[i].type() == CV_32S) && (v[i].rows == s.nPoints()) &&
141 | (v[i].cols == 1));
142 | }
143 | _pdm = s; _refs = r.clone();_cent.resize(n);_visi.resize(n);_patch.resize(n);
144 | for(int i = 0; i < n; i++){
145 | _cent[i] = c[i].clone(); _visi[i] = v[i].clone();
146 | _patch[i].resize(p[i].size());
147 | for(int j = 0; j < (int)p[i].size(); j++)_patch[i][j] = p[i][j];
148 | }
149 | _plocal.create(_pdm.nModes(),1,CV_64F);
150 | _pglobl.create(6,1,CV_64F);
151 | cshape_.create(2*_pdm.nPoints(),1,CV_64F);
152 | bshape_.create(2*_pdm.nPoints(),1,CV_64F);
153 | oshape_.create(2*_pdm.nPoints(),1,CV_64F);
154 | ms_.create(2*_pdm.nPoints(),1,CV_64F);
155 | u_.create(6+_pdm.nModes(),1,CV_64F);
156 | g_.create(6+_pdm.nModes(),1,CV_64F);
157 | J_.create(2*_pdm.nPoints(),6+_pdm.nModes(),CV_64F);
158 | H_.create(6+_pdm.nModes(),6+_pdm.nModes(),CV_64F);
159 | prob_.resize(_pdm.nPoints()); pmem_.resize(_pdm.nPoints());
160 | wmem_.resize(_pdm.nPoints()); return;
161 | }
162 | //=============================================================================
163 | void CLM::Load(const char* fname)
164 | {
165 | ifstream s(fname); assert(s.is_open()); this->Read(s); s.close(); return;
166 | }
167 | //=============================================================================
168 | void CLM::Save(const char* fname)
169 | {
170 | ofstream s(fname); assert(s.is_open()); this->Write(s);s.close(); return;
171 | }
172 | //=============================================================================
173 | void CLM::Write(ofstream &s)
174 | {
175 | s << IO::CLM << " " << _patch.size() << " ";
176 | _pdm.Write(s); IO::WriteMat(s,_refs);
177 | for(int i = 0; i < (int)_cent.size(); i++)IO::WriteMat(s,_cent[i]);
178 | for(int i = 0; i < (int)_visi.size(); i++)IO::WriteMat(s,_visi[i]);
179 | for(int i = 0; i < (int)_patch.size(); i++){
180 | for(int j = 0; j < _pdm.nPoints(); j++)_patch[i][j].Write(s);
181 | }return;
182 | }
183 | //=============================================================================
184 | void CLM::Read(ifstream &s,bool readType)
185 | {
186 | if(readType){int type; s >> type; assert(type == IO::CLM);}
187 | int n; s >> n; _pdm.Read(s); _cent.resize(n);_visi.resize(n);
188 | _patch.resize(n); IO::ReadMat(s,_refs);
189 | for(int i = 0; i < (int)_cent.size(); i++)IO::ReadMat(s,_cent[i]);
190 | for(int i = 0; i < (int)_visi.size(); i++)IO::ReadMat(s,_visi[i]);
191 | for(int i = 0; i < (int)_patch.size(); i++){
192 | _patch[i].resize(_pdm.nPoints());
193 | for(int j = 0; j < _pdm.nPoints(); j++)_patch[i][j].Read(s);
194 | }
195 | _plocal.create(_pdm.nModes(),1,CV_64F);
196 | _pglobl.create(6,1,CV_64F);
197 | cshape_.create(2*_pdm.nPoints(),1,CV_64F);
198 | bshape_.create(2*_pdm.nPoints(),1,CV_64F);
199 | oshape_.create(2*_pdm.nPoints(),1,CV_64F);
200 | ms_.create(2*_pdm.nPoints(),1,CV_64F);
201 | u_.create(6+_pdm.nModes(),1,CV_64F);
202 | g_.create(6+_pdm.nModes(),1,CV_64F);
203 | J_.create(2*_pdm.nPoints(),6+_pdm.nModes(),CV_64F);
204 | H_.create(6+_pdm.nModes(),6+_pdm.nModes(),CV_64F);
205 | prob_.resize(_pdm.nPoints()); pmem_.resize(_pdm.nPoints());
206 | wmem_.resize(_pdm.nPoints()); return;
207 | }
208 | //=============================================================================
209 | int CLM::GetViewIdx()
210 | {
211 | int idx=0;
212 | if(this->nViews() == 1)return 0;
213 | else{
214 | int i; double v1,v2,v3,d,dbest = -1.0;
215 | for(i = 0; i < this->nViews(); i++){
216 | v1 = _pglobl.db(1,0) - _cent[i].db(0,0);
217 | v2 = _pglobl.db(2,0) - _cent[i].db(1,0);
218 | v3 = _pglobl.db(3,0) - _cent[i].db(2,0);
219 | d = v1*v1 + v2*v2 + v3*v3;
220 | if(dbest < 0 || d < dbest){dbest = d; idx = i;}
221 | }return idx;
222 | }
223 | }
224 | //=============================================================================
225 | void CLM::Fit(cv::Mat im, vector &wSize,
226 | int nIter,double clamp,double fTol)
227 | {
228 | assert(im.type() == CV_8U);
229 | int i,idx,n = _pdm.nPoints(); double a1,b1,tx1,ty1,a2,b2,tx2,ty2;
230 | for(int witer = 0; witer < (int)wSize.size(); witer++){
231 | _pdm.CalcShape2D(cshape_,_plocal,_pglobl);
232 | CalcSimT(_refs,cshape_,a1,b1,tx1,ty1);
233 | invSimT(a1,b1,tx1,ty1,a2,b2,tx2,ty2);
234 | idx = this->GetViewIdx();
235 | #ifdef _OPENMP
236 | #pragma omp parallel for
237 | #endif
238 | for(i = 0; i < n; i++){
239 | if(_visi[idx].rows == n){if(_visi[idx].it(i,0) == 0)continue;}
240 | int w = wSize[witer]+_patch[idx][i]._w - 1;
241 | int h = wSize[witer]+_patch[idx][i]._h - 1;
242 | cv::Mat sim =
243 | (cv::Mat_(2,3)<wmem_[i].cols) || (h>wmem_[i].rows))wmem_[i].create(h,w,CV_32F);
245 | cv::Mat wimg = wmem_[i](cv::Rect(0,0,w,h));
246 | CvMat wimg_o = wimg,sim_o = sim; IplImage im_o = im;
247 | cvGetQuadrangleSubPix(&im_o,&wimg_o,&sim_o);
248 | if(wSize[witer] > pmem_[i].rows)
249 | pmem_[i].create(wSize[witer],wSize[witer],CV_64F);
250 | prob_[i] = pmem_[i](cv::Rect(0,0,wSize[witer],wSize[witer]));
251 | _patch[idx][i].Response(wimg,prob_[i]);
252 | }
253 | SimT(cshape_,a2,b2,tx2,ty2);
254 | _pdm.ApplySimT(a2,b2,tx2,ty2,_pglobl);
255 | cshape_.copyTo(bshape_);
256 | this->Optimize(idx,wSize[witer],nIter,fTol,clamp,1);
257 | this->Optimize(idx,wSize[witer],nIter,fTol,clamp,0);
258 | _pdm.ApplySimT(a1,b1,tx1,ty1,_pglobl);
259 | }return;
260 | }
261 | //=============================================================================
262 | void CLM::Optimize(int idx,int wSize,int nIter,
263 | double fTol,double clamp,bool rigid)
264 | {
265 | int i,m=_pdm.nModes(),n=_pdm.nPoints();
266 | double var,sigma=(wSize*wSize)/36.0; cv::Mat u,g,J,H;
267 | if(rigid){
268 | u = u_(cv::Rect(0,0,1,6)); g = g_(cv::Rect(0,0,1,6));
269 | J = J_(cv::Rect(0,0,6,2*n)); H = H_(cv::Rect(0,0,6,6));
270 | }else{u = u_; g = g_; J = J_; H = H_;}
271 | for(int iter = 0; iter < nIter; iter++){
272 | _pdm.CalcShape2D(cshape_,_plocal,_pglobl);
273 | if(iter > 0){if(cv::norm(cshape_,oshape_) < fTol)break;}
274 | cshape_.copyTo(oshape_);
275 | if(rigid)_pdm.CalcRigidJacob(_plocal,_pglobl,J);
276 | else _pdm.CalcJacob(_plocal,_pglobl,J);
277 | #ifdef _OPENMP
278 | #pragma omp parallel for
279 | #endif
280 | for(i = 0; i < n; i++){
281 | if(_visi[idx].rows == n){
282 | if(_visi[idx].it(i,0) == 0){
283 | cv::Mat Jx = J.row(i ); Jx = cvScalar(0);
284 | cv::Mat Jy = J.row(i+n); Jy = cvScalar(0);
285 | ms_.db(i,0) = 0.0; ms_.db(i+n,0) = 0.0; continue;
286 | }
287 | }
288 | double dx = cshape_.db(i ,0) - bshape_.db(i ,0) + (wSize-1)/2;
289 | double dy = cshape_.db(i+n,0) - bshape_.db(i+n,0) + (wSize-1)/2;
290 | int ii,jj; double v,vx,vy,mx=0.0,my=0.0,sum=0.0;
291 | cv::MatIterator_ p = prob_[i].begin();
292 | for(ii = 0; ii < wSize; ii++){ vx = (dy-ii)*(dy-ii);
293 | for(jj = 0; jj < wSize; jj++){ vy = (dx-jj)*(dx-jj);
294 | v = *p++; v *= exp(-0.5*(vx+vy)/sigma);
295 | sum += v; mx += v*jj; my += v*ii;
296 | }
297 | }
298 | ms_.db(i,0) = mx/sum - dx; ms_.db(i+n,0) = my/sum - dy;
299 | }
300 | g = J.t()*ms_; H = J.t()*J;
301 | if(!rigid){
302 | for(i = 0; i < m; i++){
303 | var = 0.5*sigma/_pdm._E.db(0,i);
304 | H.db(6+i,6+i) += var; g.db(6+i,0) -= var*_plocal.db(i,0);
305 | }
306 | }
307 | u_ = cvScalar(0); cv::solve(H,g,u,CV_CHOLESKY);
308 | _pdm.CalcReferenceUpdate(u_,_plocal,_pglobl);
309 | if(!rigid)_pdm.Clamp(_plocal,clamp);
310 | }return;
311 | }
312 | //=============================================================================
313 |
--------------------------------------------------------------------------------
/native-activity/jni/FaceTracker/lib/FCheck.cpp:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | // Copyright (C) 2010, Jason Mora Saragih, all rights reserved.
3 | //
4 | // This file is part of FaceTracker.
5 | //
6 | // Redistribution and use in source and binary forms, with or without
7 | // modification, are permitted provided that the following conditions are met:
8 | //
9 | // * The software is provided under the terms of this licence stricly for
10 | // academic, non-commercial, not-for-profit purposes.
11 | // * Redistributions of source code must retain the above copyright notice,
12 | // this list of conditions (licence) and the following disclaimer.
13 | // * Redistributions in binary form must reproduce the above copyright
14 | // notice, this list of conditions (licence) and the following disclaimer
15 | // in the documentation and/or other materials provided with the
16 | // distribution.
17 | // * The name of the author may not be used to endorse or promote products
18 | // derived from this software without specific prior written permission.
19 | // * As this software depends on other libraries, the user must adhere to
20 | // and keep in place any licencing terms of those libraries.
21 | // * Any publications arising from the use of this software, including but
22 | // not limited to academic journal and conference publications, technical
23 | // reports and manuals, must cite the following work:
24 | //
25 | // J. M. Saragih, S. Lucey, and J. F. Cohn. Face Alignment through
26 | // Subspace Constrained Mean-Shifts. International Conference of Computer
27 | // Vision (ICCV), September, 2009.
28 | //
29 | // THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
30 | // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
32 | // EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
36 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
38 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 | ///////////////////////////////////////////////////////////////////////////////
40 | #include
41 | using namespace FACETRACKER;
42 | using namespace std;
43 | //===========================================================================
44 | FCheck& FCheck::operator= (FCheck const& rhs)
45 | {
46 | this->_b = rhs._b; this->_w = rhs._w.clone(); this->_paw = rhs._paw;
47 | crop_.create(_paw._mask.rows,_paw._mask.cols,CV_8U);
48 | vec_.create(_paw._nPix,1,CV_64F); return *this;
49 | }
50 | //===========================================================================
51 | void FCheck::Init(double b, cv::Mat &w, PAW &paw)
52 | {
53 | assert((w.type() == CV_64F) && (w.rows == paw._nPix));
54 | _b = b; _w = w.clone(); _paw = paw;
55 | crop_.create(_paw._mask.rows,_paw._mask.cols,CV_8U);
56 | vec_.create(_paw._nPix,1,CV_64F); return;
57 | }
58 | //===========================================================================
59 | void FCheck::Load(const char* fname)
60 | {
61 | ifstream s(fname); assert(s.is_open()); this->Read(s); s.close(); return;
62 | }
63 | //===========================================================================
64 | void FCheck::Save(const char* fname)
65 | {
66 | ofstream s(fname); assert(s.is_open()); this->Write(s);s.close(); return;
67 | }
68 | //===========================================================================
69 | void FCheck::Write(ofstream &s)
70 | {
71 | s << IO::FCHECK << " " << _b << " ";
72 | IO::WriteMat(s,_w); _paw.Write(s); return;
73 | }
74 | //===========================================================================
75 | void FCheck::Read(ifstream &s,bool readType)
76 | {
77 | if(readType){int type; s >> type; assert(type == IO::FCHECK);}
78 | s >> _b; IO::ReadMat(s,_w); _paw.Read(s);
79 | crop_.create(_paw._mask.rows,_paw._mask.cols,CV_8U);
80 | vec_.create(_paw._nPix,1,CV_64F); return;
81 | }
82 | //===========================================================================
83 | bool FCheck::Check(cv::Mat &im,cv::Mat &s)
84 | {
85 | assert((im.type() == CV_8U) && (s.type() == CV_64F) &&
86 | (s.rows/2 == _paw.nPoints()) && (s.cols == 1));
87 | _paw.Crop(im,crop_,s);
88 | if((vec_.rows!=_paw._nPix)||(vec_.cols!=1))vec_.create(_paw._nPix,1,CV_64F);
89 | int i,j,w = crop_.cols,h = crop_.rows;
90 | cv::MatIterator_ vp = vec_.begin();
91 | cv::MatIterator_ cp = crop_.begin();
92 | cv::MatIterator_ mp = _paw._mask.begin();
93 | for(i=0;i 0)return true; else return false;
97 | }
98 | //===========================================================================
99 | //===========================================================================
100 | //===========================================================================
101 | //===========================================================================
102 | //===========================================================================
103 | //===========================================================================
104 | //===========================================================================
105 | //===========================================================================
106 | //===========================================================================
107 | //===========================================================================
108 | void MFCheck::Load(const char* fname)
109 | {
110 | ifstream s(fname); assert(s.is_open()); this->Read(s); s.close(); return;
111 | }
112 | //===========================================================================
113 | void MFCheck::Save(const char* fname)
114 | {
115 | ofstream s(fname); assert(s.is_open()); this->Write(s);s.close(); return;
116 | }
117 | //===========================================================================
118 | void MFCheck::Write(ofstream &s)
119 | {
120 | s << IO::MFCHECK << " " << _fcheck.size() << " ";
121 | for(int i = 0; i < (int)_fcheck.size(); i++)_fcheck[i].Write(s); return;
122 | }
123 | //===========================================================================
124 | void MFCheck::Read(ifstream &s,bool readType)
125 | {
126 | if(readType){int type; s >> type; assert(type == IO::MFCHECK);}
127 | int n; s >> n; _fcheck.resize(n);
128 | for(int i = 0; i < n; i++)_fcheck[i].Read(s); return;
129 | }
130 | //===========================================================================
131 | bool MFCheck::Check(int idx,cv::Mat &im,cv::Mat &s)
132 | {
133 | assert((idx >= 0) && (idx < (int)_fcheck.size()));
134 | return _fcheck[idx].Check(im,s);
135 | }
136 | //===========================================================================
137 |
--------------------------------------------------------------------------------
/native-activity/jni/FaceTracker/lib/FDet.cpp:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | // Copyright (C) 2010, Jason Mora Saragih, all rights reserved.
3 | //
4 | // This file is part of FaceTracker.
5 | //
6 | // Redistribution and use in source and binary forms, with or without
7 | // modification, are permitted provided that the following conditions are met:
8 | //
9 | // * The software is provided under the terms of this licence stricly for
10 | // academic, non-commercial, not-for-profit purposes.
11 | // * Redistributions of source code must retain the above copyright notice,
12 | // this list of conditions (licence) and the following disclaimer.
13 | // * Redistributions in binary form must reproduce the above copyright
14 | // notice, this list of conditions (licence) and the following disclaimer
15 | // in the documentation and/or other materials provided with the
16 | // distribution.
17 | // * The name of the author may not be used to endorse or promote products
18 | // derived from this software without specific prior written permission.
19 | // * As this software depends on other libraries, the user must adhere to
20 | // and keep in place any licencing terms of those libraries.
21 | // * Any publications arising from the use of this software, including but
22 | // not limited to academic journal and conference publications, technical
23 | // reports and manuals, must cite the following work:
24 | //
25 | // J. M. Saragih, S. Lucey, and J. F. Cohn. Face Alignment through
26 | // Subspace Constrained Mean-Shifts. International Conference of Computer
27 | // Vision (ICCV), September, 2009.
28 | //
29 | // THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
30 | // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
32 | // EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
36 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
38 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 | ///////////////////////////////////////////////////////////////////////////////
40 | #include
41 | using namespace FACETRACKER;
42 | using namespace std;
43 | //===========================================================================
44 | FDet::~FDet()
45 | {
46 | if(storage_ != NULL)cvReleaseMemStorage(&storage_);
47 | if(_cascade != NULL)cvReleaseHaarClassifierCascade(&_cascade);
48 | }
49 | //===========================================================================
50 | FDet& FDet::operator= (FDet const& rhs)
51 | {
52 | this->_min_neighbours = rhs._min_neighbours;
53 | this->_min_size = rhs._min_size;
54 | this->_img_scale = rhs._img_scale;
55 | this->_scale_factor = rhs._scale_factor;
56 | if(storage_ != NULL)cvReleaseMemStorage(&storage_);
57 | storage_ = cvCreateMemStorage(0);
58 | this->_cascade = rhs._cascade;
59 | this->small_img_ = rhs.small_img_.clone(); return *this;
60 | }
61 | //===========================================================================
62 | void FDet::Init(const char* fname,
63 | const double img_scale,
64 | const double scale_factor,
65 | const int min_neighbours,
66 | const int min_size)
67 | {
68 | if(!(_cascade = (CvHaarClassifierCascade*)cvLoad(fname,0,0,0))){
69 | printf("ERROR(%s,%d) : Failed loading classifier cascade!\n",
70 | __FILE__,__LINE__); abort();
71 | }
72 | storage_ = cvCreateMemStorage(0);
73 | _img_scale = img_scale;
74 | _scale_factor = scale_factor;
75 | _min_neighbours = min_neighbours;
76 | _min_size = min_size; return;
77 | }
78 | //===========================================================================
79 | cv::Rect FDet::Detect(cv::Mat im)
80 | {
81 | assert(im.type() == CV_8U);
82 | cv::Mat gray; int i,maxv; cv::Rect R;
83 | int w = cvRound(im.cols/_img_scale);
84 | int h = cvRound(im.rows/_img_scale);
85 | if((small_img_.rows!=h) || (small_img_.cols!=w))small_img_.create(h,w,CV_8U);
86 | if(im.channels() == 1)gray = im;
87 | else{gray=cv::Mat(im.rows,im.cols,CV_8U);cv::cvtColor(im,gray,CV_BGR2GRAY);}
88 | cv::resize(gray,small_img_,cv::Size(w,h),0,0,CV_INTER_LINEAR);
89 | cv::equalizeHist(small_img_,small_img_);
90 | cvClearMemStorage(storage_); IplImage simg = small_img_;
91 | CvSeq* obj = cvHaarDetectObjects(&simg,_cascade,storage_,
92 | _scale_factor,_min_neighbours,0,
93 | cv::Size(_min_size,_min_size));
94 | if(obj->total == 0)return cv::Rect(0,0,0,0);
95 | for(i = 0,maxv = 0; i < obj->total; i++){
96 | CvRect* r = (CvRect*)cvGetSeqElem(obj,i);
97 | if(i == 0 || maxv < r->width*r->height){
98 | maxv = r->width*r->height; R.x = r->x*_img_scale; R.y = r->y*_img_scale;
99 | R.width = r->width*_img_scale; R.height = r->height*_img_scale;
100 | }
101 | }
102 | cvRelease((void**)(&obj)); return R;
103 | }
104 | //===========================================================================
105 | void FDet::Load(const char* fname)
106 | {
107 | ifstream s(fname); assert(s.is_open()); this->Read(s); s.close(); return;
108 | }
109 | //===========================================================================
110 | void FDet::Save(const char* fname)
111 | {
112 | ofstream s(fname); assert(s.is_open()); this->Write(s);s.close(); return;
113 | }
114 | //===========================================================================
115 | void FDet::Write(ofstream &s)
116 | {
117 | int i,j,k,l;
118 | s << IO::FDET << " "
119 | << _min_neighbours << " "
120 | << _min_size << " "
121 | << _img_scale << " "
122 | << _scale_factor << " "
123 | << _cascade->count << " "
124 | << _cascade->orig_window_size.width << " "
125 | << _cascade->orig_window_size.height << " ";
126 | for(i = 0; i < _cascade->count; i++){
127 | s << _cascade->stage_classifier[i].parent << " "
128 | << _cascade->stage_classifier[i].next << " "
129 | << _cascade->stage_classifier[i].child << " "
130 | << _cascade->stage_classifier[i].threshold << " "
131 | << _cascade->stage_classifier[i].count << " ";
132 | for(j = 0; j < _cascade->stage_classifier[i].count; j++){
133 | CvHaarClassifier* classifier =
134 | &_cascade->stage_classifier[i].classifier[j];
135 | s << classifier->count << " ";
136 | for(k = 0; k < classifier->count; k++){
137 | s << classifier->threshold[k] << " "
138 | << classifier->left[k] << " "
139 | << classifier->right[k] << " "
140 | << classifier->alpha[k] << " "
141 | << classifier->haar_feature[k].tilted << " ";
142 | for(l = 0; l < CV_HAAR_FEATURE_MAX; l++){
143 | s << classifier->haar_feature[k].rect[l].weight << " "
144 | << classifier->haar_feature[k].rect[l].r.x << " "
145 | << classifier->haar_feature[k].rect[l].r.y << " "
146 | << classifier->haar_feature[k].rect[l].r.width << " "
147 | << classifier->haar_feature[k].rect[l].r.height << " ";
148 | }
149 | }
150 | s << classifier->alpha[classifier->count] << " ";
151 | }
152 | }return;
153 | }
154 | //===========================================================================
155 | void FDet::Read(ifstream &s,bool readType)
156 | {
157 | int i,j,k,l,n,m;
158 | if(readType){int type; s >> type; assert(type == IO::FDET);}
159 | s >> _min_neighbours >> _min_size >> _img_scale >> _scale_factor >> n;
160 | m = sizeof(CvHaarClassifierCascade)+n*sizeof(CvHaarStageClassifier);
161 | storage_ = cvCreateMemStorage(0);
162 | _cascade = (CvHaarClassifierCascade*)cvAlloc(m);
163 | memset(_cascade,0,m);
164 | _cascade->stage_classifier = (CvHaarStageClassifier*)(_cascade + 1);
165 | _cascade->flags = CV_HAAR_MAGIC_VAL;
166 | _cascade->count = n;
167 | s >> _cascade->orig_window_size.width >> _cascade->orig_window_size.height;
168 | for(i = 0; i < n; i++){
169 | s >> _cascade->stage_classifier[i].parent
170 | >> _cascade->stage_classifier[i].next
171 | >> _cascade->stage_classifier[i].child
172 | >> _cascade->stage_classifier[i].threshold
173 | >> _cascade->stage_classifier[i].count;
174 | _cascade->stage_classifier[i].classifier =
175 | (CvHaarClassifier*)cvAlloc(_cascade->stage_classifier[i].count*
176 | sizeof(CvHaarClassifier));
177 | for(j = 0; j < _cascade->stage_classifier[i].count; j++){
178 | CvHaarClassifier* classifier =
179 | &_cascade->stage_classifier[i].classifier[j];
180 | s >> classifier->count;
181 | classifier->haar_feature = (CvHaarFeature*)
182 | cvAlloc(classifier->count*(sizeof(CvHaarFeature) +
183 | sizeof(float) + sizeof(int) + sizeof(int))+
184 | (classifier->count+1)*sizeof(float));
185 | classifier->threshold =
186 | (float*)(classifier->haar_feature+classifier->count);
187 | classifier->left = (int*)(classifier->threshold + classifier->count);
188 | classifier->right = (int*)(classifier->left + classifier->count);
189 | classifier->alpha = (float*)(classifier->right + classifier->count);
190 | for(k = 0; k < classifier->count; k++){
191 | s >> classifier->threshold[k]
192 | >> classifier->left[k]
193 | >> classifier->right[k]
194 | >> classifier->alpha[k]
195 | >> classifier->haar_feature[k].tilted;
196 | for(l = 0; l < CV_HAAR_FEATURE_MAX; l++){
197 | s >> classifier->haar_feature[k].rect[l].weight
198 | >> classifier->haar_feature[k].rect[l].r.x
199 | >> classifier->haar_feature[k].rect[l].r.y
200 | >> classifier->haar_feature[k].rect[l].r.width
201 | >> classifier->haar_feature[k].rect[l].r.height;
202 | }
203 | }
204 | s >> classifier->alpha[classifier->count];
205 | }
206 | }return;
207 | }
208 | //===========================================================================
209 |
--------------------------------------------------------------------------------
/native-activity/jni/FaceTracker/lib/IO.cpp:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | // Copyright (C) 2010, Jason Mora Saragih, all rights reserved.
3 | //
4 | // This file is part of FaceTracker.
5 | //
6 | // Redistribution and use in source and binary forms, with or without
7 | // modification, are permitted provided that the following conditions are met:
8 | //
9 | // * The software is provided under the terms of this licence stricly for
10 | // academic, non-commercial, not-for-profit purposes.
11 | // * Redistributions of source code must retain the above copyright notice,
12 | // this list of conditions (licence) and the following disclaimer.
13 | // * Redistributions in binary form must reproduce the above copyright
14 | // notice, this list of conditions (licence) and the following disclaimer
15 | // in the documentation and/or other materials provided with the
16 | // distribution.
17 | // * The name of the author may not be used to endorse or promote products
18 | // derived from this software without specific prior written permission.
19 | // * As this software depends on other libraries, the user must adhere to
20 | // and keep in place any licencing terms of those libraries.
21 | // * Any publications arising from the use of this software, including but
22 | // not limited to academic journal and conference publications, technical
23 | // reports and manuals, must cite the following work:
24 | //
25 | // J. M. Saragih, S. Lucey, and J. F. Cohn. Face Alignment through
26 | // Subspace Constrained Mean-Shifts. International Conference of Computer
27 | // Vision (ICCV), September, 2009.
28 | //
29 | // THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
30 | // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
32 | // EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
36 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
38 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 | ///////////////////////////////////////////////////////////////////////////////
40 | #include
41 | #include
42 | using namespace FACETRACKER;
43 | using namespace std;
44 | //===========================================================================
45 | void IO::ReadMat(ifstream& s,cv::Mat &M)
46 | {
47 | int r,c,t; s >> r >> c >> t;
48 | M = cv::Mat(r,c,t);
49 | switch(M.type()){
50 | case CV_64FC1:
51 | {
52 | cv::MatIterator_ i1 = M.begin(),i2 = M.end();
53 | while(i1 != i2)s >> *i1++;
54 | }break;
55 | case CV_32FC1:
56 | {
57 | cv::MatIterator_ i1 = M.begin(),i2 = M.end();
58 | while(i1 != i2)s >> *i1++;
59 | }break;
60 | case CV_32SC1:
61 | {
62 | cv::MatIterator_ i1 = M.begin(),i2 = M.end();
63 | while(i1 != i2)s >> *i1++;
64 | }break;
65 | case CV_8UC1:
66 | {
67 | cv::MatIterator_ i1 = M.begin(),i2 = M.end();
68 | while(i1 != i2)s >> *i1++;
69 | }break;
70 | default:
71 | printf("ERROR(%s,%d) : Unsupported Matrix type %d!\n",
72 | __FILE__,__LINE__,M.type()); abort();
73 | }return;
74 | }
75 | //===========================================================================
76 | void IO::WriteMat(ofstream& s,cv::Mat &M)
77 | {
78 | s << M.rows << " " << M.cols << " " << M.type() << " ";
79 | switch(M.type()){
80 | case CV_64FC1:
81 | {
82 | cv::MatIterator_ i1 = M.begin(),i2 = M.end();
83 | while(i1 != i2)s << *i1++ << " ";
84 | }break;
85 | case CV_32FC1:
86 | {
87 | cv::MatIterator_ i1 = M.begin(),i2 = M.end();
88 | while(i1 != i2)s << *i1++ << " ";
89 | }break;
90 | case CV_32SC1:
91 | {
92 | cv::MatIterator_ i1 = M.begin(),i2 = M.end();
93 | while(i1 != i2)s << *i1++ << " ";
94 | }break;
95 | case CV_8UC1:
96 | {
97 | cv::MatIterator_ i1 = M.begin(),i2 = M.end();
98 | while(i1 != i2)s << *i1++ << " ";
99 | }break;
100 | default:
101 | printf("ERROR(%s,%d) : Unsupported Matrix type %d!\n",
102 | __FILE__,__LINE__,M.type()); abort();
103 | }return;
104 | }
105 | //===========================================================================
106 | cv::Mat IO::LoadCon(const char* fname)
107 | {
108 | int i,n; char str[256]; char c; fstream file(fname,fstream::in);
109 | if(!file.is_open()){
110 | printf("ERROR(%s,%d) : Failed opening file %s for reading\n",
111 | __FILE__,__LINE__,fname); abort();
112 | }
113 | while(1){file >> str; if(strncmp(str,"n_connections:",14) == 0)break;}
114 | file >> n; cv::Mat con(2,n,CV_32S);
115 | while(1){file >> c; if(c == '{')break;}
116 | for(i = 0; i < n; i++)file >> con.at(0,i) >> con.at(1,i);
117 | file.close(); return con;
118 | }
119 | //=============================================================================
120 | cv::Mat IO::LoadTri(const char* fname)
121 | {
122 | int i,n; char str[256]; char c; fstream file(fname,fstream::in);
123 | if(!file.is_open()){
124 | printf("ERROR(%s,%d) : Failed opening file %s for reading\n",
125 | __FILE__,__LINE__,fname); abort();
126 | }
127 | while(1){file >> str; if(strncmp(str,"n_tri:",6) == 0)break;}
128 | file >> n; cv::Mat tri(n,3,CV_32S);
129 | while(1){file >> c; if(c == '{')break;}
130 | for(i = 0; i < n; i++)
131 | file >> tri.at(i,0) >> tri.at(i,1) >> tri.at(i,2);
132 | file.close(); return tri;
133 | }
134 | //===========================================================================
135 |
--------------------------------------------------------------------------------
/native-activity/jni/FaceTracker/lib/PAW.cpp:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | // Copyright (C) 2010, Jason Mora Saragih, all rights reserved.
3 | //
4 | // This file is part of FaceTracker.
5 | //
6 | // Redistribution and use in source and binary forms, with or without
7 | // modification, are permitted provided that the following conditions are met:
8 | //
9 | // * The software is provided under the terms of this licence stricly for
10 | // academic, non-commercial, not-for-profit purposes.
11 | // * Redistributions of source code must retain the above copyright notice,
12 | // this list of conditions (licence) and the following disclaimer.
13 | // * Redistributions in binary form must reproduce the above copyright
14 | // notice, this list of conditions (licence) and the following disclaimer
15 | // in the documentation and/or other materials provided with the
16 | // distribution.
17 | // * The name of the author may not be used to endorse or promote products
18 | // derived from this software without specific prior written permission.
19 | // * As this software depends on other libraries, the user must adhere to
20 | // and keep in place any licencing terms of those libraries.
21 | // * Any publications arising from the use of this software, including but
22 | // not limited to academic journal and conference publications, technical
23 | // reports and manuals, must cite the following work:
24 | //
25 | // J. M. Saragih, S. Lucey, and J. F. Cohn. Face Alignment through
26 | // Subspace Constrained Mean-Shifts. International Conference of Computer
27 | // Vision (ICCV), September, 2009.
28 | //
29 | // THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
30 | // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
32 | // EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
36 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
38 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 | ///////////////////////////////////////////////////////////////////////////////
40 | #include
41 | #define it at
42 | #define db at
43 | using namespace FACETRACKER;
44 | using namespace std;
45 | //=============================================================================
46 | bool sameSide(double x0, double y0, double x1, double y1,
47 | double x2, double y2, double x3, double y3)
48 | {
49 | double x = (x3-x2)*(y0-y2) - (x0-x2)*(y3-y2);
50 | double y = (x3-x2)*(y1-y2) - (x1-x2)*(y3-y2);
51 | if(x*y >= 0)return true; else return false;
52 | }
53 | //=============================================================================
54 | int isWithinTri(double x,double y,cv::Mat &tri,cv::Mat &shape)
55 | {
56 | int i,j,k,t,n = tri.rows,p = shape.rows/2; double s11,s12,s21,s22,s31,s32;
57 | for(t = 0; t < n; t++){
58 | i = tri.it(t,0); j = tri.it(t,1); k = tri.it(t,2);
59 | s11 = shape.db(i ,0); s21 = shape.db(j ,0); s31 = shape.db(k ,0);
60 | s12 = shape.db(i+p,0); s22 = shape.db(j+p,0); s32 = shape.db(k+p,0);
61 | if(sameSide(x,y,s11,s12,s21,s22,s31,s32) &&
62 | sameSide(x,y,s21,s22,s11,s12,s31,s32) &&
63 | sameSide(x,y,s31,s32,s11,s12,s21,s22))return t;
64 | }return -1;
65 | }
66 | //===========================================================================
67 | //===========================================================================
68 | //===========================================================================
69 | //===========================================================================
70 | //===========================================================================
71 | //===========================================================================
72 | //===========================================================================
73 | //===========================================================================
74 | //===========================================================================
75 | PAW& PAW::operator= (PAW const& rhs)
76 | {
77 | this->_nPix = rhs._nPix;
78 | this->_xmin = rhs._xmin;
79 | this->_ymin = rhs._ymin;
80 | this->_src = rhs._src.clone();
81 | this->_tri = rhs._tri.clone();
82 | this->_tridx = rhs._tridx.clone();
83 | this->_mask = rhs._mask.clone();
84 | this->_alpha = rhs._alpha.clone();
85 | this->_beta = rhs._beta.clone();
86 | _mapx.create(_mask.rows,_mask.cols,CV_32F);
87 | _mapy.create(_mask.rows,_mask.cols,CV_32F);
88 | _coeff.create(this->nTri(),6,CV_64F);
89 | _dst = _src; return *this;
90 | }
91 | //===========================================================================
92 | void PAW::Load(const char* fname)
93 | {
94 | ifstream s(fname); assert(s.is_open()); this->Read(s); s.close(); return;
95 | }
96 | //===========================================================================
97 | void PAW::Save(const char* fname)
98 | {
99 | ofstream s(fname); assert(s.is_open()); this->Write(s);s.close(); return;
100 | }
101 | //===========================================================================
102 | void PAW::Write(ofstream &s)
103 | {
104 | s << IO::PAW << " " << _nPix << " " << _xmin << " " << _ymin << " ";
105 | IO::WriteMat(s,_src); IO::WriteMat(s,_tri); IO::WriteMat(s,_tridx);
106 | IO::WriteMat(s,_mask); IO::WriteMat(s,_alpha); IO::WriteMat(s,_beta);
107 | return;
108 | }
109 | //===========================================================================
110 | void PAW::Read(ifstream &s,bool readType)
111 | {
112 | if(readType){int type; s >> type; assert(type == IO::PAW);}
113 | s >> _nPix >> _xmin >> _ymin;
114 | IO::ReadMat(s,_src); IO::ReadMat(s,_tri); IO::ReadMat(s,_tridx);
115 | IO::ReadMat(s,_mask); IO::ReadMat(s,_alpha); IO::ReadMat(s,_beta);
116 | _mapx.create(_mask.rows,_mask.cols,CV_32F);
117 | _mapy.create(_mask.rows,_mask.cols,CV_32F);
118 | _coeff.create(this->nTri(),6,CV_64F); _dst = _src; return;
119 | }
120 | //===========================================================================
121 | void PAW::Init(cv::Mat &src,cv::Mat &tri)
122 | {
123 | assert((src.type() == CV_64F) && (src.cols == 1));
124 | assert((tri.type() == CV_32S) && (tri.cols == 3));
125 | _src = src.clone(); _tri = tri.clone();
126 | int i,j,k,l,n = this->nPoints(); double c1,c2,c3,c4,c5;
127 | _alpha.create(this->nTri(),3,CV_64F); _beta.create(this->nTri(),3,CV_64F);
128 | for(i = 0; i < this->nTri(); i++){
129 | j = _tri.it(i,0); k = _tri.it(i,1); l = _tri.it(i,2);
130 | c1 = _src.db(l+n,0) - _src.db(j+n,0); c2 = _src.db(l,0) - _src.db(j,0);
131 | c4 = _src.db(k+n,0) - _src.db(j+n,0); c3 = _src.db(k,0) - _src.db(j,0);
132 | c5 = c3*c1 - c2*c4;
133 | _alpha.db(i,0) = (_src.db(j+n,0)*c2 - _src.db(j,0)*c1)/c5;
134 | _alpha.db(i,1) = c1/c5; _alpha.db(i,2) = -c2/c5;
135 | _beta.db(i,0) = (_src.db(j,0)*c4 - _src.db(j+n,0)*c3)/c5;
136 | _beta.db(i,1) = -c4/c5; _beta.db(i,2) = c3/c5;
137 | }
138 | cv::MatIterator_ x = _src.begin(),y =_src.begin()+n;
139 | double vx,vy,xmax=*x,ymax=*y,xmin=*x,ymin=*y;
140 | for(i = 0; i < n; i++){
141 | vx = *x++; vy = *y++;
142 | xmax = std::max(xmax,vx); ymax = std::max(ymax,vy);
143 | xmin = std::min(xmin,vx); ymin = std::min(ymin,vy);
144 | }
145 | int w = int(xmax - xmin + 1.0),h = int(ymax - ymin + 1.0);
146 | _mask.create(h,w,CV_8U); _tridx = cv::Mat::zeros(h,w,CV_32S);
147 | cv::MatIterator_ mp = _mask.begin();
148 | cv::MatIterator_ tp = _tridx.begin();
149 | for(i = 0,_nPix = 0; i < h; i++){
150 | for(j = 0; j < w; j++,++mp,++tp){
151 | isWithinTri(double(j)+xmin,double(i)+ymin,tri,_src);
152 | if((*tp = isWithinTri(double(j)+xmin,double(i)+ymin,tri,_src))==-1)*mp=0;
153 | else{*mp = 1; _nPix++;}
154 | }
155 | }
156 | _mapx.create(_mask.rows,_mask.cols,CV_32F);
157 | _mapy.create(_mask.rows,_mask.cols,CV_32F);
158 | _coeff.create(this->nTri(),6,CV_64F);
159 | _dst = _src; _xmin = xmin; _ymin = ymin; return;
160 | }
161 | //=============================================================================
162 | void PAW::Crop(cv::Mat &src, cv::Mat &dst, cv::Mat &s)
163 | {
164 | assert((s.type() == CV_64F) && (s.rows == _src.rows) && (s.cols == 1) &&
165 | (src.type() == dst.type()));
166 | _dst = s; this->CalcCoeff(); this->WarpRegion(_mapx,_mapy);
167 | cv::remap(src,dst,_mapx,_mapy,CV_INTER_LINEAR); return;
168 | }
169 | //=============================================================================
170 | void PAW::CalcCoeff()
171 | {
172 | int i,j,k,l,p=this->nPoints(); double c1,c2,c3,c4,c5,c6,*coeff,*alpha,*beta;
173 | for(l = 0; l < this->nTri(); l++){
174 | i = _tri.it(l,0); j = _tri.it(l,1); k = _tri.it(l,2);
175 | c1 = _dst.db(i ,0); c2 = _dst.db(j ,0) - c1; c3 = _dst.db(k ,0) - c1;
176 | c4 = _dst.db(i+p,0); c5 = _dst.db(j+p,0) - c4; c6 = _dst.db(k+p,0) - c4;
177 | coeff = _coeff.ptr(l);
178 | alpha = _alpha.ptr(l);
179 | beta = _beta.ptr(l);
180 | coeff[0] = c1 + c2*alpha[0] + c3*beta[0];
181 | coeff[1] = c2*alpha[1] + c3*beta[1];
182 | coeff[2] = c2*alpha[2] + c3*beta[2];
183 | coeff[3] = c4 + c5*alpha[0] + c6*beta[0];
184 | coeff[4] = c5*alpha[1] + c6*beta[1];
185 | coeff[5] = c5*alpha[2] + c6*beta[2];
186 | }return;
187 | }
188 | //=============================================================================
189 | void PAW::WarpRegion(cv::Mat &mapx,cv::Mat &mapy)
190 | {
191 | assert((mapx.type() == CV_32F) && (mapy.type() == CV_32F));
192 | if((mapx.rows != _mask.rows) || (mapx.cols != _mask.cols))
193 | _mapx.create(_mask.rows,_mask.cols,CV_32F);
194 | if((mapy.rows != _mask.rows) || (mapy.cols != _mask.cols))
195 | _mapy.create(_mask.rows,_mask.cols,CV_32F);
196 | int x,y,j,k=-1; double yi,xi,xo,yo,*a=NULL,*ap;
197 | cv::MatIterator_ xp = mapx.begin();
198 | cv::MatIterator_ yp = mapy.begin();
199 | cv::MatIterator_ mp = _mask.begin();
200 | cv::MatIterator_ tp = _tridx.begin();
201 | for(y = 0; y < _mask.rows; y++){ yi = double(y) + _ymin;
202 | for(x = 0; x < _mask.cols; x++){ xi = double(x) + _xmin;
203 | if(*mp == 0){*xp = -1; *yp = -1;}
204 | else{
205 | j = *tp; if(j != k){a = _coeff.ptr(j); k = j;}
206 | ap = a;
207 | xo = *ap++; xo += *ap++ * xi; *xp = float(xo + *ap++ * yi);
208 | yo = *ap++; yo += *ap++ * xi; *yp = float(yo + *ap++ * yi);
209 | }
210 | mp++; tp++; xp++; yp++;
211 | }
212 | }return;
213 | }
214 | //===========================================================================
215 |
--------------------------------------------------------------------------------
/native-activity/jni/FaceTracker/lib/PDM.cpp:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | // Copyright (C) 2010, Jason Mora Saragih, all rights reserved.
3 | //
4 | // This file is part of FaceTracker.
5 | //
6 | // Redistribution and use in source and binary forms, with or without
7 | // modification, are permitted provided that the following conditions are met:
8 | //
9 | // * The software is provided under the terms of this licence stricly for
10 | // academic, non-commercial, not-for-profit purposes.
11 | // * Redistributions of source code must retain the above copyright notice,
12 | // this list of conditions (licence) and the following disclaimer.
13 | // * Redistributions in binary form must reproduce the above copyright
14 | // notice, this list of conditions (licence) and the following disclaimer
15 | // in the documentation and/or other materials provided with the
16 | // distribution.
17 | // * The name of the author may not be used to endorse or promote products
18 | // derived from this software without specific prior written permission.
19 | // * As this software depends on other libraries, the user must adhere to
20 | // and keep in place any licencing terms of those libraries.
21 | // * Any publications arising from the use of this software, including but
22 | // not limited to academic journal and conference publications, technical
23 | // reports and manuals, must cite the following work:
24 | //
25 | // J. M. Saragih, S. Lucey, and J. F. Cohn. Face Alignment through
26 | // Subspace Constrained Mean-Shifts. International Conference of Computer
27 | // Vision (ICCV), September, 2009.
28 | //
29 | // THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
30 | // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
32 | // EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
36 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
38 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 | ///////////////////////////////////////////////////////////////////////////////
40 | #include
41 | #define db at
42 | using namespace FACETRACKER;
43 | using namespace std;
44 | //===========================================================================
45 | void AddOrthRow(cv::Mat &R)
46 | {
47 | assert((R.rows == 3) && (R.cols == 3));
48 | R.db(2,0) = R.db(0,1)*R.db(1,2) - R.db(0,2)*R.db(1,1);
49 | R.db(2,1) = R.db(0,2)*R.db(1,0) - R.db(0,0)*R.db(1,2);
50 | R.db(2,2) = R.db(0,0)*R.db(1,1) - R.db(0,1)*R.db(1,0);
51 | return;
52 | }
53 | //=============================================================================
54 | void MetricUpgrade(cv::Mat &R)
55 | {
56 | assert((R.rows == 3) && (R.cols == 3));
57 | cv::SVD svd(R,cv::SVD::MODIFY_A);
58 | cv::Mat X = svd.u*svd.vt,W = cv::Mat::eye(3,3,CV_64F);
59 | W.db(2,2) = determinant(X); R = svd.u*W*svd.vt; return;
60 | }
61 | //===========================================================================
62 | void Euler2Rot(cv::Mat &R,const double pitch,const double yaw,const double roll,
63 | bool full = true)
64 | {
65 | if(full){if((R.rows != 3) || (R.cols != 3))R.create(3,3,CV_64F);}
66 | else{if((R.rows != 2) || (R.cols != 3))R.create(2,3,CV_64F);}
67 | double sina = sin(pitch), sinb = sin(yaw), sinc = sin(roll);
68 | double cosa = cos(pitch), cosb = cos(yaw), cosc = cos(roll);
69 | R.db(0,0) = cosb*cosc; R.db(0,1) = -cosb*sinc; R.db(0,2) = sinb;
70 | R.db(1,0) = cosa*sinc + sina*sinb*cosc;
71 | R.db(1,1) = cosa*cosc - sina*sinb*sinc;
72 | R.db(1,2) = -sina*cosb; if(full)AddOrthRow(R); return;
73 | }
74 | //===========================================================================
75 | void Euler2Rot(cv::Mat &R,cv::Mat &p,bool full = true)
76 | {
77 | assert((p.rows == 6) && (p.cols == 1));
78 | Euler2Rot(R,p.db(1,0),p.db(2,0),p.db(3,0),full); return;
79 | }
80 | //=============================================================================
81 | void Rot2Euler(cv::Mat &R,double& pitch,double& yaw,double& roll)
82 | {
83 | assert((R.rows == 3) && (R.cols == 3));
84 | double q[4];
85 | q[0] = sqrt(1+R.db(0,0)+R.db(1,1)+R.db(2,2))/2;
86 | q[1] = (R.db(2,1) - R.db(1,2)) / (4*q[0]) ;
87 | q[2] = (R.db(0,2) - R.db(2,0)) / (4*q[0]) ;
88 | q[3] = (R.db(1,0) - R.db(0,1)) / (4*q[0]) ;
89 | yaw = asin(2*(q[0]*q[2] + q[1]*q[3]));
90 | pitch= atan2(2*(q[0]*q[1]-q[2]*q[3]),
91 | q[0]*q[0]-q[1]*q[1]-q[2]*q[2]+q[3]*q[3]);
92 | roll = atan2(2*(q[0]*q[3]-q[1]*q[2]),
93 | q[0]*q[0]+q[1]*q[1]-q[2]*q[2]-q[3]*q[3]);
94 | return;
95 | }
96 | //=============================================================================
97 | void Rot2Euler(cv::Mat &R,cv::Mat &p)
98 | {
99 | assert((p.rows == 6) && (p.cols == 1));
100 | Rot2Euler(R,p.db(1,0),p.db(2,0),p.db(3,0)); return;
101 | }
102 | //=============================================================================
103 | void Align3Dto2DShapes(double& scale,double& pitch,double& yaw,double& roll,
104 | double& x,double& y,cv::Mat &s2D,cv::Mat &s3D)
105 | {
106 | assert((s2D.cols == 1) && (s3D.rows == 3*(s2D.rows/2)) && (s3D.cols == 1));
107 | int i,n = s2D.rows/2; double t2[2],t3[3];
108 | cv::Mat s2D_cpy = s2D.clone(),s3D_cpy = s3D.clone();
109 | cv::Mat X = (s2D_cpy.reshape(1,2)).t(),S = (s3D_cpy.reshape(1,3)).t();
110 | for(i = 0; i < 2; i++){cv::Mat v = X.col(i); t2[i] = sum(v)[0]/n; v-=t2[i];}
111 | for(i = 0; i < 3; i++){cv::Mat v = S.col(i); t3[i] = sum(v)[0]/n; v-=t3[i];}
112 | cv::Mat M = ((S.t()*S).inv(cv::DECOMP_CHOLESKY))*S.t()*X;
113 | cv::Mat MtM = M.t()*M; cv::SVD svd(MtM,cv::SVD::MODIFY_A);
114 | svd.w.db(0,0) = 1.0/sqrt(svd.w.db(0,0));
115 | svd.w.db(1,0) = 1.0/sqrt(svd.w.db(1,0));
116 | cv::Mat T(3,3,CV_64F);
117 | T(cv::Rect(0,0,3,2)) = svd.u*cv::Mat::diag(svd.w)*svd.vt*M.t();
118 | scale = 0.5*sum(T(cv::Rect(0,0,3,2)).mul(M.t()))[0];
119 | AddOrthRow(T); Rot2Euler(T,pitch,yaw,roll); T *= scale;
120 | x = t2[0] - (T.db(0,0)*t3[0] + T.db(0,1)*t3[1] + T.db(0,2)*t3[2]);
121 | y = t2[1] - (T.db(1,0)*t3[0] + T.db(1,1)*t3[1] + T.db(1,2)*t3[2]); return;
122 | }
123 | //=============================================================================
124 | //=============================================================================
125 | //=============================================================================
126 | //=============================================================================
127 | //=============================================================================
128 | //=============================================================================
129 | //=============================================================================
130 | //=============================================================================
131 | //=============================================================================
132 | //=============================================================================
133 | //=============================================================================
134 | PDM& PDM::operator= (PDM const& rhs)
135 | {
136 | this->_V = rhs._V.clone(); this->_E = rhs._E.clone();
137 | this->_M = rhs._M.clone(); this->S_ = rhs.S_.clone();
138 | this->R_ = rhs.R_.clone(); this->s_ = rhs.s_.clone();
139 | this->P_ = rhs.P_.clone(); this->Px_ = rhs.Px_.clone();
140 | this->Py_ = rhs.Py_.clone(); this->Pz_ = rhs.Pz_.clone();
141 | this->R1_ = rhs.R1_.clone(); this->R2_ = rhs.R2_.clone();
142 | this->R3_ = rhs.R3_.clone(); return *this;
143 | }
144 | //===========================================================================
145 | void PDM::Init(cv::Mat &M, cv::Mat &V, cv::Mat &E)
146 | {
147 | assert((M.type() == CV_64F) && (V.type() == CV_64F) && (E.type() == CV_64F));
148 | assert((V.rows == M.rows) && (V.cols == E.cols));
149 | _M = M.clone(); _V = V.clone(); _E = E.clone();
150 | S_.create(_M.rows,1,CV_64F);
151 | R_.create(3,3,CV_64F); s_.create(_M.rows,1,CV_64F); P_.create(2,3,CV_64F);
152 | Px_.create(2,3,CV_64F); Py_.create(2,3,CV_64F); Pz_.create(2,3,CV_64F);
153 | R1_.create(3,3,CV_64F); R2_.create(3,3,CV_64F); R3_.create(3,3,CV_64F);
154 | return;
155 | }
156 | //===========================================================================
157 | void PDM::Clamp(cv::Mat &p,double c)
158 | {
159 | assert((p.rows == _E.cols) && (p.cols == 1) && (p.type() == CV_64F));
160 | cv::MatIterator_ e = _E.begin();
161 | cv::MatIterator_ p1 = p.begin();
162 | cv::MatIterator_ p2 = p.end(); double v;
163 | for(; p1 != p2; ++p1,++e){
164 | v = c*sqrt(*e); if(fabs(*p1) > v){if(*p1 > 0.0)*p1=v; else *p1=-v;}
165 | }return;
166 | }
167 | //===========================================================================
168 | void PDM::CalcShape3D(cv::Mat &s,cv::Mat &plocal)
169 | {
170 | assert((s.type() == CV_64F) && (plocal.type() == CV_64F));
171 | assert((s.rows == _M.rows) && (s.cols = 1));
172 | assert((plocal.rows == _E.cols) && (plocal.cols == 1));
173 | s = _M + _V*plocal; return;
174 | }
175 | //===========================================================================
176 | void PDM::CalcShape2D(cv::Mat &s,cv::Mat &plocal,cv::Mat &pglobl)
177 | {
178 | assert((s.type() == CV_64F) && (plocal.type() == CV_64F) &&
179 | (pglobl.type() == CV_64F));
180 | assert((plocal.rows == _E.cols) && (plocal.cols == 1));
181 | assert((pglobl.rows == 6) && (pglobl.cols == 1));
182 | int n = _M.rows/3; double a=pglobl.db(0,0),x=pglobl.db(4,0),y=pglobl.db(5,0);
183 | Euler2Rot(R_,pglobl); S_ = _M + _V*plocal;
184 | if((s.rows != _M.rows) || (s.cols = 1))s.create(2*n,1,CV_64F);
185 | for(int i = 0; i < n; i++){
186 | s.db(i ,0) = a*( R_.db(0,0)*S_.db(i ,0) + R_.db(0,1)*S_.db(i+n ,0) +
187 | R_.db(0,2)*S_.db(i+n*2,0) )+x;
188 | s.db(i+n,0) = a*( R_.db(1,0)*S_.db(i ,0) + R_.db(1,1)*S_.db(i+n ,0) +
189 | R_.db(1,2)*S_.db(i+n*2,0) )+y;
190 | }return;
191 | }
192 | //===========================================================================
193 | void PDM::CalcParams(cv::Mat &s,cv::Mat &plocal,cv::Mat &pglobl)
194 | {
195 | assert((s.type() == CV_64F) && (s.rows == 2*(_M.rows/3)) && (s.cols = 1));
196 | if((pglobl.rows != 6) || (pglobl.cols != 1) || (pglobl.type() != CV_64F))
197 | pglobl.create(6,1,CV_64F);
198 | int j,n = _M.rows/3; double si,scale,pitch,yaw,roll,tx,ty,Tx,Ty,Tz;
199 | cv::Mat R(3,3,CV_64F),z(n,1,CV_64F),t(3,1,CV_64F),p(_V.cols,1,CV_64F);
200 | cv::Mat r = R.row(2), S(this->nPoints(),3,CV_64F);
201 | plocal = cv::Mat::zeros(_V.cols,1,CV_64F);
202 | for(int iter = 0; iter < 100; iter++){
203 | this->CalcShape3D(S_,plocal);
204 | Align3Dto2DShapes(scale,pitch,yaw,roll,tx,ty,s,S_);
205 | Euler2Rot(R,pitch,yaw,roll); S = (S_.reshape(1,3)).t();
206 | z = scale*S*r.t(); si = 1.0/scale;
207 | Tx = -si*(R.db(0,0)*tx + R.db(1,0)*ty);
208 | Ty = -si*(R.db(0,1)*tx + R.db(1,1)*ty);
209 | Tz = -si*(R.db(0,2)*tx + R.db(1,2)*ty);
210 | for(j = 0; j < n; j++){
211 | t.db(0,0) = s.db(j,0); t.db(1,0) = s.db(j+n,0); t.db(2,0) = z.db(j,0);
212 | S_.db(j ,0) = si*t.dot(R.col(0))+Tx;
213 | S_.db(j+n ,0) = si*t.dot(R.col(1))+Ty;
214 | S_.db(j+n*2,0) = si*t.dot(R.col(2))+Tz;
215 | }
216 | plocal = _V.t()*(S_-_M);
217 | if(iter > 0){if(cv::norm(plocal-p) < 1.0e-5)break;}
218 | plocal.copyTo(p);
219 | }
220 | pglobl.db(0,0) = scale; pglobl.db(1,0) = pitch;
221 | pglobl.db(2,0) = yaw; pglobl.db(3,0) = roll;
222 | pglobl.db(4,0) = tx; pglobl.db(5,0) = ty;
223 | return;
224 | }
225 | //===========================================================================
226 | void PDM::Identity(cv::Mat &plocal,cv::Mat &pglobl)
227 | {
228 | plocal = cv::Mat::zeros(_V.cols,1,CV_64F);
229 | pglobl = (cv::Mat_(6,1) << 1, 0, 0, 0, 0, 0);
230 | }
231 | //===========================================================================
232 | void PDM::CalcRigidJacob(cv::Mat &plocal,cv::Mat &pglobl,cv::Mat &Jacob)
233 | {
234 | int i,n = _M.rows/3,m = _V.cols; double X,Y,Z;
235 | assert((plocal.rows == m) && (plocal.cols == 1) &&
236 | (pglobl.rows == 6) && (pglobl.cols == 1) &&
237 | (Jacob.rows == 2*n) && (Jacob.cols == 6));
238 | double rx[3][3] = {{0,0,0},{0,0,-1},{0,1,0}}; cv::Mat Rx(3,3,CV_64F,rx);
239 | double ry[3][3] = {{0,0,1},{0,0,0},{-1,0,0}}; cv::Mat Ry(3,3,CV_64F,ry);
240 | double rz[3][3] = {{0,-1,0},{1,0,0},{0,0,0}}; cv::Mat Rz(3,3,CV_64F,rz);
241 | double s = pglobl.db(0,0);
242 | this->CalcShape3D(S_,plocal); Euler2Rot(R_,pglobl);
243 | P_ = s*R_(cv::Rect(0,0,3,2)); Px_ = P_*Rx; Py_ = P_*Ry; Pz_ = P_*Rz;
244 | assert(R_.isContinuous() && Px_.isContinuous() &&
245 | Py_.isContinuous() && Pz_.isContinuous());
246 | const double* px = Px_.ptr(0);
247 | const double* py = Py_.ptr(0);
248 | const double* pz = Pz_.ptr(0);
249 | const double* r = R_.ptr(0);
250 | cv::MatIterator_ Jx = Jacob.begin();
251 | cv::MatIterator_ Jy = Jx + n*6;
252 | for(i = 0; i < n; i++){
253 | X=S_.db(i,0); Y=S_.db(i+n,0); Z=S_.db(i+n*2,0);
254 | *Jx++ = r[0]*X + r[1]*Y + r[2]*Z;
255 | *Jy++ = r[3]*X + r[4]*Y + r[5]*Z;
256 | *Jx++ = px[0]*X + px[1]*Y + px[2]*Z;
257 | *Jy++ = px[3]*X + px[4]*Y + px[5]*Z;
258 | *Jx++ = py[0]*X + py[1]*Y + py[2]*Z;
259 | *Jy++ = py[3]*X + py[4]*Y + py[5]*Z;
260 | *Jx++ = pz[0]*X + pz[1]*Y + pz[2]*Z;
261 | *Jy++ = pz[3]*X + pz[4]*Y + pz[5]*Z;
262 | *Jx++ = 1.0; *Jy++ = 0.0; *Jx++ = 0.0; *Jy++ = 1.0;
263 | }return;
264 | }
265 | //===========================================================================
266 | void PDM::CalcJacob(cv::Mat &plocal,cv::Mat &pglobl,cv::Mat &Jacob)
267 | {
268 | int i,j,n = _M.rows/3,m = _V.cols; double X,Y,Z;
269 | assert((plocal.rows == m) && (plocal.cols == 1) &&
270 | (pglobl.rows == 6) && (pglobl.cols == 1) &&
271 | (Jacob.rows == 2*n) && (Jacob.cols == 6+m));
272 | double s = pglobl.db(0,0);
273 | double rx[3][3] = {{0,0,0},{0,0,-1},{0,1,0}}; cv::Mat Rx(3,3,CV_64F,rx);
274 | double ry[3][3] = {{0,0,1},{0,0,0},{-1,0,0}}; cv::Mat Ry(3,3,CV_64F,ry);
275 | double rz[3][3] = {{0,-1,0},{1,0,0},{0,0,0}}; cv::Mat Rz(3,3,CV_64F,rz);
276 | this->CalcShape3D(S_,plocal); Euler2Rot(R_,pglobl);
277 | P_ = s*R_(cv::Rect(0,0,3,2)); Px_ = P_*Rx; Py_ = P_*Ry; Pz_ = P_*Rz;
278 | assert(R_.isContinuous() && Px_.isContinuous() &&
279 | Py_.isContinuous() && Pz_.isContinuous() && P_.isContinuous());
280 | const double* px = Px_.ptr(0);
281 | const double* py = Py_.ptr(0);
282 | const double* pz = Pz_.ptr(0);
283 | const double* p = P_.ptr(0);
284 | const double* r = R_.ptr(0);
285 | cv::MatIterator_ Jx = Jacob.begin();
286 | cv::MatIterator_ Jy = Jx + n*(6+m);
287 | cv::MatIterator_ Vx = _V.begin();
288 | cv::MatIterator_ Vy = Vx + n*m;
289 | cv::MatIterator_ Vz = Vy + n*m;
290 | for(i = 0; i < n; i++){
291 | X=S_.db(i,0); Y=S_.db(i+n,0); Z=S_.db(i+n*2,0);
292 | *Jx++ = r[0]*X + r[1]*Y + r[2]*Z;
293 | *Jy++ = r[3]*X + r[4]*Y + r[5]*Z;
294 | *Jx++ = px[0]*X + px[1]*Y + px[2]*Z;
295 | *Jy++ = px[3]*X + px[4]*Y + px[5]*Z;
296 | *Jx++ = py[0]*X + py[1]*Y + py[2]*Z;
297 | *Jy++ = py[3]*X + py[4]*Y + py[5]*Z;
298 | *Jx++ = pz[0]*X + pz[1]*Y + pz[2]*Z;
299 | *Jy++ = pz[3]*X + pz[4]*Y + pz[5]*Z;
300 | *Jx++ = 1.0; *Jy++ = 0.0; *Jx++ = 0.0; *Jy++ = 1.0;
301 | for(j = 0; j < m; j++,++Vx,++Vy,++Vz){
302 | *Jx++ = p[0]*(*Vx) + p[1]*(*Vy) + p[2]*(*Vz);
303 | *Jy++ = p[3]*(*Vx) + p[4]*(*Vy) + p[5]*(*Vz);
304 | }
305 | }return;
306 | }
307 | //===========================================================================
308 | void PDM::CalcReferenceUpdate(cv::Mat &dp,cv::Mat &plocal,cv::Mat &pglobl)
309 | {
310 | assert((dp.rows == 6+_V.cols) && (dp.cols == 1));
311 | plocal += dp(cv::Rect(0,6,1,_V.cols));
312 | pglobl.db(0,0) += dp.db(0,0);
313 | pglobl.db(4,0) += dp.db(4,0);
314 | pglobl.db(5,0) += dp.db(5,0);
315 | Euler2Rot(R1_,pglobl); R2_ = cv::Mat::eye(3,3,CV_64F);
316 | R2_.db(1,2) = -1.0*(R2_.db(2,1) = dp.db(1,0));
317 | R2_.db(2,0) = -1.0*(R2_.db(0,2) = dp.db(2,0));
318 | R2_.db(0,1) = -1.0*(R2_.db(1,0) = dp.db(3,0));
319 | MetricUpgrade(R2_); R3_ = R1_*R2_; Rot2Euler(R3_,pglobl); return;
320 | }
321 | //===========================================================================
322 | void PDM::ApplySimT(double a,double b,double tx,double ty,cv::Mat &pglobl)
323 | {
324 | assert((pglobl.rows == 6) && (pglobl.cols == 1) && (pglobl.type()==CV_64F));
325 | double angle = atan2(b,a),scale = a/cos(angle);
326 | double ca = cos(angle),sa = sin(angle);
327 | double xc = pglobl.db(4,0),yc = pglobl.db(5,0);
328 | R1_ = cv::Scalar(0); R1_.db(2,2) = 1.0;
329 | R1_.db(0,0) = ca; R1_.db(0,1) = -sa; R1_.db(1,0) = sa; R1_.db(1,1) = ca;
330 | Euler2Rot(R2_,pglobl); R3_ = R1_*R2_;
331 | pglobl.db(0,0) *= scale; Rot2Euler(R3_,pglobl);
332 | pglobl.db(4,0) = a*xc - b*yc + tx; pglobl.db(5,0) = b*xc + a*yc + ty;
333 | return;
334 | }
335 | //===========================================================================
336 | void PDM::Read(ifstream &s,bool readType)
337 | {
338 | if(readType){int type; s >> type; assert(type == IO::PDM);}
339 | IO::ReadMat(s,_V); IO::ReadMat(s,_E); IO::ReadMat(s,_M);
340 | S_.create(_M.rows,1,CV_64F);
341 | R_.create(3,3,CV_64F); s_.create(_M.rows,1,CV_64F); P_.create(2,3,CV_64F);
342 | Px_.create(2,3,CV_64F); Py_.create(2,3,CV_64F); Pz_.create(2,3,CV_64F);
343 | R1_.create(3,3,CV_64F); R2_.create(3,3,CV_64F); R3_.create(3,3,CV_64F);
344 | return;
345 | }
346 | //===========================================================================
347 | void PDM::Write(ofstream &s)
348 | {
349 | s << IO::PDM << " ";
350 | IO::WriteMat(s,_V); IO::WriteMat(s,_E); IO::WriteMat(s,_M); return;
351 | }
352 | //===========================================================================
353 | void PDM::Load(const char* fname)
354 | {
355 | ifstream s(fname); assert(s.is_open()); this->Read(s); s.close(); return;
356 | }
357 | //===========================================================================
358 | void PDM::Save(const char* fname)
359 | {
360 | ofstream s(fname); assert(s.is_open()); this->Write(s);s.close(); return;
361 | }
362 | //===========================================================================
363 |
--------------------------------------------------------------------------------
/native-activity/jni/FaceTracker/lib/Patch.cpp:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | // Copyright (C) 2010, Jason Mora Saragih, all rights reserved.
3 | //
4 | // This file is part of FaceTracker.
5 | //
6 | // Redistribution and use in source and binary forms, with or without
7 | // modification, are permitted provided that the following conditions are met:
8 | //
9 | // * The software is provided under the terms of this licence stricly for
10 | // academic, non-commercial, not-for-profit purposes.
11 | // * Redistributions of source code must retain the above copyright notice,
12 | // this list of conditions (licence) and the following disclaimer.
13 | // * Redistributions in binary form must reproduce the above copyright
14 | // notice, this list of conditions (licence) and the following disclaimer
15 | // in the documentation and/or other materials provided with the
16 | // distribution.
17 | // * The name of the author may not be used to endorse or promote products
18 | // derived from this software without specific prior written permission.
19 | // * As this software depends on other libraries, the user must adhere to
20 | // and keep in place any licencing terms of those libraries.
21 | // * Any publications arising from the use of this software, including but
22 | // not limited to academic journal and conference publications, technical
23 | // reports and manuals, must cite the following work:
24 | //
25 | // J. M. Saragih, S. Lucey, and J. F. Cohn. Face Alignment through
26 | // Subspace Constrained Mean-Shifts. International Conference of Computer
27 | // Vision (ICCV), September, 2009.
28 | //
29 | // THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
30 | // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
32 | // EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
36 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
38 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 | ///////////////////////////////////////////////////////////////////////////////
40 | #include
41 | #define SGN(x) ((x) < 0 ? 0 : 1)
42 | using namespace FACETRACKER;
43 | using namespace std;
44 | //===========================================================================
45 | void sum2one(cv::Mat &M)
46 | {
47 | assert(M.type() == CV_64F);
48 | double sum = 0; int cols = M.cols, rows = M.rows;
49 | if(M.isContinuous()){cols *= rows;rows = 1;}
50 | for(int i = 0; i < rows; i++){
51 | const double* Mi = M.ptr(i);
52 | for(int j = 0; j < cols; j++)sum += *Mi++;
53 | }
54 | M /= sum; return;
55 | }
56 | //===========================================================================
57 | void Grad(cv::Mat im,cv::Mat grad)
58 | {
59 | assert((im.rows == grad.rows) && (im.cols == grad.cols));
60 | assert((im.type() == CV_32F) && (grad.type() == CV_32F));
61 | int x,y,h = im.rows,w = im.cols; float vx,vy; grad = cv::Scalar(0);
62 | cv::MatIterator_ gp = grad.begin() + w+1;
63 | cv::MatIterator_ px1 = im.begin() + w+2;
64 | cv::MatIterator_ px2 = im.begin() + w;
65 | cv::MatIterator_ py1 = im.begin() + 2*w+1;
66 | cv::MatIterator_ py2 = im.begin() + 1;
67 | for(y = 1; y < h-1; y++){
68 | for(x = 1; x < w-1; x++){
69 | vx = *px1++ - *px2++; vy = *py1++ - *py2++; *gp++ = vx*vx + vy*vy;
70 | }
71 | px1 += 2; px2 += 2; py1 += 2; py2 += 2; gp += 2;
72 | }return;
73 | }
74 | //===========================================================================
75 | void LBP(cv::Mat im,cv::Mat lbp)
76 | {
77 | assert((im.rows == lbp.rows) && (im.cols == lbp.cols));
78 | assert((im.type() == CV_32F) && (lbp.type() == CV_32F));
79 | int x,y,h = im.rows,w = im.cols; float v[9]; lbp = cv::Scalar(0);
80 | cv::MatIterator_ lp = lbp.begin() + w+1;
81 | cv::MatIterator_ p1 = im.begin();
82 | cv::MatIterator_ p2 = im.begin() + w;
83 | cv::MatIterator_ p3 = im.begin() + w*2;
84 | for(y = 1; y < h-1; y++){
85 | for(x = 1; x < w-1; x++){
86 | v[4] = *p2++; v[0] = *p2++; v[5] = *p2;
87 | v[1] = *p1++; v[2] = *p1++; v[3] = *p1;
88 | v[6] = *p3++; v[7] = *p3++; v[8] = *p3;
89 | *lp++ =
90 | SGN(v[0]-v[1])*2 + SGN(v[0]-v[2])*4 +
91 | SGN(v[0]-v[3])*8 + SGN(v[0]-v[4])*16 +
92 | SGN(v[0]-v[5])*32 + SGN(v[0]-v[6])*64 +
93 | SGN(v[0]-v[7])*128 + SGN(v[0]-v[8])*256 ;
94 | p1--; p2--; p3--;
95 | }
96 | p1 += 2; p2 += 2; p3 += 2; lp += 2;
97 | }return;
98 | }
99 | //=============================================================================
100 | //=============================================================================
101 | //=============================================================================
102 | //=============================================================================
103 | //=============================================================================
104 | //=============================================================================
105 | //=============================================================================
106 | //=============================================================================
107 | //=============================================================================
108 | //=============================================================================
109 | //=============================================================================
110 | Patch& Patch::operator= (Patch const& rhs)
111 | {
112 | this->_t = rhs._t; this->_a = rhs._a; this->_b = rhs._b;
113 | this->_W = rhs._W.clone(); this->im_ = rhs.im_.clone();
114 | this->res_ = rhs.res_.clone(); return *this;
115 | }
116 | //===========================================================================
117 | void Patch::Load(const char* fname)
118 | {
119 | ifstream s(fname); assert(s.is_open()); this->Read(s); s.close(); return;
120 | }
121 | //===========================================================================
122 | void Patch::Save(const char* fname){
123 | ofstream s(fname); assert(s.is_open()); this->Write(s);s.close(); return;
124 | }
125 | //===========================================================================
126 | void Patch::Write(ofstream &s)
127 | {
128 | s << IO::PATCH << " " << _t << " " << _a << " " << _b <<" ";
129 | IO::WriteMat(s,_W); return;
130 | }
131 | //===========================================================================
132 | void Patch::Read(ifstream &s,bool readType)
133 | {
134 | if(readType){int type; s >> type; assert(type == IO::PATCH);}
135 | s >> _t >> _a >> _b; IO::ReadMat(s,_W); return;
136 | }
137 | //===========================================================================
138 | void Patch::Init(int t, double a, double b, cv::Mat &W)
139 | {
140 | assert((W.type() == CV_32F)); _t=t; _a=a; _b=b; _W=W.clone(); return;
141 | }
142 | //===========================================================================
143 | void Patch::Response(cv::Mat &im,cv::Mat &resp)
144 | {
145 | assert((im.type() == CV_32F) && (resp.type() == CV_64F));
146 | assert((im.rows>=_W.rows) && (im.cols>=_W.cols));
147 | int h = im.rows - _W.rows + 1, w = im.cols - _W.cols + 1; cv::Mat I;
148 | if(resp.rows != h || resp.cols != w)resp.create(h,w,CV_64F);
149 | if(res_.rows != h || res_.cols != w)res_.create(h,w,CV_32F);
150 | if(_t == 0)I = im;
151 | else{
152 | if(im_.rows == im.rows && im_.cols == im.cols)I = im_;
153 | else if(im_.rows >= im.rows && im_.cols >= im.cols)
154 | I = im_(cv::Rect(0,0,im.cols,im.rows));
155 | else{im_.create(im.rows,im.cols,CV_32F); I = im_;}
156 | if (_t == 1)Grad(im,I);
157 | else if(_t == 2)LBP(im,I);
158 | else{
159 | printf("ERROR(%s,%d): Unsupported patch type %d!\n",
160 | __FILE__,__LINE__,_t); abort();
161 | }
162 | }
163 | cv::matchTemplate(I,_W,res_,CV_TM_CCOEFF_NORMED);
164 | cv::MatIterator_ p = resp.begin();
165 | cv::MatIterator_ q1 = res_.begin();
166 | cv::MatIterator_ q2 = res_.end();
167 | while(q1 != q2)*p++ = 1.0/(1.0 + exp( *q1++ * _a + _b ));
168 | return;
169 | }
170 | //===========================================================================
171 | //===========================================================================
172 | //===========================================================================
173 | //===========================================================================
174 | //===========================================================================
175 | //===========================================================================
176 | //===========================================================================
177 | //===========================================================================
178 | //===========================================================================
179 | //===========================================================================
180 | //===========================================================================
181 | MPatch& MPatch::operator= (MPatch const& rhs)
182 | {
183 | _w = rhs._p[0]._W.cols; _h = rhs._p[0]._W.rows;
184 | for(int i = 1; i < (int)rhs._p.size(); i++){
185 | if((rhs._p[i]._W.cols != _w) || (rhs._p[i]._W.rows != _h)){
186 | printf("ERROR(%s,%d): Incompatible patch sizes!\n",
187 | __FILE__,__LINE__); abort();
188 | }
189 | }
190 | _p = rhs._p; return *this;
191 | }
192 | //===========================================================================
193 | void MPatch::Init(std::vector &p)
194 | {
195 | _w = p[0]._W.cols; _h = p[0]._W.rows;
196 | for(int i = 1; i < (int)p.size(); i++){
197 | if((p[i]._W.cols != _w) || (p[i]._W.rows != _h)){
198 | printf("ERROR(%s,%d): Incompatible patch sizes!\n",
199 | __FILE__,__LINE__); abort();
200 | }
201 | }
202 | _p = p; return;
203 | }
204 | //===========================================================================
205 | void MPatch::Load(const char* fname)
206 | {
207 | ifstream s(fname); assert(s.is_open()); this->Read(s); s.close(); return;
208 | }
209 | //===========================================================================
210 | void MPatch::Save(const char* fname){
211 | ofstream s(fname); assert(s.is_open()); this->Write(s);s.close(); return;
212 | }
213 | //===========================================================================
214 | void MPatch::Write(ofstream &s)
215 | {
216 | s << IO::MPATCH << " " << _w << " " << _h << " " << _p.size() << " ";
217 | for(int i = 0; i < (int)_p.size(); i++)_p[i].Write(s); return;
218 | }
219 | //===========================================================================
220 | void MPatch::Read(ifstream &s,bool readType)
221 | {
222 | if(readType){int type; s >> type; assert(type == IO::MPATCH);}
223 | int n; s >> _w >> _h >> n; _p.resize(n);
224 | for(int i = 0; i < n; i++)_p[i].Read(s);
225 | return;
226 | }
227 | //===========================================================================
228 | void MPatch::Response(cv::Mat &im,cv::Mat &resp)
229 | {
230 | assert((im.type() == CV_32F) && (resp.type() == CV_64F));
231 | assert((im.rows >= _h) && (im.cols >= _w));
232 | int h = im.rows - _h + 1, w = im.cols - _w + 1;
233 | if(resp.rows != h || resp.cols != w)resp.create(h,w,CV_64F);
234 | if(res_.rows != h || res_.cols != w)res_.create(h,w,CV_64F);
235 | if(_p.size() == 1){_p[0].Response(im,resp); sum2one(resp);}
236 | else{
237 | resp = cvScalar(1.0);
238 | for(int i = 0; i < (int)_p.size(); i++){
239 | _p[i].Response(im,res_); sum2one(res_); resp = resp.mul(res_);
240 | }
241 | sum2one(resp);
242 | }return;
243 | }
244 | //===========================================================================
245 |
--------------------------------------------------------------------------------
/native-activity/jni/FaceTracker/lib/Tracker.cpp:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | // Copyright (C) 2010, Jason Mora Saragih, all rights reserved.
3 | //
4 | // This file is part of FaceTracker.
5 | //
6 | // Redistribution and use in source and binary forms, with or without
7 | // modification, are permitted provided that the following conditions are met:
8 | //
9 | // * The software is provided under the terms of this licence stricly for
10 | // academic, non-commercial, not-for-profit purposes.
11 | // * Redistributions of source code must retain the above copyright notice,
12 | // this list of conditions (licence) and the following disclaimer.
13 | // * Redistributions in binary form must reproduce the above copyright
14 | // notice, this list of conditions (licence) and the following disclaimer
15 | // in the documentation and/or other materials provided with the
16 | // distribution.
17 | // * The name of the author may not be used to endorse or promote products
18 | // derived from this software without specific prior written permission.
19 | // * As this software depends on other libraries, the user must adhere to
20 | // and keep in place any licencing terms of those libraries.
21 | // * Any publications arising from the use of this software, including but
22 | // not limited to academic journal and conference publications, technical
23 | // reports and manuals, must cite the following work:
24 | //
25 | // J. M. Saragih, S. Lucey, and J. F. Cohn. Face Alignment through
26 | // Subspace Constrained Mean-Shifts. International Conference of Computer
27 | // Vision (ICCV), September, 2009.
28 | //
29 | // THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
30 | // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
32 | // EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
36 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
38 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 | ///////////////////////////////////////////////////////////////////////////////
40 | #include
41 | #define db at
42 | #define TSCALE 0.3
43 | using namespace FACETRACKER;
44 | using namespace std;
45 | //===========================================================================
46 | void Tracker::Init(CLM &clm,FDet &fdet,MFCheck &fcheck,
47 | cv::Mat &rshape,cv::Scalar &simil)
48 | {
49 | _clm = clm; _fdet = fdet; _fcheck = fcheck;
50 | _rshape = rshape.clone(); _simil = simil;
51 | _shape.create(2*_clm._pdm.nPoints(),1,CV_64F);
52 | _rect.x = 0; _rect.y = 0; _rect.width = 0; _rect.height = 0;
53 | _frame = -1; _clm._pdm.Identity(_clm._plocal,_clm._pglobl);
54 | return;
55 | }
56 | //===========================================================================
57 | void Tracker::Load(const char* fname)
58 | {
59 | ifstream s(fname); assert(s.is_open()); this->Read(s); s.close(); return;
60 | }
61 | //===========================================================================
62 | void Tracker::Save(const char* fname)
63 | {
64 | ofstream s(fname); assert(s.is_open()); this->Write(s);s.close(); return;
65 | }
66 | //===========================================================================
67 | void Tracker::Write(ofstream &s)
68 | {
69 | s << IO::TRACKER << " "; _clm.Write(s); _fdet.Write(s); _fcheck.Write(s);
70 | IO::WriteMat(s,_rshape);
71 | s << _simil[0] << " " << _simil[1] << " "
72 | << _simil[2] << " " << _simil[3] << " "; return;
73 | }
74 | //===========================================================================
75 | void Tracker::Read(ifstream &s,bool readType)
76 | {
77 | if(readType){int type; s >> type; assert(type == IO::TRACKER);}
78 | _clm.Read(s); _fdet.Read(s); _fcheck.Read(s); IO::ReadMat(s,_rshape);
79 | s >> _simil[0] >> _simil[1] >> _simil[2] >> _simil[3];
80 | _shape.create(2*_clm._pdm.nPoints(),1,CV_64F);
81 | _rect.x = 0; _rect.y = 0; _rect.width = 0; _rect.height = 0;
82 | _frame = -1; _clm._pdm.Identity(_clm._plocal,_clm._pglobl); return;
83 | }
84 | //===========================================================================
85 | int Tracker::Track(cv::Mat im,vector &wSize, const int fpd,
86 | const int nIter, const double clamp,const double fTol,
87 | const bool fcheck)
88 | {
89 | assert(im.type() == CV_8U);
90 | if(im.channels() == 1)gray_ = im;
91 | else{
92 | if((gray_.rows != im.rows) || (gray_.cols != im.cols))
93 | gray_.create(im.rows,im.cols,CV_8U);
94 | cv::cvtColor(im,gray_,CV_BGR2GRAY);
95 | }
96 | p1 = cv::Point(shape.at(i,0), shape.at(i+n,0));
97 | c = CV_RGB(0,0,255); cv::circle(image,p1,3,c)
98 | bool gen,rsize=true; cv::Rect R;
99 | if((_frame < 0) || (fpd >= 0 && fpd < _frame)){
100 | _frame = 0; R = _fdet.Detect(gray_); gen = true;
101 | }else{R = this->ReDetect(gray_); gen = false;}
102 | if((R.width == 0) || (R.height == 0)){_frame = -1; return -1;}
103 | _frame++;
104 | if(gen){
105 | this->InitShape(R,_shape);
106 | _clm._pdm.CalcParams(_shape,_clm._plocal,_clm._pglobl);
107 | }else{
108 | double tx = R.x - _rect.x,ty = R.y - _rect.y;
109 | _clm._pglobl.db(4,0) += tx; _clm._pglobl.db(5,0) += ty; rsize = false;
110 | }
111 | _clm.Fit(gray_,wSize,nIter,clamp,fTol);
112 | _clm._pdm.CalcShape2D(_shape,_clm._plocal,_clm._pglobl);
113 | if(fcheck){if(!_fcheck.Check(_clm.GetViewIdx(),gray_,_shape))return -1;}
114 | _rect = this->UpdateTemplate(gray_,_shape,rsize);
115 | if((_rect.width == 0) || (_rect.height == 0))return -1; else return 0;
116 | }
117 | //===========================================================================
118 | void Tracker::InitShape(cv::Rect &r,cv::Mat &shape)
119 | {
120 | assert((shape.rows == _rshape.rows) && (shape.cols == _rshape.cols) &&
121 | (shape.type() == CV_64F));
122 | int i,n = _rshape.rows/2; double a,b,tx,ty;
123 | a = r.width*cos(_simil[1])*_simil[0] + 1;
124 | b = r.width*sin(_simil[1])*_simil[0];
125 | tx = r.x + r.width/2 + r.width *_simil[2];
126 | ty = r.y + r.height/2 + r.height*_simil[3];
127 | cv::MatIterator_ sx = _rshape.begin();
128 | cv::MatIterator_ sy = _rshape.begin()+n;
129 | cv::MatIterator_ dx = shape.begin();
130 | cv::MatIterator_ dy = shape.begin()+n;
131 | for(i = 0; i < n; i++,++sx,++sy,++dx,++dy){
132 | *dx = a*(*sx) - b*(*sy) + tx; *dy = b*(*sx) + a*(*sy) + ty;
133 | }return;
134 | }
135 | //===========================================================================
136 | cv::Rect Tracker::ReDetect(cv::Mat &im)
137 | {
138 | int x,y; float v,vb=-2;
139 | int ww = im.cols,hh = im.rows;
140 | int w = TSCALE*ww-temp_.cols+1,h = TSCALE*hh-temp_.rows+1;
141 | if((small_.rows != TSCALE*hh) || (small_.cols != TSCALE*ww))
142 | small_.create(TSCALE*hh,TSCALE*ww,CV_8U);
143 | cv::resize(im,small_,cv::Size(TSCALE*ww,TSCALE*hh),0,0,CV_INTER_LINEAR);
144 | if((ncc_.rows != h) || (ncc_.cols != w))ncc_.create(h,w,CV_32F);
145 | IplImage im_o = small_,temp_o = temp_,ncc_o = ncc_;
146 | cvMatchTemplate(&im_o,&temp_o,&ncc_o,CV_TM_CCOEFF_NORMED);
147 | cv::MatIterator_ p = ncc_.begin(); cv::Rect R;
148 | R.width = temp_.cols; R.height = temp_.rows;
149 | for(y = 0; y < h; y++){
150 | for(x = 0; x < w; x++){
151 | v = *p++; if(v > vb){vb = v; R.x = x; R.y = y;}
152 | }
153 | }
154 | R.x *= 1.0/TSCALE; R.y *= 1.0/TSCALE;
155 | R.width *= 1.0/TSCALE; R.height *= 1.0/TSCALE; return R;
156 | }
157 | //===========================================================================
158 | cv::Rect Tracker::UpdateTemplate(cv::Mat &im,cv::Mat &s,bool rsize)
159 | {
160 | int i,n = s.rows/2; double vx,vy;
161 | cv::MatIterator_ x = s.begin(),y = s.begin()+n;
162 | double xmax=*x,ymax=*y,xmin=*x,ymin=*y;
163 | for(i = 0; i < n; i++){
164 | vx = *x++; vy = *y++;
165 | xmax = std::max(xmax,vx); ymax = std::max(ymax,vy);
166 | xmin = std::min(xmin,vx); ymin = std::min(ymin,vy);
167 | }
168 | if((xmin < 0) || (ymin < 0) || (xmax >= im.cols) || (ymax >= im.rows) ||
169 | cvIsNaN(xmin) || cvIsInf(xmin) || cvIsNaN(xmax) || cvIsInf(xmax) ||
170 | cvIsNaN(ymin) || cvIsInf(ymin) || cvIsNaN(ymax) || cvIsInf(ymax))
171 | return cv::Rect(0,0,0,0);
172 | else{
173 | xmin *= TSCALE; ymin *= TSCALE; xmax *= TSCALE; ymax *= TSCALE;
174 | cv::Rect R = cv::Rect(std::floor(xmin),std::floor(ymin),
175 | std::ceil(xmax-xmin),std::ceil(ymax-ymin));
176 | int ww = im.cols,hh = im.rows;
177 | if(rsize){
178 | if((small_.rows != TSCALE*hh) || (small_.cols != TSCALE*ww))
179 | small_.create(TSCALE*hh,TSCALE*ww,CV_8U);
180 | cv::resize(im,small_,cv::Size(TSCALE*ww,TSCALE*hh),0,0,CV_INTER_LINEAR);
181 | }
182 | if (temp_.rows > 0)
183 | R.width = (((R.width) < (temp_.rows)) ? (R.width) : (temp_.rows));
184 | if (temp_.cols > 0)
185 | R.height = (((R.height) < (temp_.cols)) ? (R.height) : (temp_.cols));
186 | temp_ = small_(R).clone();
187 | R.x *= 1.0/TSCALE; R.y *= 1.0/TSCALE;
188 | R.width *= 1.0/TSCALE; R.height *= 1.0/TSCALE; return R;
189 | }
190 | }
191 | //===========================================================================
192 |
--------------------------------------------------------------------------------
/native-activity/jni/Tracker.h:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | // Copyright (C) 2010, Jason Mora Saragih, all rights reserved.
3 | //
4 | // This file is part of FaceTracker.
5 | //
6 | // Redistribution and use in source and binary forms, with or without
7 | // modification, are permitted provided that the following conditions are met:
8 | //
9 | // * The software is provided under the terms of this licence stricly for
10 | // academic, non-commercial, not-for-profit purposes.
11 | // * Redistributions of source code must retain the above copyright notice,
12 | // this list of conditions (licence) and the following disclaimer.
13 | // * Redistributions in binary form must reproduce the above copyright
14 | // notice, this list of conditions (licence) and the following disclaimer
15 | // in the documentation and/or other materials provided with the
16 | // distribution.
17 | // * The name of the author may not be used to endorse or promote products
18 | // derived from this software without specific prior written permission.
19 | // * As this software depends on other libraries, the user must adhere to
20 | // and keep in place any licencing terms of those libraries.
21 | // * Any publications arising from the use of this software, including but
22 | // not limited to academic journal and conference publications, technical
23 | // reports and manuals, must cite the following work:
24 | //
25 | // J. M. Saragih, S. Lucey, and J. F. Cohn. Face Alignment through
26 | // Subspace Constrained Mean-Shifts. International Conference of Computer
27 | // Vision (ICCV), September, 2009.
28 | //
29 | // THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
30 | // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
32 | // EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 | // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
36 | // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
38 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 | ///////////////////////////////////////////////////////////////////////////////
40 | #ifndef __Tracker_h_
41 | #define __Tracker_h_
42 | #include
43 | #include
44 | #include
45 | namespace FACETRACKER
46 | {
47 | //===========================================================================
48 | /**
49 | Face Tracker
50 | */
51 | class Tracker {
52 | public:
53 | CLM _clm; /**< Constrained Local Model */
54 | FDet _fdet; /**< Face Detector */
55 | int64 _frame; /**< Frame number since last detection */
56 | MFCheck _fcheck; /**< Failure checker */
57 | cv::Mat _shape; /**< Current shape */
58 | cv::Mat _rshape; /**< Reference shape */
59 | cv::Rect _rect; /**< Detected rectangle */
60 | cv::Scalar _simil; /**< Initialization similarity */
61 |
62 | /** NULL constructor */
63 | Tracker(){;}
64 |
65 | /** Constructor from model file */
66 | Tracker(const char* fname){this->Load(fname);}
67 |
68 | /** Constructor from components */
69 | Tracker(CLM &clm,FDet &fdet,MFCheck &fcheck,
70 | cv::Mat &rshape,cv::Scalar &simil){
71 | this->Init(clm,fdet,fcheck,rshape,simil);
72 | }
73 | /**
74 | Track model in current frame
75 | @param im Image containing face
76 | @param wSize List of search window sizes (set from large to small)
77 | @param fpd Number of frames between detections (-1: never)
78 | @param nIter Maximum number of optimization steps to perform.
79 | @param clamp Shape model parameter clamping factor (in standard dev's)
80 | @param fTol Convergence tolerance of optimization
81 | @param fcheck Check if tracking succeeded?
82 | @return -1 on failure, 0 otherwise.
83 | */
84 | int Track(cv::Mat im,std::vector &wSize,
85 | const int fpd =-1,
86 | const int nIter = 10,
87 | const double clamp = 3.0,
88 | const double fTol = 0.01,
89 | const bool fcheck = true);
90 |
91 | /** Reset frame number (will perform detection in next image) */
92 | inline void FrameReset(){_frame = -1;}
93 |
94 | /** Load tracker from model file */
95 | void Load(const char* fname);
96 |
97 | /** Save tracker to model file */
98 | void Save(const char* fname);
99 |
100 | /** Write tracker to file stream */
101 | void Write(std::ofstream &s);
102 |
103 | /** Read tracking from file stream */
104 | void Read(std::ifstream &s,bool readType = true);
105 |
106 | private:
107 | cv::Mat gray_,temp_,ncc_,small_;
108 | void Init(CLM &clm,FDet &fdet,MFCheck &fcheck,
109 | cv::Mat &rshape,cv::Scalar &simil);
110 | void InitShape(cv::Rect &r,cv::Mat &shape);
111 | cv::Rect ReDetect(cv::Mat &im);
112 | cv::Rect UpdateTemplate(cv::Mat &im,cv::Mat &s,bool rsize);
113 | };
114 | //===========================================================================
115 | }
116 | #endif
117 |
--------------------------------------------------------------------------------
/native-activity/jni/libFaceTracker.a:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ajdroid/facetrackerapp/ac0d9c8d2dd1fd64cebb2b4b6120452cfc36a38a/native-activity/jni/libFaceTracker.a
--------------------------------------------------------------------------------
/native-activity/jni/libFaceTracker.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ajdroid/facetrackerapp/ac0d9c8d2dd1fd64cebb2b4b6120452cfc36a38a/native-activity/jni/libFaceTracker.so
--------------------------------------------------------------------------------
/native-activity/jni/model/face.con:
--------------------------------------------------------------------------------
1 | n_connections: 61
2 | {
3 | 0 1
4 | 1 2
5 | 2 3
6 | 3 4
7 | 4 5
8 | 5 6
9 | 6 7
10 | 7 8
11 | 8 9
12 | 9 10
13 | 10 11
14 | 11 12
15 | 12 13
16 | 13 14
17 | 14 15
18 | 15 16
19 | 17 18
20 | 18 19
21 | 19 20
22 | 20 21
23 | 22 23
24 | 23 24
25 | 24 25
26 | 25 26
27 | 27 28
28 | 28 29
29 | 29 30
30 | 31 32
31 | 32 33
32 | 33 34
33 | 34 35
34 | 36 37
35 | 37 38
36 | 38 39
37 | 39 40
38 | 40 41
39 | 41 36
40 | 42 43
41 | 43 44
42 | 44 45
43 | 45 46
44 | 46 47
45 | 47 42
46 | 48 49
47 | 49 50
48 | 50 51
49 | 51 52
50 | 52 53
51 | 53 54
52 | 54 55
53 | 55 56
54 | 56 57
55 | 57 58
56 | 58 59
57 | 59 48
58 | 60 65
59 | 60 61
60 | 61 62
61 | 62 63
62 | 63 64
63 | 64 65
64 | }
65 |
--------------------------------------------------------------------------------
/native-activity/jni/model/face.tri:
--------------------------------------------------------------------------------
1 | n_tri: 91
2 | {
3 | 20 21 23
4 | 21 22 23
5 | 0 1 36
6 | 15 16 45
7 | 0 17 36
8 | 16 26 45
9 | 17 18 37
10 | 25 26 44
11 | 17 36 37
12 | 26 44 45
13 | 18 19 38
14 | 24 25 43
15 | 18 37 38
16 | 25 43 44
17 | 19 20 38
18 | 23 24 43
19 | 20 21 39
20 | 22 23 42
21 | 20 38 39
22 | 23 42 43
23 | 21 22 27
24 | 21 27 39
25 | 22 27 42
26 | 27 28 42
27 | 27 28 39
28 | 28 42 47
29 | 28 39 40
30 | 1 36 41
31 | 15 45 46
32 | 1 2 41
33 | 14 15 46
34 | 28 29 40
35 | 28 29 47
36 | 2 40 41
37 | 14 46 47
38 | 2 29 40
39 | 14 29 47
40 | 2 3 29
41 | 13 14 29
42 | 29 30 31
43 | 29 30 35
44 | 3 29 31
45 | 13 29 35
46 | 30 32 33
47 | 30 33 34
48 | 30 31 32
49 | 30 34 35
50 | 3 4 31
51 | 12 13 35
52 | 4 5 48
53 | 11 12 54
54 | 5 6 48
55 | 10 11 54
56 | 6 48 59
57 | 10 54 55
58 | 6 7 59
59 | 9 10 55
60 | 7 58 59
61 | 9 55 56
62 | 8 57 58
63 | 8 56 57
64 | 7 8 58
65 | 8 9 56
66 | 4 31 48
67 | 12 35 54
68 | 31 48 49
69 | 35 53 54
70 | 31 49 50
71 | 35 52 53
72 | 31 32 50
73 | 34 35 52
74 | 32 33 50
75 | 33 34 52
76 | 33 50 51
77 | 33 51 52
78 | 48 49 60
79 | 49 60 50
80 | 50 60 61
81 | 50 51 61
82 | 51 52 61
83 | 61 62 52
84 | 52 53 62
85 | 53 54 62
86 | 54 55 63
87 | 55 56 63
88 | 56 63 64
89 | 56 57 64
90 | 64 65 57
91 | 57 58 65
92 | 58 59 65
93 | 48 59 65
94 | }
95 |
--------------------------------------------------------------------------------
/native-activity/jni/native.cpp:
--------------------------------------------------------------------------------
1 | #ifndef rectshow
2 | #define rectshow 0
3 | #endif
4 |
5 | #ifndef cam
6 | #define cam 1
7 | #endif
8 |
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | //#include
23 |
24 | using namespace FACETRACKER;
25 | using namespace std;
26 | using namespace cv;
27 |
28 | //== Global variables
29 | std::queue time_queue;
30 |
31 | CV_INLINE int cvRound( float value )
32 | {
33 | #if defined HAVE_LRINT || defined CV_ICC || defined __GNUC__
34 | return (int)lrint(value);
35 | #else
36 | // while this is not IEEE754-compliant rounding, it's usually a good enough approximation
37 | return (int)(value + (value >= 0 ? 0.5f : -0.5f));
38 | #endif
39 | }
40 | //============================================================= Put shape points on screen
41 | void Draw(cv::Mat &image, cv::Mat &shape, cv::Mat &visi)
42 | {
43 | int i,n = shape.rows/2; cv::Point p1,p2; cv::Scalar c;
44 |
45 | //draw points
46 | for(i = 0; i < n; i++)
47 | {
48 | if(visi.at (i,0) == 0)continue;
49 | p1 = cv::Point(shape.at(i,0), shape.at(i+n,0));
50 | c = CV_RGB(0,0,255); cv::circle(image,p1,3,c);
51 | }return;
52 | }
53 | //========================================================================================
54 | struct Engine
55 | {
56 | android_app* app;
57 | cv::Ptr capture;
58 | };
59 | //========================================================================================
60 | static cv::Size calc_optimal_camera_resolution(const char* supported, int width, int height)
61 | {
62 | int frame_width = 0;
63 | int frame_height = 0;
64 |
65 | size_t prev_idx = 0;
66 | size_t idx = 0;
67 | float min_diff = FLT_MAX;
68 |
69 | do
70 | {
71 | int tmp_width;
72 | int tmp_height;
73 |
74 | prev_idx = idx;
75 | while ((supported[idx] != '\0') && (supported[idx] != ','))
76 | idx++;
77 |
78 | sscanf(&supported[prev_idx], "%dx%d", &tmp_width, &tmp_height);
79 |
80 | int w_diff = width - tmp_width;
81 | int h_diff = height - tmp_height;
82 | if ((h_diff >= 0) && (w_diff >= 0))
83 | {
84 | if ((h_diff <= min_diff) && (tmp_height <= 720))
85 | {
86 | frame_width = tmp_width;
87 | frame_height = tmp_height;
88 | min_diff = h_diff;
89 | }
90 | }
91 |
92 | idx++; // to skip comma symbol
93 |
94 | } while(supported[idx-1] != '\0');
95 |
96 | return cv::Size(frame_width, frame_height);
97 | }
98 | //========================================================================================
99 | static void engine_draw_frame(Engine* engine, const cv::Mat& frame)
100 | {
101 | if (engine->app->window == NULL)
102 | return; // No window.
103 |
104 | ANativeWindow_Buffer buffer;
105 | if (ANativeWindow_lock(engine->app->window, &buffer, NULL) < 0)
106 | {
107 | LOGW("Unable to lock window buffer");
108 | return;
109 | }
110 |
111 | int32_t* pixels = (int32_t*)buffer.bits;
112 |
113 | int left_indent = (buffer.width-frame.cols)/2;
114 | int top_indent = (buffer.height-frame.rows)/2;
115 |
116 | if (top_indent > 0)
117 | {
118 | memset(pixels, 0, top_indent*buffer.stride*sizeof(int32_t));
119 | pixels += top_indent*buffer.stride;
120 | }
121 |
122 | for (int yy = 0; yy < frame.rows; yy++)
123 | {
124 | if (left_indent > 0)
125 | {
126 | memset(pixels, 0, left_indent*sizeof(int32_t));
127 | memset(pixels+left_indent+frame.cols, 0, (buffer.stride-frame.cols-left_indent)*sizeof(int32_t));
128 | }
129 | int32_t* line = pixels + left_indent;
130 | size_t line_size = frame.cols*4*sizeof(unsigned char);
131 | memcpy(line, frame.ptr(yy), line_size);
132 | // go to next line
133 | pixels += buffer.stride;
134 | }
135 | ANativeWindow_unlockAndPost(engine->app->window);
136 | }
137 | //========================================================================================
138 | static void engine_handle_cmd(android_app* app, int32_t cmd)
139 | {
140 | Engine* engine = (Engine*)app->userData;
141 | switch (cmd)
142 | {
143 | case APP_CMD_INIT_WINDOW:
144 | if (app->window != NULL)
145 | {
146 | LOGI("APP_CMD_INIT_WINDOW");
147 | //ANativeActivity_setWindowFlags(app->activity, AWINDOW_FLAG_KEEP_SCREEN_ON, 0);
148 | engine->capture = new cv::VideoCapture(cam);
149 | LOGI("VideoCapture Init");
150 | union {double prop; const char* name;} u;
151 | u.prop = engine->capture->get(CV_CAP_PROP_SUPPORTED_PREVIEW_SIZES_STRING);
152 |
153 | int view_width = ANativeWindow_getWidth(app->window);
154 | int view_height = ANativeWindow_getHeight(app->window);
155 |
156 | cv::Size camera_resolution;
157 | if (u.name)
158 | camera_resolution = calc_optimal_camera_resolution(u.name, 640, 480);//cv::Size(720,480);
159 | else
160 | {
161 | LOGE("Cannot get supported camera camera_resolutions");
162 | camera_resolution = cv::Size(ANativeWindow_getWidth(app->window),
163 | ANativeWindow_getHeight(app->window));
164 | }
165 |
166 | if ((camera_resolution.width != 0) && (camera_resolution.height != 0))
167 | {
168 | engine->capture->set(CV_CAP_PROP_FRAME_WIDTH, camera_resolution.width);
169 | engine->capture->set(CV_CAP_PROP_FRAME_HEIGHT, camera_resolution.height);
170 | }
171 |
172 | float scale = std::min((float)view_width/camera_resolution.width,
173 | (float)view_height/camera_resolution.height);
174 |
175 | if (ANativeWindow_setBuffersGeometry(app->window, (int)(view_width/scale),
176 | int(view_height/scale), WINDOW_FORMAT_RGBA_8888) < 0)
177 | {
178 | LOGE("Cannot set pixel format!");
179 | return;
180 | }
181 |
182 | LOGI("Camera initialized at resolution %dx%d", camera_resolution.width, camera_resolution.height);
183 | }
184 | break;
185 | case APP_CMD_TERM_WINDOW:
186 | LOGI("APP_CMD_TERM_WINDOW");
187 |
188 | engine->capture->release();
189 | break;
190 | }
191 | }
192 | //========================================================================================
193 | void android_main(android_app* app)
194 | {
195 | Engine engine;
196 |
197 | LOGI("Entering main");
198 | // Make sure glue isn't stripped.
199 | app_dummy();
200 |
201 | LOGI("Unable to lock window buffer");
202 | size_t engine_size = sizeof(engine); // for Eclipse CDT parser
203 | memset((void*)&engine, 0, engine_size);
204 | app->userData = &engine;
205 | app->onAppCmd = engine_handle_cmd;
206 | engine.app = app;
207 |
208 | //=========================================== Get internal storage paths
209 |
210 | std::string dataPath = engine.app->activity->internalDataPath;
211 | LOGI("Internal data path: %s", dataPath.c_str());
212 | std::string ConfigFile = dataPath + "/face.con";//"storage/sdcard0/assets/model/face.con";
213 | std::string TriFile = dataPath + "/face.tri";
214 | std::string TrackerFile = dataPath + "/face.tracker";
215 | std::string ModelFile = dataPath + "/svm.model";
216 |
217 | //=========================================== Try writing to SD card
218 |
219 | // If this is the first time the app is run
220 | // we need to create the internal storage "files" directory
221 | struct stat sb,sc,sd,sm;
222 | int32_t rescon = stat(dataPath.c_str(), &sb);
223 | int32_t restri = stat(dataPath.c_str(), &sc);
224 | int32_t restrack = stat(dataPath.c_str(), &sd);
225 | // int32_t resmodel = stat(dataPath.c_str(), &sm);
226 |
227 | if (0 == rescon && sb.st_mode & S_IFDIR)
228 | {
229 | LOGD("'files/' dir already in app's internal data storage.");
230 | }
231 | else if (ENOENT == errno)
232 | {
233 | rescon = mkdir(dataPath.c_str(), 0770);
234 | LOGD("'files/' dir created");
235 | }
236 |
237 | if (0 == rescon)
238 | {
239 | // test to see if the config file is already present
240 | rescon = stat(ConfigFile.c_str(), &sb);
241 | restri = stat(TriFile.c_str(), &sc);
242 | restrack = stat(TrackerFile.c_str(), &sd);
243 | // resmodel = stat(TrackerFile.c_str(), &sm);
244 | // if (restrack == 0 && sd.st_mode & S_IFREG)
245 | // {
246 | // LOGI("App config files already present");
247 | //
248 | // }
249 | // else
250 | {
251 | LOGI("Application config files do not exist. Creating them ...");
252 | // read our application config file from the assets inside the apk
253 | // save the config file contents in the application's internal storage
254 | LOGD("Reading config files using the asset manager");
255 |
256 | AAssetManager* assetManager = engine.app->activity->assetManager;
257 | AAsset* configFileAsset = AAssetManager_open(assetManager, "face.con", AASSET_MODE_BUFFER);
258 | const void* configData = AAsset_getBuffer(configFileAsset);
259 | const off_t configLen = AAsset_getLength(configFileAsset);
260 | FILE* appConfigFile = std::fopen(ConfigFile.c_str(), "w+");
261 | AAsset* trackerFileAsset = AAssetManager_open(assetManager, "face.tracker", AASSET_MODE_BUFFER);
262 | const void* trackerData = AAsset_getBuffer(trackerFileAsset);
263 | const off_t trackerLen = AAsset_getLength(trackerFileAsset);
264 | FILE* appTrackerFile = std::fopen(TrackerFile.c_str(), "w+");
265 | AAsset* triFileAsset = AAssetManager_open(assetManager, "face.tri", AASSET_MODE_BUFFER);
266 | const void* triData = AAsset_getBuffer(triFileAsset);
267 | const off_t triLen = AAsset_getLength(triFileAsset);
268 | FILE* appTriFile = std::fopen(TriFile.c_str(), "w+");
269 | // AAsset* modelFileAsset = AAssetManager_open(assetManager, "svm.model", AASSET_MODE_BUFFER);
270 | // const void* modelData = AAsset_getBuffer(modelFileAsset);
271 | // const off_t modelLen = AAsset_getLength(modelFileAsset);
272 | // FILE* appModelFile = std::fopen(ModelFile.c_str(), "w+");
273 |
274 | if (NULL == appConfigFile||NULL == appTriFile||NULL == appTrackerFile)
275 | {
276 | LOGE("Could not create app configuration files");
277 | }
278 | else
279 | {
280 | LOGI("App config file created successfully. Writing config data ...\n");
281 | rescon = std::fwrite(configData, sizeof(char), configLen, appConfigFile);
282 | restri = std::fwrite(triData, sizeof(char), triLen, appTriFile);
283 | restrack = std::fwrite(trackerData, sizeof(char), trackerLen, appTrackerFile);
284 | // resmodel = std::fwrite(modelData, sizeof(char), modelLen, appModelFile);
285 | if (configLen != rescon)
286 | {
287 | LOGE("Error generating app configuration file.\n");
288 | }
289 | }
290 | std::fclose(appConfigFile);
291 | AAsset_close(configFileAsset);
292 | std::fclose(appTriFile);
293 | AAsset_close(triFileAsset);
294 | std::fclose(appTrackerFile);
295 | AAsset_close(trackerFileAsset);
296 | // std::fclose(appModelFile);
297 | // AAsset_close(modelFileAsset);
298 |
299 | }
300 | }
301 |
302 | //=======================================================================================
303 | LOGD("Done some inits");
304 | ANativeActivity_setWindowFlags(engine.app->activity, AWINDOW_FLAG_KEEP_SCREEN_ON, 0); //set screen always on
305 |
306 | float fps = 0;
307 | char ftFile[512],conFile[512],triFile[512], modelFile[512];
308 | bool fcheck = false; double scale = 1; int fpd = -1; bool show = true;
309 | LOGD("Done some inits");
310 | //=========================================== set paths to model files
311 |
312 | strcpy(ftFile,TrackerFile.c_str());
313 | strcpy(triFile,TriFile.c_str());//"/storage/sdcard0/assets/model/face.tri");
314 | strcpy(conFile,ConfigFile.c_str());//"/storage/sdcard0/assets/model/face.con");
315 | // strcpy(modelFile,ModelFile.c_str());//"/storage/sdcard0/assets/model/svm.model");
316 | cv::Mat drawing_frame, gray_frame,temp_frame;
317 | LOGD("Can access file locations: %s", TrackerFile.c_str());
318 | //=========================================== init vars and set other tracking parameters
319 |
320 | std::vector wSize1(1); wSize1[0] = 7;
321 | std::vector wSize2(3); wSize2[0] = 11; wSize2[1] = 9; wSize2[2] = 7;
322 | int nIter = 5; double clamp=3,fTol=0.01;
323 | LOGD("Fine till inits");
324 |
325 | FACETRACKER::Tracker model(ftFile);
326 | // cv::Mat tri=FACETRACKER::IO::LoadTri(triFile);
327 | // cv::Mat con=FACETRACKER::IO::LoadCon(conFile);
328 |
329 |
330 | LOGD("Fine till inits");
331 | double top, left, bottom, right;
332 | cv:: Point topleft,botright;
333 | const Mat& pose = model._clm._pglobl;
334 | double pitch, yaw, roll;
335 | std::string text;
336 | char sss[128];
337 |
338 |
339 | bool failed=true;
340 |
341 | //================================================ loop waiting for stuff to do
342 | //================================================ actual vision part
343 | LOGD("Entering while");
344 | while (1)
345 | {
346 | // Read all pending events.
347 | int ident;
348 | int events;
349 | android_poll_source* source;
350 |
351 | // Process system events
352 | while ((ident=ALooper_pollAll(0, NULL, &events, (void**)&source)) >= 0)
353 | {
354 | // Process this event.
355 | if (source != NULL)
356 | {
357 | source->process(app, source);
358 | }
359 |
360 | // Check if we are exiting.
361 | if (app->destroyRequested != 0)
362 | {
363 | LOGI("Engine thread destroy requested!");
364 | return;
365 | }
366 | }
367 |
368 | int64 then;
369 | int64 now = cv::getTickCount();
370 | time_queue.push(now);
371 | // Capture frame from camera and draw it
372 | if (!engine.capture.empty())
373 | {
374 | if (engine.capture->grab())
375 | engine.capture->retrieve(drawing_frame, CV_CAP_ANDROID_COLOR_FRAME_RGBA);
376 | #if cam
377 | cv::flip(drawing_frame, drawing_frame,1);
378 | #endif
379 | cv::cvtColor(drawing_frame, gray_frame, CV_RGBA2GRAY);
380 | if ((int)model._shape.at(0,0))
381 | {
382 |
383 | int n = model._shape.rows/2;
384 | pitch = pose.at(1, 0);
385 | yaw = pose.at(2, 0);
386 | roll = pose.at(3, 0);
387 |
388 |
389 | //================================================= Set face equalization region extremities
390 |
391 | if (model._shape.at(0,0)<20.5)
392 | {
393 | if(model._shape.at(0,0)<0)
394 | left = 0;
395 | else
396 | left = model._shape.at(0,0);
397 | }else
398 | left = model._shape.at(0,0)-20;
399 |
400 | if(model._shape.at(16,0)+20>drawing_frame.cols-0.5)
401 | {
402 | if(model._shape.at(16,0)>drawing_frame.cols)
403 | right = drawing_frame.cols;
404 | else
405 | right = model._shape.at(16,0);
406 | }else
407 | right= model._shape.at(16,0)+20;
408 |
409 | if(model._shape.at(8+n,0)>drawing_frame.rows-0.5)
410 | {
411 | if(model._shape.at(8+n,0)>drawing_frame.rows)
412 | bottom = drawing_frame.rows;
413 | else
414 | bottom = model._shape.at(8+n,0);
415 | }else
416 | bottom = model._shape.at(8+n,0)+20;
417 |
418 | if(model._shape.at(19+n,0)<10.5)
419 | {
420 | if(model._shape.at(19+n,0)<0)
421 | top = 0;
422 | else
423 | top = model._shape.at(19+n,0);
424 | }else
425 | top = model._shape.at(19+n,0)-10;
426 |
427 |
428 | cv::Rect facereg(cv::Point(left,top),cv::Point(right,bottom));
429 | Mat ROI;
430 | try{
431 | ROI = gray_frame(facereg);
432 | }
433 | catch(...){
434 | LOGE("Lost track at:\n (%.4f, %.4f)", left, top);
435 | LOGE("Lost track at:\n (%.4f, %.4f)", right, bottom);
436 | }
437 | cv::rectangle(gray_frame, facereg, cv::Scalar(0,0,0));
438 | //cv::rectangle(gray_frame, model._rect, cv::Scalar(255,255,255));
439 | cv::equalizeHist(ROI,ROI);
440 | //drawing_frame;
441 | }
442 |
443 |
444 |
445 |
446 | std::vector wSize; if(failed)wSize = wSize2; else wSize = wSize1;
447 | if(model.Track(gray_frame,wSize,fpd,nIter,clamp,fTol,fcheck) == 0)
448 | {
449 | int idx = model._clm.GetViewIdx(); failed = false;
450 | //Draw(drawing_frame,model._shape,model._clm._visi[idx]);
451 | Draw(gray_frame,model._shape,model._clm._visi[idx]);
452 | }else
453 | {
454 | if(show)
455 | {
456 | cv::Mat R(gray_frame,cv::Rect(0,0,150,50)); R = cv::Scalar(0,0,255);
457 | }
458 | model.FrameReset(); failed = true;
459 | }
460 | cvtColor(gray_frame,temp_frame,COLOR_GRAY2RGBA);
461 |
462 | //temp_frame=drawing_frame;
463 |
464 | char buffer[256];
465 | sprintf(buffer, "Display performance: %dx%d @ %.3f", temp_frame.cols, temp_frame.rows, fps);
466 | cv::putText(temp_frame, std::string(buffer), cv::Point(8,420),
467 | cv::FONT_HERSHEY_COMPLEX_SMALL, 1, cv::Scalar(0,255,0,255));
468 | #if rectshow
469 | cv::Point pTopLeft(temp_frame.cols/3, temp_frame.rows/4), pBottomRight(2*temp_frame.cols/3, 3*temp_frame.rows/4);
470 | cv::Rect R(pTopLeft, pBottomRight);
471 | cv::rectangle(temp_frame, R, cv::Scalar(0,0,0));
472 |
473 | cv::Point p1(320, 240);
474 | cv::Scalar c = CV_RGB(0,0,255);
475 | cv::circle(temp_frame,p1,10,c);
476 | #endif
477 |
478 | sprintf(sss,"pitch:%.3f",pitch*180/3.14); text = sss;
479 | cv::putText(temp_frame,text,cv::Point(10,70),CV_FONT_HERSHEY_DUPLEX,1,CV_RGB(0,255,0),2);
480 | sprintf(sss,"yaw:%.3f",yaw*180/3.14); text = sss;
481 | cv::putText(temp_frame,text,cv::Point(10,100),CV_FONT_HERSHEY_DUPLEX,1,CV_RGB(0,255,0),2);
482 | sprintf(sss,"roll:%.3f",roll*180/3.14); text = sss;
483 | cv::putText(temp_frame,text,cv::Point(10,130),CV_FONT_HERSHEY_DUPLEX,1,CV_RGB(0,255,0),2);
484 |
485 |
486 | engine_draw_frame(&engine, temp_frame);
487 |
488 |
489 | if (time_queue.size() >= 2)
490 | then = cv::getTickCount();
491 | else
492 | then = 0;
493 |
494 | time_queue.pop();
495 |
496 | fps = (float)cv::getTickFrequency() / (then-now);
497 | //fps = 24;
498 | }
499 | }
500 | }
501 |
--------------------------------------------------------------------------------
/native-activity/jni/nativeact.h:
--------------------------------------------------------------------------------
1 | /*
2 | * nativeact.h
3 | *
4 | * Created on: 24-May-2015
5 | * Author: abhijat
6 | */
7 |
8 | #ifndef NATIVEACT_H_
9 | #define NATIVEACT_H_
10 |
11 | #include
12 |
13 |
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 |
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 |
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 |
33 |
34 |
35 | #define LOG_TAG "OCV:libnative_activity"
36 | #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
37 | #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
38 | #define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)
39 | #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
40 |
41 |
42 |
43 |
44 | #endif /* NATIVEACT_H_ */
45 |
--------------------------------------------------------------------------------
/native-activity/jni/vecthelp.h:
--------------------------------------------------------------------------------
1 | /*
2 | * vecthelp.h
3 | *
4 | * Created on: 08-Jul-2015
5 | * Author: abhijat
6 | */
7 |
8 | #ifndef VECTHELP_H_
9 | #define VECTHELP_H_
10 | #include