update 1.0.7
This commit is contained in:
Родитель
c71b4a68f5
Коммит
4587fd7431
|
@ -4,9 +4,9 @@ using System.Collections.Generic;
|
|||
|
||||
namespace FaceMaskExample
|
||||
{
|
||||
[CustomEditor(typeof(FaceMaskData))]
|
||||
[CustomEditor (typeof(FaceMaskData))]
|
||||
public class FaceMaskDataEditor : Editor
|
||||
{
|
||||
{
|
||||
SerializedProperty image;
|
||||
SerializedProperty isDynamicMode;
|
||||
SerializedProperty enableColorCorrection;
|
||||
|
@ -16,25 +16,24 @@ namespace FaceMaskExample
|
|||
bool isDrag = false;
|
||||
int currentPointID = -1;
|
||||
|
||||
private void OnEnable()
|
||||
private void OnEnable ()
|
||||
{
|
||||
image = serializedObject.FindProperty("_image");
|
||||
isDynamicMode = serializedObject.FindProperty("isDynamicMode");
|
||||
enableColorCorrection = serializedObject.FindProperty("enableColorCorrection");
|
||||
faceRect = serializedObject.FindProperty("_faceRect");
|
||||
landmarkPoints = serializedObject.FindProperty("_landmarkPoints");
|
||||
image = serializedObject.FindProperty ("_image");
|
||||
isDynamicMode = serializedObject.FindProperty ("isDynamicMode");
|
||||
enableColorCorrection = serializedObject.FindProperty ("enableColorCorrection");
|
||||
faceRect = serializedObject.FindProperty ("_faceRect");
|
||||
landmarkPoints = serializedObject.FindProperty ("_landmarkPoints");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
public override void OnInspectorGUI ()
|
||||
{
|
||||
serializedObject.Update();
|
||||
serializedObject.Update ();
|
||||
|
||||
Texture2D tex = image.objectReferenceValue as Texture2D;
|
||||
|
||||
// Draw image.
|
||||
if (tex != null)
|
||||
{
|
||||
GUILayout.Box(GUIContent.none, GUILayout.Width(tex.width), GUILayout.Height(tex.height));
|
||||
if (tex != null) {
|
||||
GUILayout.Box (GUIContent.none, GUILayout.Width (tex.width), GUILayout.Height (tex.height));
|
||||
Rect imageRect = GUILayoutUtility.GetLastRect ();
|
||||
GUI.DrawTexture (imageRect, tex);
|
||||
|
||||
|
@ -106,20 +105,21 @@ namespace FaceMaskExample
|
|||
}
|
||||
|
||||
// Display input field.
|
||||
EditorGUILayout.PropertyField(image);
|
||||
EditorGUILayout.PropertyField(isDynamicMode);
|
||||
EditorGUILayout.PropertyField(enableColorCorrection);
|
||||
EditorGUILayout.PropertyField(faceRect);
|
||||
EditorGUILayout.PropertyField(landmarkPoints, true);
|
||||
EditorGUILayout.PropertyField (image);
|
||||
EditorGUILayout.PropertyField (isDynamicMode);
|
||||
EditorGUILayout.PropertyField (enableColorCorrection);
|
||||
EditorGUILayout.PropertyField (faceRect);
|
||||
EditorGUILayout.PropertyField (landmarkPoints, true);
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
serializedObject.ApplyModifiedProperties ();
|
||||
}
|
||||
|
||||
private void DrawFaceRect (Rect imageRect, Rect faceRect, Color color)
|
||||
{
|
||||
faceRect.x += imageRect.x; faceRect.y += imageRect.y;
|
||||
faceRect.x += imageRect.x;
|
||||
faceRect.y += imageRect.y;
|
||||
Handles.color = color;
|
||||
Handles.DrawSolidRectangleWithOutline(faceRect, new Color(0, 0, 0, 0), Color.white);
|
||||
Handles.DrawSolidRectangleWithOutline (faceRect, new Color (0, 0, 0, 0), Color.white);
|
||||
}
|
||||
|
||||
private void DrawFaceLandmark (Rect imageRect, SerializedProperty landmarkPoints, Color lineColor, Color pointColor)
|
||||
|
@ -129,49 +129,52 @@ namespace FaceMaskExample
|
|||
Handles.color = lineColor;
|
||||
|
||||
for (int i = 1; i <= 16; ++i)
|
||||
DrawLine(imageRect, landmarkPoints.GetArrayElementAtIndex(i).vector2Value, landmarkPoints.GetArrayElementAtIndex(i-1).vector2Value);
|
||||
DrawLine (imageRect, landmarkPoints.GetArrayElementAtIndex (i).vector2Value, landmarkPoints.GetArrayElementAtIndex (i - 1).vector2Value);
|
||||
|
||||
for (int i = 28; i <= 30; ++i)
|
||||
DrawLine(imageRect, landmarkPoints.GetArrayElementAtIndex(i).vector2Value, landmarkPoints.GetArrayElementAtIndex(i-1).vector2Value);
|
||||
DrawLine (imageRect, landmarkPoints.GetArrayElementAtIndex (i).vector2Value, landmarkPoints.GetArrayElementAtIndex (i - 1).vector2Value);
|
||||
|
||||
for (int i = 18; i <= 21; ++i)
|
||||
DrawLine(imageRect, landmarkPoints.GetArrayElementAtIndex(i).vector2Value, landmarkPoints.GetArrayElementAtIndex(i-1).vector2Value);
|
||||
DrawLine (imageRect, landmarkPoints.GetArrayElementAtIndex (i).vector2Value, landmarkPoints.GetArrayElementAtIndex (i - 1).vector2Value);
|
||||
for (int i = 23; i <= 26; ++i)
|
||||
DrawLine(imageRect, landmarkPoints.GetArrayElementAtIndex(i).vector2Value, landmarkPoints.GetArrayElementAtIndex(i-1).vector2Value);
|
||||
DrawLine (imageRect, landmarkPoints.GetArrayElementAtIndex (i).vector2Value, landmarkPoints.GetArrayElementAtIndex (i - 1).vector2Value);
|
||||
for (int i = 31; i <= 35; ++i)
|
||||
DrawLine(imageRect, landmarkPoints.GetArrayElementAtIndex(i).vector2Value, landmarkPoints.GetArrayElementAtIndex(i-1).vector2Value);
|
||||
DrawLine(imageRect, landmarkPoints.GetArrayElementAtIndex(30).vector2Value, landmarkPoints.GetArrayElementAtIndex(35).vector2Value);
|
||||
DrawLine (imageRect, landmarkPoints.GetArrayElementAtIndex (i).vector2Value, landmarkPoints.GetArrayElementAtIndex (i - 1).vector2Value);
|
||||
DrawLine (imageRect, landmarkPoints.GetArrayElementAtIndex (30).vector2Value, landmarkPoints.GetArrayElementAtIndex (35).vector2Value);
|
||||
|
||||
for (int i = 37; i <= 41; ++i)
|
||||
DrawLine(imageRect, landmarkPoints.GetArrayElementAtIndex(i).vector2Value, landmarkPoints.GetArrayElementAtIndex(i-1).vector2Value);
|
||||
DrawLine(imageRect, landmarkPoints.GetArrayElementAtIndex(36).vector2Value, landmarkPoints.GetArrayElementAtIndex(41).vector2Value);
|
||||
DrawLine (imageRect, landmarkPoints.GetArrayElementAtIndex (i).vector2Value, landmarkPoints.GetArrayElementAtIndex (i - 1).vector2Value);
|
||||
DrawLine (imageRect, landmarkPoints.GetArrayElementAtIndex (36).vector2Value, landmarkPoints.GetArrayElementAtIndex (41).vector2Value);
|
||||
|
||||
for (int i = 43; i <= 47; ++i)
|
||||
DrawLine(imageRect, landmarkPoints.GetArrayElementAtIndex(i).vector2Value, landmarkPoints.GetArrayElementAtIndex(i-1).vector2Value);
|
||||
DrawLine(imageRect, landmarkPoints.GetArrayElementAtIndex(42).vector2Value, landmarkPoints.GetArrayElementAtIndex(47).vector2Value);
|
||||
DrawLine (imageRect, landmarkPoints.GetArrayElementAtIndex (i).vector2Value, landmarkPoints.GetArrayElementAtIndex (i - 1).vector2Value);
|
||||
DrawLine (imageRect, landmarkPoints.GetArrayElementAtIndex (42).vector2Value, landmarkPoints.GetArrayElementAtIndex (47).vector2Value);
|
||||
|
||||
for (int i = 49; i <= 59; ++i)
|
||||
DrawLine(imageRect, landmarkPoints.GetArrayElementAtIndex(i).vector2Value, landmarkPoints.GetArrayElementAtIndex(i-1).vector2Value);
|
||||
DrawLine(imageRect, landmarkPoints.GetArrayElementAtIndex(48).vector2Value, landmarkPoints.GetArrayElementAtIndex(59).vector2Value);
|
||||
DrawLine (imageRect, landmarkPoints.GetArrayElementAtIndex (i).vector2Value, landmarkPoints.GetArrayElementAtIndex (i - 1).vector2Value);
|
||||
DrawLine (imageRect, landmarkPoints.GetArrayElementAtIndex (48).vector2Value, landmarkPoints.GetArrayElementAtIndex (59).vector2Value);
|
||||
|
||||
for (int i = 61; i <= 67; ++i)
|
||||
DrawLine(imageRect, landmarkPoints.GetArrayElementAtIndex(i).vector2Value, landmarkPoints.GetArrayElementAtIndex(i-1).vector2Value);
|
||||
DrawLine(imageRect, landmarkPoints.GetArrayElementAtIndex(60).vector2Value, landmarkPoints.GetArrayElementAtIndex(67).vector2Value);
|
||||
DrawLine (imageRect, landmarkPoints.GetArrayElementAtIndex (i).vector2Value, landmarkPoints.GetArrayElementAtIndex (i - 1).vector2Value);
|
||||
DrawLine (imageRect, landmarkPoints.GetArrayElementAtIndex (60).vector2Value, landmarkPoints.GetArrayElementAtIndex (67).vector2Value);
|
||||
|
||||
// Draw Points.
|
||||
Handles.color = pointColor;
|
||||
for (int i = 0; i < landmarkPoints.arraySize; i++) {
|
||||
Vector2 pt = landmarkPoints.GetArrayElementAtIndex(i).vector2Value;
|
||||
pt.x += imageRect.x; pt.y += imageRect.y;
|
||||
Handles.DrawSolidDisc(pt, Vector3.forward, 2f);
|
||||
Vector2 pt = landmarkPoints.GetArrayElementAtIndex (i).vector2Value;
|
||||
pt.x += imageRect.x;
|
||||
pt.y += imageRect.y;
|
||||
Handles.DrawSolidDisc (pt, Vector3.forward, 2f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawLine (Rect imageRect, Vector2 pt1, Vector2 pt2)
|
||||
{
|
||||
pt1.x += imageRect.x; pt1.y += imageRect.y;
|
||||
pt2.x += imageRect.x; pt2.y += imageRect.y;
|
||||
pt1.x += imageRect.x;
|
||||
pt1.y += imageRect.y;
|
||||
pt2.x += imageRect.x;
|
||||
pt2.y += imageRect.y;
|
||||
Handles.DrawLine (pt1, pt2);
|
||||
}
|
||||
|
||||
|
@ -179,9 +182,10 @@ namespace FaceMaskExample
|
|||
{
|
||||
if (landmarkPoints.isArray && landmarkPoints.arraySize == 68) {
|
||||
for (int i = 0; i < landmarkPoints.arraySize; i++) {
|
||||
Vector2 pt = landmarkPoints.GetArrayElementAtIndex(i).vector2Value;
|
||||
pt.x += imageRect.x; pt.y += imageRect.y;
|
||||
if (rect.Contains(pt))
|
||||
Vector2 pt = landmarkPoints.GetArrayElementAtIndex (i).vector2Value;
|
||||
pt.x += imageRect.x;
|
||||
pt.y += imageRect.y;
|
||||
if (rect.Contains (pt))
|
||||
return i;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
#if UNITY_5 || UNITY_5_3_OR_NEWER
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
|
||||
namespace FaceMaskExample
|
||||
{
|
||||
|
@ -15,17 +14,17 @@ namespace FaceMaskExample
|
|||
/// <summary>
|
||||
/// Create face mask tracked mesh prefab.
|
||||
/// </summary>
|
||||
[MenuItem("Tools/Face Mask Example/Create Face Mask Prefab")]
|
||||
[MenuItem ("Tools/Face Mask Example/Create Face Mask Prefab")]
|
||||
private static void CreateFaceMaskPrefab ()
|
||||
{
|
||||
float width = 512f;
|
||||
float height = 512f;
|
||||
string basePath = "Assets/FaceMaskExample/FaceMaskPrefab/";
|
||||
|
||||
GameObject newObj = new GameObject("FaceMaskTrackedMesh");
|
||||
GameObject newObj = new GameObject ("FaceMaskTrackedMesh");
|
||||
|
||||
//Add MeshFilter Component.
|
||||
MeshFilter meshFilter = newObj.AddComponent<MeshFilter>();
|
||||
MeshFilter meshFilter = newObj.AddComponent<MeshFilter> ();
|
||||
|
||||
// Create Mesh.
|
||||
meshFilter.mesh = new Mesh ();
|
||||
|
@ -33,230 +32,230 @@ namespace FaceMaskExample
|
|||
mesh.name = "DlibFaceLandmark68Mesh";
|
||||
|
||||
// Mesh_vertices
|
||||
Vector3[] vertices = new Vector3[68]{
|
||||
new Vector3(117, 250),
|
||||
new Vector3(124, 291),
|
||||
new Vector3(131, 330),
|
||||
new Vector3(136, 369),
|
||||
new Vector3(146, 404),
|
||||
new Vector3(167, 433),
|
||||
new Vector3(192, 459),
|
||||
new Vector3(222, 480),
|
||||
new Vector3(261, 485),
|
||||
new Vector3(300, 478),
|
||||
Vector3[] vertices = new Vector3[68] {
|
||||
new Vector3 (117, 250),
|
||||
new Vector3 (124, 291),
|
||||
new Vector3 (131, 330),
|
||||
new Vector3 (136, 369),
|
||||
new Vector3 (146, 404),
|
||||
new Vector3 (167, 433),
|
||||
new Vector3 (192, 459),
|
||||
new Vector3 (222, 480),
|
||||
new Vector3 (261, 485),
|
||||
new Vector3 (300, 478),
|
||||
|
||||
new Vector3(328, 453),
|
||||
new Vector3(353, 425),
|
||||
new Vector3(372, 394),
|
||||
new Vector3(383, 357),
|
||||
new Vector3(387, 319),
|
||||
new Vector3(392, 281),
|
||||
new Vector3(397, 241),
|
||||
new Vector3(135, 224),
|
||||
new Vector3(151, 205),
|
||||
new Vector3(175, 196),
|
||||
new Vector3 (328, 453),
|
||||
new Vector3 (353, 425),
|
||||
new Vector3 (372, 394),
|
||||
new Vector3 (383, 357),
|
||||
new Vector3 (387, 319),
|
||||
new Vector3 (392, 281),
|
||||
new Vector3 (397, 241),
|
||||
new Vector3 (135, 224),
|
||||
new Vector3 (151, 205),
|
||||
new Vector3 (175, 196),
|
||||
|
||||
new Vector3(202, 192),
|
||||
new Vector3 (202, 192),
|
||||
//22^23
|
||||
new Vector3(228, 205), //new Vector3(228, 197), y+10
|
||||
new Vector3(281, 205), //new Vector3(281, 197), y+10
|
||||
new Vector3 (228, 205), //new Vector3(228, 197), y+10
|
||||
new Vector3 (281, 205), //new Vector3(281, 197), y+10
|
||||
|
||||
new Vector3(308, 191),
|
||||
new Vector3(334, 195),
|
||||
new Vector3(358, 205),
|
||||
new Vector3(374, 222),
|
||||
new Vector3(255, 228),
|
||||
new Vector3(256, 254),
|
||||
new Vector3(257, 279),
|
||||
new Vector3 (308, 191),
|
||||
new Vector3 (334, 195),
|
||||
new Vector3 (358, 205),
|
||||
new Vector3 (374, 222),
|
||||
new Vector3 (255, 228),
|
||||
new Vector3 (256, 254),
|
||||
new Vector3 (257, 279),
|
||||
|
||||
new Vector3(258, 306),
|
||||
new Vector3(230, 322),
|
||||
new Vector3(243, 325),
|
||||
new Vector3(259, 329),
|
||||
new Vector3(274, 324),
|
||||
new Vector3(288, 320),
|
||||
new Vector3(168, 237),
|
||||
new Vector3(182, 229),
|
||||
new Vector3(200, 229),
|
||||
new Vector3(214, 239),
|
||||
new Vector3 (258, 306),
|
||||
new Vector3 (230, 322),
|
||||
new Vector3 (243, 325),
|
||||
new Vector3 (259, 329),
|
||||
new Vector3 (274, 324),
|
||||
new Vector3 (288, 320),
|
||||
new Vector3 (168, 237),
|
||||
new Vector3 (182, 229),
|
||||
new Vector3 (200, 229),
|
||||
new Vector3 (214, 239),
|
||||
|
||||
new Vector3(199, 241),
|
||||
new Vector3(182, 242),
|
||||
new Vector3(296, 238),
|
||||
new Vector3(310, 228),
|
||||
new Vector3(327, 228),
|
||||
new Vector3(341, 235),
|
||||
new Vector3(328, 240),
|
||||
new Vector3(311, 240),
|
||||
new Vector3 (199, 241),
|
||||
new Vector3 (182, 242),
|
||||
new Vector3 (296, 238),
|
||||
new Vector3 (310, 228),
|
||||
new Vector3 (327, 228),
|
||||
new Vector3 (341, 235),
|
||||
new Vector3 (328, 240),
|
||||
new Vector3 (311, 240),
|
||||
//49
|
||||
new Vector3(198, 372), //new Vector3(198, 367), y+5
|
||||
new Vector3 (198, 372), //new Vector3(198, 367), y+5
|
||||
|
||||
new Vector3(219, 360),
|
||||
new Vector3 (219, 360),
|
||||
|
||||
new Vector3(242, 357),
|
||||
new Vector3(261, 360),
|
||||
new Vector3(280, 357),
|
||||
new Vector3(301, 357),
|
||||
new Vector3 (242, 357),
|
||||
new Vector3 (261, 360),
|
||||
new Vector3 (280, 357),
|
||||
new Vector3 (301, 357),
|
||||
//55
|
||||
new Vector3(322, 367), //new Vector3(322, 362), y+5
|
||||
new Vector3 (322, 367), //new Vector3(322, 362), y+5
|
||||
|
||||
new Vector3(303, 387),
|
||||
new Vector3(282, 396),
|
||||
new Vector3(261, 398),
|
||||
new Vector3(241, 396),
|
||||
new Vector3(218, 388),
|
||||
new Vector3 (303, 387),
|
||||
new Vector3 (282, 396),
|
||||
new Vector3 (261, 398),
|
||||
new Vector3 (241, 396),
|
||||
new Vector3 (218, 388),
|
||||
//61^65
|
||||
new Vector3(205, 373), //new Vector3(205, 368), y+5
|
||||
new Vector3(242, 371), //new Vector3(242, 366), y+5
|
||||
new Vector3(261, 373), //new Vector3(261, 368), y+5
|
||||
new Vector3(280, 370), //new Vector3(280, 365), y+5
|
||||
new Vector3(314, 368), //new Vector3(314, 363) y+5
|
||||
new Vector3 (205, 373), //new Vector3(205, 368), y+5
|
||||
new Vector3 (242, 371), //new Vector3(242, 366), y+5
|
||||
new Vector3 (261, 373), //new Vector3(261, 368), y+5
|
||||
new Vector3 (280, 370), //new Vector3(280, 365), y+5
|
||||
new Vector3 (314, 368), //new Vector3(314, 363) y+5
|
||||
|
||||
new Vector3(281, 382),
|
||||
new Vector3(261, 384),
|
||||
new Vector3(242, 383)
|
||||
new Vector3 (281, 382),
|
||||
new Vector3 (261, 384),
|
||||
new Vector3 (242, 383)
|
||||
};
|
||||
|
||||
Vector3[] vertices2 = (Vector3[])vertices.Clone();
|
||||
Vector3[] vertices2 = (Vector3[])vertices.Clone ();
|
||||
for (int j = 0; j < vertices2.Length; j++) {
|
||||
vertices2 [j].x = (vertices2 [j].x - width/2f) / width;
|
||||
vertices2 [j].y = (height/2f - vertices2 [j].y) / height;
|
||||
vertices2 [j].x = (vertices2 [j].x - width / 2f) / width;
|
||||
vertices2 [j].y = (height / 2f - vertices2 [j].y) / height;
|
||||
}
|
||||
mesh.vertices = vertices2;
|
||||
|
||||
// Mesh_triangles
|
||||
int[] triangles = new int[327]{
|
||||
int[] triangles = new int[327] {
|
||||
// Around the right eye 21
|
||||
0,36,1,
|
||||
1,36,41,
|
||||
1,41,31,
|
||||
41,40,31,
|
||||
40,29,31,
|
||||
40,39,29,
|
||||
39,28,29,
|
||||
39,27,28,
|
||||
39,21,27,
|
||||
38,21,39,
|
||||
20,21,38,
|
||||
37,20,38,
|
||||
37,19,20,
|
||||
18,19,37,
|
||||
18,37,36,
|
||||
17,18,36,
|
||||
0,17,36,
|
||||
0, 36, 1,
|
||||
1, 36, 41,
|
||||
1, 41, 31,
|
||||
41, 40, 31,
|
||||
40, 29, 31,
|
||||
40, 39, 29,
|
||||
39, 28, 29,
|
||||
39, 27, 28,
|
||||
39, 21, 27,
|
||||
38, 21, 39,
|
||||
20, 21, 38,
|
||||
37, 20, 38,
|
||||
37, 19, 20,
|
||||
18, 19, 37,
|
||||
18, 37, 36,
|
||||
17, 18, 36,
|
||||
0, 17, 36,
|
||||
|
||||
// (inner right eye 4)
|
||||
36,37,41,
|
||||
37,40,41,
|
||||
37,38,40,
|
||||
38,39,40,
|
||||
36, 37, 41,
|
||||
37, 40, 41,
|
||||
37, 38, 40,
|
||||
38, 39, 40,
|
||||
|
||||
// Around the left eye 21
|
||||
45,16,15,
|
||||
46,45,15,
|
||||
46,15,35,
|
||||
47,46,35,
|
||||
29,47,35,
|
||||
42,47,29,
|
||||
28,42,29,
|
||||
27,42,28,
|
||||
27,22,42,
|
||||
22,43,42,
|
||||
22,23,43,
|
||||
23,44,43,
|
||||
23,24,44,
|
||||
24,25,44,
|
||||
44,25,45,
|
||||
25,26,45,
|
||||
45,26,16,
|
||||
45, 16, 15,
|
||||
46, 45, 15,
|
||||
46, 15, 35,
|
||||
47, 46, 35,
|
||||
29, 47, 35,
|
||||
42, 47, 29,
|
||||
28, 42, 29,
|
||||
27, 42, 28,
|
||||
27, 22, 42,
|
||||
22, 43, 42,
|
||||
22, 23, 43,
|
||||
23, 44, 43,
|
||||
23, 24, 44,
|
||||
24, 25, 44,
|
||||
44, 25, 45,
|
||||
25, 26, 45,
|
||||
45, 26, 16,
|
||||
|
||||
// (inner left eye 4)
|
||||
44,45,46,
|
||||
47,44,46,
|
||||
43,44,47,
|
||||
42,43,47,
|
||||
44, 45, 46,
|
||||
47, 44, 46,
|
||||
43, 44, 47,
|
||||
42, 43, 47,
|
||||
|
||||
// Eyebrows, nose and cheeks 13
|
||||
20,23,21,
|
||||
21,23,22,
|
||||
21,22,27,
|
||||
29,30,31,
|
||||
29,35,30,
|
||||
30,32,31,
|
||||
30,33,32,
|
||||
30,34,33,
|
||||
30,35,34,
|
||||
1,31,2,
|
||||
2,31,3,
|
||||
35,15,14,
|
||||
35,14,13,
|
||||
20, 23, 21,
|
||||
21, 23, 22,
|
||||
21, 22, 27,
|
||||
29, 30, 31,
|
||||
29, 35, 30,
|
||||
30, 32, 31,
|
||||
30, 33, 32,
|
||||
30, 34, 33,
|
||||
30, 35, 34,
|
||||
1, 31, 2,
|
||||
2, 31, 3,
|
||||
35, 15, 14,
|
||||
35, 14, 13,
|
||||
|
||||
// mouth 48
|
||||
33,51,50,
|
||||
32,33,50,
|
||||
31,32,50,
|
||||
31,50,49,
|
||||
31,49,48,
|
||||
3,31,48,
|
||||
3,48,4,
|
||||
4,48,5,
|
||||
48,59,5,
|
||||
5,59,6,
|
||||
59,58,6,
|
||||
58,7,6,
|
||||
58,57,7,
|
||||
57,8,7,
|
||||
57,9,8,
|
||||
57,56,9,
|
||||
56,10,9,
|
||||
56,55,10,
|
||||
55,11,10,
|
||||
55,54,11,
|
||||
54,12,11,
|
||||
54,13,12,
|
||||
35,13,54,
|
||||
35,54,53,
|
||||
35,53,52,
|
||||
34,35,52,
|
||||
33,34,52,
|
||||
33,52,51,
|
||||
33, 51, 50,
|
||||
32, 33, 50,
|
||||
31, 32, 50,
|
||||
31, 50, 49,
|
||||
31, 49, 48,
|
||||
3, 31, 48,
|
||||
3, 48, 4,
|
||||
4, 48, 5,
|
||||
48, 59, 5,
|
||||
5, 59, 6,
|
||||
59, 58, 6,
|
||||
58, 7, 6,
|
||||
58, 57, 7,
|
||||
57, 8, 7,
|
||||
57, 9, 8,
|
||||
57, 56, 9,
|
||||
56, 10, 9,
|
||||
56, 55, 10,
|
||||
55, 11, 10,
|
||||
55, 54, 11,
|
||||
54, 12, 11,
|
||||
54, 13, 12,
|
||||
35, 13, 54,
|
||||
35, 54, 53,
|
||||
35, 53, 52,
|
||||
34, 35, 52,
|
||||
33, 34, 52,
|
||||
33, 52, 51,
|
||||
|
||||
48,49,60,
|
||||
48,60,59,
|
||||
49,50,61,
|
||||
49,61,60,
|
||||
60,67,59,
|
||||
59,67,58,
|
||||
50,51,61,
|
||||
51,62,61,
|
||||
67,66,58,
|
||||
66,57,58,
|
||||
51,52,63,
|
||||
51,63,62,
|
||||
66,65,56,
|
||||
66,56,57,
|
||||
52,53,63,
|
||||
53,64,63,
|
||||
65,64,55,
|
||||
65,55,56,
|
||||
53,54,64,
|
||||
64,54,55,
|
||||
48, 49, 60,
|
||||
48, 60, 59,
|
||||
49, 50, 61,
|
||||
49, 61, 60,
|
||||
60, 67, 59,
|
||||
59, 67, 58,
|
||||
50, 51, 61,
|
||||
51, 62, 61,
|
||||
67, 66, 58,
|
||||
66, 57, 58,
|
||||
51, 52, 63,
|
||||
51, 63, 62,
|
||||
66, 65, 56,
|
||||
66, 56, 57,
|
||||
52, 53, 63,
|
||||
53, 64, 63,
|
||||
65, 64, 55,
|
||||
65, 55, 56,
|
||||
53, 54, 64,
|
||||
64, 54, 55,
|
||||
|
||||
// inner mouth 6
|
||||
60,61,67,
|
||||
61,62,67,
|
||||
62,66,67,
|
||||
62,63,65,
|
||||
62,65,66,
|
||||
63,64,65
|
||||
60, 61, 67,
|
||||
61, 62, 67,
|
||||
62, 66, 67,
|
||||
62, 63, 65,
|
||||
62, 65, 66,
|
||||
63, 64, 65
|
||||
};
|
||||
mesh.triangles = triangles;
|
||||
|
||||
// Mesh_uv
|
||||
Vector2[] uv = new Vector2[68];
|
||||
for (int j = 0; j < uv.Length; j++) {
|
||||
uv [j].x = vertices[j].x / width;
|
||||
uv [j].y = (height - vertices[j].y) / height;
|
||||
uv [j].x = vertices [j].x / width;
|
||||
uv [j].y = (height - vertices [j].y) / height;
|
||||
}
|
||||
mesh.uv = uv;
|
||||
mesh.uv2 = (Vector2[])uv.Clone ();
|
||||
|
@ -264,40 +263,40 @@ namespace FaceMaskExample
|
|||
mesh.RecalculateNormals ();
|
||||
|
||||
// Add Collider Component.
|
||||
MeshCollider meshCollider = newObj.AddComponent<MeshCollider>();
|
||||
MeshCollider meshCollider = newObj.AddComponent<MeshCollider> ();
|
||||
meshCollider.sharedMesh = CreatePrimitiveQuadMesh ();
|
||||
|
||||
// Add Renderer Component.
|
||||
MeshRenderer meshRenderer = newObj.AddComponent<MeshRenderer>();
|
||||
Material material = new Material(Shader.Find("Hide/FaceMaskShader"));
|
||||
MeshRenderer meshRenderer = newObj.AddComponent<MeshRenderer> ();
|
||||
Material material = new Material (Shader.Find ("Hide/FaceMaskShader"));
|
||||
|
||||
// Create alpha mask texture.
|
||||
Vector2[] facialContourUVPoints = new Vector2[]{
|
||||
uv[0],
|
||||
uv[1],
|
||||
uv[2],
|
||||
uv[3],
|
||||
uv[4],
|
||||
uv[5],
|
||||
uv[6],
|
||||
uv[7],
|
||||
uv[8],
|
||||
uv[9],
|
||||
uv[10],
|
||||
uv[11],
|
||||
uv[12],
|
||||
uv[13],
|
||||
uv[14],
|
||||
uv[15],
|
||||
uv[16],
|
||||
uv[26],
|
||||
uv[25],
|
||||
uv[24],
|
||||
uv[23],
|
||||
uv[20],
|
||||
uv[19],
|
||||
uv[18],
|
||||
uv[17]
|
||||
Vector2[] facialContourUVPoints = new Vector2[] {
|
||||
uv [0],
|
||||
uv [1],
|
||||
uv [2],
|
||||
uv [3],
|
||||
uv [4],
|
||||
uv [5],
|
||||
uv [6],
|
||||
uv [7],
|
||||
uv [8],
|
||||
uv [9],
|
||||
uv [10],
|
||||
uv [11],
|
||||
uv [12],
|
||||
uv [13],
|
||||
uv [14],
|
||||
uv [15],
|
||||
uv [16],
|
||||
uv [26],
|
||||
uv [25],
|
||||
uv [24],
|
||||
uv [23],
|
||||
uv [20],
|
||||
uv [19],
|
||||
uv [18],
|
||||
uv [17]
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -320,20 +319,20 @@ namespace FaceMaskExample
|
|||
};
|
||||
*/
|
||||
|
||||
Vector2[] mouthContourUVPoints = new Vector2[]{
|
||||
uv[60],
|
||||
uv[61],
|
||||
uv[62],
|
||||
uv[63],
|
||||
uv[64],
|
||||
uv[65],
|
||||
uv[66],
|
||||
uv[67]
|
||||
Vector2[] mouthContourUVPoints = new Vector2[] {
|
||||
uv [60],
|
||||
uv [61],
|
||||
uv [62],
|
||||
uv [63],
|
||||
uv [64],
|
||||
uv [65],
|
||||
uv [66],
|
||||
uv [67]
|
||||
};
|
||||
|
||||
Texture2D alphaMaskTexture = AlphaMaskTextureCreater.CreateAlphaMaskTexture (width, height, facialContourUVPoints, /*rightEyeContourUVPoints, leftEyeContourUVPoints,*/ mouthContourUVPoints);
|
||||
Texture2D alphaMaskTexture = AlphaMaskTextureCreater.CreateAlphaMaskTexture (width, height, facialContourUVPoints, /*rightEyeContourUVPoints, leftEyeContourUVPoints,*/mouthContourUVPoints);
|
||||
string alphaMaskTexturePath = basePath + "FaceMaskAlphaMask.png";
|
||||
byte [] pngData = alphaMaskTexture.EncodeToPNG();
|
||||
byte[] pngData = alphaMaskTexture.EncodeToPNG ();
|
||||
|
||||
if (CreateWithoutFolder (basePath)) {
|
||||
File.WriteAllBytes (alphaMaskTexturePath, pngData);
|
||||
|
@ -346,18 +345,18 @@ namespace FaceMaskExample
|
|||
importer.mipmapEnabled = false;
|
||||
importer.wrapMode = TextureWrapMode.Clamp;
|
||||
importer.maxTextureSize = 1024;
|
||||
importer.textureFormat = TextureImporterFormat.RGBA16;
|
||||
// importer.textureFormat = TextureImporterFormat.RGBA16;
|
||||
EditorUtility.SetDirty (importer);
|
||||
AssetDatabase.ImportAsset (alphaMaskTexturePath, ImportAssetOptions.ForceUpdate);
|
||||
AssetDatabase.SaveAssets ();
|
||||
|
||||
GameObject.DestroyImmediate (alphaMaskTexture);
|
||||
alphaMaskTexture = AssetDatabase.LoadAssetAtPath(alphaMaskTexturePath, typeof(Texture2D)) as Texture2D;
|
||||
alphaMaskTexture = AssetDatabase.LoadAssetAtPath (alphaMaskTexturePath, typeof(Texture2D)) as Texture2D;
|
||||
material.SetTexture ("_MaskTex", alphaMaskTexture);
|
||||
meshRenderer.material = material;
|
||||
|
||||
// Add TracedMesh Compornent.
|
||||
newObj.AddComponent<TrackedMesh>();
|
||||
newObj.AddComponent<TrackedMesh> ();
|
||||
|
||||
// Save FaceMask Assets.
|
||||
if (CreateWithoutFolder (basePath)) {
|
||||
|
@ -365,10 +364,10 @@ namespace FaceMaskExample
|
|||
AssetDatabase.CreateAsset (mesh, basePath + "DlibFaceLandmark68Mesh.asset");
|
||||
AssetDatabase.SaveAssets ();
|
||||
|
||||
UnityEngine.Object prefab = AssetDatabase.LoadAssetAtPath(basePath + "FaceMaskTrackedMesh.prefab", typeof(UnityEngine.Object));
|
||||
if (prefab == null){
|
||||
UnityEngine.Object prefab = AssetDatabase.LoadAssetAtPath (basePath + "FaceMaskTrackedMesh.prefab", typeof(UnityEngine.Object));
|
||||
if (prefab == null) {
|
||||
UnityEditor.PrefabUtility.CreatePrefab (basePath + "FaceMaskTrackedMesh.prefab", newObj);
|
||||
}else{
|
||||
} else {
|
||||
UnityEditor.PrefabUtility.ReplacePrefab (newObj, prefab);
|
||||
}
|
||||
AssetDatabase.SaveAssets ();
|
||||
|
@ -377,31 +376,32 @@ namespace FaceMaskExample
|
|||
GameObject.DestroyImmediate (newObj);
|
||||
}
|
||||
|
||||
private static Mesh CreatePrimitiveQuadMesh()
|
||||
private static Mesh CreatePrimitiveQuadMesh ()
|
||||
{
|
||||
GameObject gameObject = GameObject.CreatePrimitive(PrimitiveType.Quad);
|
||||
Mesh mesh = gameObject.GetComponent<MeshFilter>().sharedMesh;
|
||||
GameObject.DestroyImmediate(gameObject);
|
||||
GameObject gameObject = GameObject.CreatePrimitive (PrimitiveType.Quad);
|
||||
Mesh mesh = gameObject.GetComponent<MeshFilter> ().sharedMesh;
|
||||
GameObject.DestroyImmediate (gameObject);
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
private static bool CreateWithoutFolder( string filename )
|
||||
private static bool CreateWithoutFolder (string filename)
|
||||
{
|
||||
string directory = Path.GetDirectoryName(filename);
|
||||
string directory = Path.GetDirectoryName (filename);
|
||||
|
||||
if (Directory.Exists (directory + "/") == true) return true;
|
||||
if (Directory.Exists (directory + "/") == true)
|
||||
return true;
|
||||
|
||||
string[] values = directory.Split( new char[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries );
|
||||
string[] values = directory.Split (new char[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
string checkFolder = string.Empty;
|
||||
foreach( var folder in values ) {
|
||||
foreach (var folder in values) {
|
||||
string baseFolder = checkFolder;
|
||||
if(!string.IsNullOrEmpty(checkFolder)){
|
||||
baseFolder = Path.GetDirectoryName(checkFolder);
|
||||
if (!string.IsNullOrEmpty (checkFolder)) {
|
||||
baseFolder = Path.GetDirectoryName (checkFolder);
|
||||
}
|
||||
checkFolder += folder;
|
||||
if (System.IO.Directory.Exists(checkFolder + "/") != true) {
|
||||
UnityEditor.AssetDatabase.CreateFolder( baseFolder, folder );
|
||||
if (System.IO.Directory.Exists (checkFolder + "/") != true) {
|
||||
UnityEditor.AssetDatabase.CreateFolder (baseFolder, folder);
|
||||
}
|
||||
checkFolder += "/";
|
||||
}
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using UnityEngine.UI;
|
||||
|
||||
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
#endif
|
||||
using UnityEngine.UI;
|
||||
using OpenCVForUnity.CoreModule;
|
||||
|
||||
namespace FaceMaskExample
|
||||
{
|
||||
/// <summary>
|
||||
/// Face mask example.
|
||||
/// FaceMask Example
|
||||
/// </summary>
|
||||
public class FaceMaskExample : MonoBehaviour
|
||||
{
|
||||
|
@ -23,8 +21,8 @@ namespace FaceMaskExample
|
|||
{
|
||||
exampleTitle.text = "FaceMask Example " + Application.version;
|
||||
|
||||
versionInfo.text = OpenCVForUnity.Core.NATIVE_LIBRARY_NAME + " " + OpenCVForUnity.Utils.getVersion () + " (" + OpenCVForUnity.Core.VERSION + ")";
|
||||
versionInfo.text += " / " + "dlibfacelandmarkdetector" + " " + DlibFaceLandmarkDetector.Utils.getVersion ();
|
||||
versionInfo.text = Core.NATIVE_LIBRARY_NAME + " " + OpenCVForUnity.UnityUtils.Utils.getVersion () + " (" + Core.VERSION + ")";
|
||||
versionInfo.text += " / " + "dlibfacelandmarkdetector" + " " + DlibFaceLandmarkDetector.UnityUtils.Utils.getVersion ();
|
||||
versionInfo.text += " / UnityEditor " + Application.unityVersion;
|
||||
versionInfo.text += " / ";
|
||||
|
||||
|
@ -45,9 +43,9 @@ namespace FaceMaskExample
|
|||
#elif UNITY_WEBGL
|
||||
versionInfo.text += "WebGL";
|
||||
#endif
|
||||
versionInfo.text += " ";
|
||||
versionInfo.text += " ";
|
||||
#if ENABLE_MONO
|
||||
versionInfo.text += "Mono";
|
||||
versionInfo.text += "Mono";
|
||||
#elif ENABLE_IL2CPP
|
||||
versionInfo.text += "IL2CPP";
|
||||
#elif ENABLE_DOTNET
|
||||
|
@ -71,47 +69,27 @@ namespace FaceMaskExample
|
|||
|
||||
public void OnShowLicenseButtonClick ()
|
||||
{
|
||||
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
|
||||
SceneManager.LoadScene ("ShowLicense");
|
||||
#else
|
||||
Application.LoadLevel ("ShowLicense");
|
||||
#endif
|
||||
}
|
||||
|
||||
public void OnTexture2DFaceMaskExampleButtonClick ()
|
||||
{
|
||||
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
|
||||
SceneManager.LoadScene ("Texture2DFaceMaskExample");
|
||||
#else
|
||||
Application.LoadLevel ("Texture2DFaceMaskExample");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
public void OnVideoCaptureFaceMaskExampleButtonClick ()
|
||||
{
|
||||
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
|
||||
SceneManager.LoadScene ("VideoCaptureFaceMaskExample");
|
||||
#else
|
||||
Application.LoadLevel ("VideoCaptureFaceMaskExample");
|
||||
#endif
|
||||
}
|
||||
|
||||
public void OnWebCamTextureFaceMaskExampleButtonClick ()
|
||||
{
|
||||
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
|
||||
SceneManager.LoadScene ("WebCamTextureFaceMaskExample");
|
||||
#else
|
||||
Application.LoadLevel ("WebCamTextureFaceMaskExample");
|
||||
#endif
|
||||
}
|
||||
|
||||
public void OnWebCamTextureFaceMaskAdditionalExampleButtonClick ()
|
||||
{
|
||||
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
|
||||
SceneManager.LoadScene ("WebCamTextureFaceMaskAdditionalExample");
|
||||
#else
|
||||
Application.LoadLevel ("WebCamTextureFaceMaskAdditionalExample");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,19 +1,19 @@
|
|||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!29 &1
|
||||
SceneSettings:
|
||||
OcclusionCullingSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PVSData:
|
||||
m_PVSObjectsArray: []
|
||||
m_PVSPortalsArray: []
|
||||
serializedVersion: 2
|
||||
m_OcclusionBakeSettings:
|
||||
smallestOccluder: 5
|
||||
smallestHole: 0.25
|
||||
backfaceThreshold: 100
|
||||
m_SceneGUID: 00000000000000000000000000000000
|
||||
m_OcclusionCullingData: {fileID: 0}
|
||||
--- !u!104 &2
|
||||
RenderSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 6
|
||||
serializedVersion: 8
|
||||
m_Fog: 0
|
||||
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
|
||||
m_FogMode: 3
|
||||
|
@ -25,6 +25,7 @@ RenderSettings:
|
|||
m_AmbientGroundColor: {r: 0.2, g: 0.2, b: 0.2, a: 1}
|
||||
m_AmbientIntensity: 1
|
||||
m_AmbientMode: 3
|
||||
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
|
||||
m_SkyboxMaterial: {fileID: 0}
|
||||
m_HaloStrength: 0.5
|
||||
m_FlareStrength: 1
|
||||
|
@ -37,12 +38,12 @@ RenderSettings:
|
|||
m_ReflectionIntensity: 1
|
||||
m_CustomReflection: {fileID: 0}
|
||||
m_Sun: {fileID: 0}
|
||||
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
--- !u!157 &4
|
||||
LightmapSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 6
|
||||
serializedVersion: 9
|
||||
m_GIWorkflowMode: 1
|
||||
m_LightmapsMode: 1
|
||||
m_GISettings:
|
||||
serializedVersion: 2
|
||||
m_BounceScale: 1
|
||||
|
@ -53,51 +54,75 @@ LightmapSettings:
|
|||
m_EnableBakedLightmaps: 1
|
||||
m_EnableRealtimeLightmaps: 0
|
||||
m_LightmapEditorSettings:
|
||||
serializedVersion: 3
|
||||
serializedVersion: 8
|
||||
m_Resolution: 1
|
||||
m_BakeResolution: 50
|
||||
m_TextureWidth: 1024
|
||||
m_TextureHeight: 1024
|
||||
m_AO: 0
|
||||
m_AOMaxDistance: 1
|
||||
m_Padding: 2
|
||||
m_CompAOExponent: 0
|
||||
m_CompAOExponentDirect: 0
|
||||
m_Padding: 2
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_LightmapsBakeMode: 1
|
||||
m_TextureCompression: 0
|
||||
m_FinalGather: 0
|
||||
m_FinalGatherFiltering: 1
|
||||
m_FinalGatherRayCount: 1024
|
||||
m_ReflectionCompression: 2
|
||||
m_MixedBakeMode: 1
|
||||
m_BakeBackend: 0
|
||||
m_PVRSampling: 1
|
||||
m_PVRDirectSampleCount: 32
|
||||
m_PVRSampleCount: 500
|
||||
m_PVRBounces: 2
|
||||
m_PVRFilterTypeDirect: 0
|
||||
m_PVRFilterTypeIndirect: 0
|
||||
m_PVRFilterTypeAO: 0
|
||||
m_PVRFilteringMode: 0
|
||||
m_PVRCulling: 1
|
||||
m_PVRFilteringGaussRadiusDirect: 1
|
||||
m_PVRFilteringGaussRadiusIndirect: 5
|
||||
m_PVRFilteringGaussRadiusAO: 2
|
||||
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
|
||||
m_PVRFilteringAtrousPositionSigmaIndirect: 2
|
||||
m_PVRFilteringAtrousPositionSigmaAO: 1
|
||||
m_LightingDataAsset: {fileID: 0}
|
||||
m_RuntimeCPUUsage: 25
|
||||
m_ShadowMaskMode: 2
|
||||
--- !u!196 &5
|
||||
NavMeshSettings:
|
||||
serializedVersion: 2
|
||||
m_ObjectHideFlags: 0
|
||||
m_BuildSettings:
|
||||
serializedVersion: 2
|
||||
agentTypeID: 0
|
||||
agentRadius: 0.5
|
||||
agentHeight: 2
|
||||
agentSlope: 45
|
||||
agentClimb: 0.4
|
||||
ledgeDropHeight: 0
|
||||
maxJumpAcrossDistance: 0
|
||||
accuratePlacement: 0
|
||||
minRegionArea: 2
|
||||
cellSize: 0.16666666
|
||||
manualCellSize: 0
|
||||
cellSize: 0.16666666
|
||||
manualTileSize: 0
|
||||
tileSize: 256
|
||||
accuratePlacement: 0
|
||||
m_NavMeshData: {fileID: 0}
|
||||
--- !u!1 &96283524
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 4
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- 4: {fileID: 96283530}
|
||||
- 20: {fileID: 96283529}
|
||||
- 92: {fileID: 96283528}
|
||||
- 124: {fileID: 96283527}
|
||||
- 81: {fileID: 96283526}
|
||||
- 114: {fileID: 96283525}
|
||||
- component: {fileID: 96283530}
|
||||
- component: {fileID: 96283529}
|
||||
- component: {fileID: 96283528}
|
||||
- component: {fileID: 96283527}
|
||||
- component: {fileID: 96283526}
|
||||
- component: {fileID: 96283525}
|
||||
m_Layer: 0
|
||||
m_Name: Main Camera
|
||||
m_TagString: MainCamera
|
||||
|
@ -170,6 +195,8 @@ Camera:
|
|||
m_TargetDisplay: 0
|
||||
m_TargetEye: 3
|
||||
m_HDR: 0
|
||||
m_AllowMSAA: 1
|
||||
m_ForceIntoRT: 0
|
||||
m_OcclusionCulling: 1
|
||||
m_StereoConvergence: 10
|
||||
m_StereoSeparation: 0.022
|
||||
|
@ -183,21 +210,21 @@ Transform:
|
|||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 1, z: -10}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &235587655
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 100058, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 4
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- 224: {fileID: 235587656}
|
||||
- 222: {fileID: 235587659}
|
||||
- 114: {fileID: 235587658}
|
||||
- 114: {fileID: 235587657}
|
||||
- component: {fileID: 235587656}
|
||||
- component: {fileID: 235587659}
|
||||
- component: {fileID: 235587658}
|
||||
- component: {fileID: 235587657}
|
||||
m_Layer: 5
|
||||
m_Name: Scrollbar
|
||||
m_TagString: Untagged
|
||||
|
@ -215,11 +242,11 @@ RectTransform:
|
|||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_Children:
|
||||
- {fileID: 707767033}
|
||||
m_Father: {fileID: 537841981}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 1, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: -10, y: 0}
|
||||
|
@ -264,7 +291,7 @@ MonoBehaviour:
|
|||
m_TargetGraphic: {fileID: 1039786616}
|
||||
m_HandleRect: {fileID: 1039786615}
|
||||
m_Direction: 2
|
||||
m_Value: 0
|
||||
m_Value: 1
|
||||
m_Size: 1
|
||||
m_NumberOfSteps: 0
|
||||
m_OnValueChanged:
|
||||
|
@ -312,12 +339,12 @@ GameObject:
|
|||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 100000, guid: 1ccccd5701fc6ee48964a3c728b8ab62, type: 2}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 4
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- 4: {fileID: 399121681}
|
||||
- 114: {fileID: 399121680}
|
||||
- 114: {fileID: 399121679}
|
||||
- 114: {fileID: 399121678}
|
||||
- component: {fileID: 399121681}
|
||||
- component: {fileID: 399121680}
|
||||
- component: {fileID: 399121679}
|
||||
- component: {fileID: 399121678}
|
||||
m_Layer: 0
|
||||
m_Name: EventSystem
|
||||
m_TagString: Untagged
|
||||
|
@ -381,19 +408,19 @@ Transform:
|
|||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 2
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &537841980
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 100012, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 4
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- 224: {fileID: 537841981}
|
||||
- 114: {fileID: 537841982}
|
||||
- component: {fileID: 537841981}
|
||||
- component: {fileID: 537841982}
|
||||
m_Layer: 5
|
||||
m_Name: SceneList
|
||||
m_TagString: Untagged
|
||||
|
@ -411,12 +438,12 @@ RectTransform:
|
|||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_Children:
|
||||
- {fileID: 976017881}
|
||||
- {fileID: 235587656}
|
||||
m_Father: {fileID: 1661287683}
|
||||
m_RootOrder: 2
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
|
@ -445,13 +472,13 @@ GameObject:
|
|||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 100078, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 4
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- 224: {fileID: 542799651}
|
||||
- 222: {fileID: 542799655}
|
||||
- 114: {fileID: 542799654}
|
||||
- 114: {fileID: 542799653}
|
||||
- 114: {fileID: 542799652}
|
||||
- component: {fileID: 542799651}
|
||||
- component: {fileID: 542799655}
|
||||
- component: {fileID: 542799654}
|
||||
- component: {fileID: 542799653}
|
||||
- component: {fileID: 542799652}
|
||||
m_Layer: 5
|
||||
m_Name: VideoCaptureFaceMaskExampleButton
|
||||
m_TagString: Untagged
|
||||
|
@ -469,11 +496,11 @@ RectTransform:
|
|||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_Children:
|
||||
- {fileID: 1149847639}
|
||||
m_Father: {fileID: 1339781662}
|
||||
m_RootOrder: 3
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
|
@ -591,11 +618,11 @@ GameObject:
|
|||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 100030, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 4
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- 224: {fileID: 629095087}
|
||||
- 222: {fileID: 629095089}
|
||||
- 114: {fileID: 629095088}
|
||||
- component: {fileID: 629095087}
|
||||
- component: {fileID: 629095089}
|
||||
- component: {fileID: 629095088}
|
||||
m_Layer: 5
|
||||
m_Name: Text
|
||||
m_TagString: Untagged
|
||||
|
@ -613,10 +640,10 @@ RectTransform:
|
|||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 2121722087}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
|
@ -668,10 +695,10 @@ GameObject:
|
|||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 4
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- 224: {fileID: 683672276}
|
||||
- 114: {fileID: 683672277}
|
||||
- component: {fileID: 683672276}
|
||||
- component: {fileID: 683672277}
|
||||
m_Layer: 0
|
||||
m_Name: Spacer
|
||||
m_TagString: Untagged
|
||||
|
@ -688,10 +715,10 @@ RectTransform:
|
|||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1339781662}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
|
@ -720,9 +747,9 @@ GameObject:
|
|||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 100044, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 4
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- 224: {fileID: 707767033}
|
||||
- component: {fileID: 707767033}
|
||||
m_Layer: 5
|
||||
m_Name: Sliding Area
|
||||
m_TagString: Untagged
|
||||
|
@ -740,11 +767,11 @@ RectTransform:
|
|||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_Children:
|
||||
- {fileID: 1039786615}
|
||||
m_Father: {fileID: 235587656}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
|
@ -755,11 +782,11 @@ GameObject:
|
|||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 4
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- 224: {fileID: 942732234}
|
||||
- 222: {fileID: 942732236}
|
||||
- 114: {fileID: 942732235}
|
||||
- component: {fileID: 942732234}
|
||||
- component: {fileID: 942732236}
|
||||
- component: {fileID: 942732235}
|
||||
m_Layer: 5
|
||||
m_Name: VersionInfo
|
||||
m_TagString: Untagged
|
||||
|
@ -775,11 +802,11 @@ RectTransform:
|
|||
m_GameObject: {fileID: 942732233}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1.1062992, y: 1.1062992, z: 1}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1661287683}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
|
@ -829,13 +856,13 @@ GameObject:
|
|||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 100010, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 4
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- 224: {fileID: 976017881}
|
||||
- 114: {fileID: 976017885}
|
||||
- 114: {fileID: 976017884}
|
||||
- 222: {fileID: 976017883}
|
||||
- 114: {fileID: 976017882}
|
||||
- component: {fileID: 976017881}
|
||||
- component: {fileID: 976017885}
|
||||
- component: {fileID: 976017884}
|
||||
- component: {fileID: 976017883}
|
||||
- component: {fileID: 976017882}
|
||||
m_Layer: 0
|
||||
m_Name: ScrollView
|
||||
m_TagString: Untagged
|
||||
|
@ -853,11 +880,11 @@ RectTransform:
|
|||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_Children:
|
||||
- {fileID: 1339781662}
|
||||
m_Father: {fileID: 537841981}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: -15, y: 0}
|
||||
|
@ -948,11 +975,11 @@ GameObject:
|
|||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 100050, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 4
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- 224: {fileID: 1020154883}
|
||||
- 222: {fileID: 1020154885}
|
||||
- 114: {fileID: 1020154884}
|
||||
- component: {fileID: 1020154883}
|
||||
- component: {fileID: 1020154885}
|
||||
- component: {fileID: 1020154884}
|
||||
m_Layer: 5
|
||||
m_Name: Text
|
||||
m_TagString: Untagged
|
||||
|
@ -970,10 +997,10 @@ RectTransform:
|
|||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1088752999}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
|
@ -1025,11 +1052,11 @@ GameObject:
|
|||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 100024, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 4
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- 224: {fileID: 1039786615}
|
||||
- 222: {fileID: 1039786617}
|
||||
- 114: {fileID: 1039786616}
|
||||
- component: {fileID: 1039786615}
|
||||
- component: {fileID: 1039786617}
|
||||
- component: {fileID: 1039786616}
|
||||
m_Layer: 5
|
||||
m_Name: Handle
|
||||
m_TagString: Untagged
|
||||
|
@ -1047,10 +1074,10 @@ RectTransform:
|
|||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 707767033}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
|
@ -1096,13 +1123,13 @@ GameObject:
|
|||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 100000, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 4
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- 224: {fileID: 1088752999}
|
||||
- 222: {fileID: 1088753003}
|
||||
- 114: {fileID: 1088753002}
|
||||
- 114: {fileID: 1088753001}
|
||||
- 114: {fileID: 1088753000}
|
||||
- component: {fileID: 1088752999}
|
||||
- component: {fileID: 1088753003}
|
||||
- component: {fileID: 1088753002}
|
||||
- component: {fileID: 1088753001}
|
||||
- component: {fileID: 1088753000}
|
||||
m_Layer: 5
|
||||
m_Name: ShowLicenseButton
|
||||
m_TagString: Untagged
|
||||
|
@ -1120,11 +1147,11 @@ RectTransform:
|
|||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_Children:
|
||||
- {fileID: 1020154883}
|
||||
m_Father: {fileID: 1339781662}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
|
@ -1242,11 +1269,11 @@ GameObject:
|
|||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 100030, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 4
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- 224: {fileID: 1097508684}
|
||||
- 222: {fileID: 1097508686}
|
||||
- 114: {fileID: 1097508685}
|
||||
- component: {fileID: 1097508684}
|
||||
- component: {fileID: 1097508686}
|
||||
- component: {fileID: 1097508685}
|
||||
m_Layer: 5
|
||||
m_Name: Text
|
||||
m_TagString: Untagged
|
||||
|
@ -1264,10 +1291,10 @@ RectTransform:
|
|||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1718137805}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
|
@ -1319,11 +1346,11 @@ GameObject:
|
|||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 100030, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 4
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- 224: {fileID: 1149847639}
|
||||
- 222: {fileID: 1149847641}
|
||||
- 114: {fileID: 1149847640}
|
||||
- component: {fileID: 1149847639}
|
||||
- component: {fileID: 1149847641}
|
||||
- component: {fileID: 1149847640}
|
||||
m_Layer: 5
|
||||
m_Name: Text
|
||||
m_TagString: Untagged
|
||||
|
@ -1341,10 +1368,10 @@ RectTransform:
|
|||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 542799651}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
|
@ -1396,11 +1423,11 @@ GameObject:
|
|||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 100014, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 4
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- 224: {fileID: 1266655927}
|
||||
- 222: {fileID: 1266655929}
|
||||
- 114: {fileID: 1266655928}
|
||||
- component: {fileID: 1266655927}
|
||||
- component: {fileID: 1266655929}
|
||||
- component: {fileID: 1266655928}
|
||||
m_Layer: 5
|
||||
m_Name: Text
|
||||
m_TagString: Untagged
|
||||
|
@ -1418,10 +1445,10 @@ RectTransform:
|
|||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1775689014}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
|
@ -1473,11 +1500,11 @@ GameObject:
|
|||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 100064, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 4
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- 224: {fileID: 1339781662}
|
||||
- 114: {fileID: 1339781664}
|
||||
- 114: {fileID: 1339781663}
|
||||
- component: {fileID: 1339781662}
|
||||
- component: {fileID: 1339781664}
|
||||
- component: {fileID: 1339781663}
|
||||
m_Layer: 0
|
||||
m_Name: List
|
||||
m_TagString: Untagged
|
||||
|
@ -1495,7 +1522,6 @@ RectTransform:
|
|||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_Children:
|
||||
- {fileID: 1088752999}
|
||||
- {fileID: 683672276}
|
||||
|
@ -1505,9 +1531,10 @@ RectTransform:
|
|||
- {fileID: 2121722087}
|
||||
m_Father: {fileID: 976017881}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: -0.000030517578}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 1}
|
||||
--- !u!114 &1339781663
|
||||
|
@ -1531,6 +1558,8 @@ MonoBehaviour:
|
|||
m_Spacing: 5
|
||||
m_ChildForceExpandWidth: 1
|
||||
m_ChildForceExpandHeight: 0
|
||||
m_ChildControlWidth: 1
|
||||
m_ChildControlHeight: 1
|
||||
--- !u!114 &1339781664
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
|
@ -1550,11 +1579,11 @@ GameObject:
|
|||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 4
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- 224: {fileID: 1369632058}
|
||||
- 222: {fileID: 1369632057}
|
||||
- 114: {fileID: 1369632056}
|
||||
- component: {fileID: 1369632058}
|
||||
- component: {fileID: 1369632057}
|
||||
- component: {fileID: 1369632056}
|
||||
m_Layer: 5
|
||||
m_Name: ExampleTitle
|
||||
m_TagString: Untagged
|
||||
|
@ -1609,11 +1638,11 @@ RectTransform:
|
|||
m_GameObject: {fileID: 1369632055}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1.1062992, y: 1.1062992, z: 1}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1661287683}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
|
@ -1624,12 +1653,12 @@ GameObject:
|
|||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 100070, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 4
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- 224: {fileID: 1488394138}
|
||||
- 223: {fileID: 1488394141}
|
||||
- 114: {fileID: 1488394140}
|
||||
- 114: {fileID: 1488394139}
|
||||
- component: {fileID: 1488394138}
|
||||
- component: {fileID: 1488394141}
|
||||
- component: {fileID: 1488394140}
|
||||
- component: {fileID: 1488394139}
|
||||
m_Layer: 5
|
||||
m_Name: Canvas
|
||||
m_TagString: Untagged
|
||||
|
@ -1647,11 +1676,11 @@ RectTransform:
|
|||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 0, y: 0, z: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_Children:
|
||||
- {fileID: 1661287683}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
|
@ -1704,7 +1733,7 @@ Canvas:
|
|||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 1488394137}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 2
|
||||
serializedVersion: 3
|
||||
m_RenderMode: 0
|
||||
m_Camera: {fileID: 0}
|
||||
m_PlaneDistance: 100
|
||||
|
@ -1713,6 +1742,7 @@ Canvas:
|
|||
m_OverrideSorting: 0
|
||||
m_OverridePixelPerfect: 0
|
||||
m_SortingBucketNormalizedSize: 0
|
||||
m_AdditionalShaderChannelsFlag: 25
|
||||
m_SortingLayerID: 0
|
||||
m_SortingOrder: 0
|
||||
m_TargetDisplay: 0
|
||||
|
@ -1721,10 +1751,10 @@ GameObject:
|
|||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 4
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- 224: {fileID: 1661287683}
|
||||
- 114: {fileID: 1661287684}
|
||||
- component: {fileID: 1661287683}
|
||||
- component: {fileID: 1661287684}
|
||||
m_Layer: 5
|
||||
m_Name: Panel
|
||||
m_TagString: Untagged
|
||||
|
@ -1741,13 +1771,13 @@ RectTransform:
|
|||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_Children:
|
||||
- {fileID: 1369632058}
|
||||
- {fileID: 942732234}
|
||||
- {fileID: 537841981}
|
||||
m_Father: {fileID: 1488394138}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
|
@ -1773,18 +1803,20 @@ MonoBehaviour:
|
|||
m_Spacing: 10
|
||||
m_ChildForceExpandWidth: 1
|
||||
m_ChildForceExpandHeight: 0
|
||||
m_ChildControlWidth: 1
|
||||
m_ChildControlHeight: 1
|
||||
--- !u!1 &1718137804
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 100078, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 4
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- 224: {fileID: 1718137805}
|
||||
- 222: {fileID: 1718137809}
|
||||
- 114: {fileID: 1718137808}
|
||||
- 114: {fileID: 1718137807}
|
||||
- 114: {fileID: 1718137806}
|
||||
- component: {fileID: 1718137805}
|
||||
- component: {fileID: 1718137809}
|
||||
- component: {fileID: 1718137808}
|
||||
- component: {fileID: 1718137807}
|
||||
- component: {fileID: 1718137806}
|
||||
m_Layer: 5
|
||||
m_Name: WebCamTextureFaceMaskExampleButton
|
||||
m_TagString: Untagged
|
||||
|
@ -1802,11 +1834,11 @@ RectTransform:
|
|||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_Children:
|
||||
- {fileID: 1097508684}
|
||||
m_Father: {fileID: 1339781662}
|
||||
m_RootOrder: 4
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
|
@ -1924,13 +1956,13 @@ GameObject:
|
|||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 100056, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 4
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- 224: {fileID: 1775689014}
|
||||
- 222: {fileID: 1775689018}
|
||||
- 114: {fileID: 1775689017}
|
||||
- 114: {fileID: 1775689016}
|
||||
- 114: {fileID: 1775689015}
|
||||
- component: {fileID: 1775689014}
|
||||
- component: {fileID: 1775689018}
|
||||
- component: {fileID: 1775689017}
|
||||
- component: {fileID: 1775689016}
|
||||
- component: {fileID: 1775689015}
|
||||
m_Layer: 5
|
||||
m_Name: Texture2DFaceMaskExampleButton
|
||||
m_TagString: Untagged
|
||||
|
@ -1948,11 +1980,11 @@ RectTransform:
|
|||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_Children:
|
||||
- {fileID: 1266655927}
|
||||
m_Father: {fileID: 1339781662}
|
||||
m_RootOrder: 2
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
|
@ -2070,13 +2102,13 @@ GameObject:
|
|||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 100078, guid: e4ed316126173e54da8ebe67c2421b33, type: 2}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 4
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- 224: {fileID: 2121722087}
|
||||
- 222: {fileID: 2121722091}
|
||||
- 114: {fileID: 2121722090}
|
||||
- 114: {fileID: 2121722089}
|
||||
- 114: {fileID: 2121722088}
|
||||
- component: {fileID: 2121722087}
|
||||
- component: {fileID: 2121722091}
|
||||
- component: {fileID: 2121722090}
|
||||
- component: {fileID: 2121722089}
|
||||
- component: {fileID: 2121722088}
|
||||
m_Layer: 5
|
||||
m_Name: WebCamTextureFaceMaskAdditionalExampleButton
|
||||
m_TagString: Untagged
|
||||
|
@ -2094,11 +2126,11 @@ RectTransform:
|
|||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_Children:
|
||||
- {fileID: 629095087}
|
||||
m_Father: {fileID: 1339781662}
|
||||
m_RootOrder: 5
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 67f7db10ac869ee479d4495c3d7af34d
|
||||
timeCreated: 1527248034
|
||||
licenseType: Free
|
||||
timeCreated: 1543732417
|
||||
licenseType: Pro
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 4300000
|
||||
userData:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 470faf94133e4a741bb9abe37e1dfb1f
|
||||
timeCreated: 1527248034
|
||||
licenseType: Free
|
||||
timeCreated: 1543732416
|
||||
licenseType: Pro
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 4
|
||||
|
@ -24,8 +24,8 @@ TextureImporter:
|
|||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 13
|
||||
maxTextureSize: 1024
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
|
@ -53,7 +53,7 @@ TextureImporter:
|
|||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 1024
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 61fa2fcb482ca224e991e0be29d75304
|
||||
timeCreated: 1527248034
|
||||
licenseType: Free
|
||||
timeCreated: 1543732416
|
||||
licenseType: Pro
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
|
|
|
@ -9,20 +9,20 @@ Prefab:
|
|||
m_Modifications: []
|
||||
m_RemovedComponents: []
|
||||
m_ParentPrefab: {fileID: 0}
|
||||
m_RootGameObject: {fileID: 1138294731141240}
|
||||
m_RootGameObject: {fileID: 1150371196015818}
|
||||
m_IsPrefabParent: 1
|
||||
--- !u!1 &1138294731141240
|
||||
--- !u!1 &1150371196015818
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 4506640658691720}
|
||||
- component: {fileID: 33613210590286308}
|
||||
- component: {fileID: 64714649276791744}
|
||||
- component: {fileID: 23122890318565152}
|
||||
- component: {fileID: 114248784669247606}
|
||||
- component: {fileID: 4046574357089060}
|
||||
- component: {fileID: 33026588760814164}
|
||||
- component: {fileID: 64386665923618390}
|
||||
- component: {fileID: 23993217649141104}
|
||||
- component: {fileID: 114013133127415782}
|
||||
m_Layer: 0
|
||||
m_Name: FaceMaskTrackedMesh
|
||||
m_TagString: Untagged
|
||||
|
@ -30,12 +30,12 @@ GameObject:
|
|||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &4506640658691720
|
||||
--- !u!4 &4046574357089060
|
||||
Transform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1138294731141240}
|
||||
m_GameObject: {fileID: 1150371196015818}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
|
@ -43,12 +43,12 @@ Transform:
|
|||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!23 &23122890318565152
|
||||
--- !u!23 &23993217649141104
|
||||
MeshRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1138294731141240}
|
||||
m_GameObject: {fileID: 1150371196015818}
|
||||
m_Enabled: 1
|
||||
m_CastShadows: 1
|
||||
m_ReceiveShadows: 1
|
||||
|
@ -75,19 +75,19 @@ MeshRenderer:
|
|||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
--- !u!33 &33613210590286308
|
||||
--- !u!33 &33026588760814164
|
||||
MeshFilter:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1138294731141240}
|
||||
m_GameObject: {fileID: 1150371196015818}
|
||||
m_Mesh: {fileID: 4300000, guid: 67f7db10ac869ee479d4495c3d7af34d, type: 2}
|
||||
--- !u!64 &64714649276791744
|
||||
--- !u!64 &64386665923618390
|
||||
MeshCollider:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1138294731141240}
|
||||
m_GameObject: {fileID: 1150371196015818}
|
||||
m_Material: {fileID: 0}
|
||||
m_IsTrigger: 0
|
||||
m_Enabled: 1
|
||||
|
@ -96,12 +96,12 @@ MeshCollider:
|
|||
m_InflateMesh: 0
|
||||
m_SkinWidth: 0.01
|
||||
m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0}
|
||||
--- !u!114 &114248784669247606
|
||||
--- !u!114 &114013133127415782
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1138294731141240}
|
||||
m_GameObject: {fileID: 1150371196015818}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: c47754ddde934e14c95f9de06ad6413d, type: 3}
|
||||
|
|
Двоичные данные
Assets/FaceMaskExample/ReadMe.pdf
Двоичные данные
Assets/FaceMaskExample/ReadMe.pdf
Двоичный файл не отображается.
|
@ -2,83 +2,76 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using OpenCVForUnity.CoreModule;
|
||||
using Rect = OpenCVForUnity.CoreModule.Rect;
|
||||
|
||||
namespace OpenCVForUnity.RectangleTrack
|
||||
{
|
||||
/// <summary>
|
||||
/// Rectangle tracker.
|
||||
/// Referring to https://github.com/Itseez/opencv/blob/master/modules/objdetect/src/detection_based_tracker.cpp.
|
||||
/// v 1.0.2
|
||||
/// v 1.0.3
|
||||
/// </summary>
|
||||
public class RectangleTracker
|
||||
{
|
||||
public List<TrackedObject> trackedObjects
|
||||
{
|
||||
public List<TrackedObject> trackedObjects {
|
||||
get { return _trackedObjects; }
|
||||
}
|
||||
|
||||
private List<TrackedObject> _trackedObjects;
|
||||
|
||||
|
||||
public TrackerParameters trackerParameters
|
||||
{
|
||||
public TrackerParameters trackerParameters {
|
||||
get { return _trackerParameters; }
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw new ArgumentNullException("value");
|
||||
set {
|
||||
if (value == null) {
|
||||
throw new ArgumentNullException ("value");
|
||||
}
|
||||
_trackerParameters = value;
|
||||
}
|
||||
}
|
||||
|
||||
private TrackerParameters _trackerParameters;
|
||||
|
||||
|
||||
public List<float> weightsPositionsSmoothing
|
||||
{
|
||||
public List<float> weightsPositionsSmoothing {
|
||||
get { return _weightsPositionsSmoothing; }
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw new ArgumentNullException("value");
|
||||
set {
|
||||
if (value == null) {
|
||||
throw new ArgumentNullException ("value");
|
||||
}
|
||||
_weightsPositionsSmoothing = value;
|
||||
}
|
||||
}
|
||||
private List<float> _weightsPositionsSmoothing = new List<float>();
|
||||
|
||||
public List<float> weightsSizesSmoothing
|
||||
{
|
||||
private List<float> _weightsPositionsSmoothing = new List<float> ();
|
||||
|
||||
public List<float> weightsSizesSmoothing {
|
||||
get { return _weightsSizesSmoothing; }
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw new ArgumentNullException("value");
|
||||
set {
|
||||
if (value == null) {
|
||||
throw new ArgumentNullException ("value");
|
||||
}
|
||||
_weightsSizesSmoothing = value;
|
||||
}
|
||||
}
|
||||
private List<float> _weightsSizesSmoothing = new List<float>();
|
||||
|
||||
public RectangleTracker(TrackerParameters trackerParamerers = null)
|
||||
private List<float> _weightsSizesSmoothing = new List<float> ();
|
||||
|
||||
public RectangleTracker (TrackerParameters trackerParamerers = null)
|
||||
{
|
||||
_trackedObjects = new List<TrackedObject>();
|
||||
_trackedObjects = new List<TrackedObject> ();
|
||||
|
||||
if (trackerParamerers != null)
|
||||
{
|
||||
if (trackerParamerers != null) {
|
||||
this._trackerParameters = trackerParamerers;
|
||||
}
|
||||
else
|
||||
{
|
||||
this._trackerParameters = new TrackerParameters();
|
||||
} else {
|
||||
this._trackerParameters = new TrackerParameters ();
|
||||
}
|
||||
|
||||
_weightsPositionsSmoothing.Add(1);
|
||||
_weightsSizesSmoothing.Add(0.5f);
|
||||
_weightsSizesSmoothing.Add(0.3f);
|
||||
_weightsSizesSmoothing.Add(0.2f);
|
||||
_weightsPositionsSmoothing.Add (1);
|
||||
_weightsSizesSmoothing.Add (0.5f);
|
||||
_weightsSizesSmoothing.Add (0.3f);
|
||||
_weightsSizesSmoothing.Add (0.2f);
|
||||
}
|
||||
|
||||
public enum TrackedRectState : int
|
||||
|
@ -88,76 +81,66 @@ namespace OpenCVForUnity.RectangleTrack
|
|||
}
|
||||
|
||||
|
||||
public void GetObjects(List<Rect> result, bool smoothing = true)
|
||||
public void GetObjects (List<Rect> result, bool smoothing = true)
|
||||
{
|
||||
result.Clear();
|
||||
result.Clear ();
|
||||
|
||||
int count = _trackedObjects.Count;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
for (int i = 0; i < count; i++) {
|
||||
Rect r;
|
||||
if (smoothing)
|
||||
{
|
||||
r = GetSmoothingRect(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
r = _trackedObjects[i].position;
|
||||
if (smoothing) {
|
||||
r = GetSmoothingRect (i);
|
||||
} else {
|
||||
r = _trackedObjects [i].position;
|
||||
}
|
||||
|
||||
if (_trackedObjects[i].state > TrackedState.NEW_DISPLAYED && _trackedObjects[i].state < TrackedState.NEW_HIDED)
|
||||
result.Add(r);
|
||||
if (_trackedObjects [i].state > TrackedState.NEW_DISPLAYED && _trackedObjects [i].state < TrackedState.NEW_HIDED)
|
||||
result.Add (r);
|
||||
|
||||
//LOGD("DetectionBasedTracker::process: found a object with SIZE %d x %d, rect={%d, %d, %d x %d}", r.width, r.height, r.x, r.y, r.width, r.height);
|
||||
//Debug.Log("GetObjects" + r.width + " " + r.height + " " + r.x + " " + r.y + " " + r.width + " " + r.height + " " + trackedObjects[i].state + " " + trackedObjects[i].numDetectedFrames + " " + trackedObjects[i].numFramesNotDetected);
|
||||
}
|
||||
}
|
||||
|
||||
public void GetObjects(List<TrackedRect> result, bool smoothing = true)
|
||||
public void GetObjects (List<TrackedRect> result, bool smoothing = true)
|
||||
{
|
||||
result.Clear();
|
||||
result.Clear ();
|
||||
|
||||
int count = _trackedObjects.Count;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
for (int i = 0; i < count; i++) {
|
||||
Rect r;
|
||||
if (smoothing)
|
||||
{
|
||||
r = GetSmoothingRect(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
r = _trackedObjects[i].position;
|
||||
if (smoothing) {
|
||||
r = GetSmoothingRect (i);
|
||||
} else {
|
||||
r = _trackedObjects [i].position;
|
||||
}
|
||||
|
||||
result.Add(new TrackedRect(_trackedObjects[i].id, r, _trackedObjects[i].state, _trackedObjects[i].numDetectedFrames, _trackedObjects[i].numFramesNotDetected));
|
||||
result.Add (new TrackedRect (_trackedObjects [i].id, r, _trackedObjects [i].state, _trackedObjects [i].numDetectedFrames, _trackedObjects [i].numFramesNotDetected));
|
||||
|
||||
//LOGD("DetectionBasedTracker::process: found a object with SIZE %d x %d, rect={%d, %d, %d x %d}", r.width, r.height, r.x, r.y, r.width, r.height);
|
||||
//Debug.Log("GetObjects" + r.width + " " + r.height + " " + r.x + " " + r.y + " " + r.width + " " + r.height + " " + trackedObjects[i].state + " " + trackedObjects[i].numDetectedFrames + " " + trackedObjects[i].numFramesNotDetected);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateTrackedObjects(List<Rect> detectedObjects)
|
||||
public void UpdateTrackedObjects (List<Rect> detectedObjects)
|
||||
{
|
||||
if (detectedObjects == null)
|
||||
throw new ArgumentNullException("detectedObjects");
|
||||
throw new ArgumentNullException ("detectedObjects");
|
||||
|
||||
Rect[] correctionRects = CreateCorrectionBySpeedOfRects();
|
||||
Rect[] correctionRects = CreateCorrectionBySpeedOfRects ();
|
||||
|
||||
int N1 = (int)_trackedObjects.Count;
|
||||
int N2 = (int)detectedObjects.Count;
|
||||
|
||||
for (int i = 0; i < N1; i++)
|
||||
{
|
||||
_trackedObjects[i].numDetectedFrames++;
|
||||
for (int i = 0; i < N1; i++) {
|
||||
_trackedObjects [i].numDetectedFrames++;
|
||||
}
|
||||
|
||||
int[] correspondence = Enumerable.Repeat<int>((int)TrackedRectState.NEW_RECTANGLE, N2).ToArray();
|
||||
int[] correspondence = Enumerable.Repeat<int> ((int)TrackedRectState.NEW_RECTANGLE, N2).ToArray ();
|
||||
|
||||
|
||||
for (int i = 0; i < N1; i++)
|
||||
{
|
||||
TrackedObject curObject = _trackedObjects[i];
|
||||
for (int i = 0; i < N1; i++) {
|
||||
TrackedObject curObject = _trackedObjects [i];
|
||||
|
||||
int bestIndex = -1;
|
||||
int bestArea = -1;
|
||||
|
@ -165,101 +148,83 @@ namespace OpenCVForUnity.RectangleTrack
|
|||
//int numpositions = (int)curObject.lastPositions.Count;
|
||||
//if (numpositions > 0) UnityEngine.Debug.LogError("numpositions > 0 is false");
|
||||
|
||||
//Rect prevRect = curObject.lastPositions[numpositions - 1];
|
||||
Rect prevRect = correctionRects[i];
|
||||
//OpenCVRect prevRect = curObject.lastPositions[numpositions - 1];
|
||||
Rect prevRect = correctionRects [i];
|
||||
|
||||
for (int j = 0; j < N2; j++)
|
||||
{
|
||||
if (correspondence[j] >= 0)
|
||||
{
|
||||
for (int j = 0; j < N2; j++) {
|
||||
if (correspondence [j] >= 0) {
|
||||
//Debug.Log("DetectionBasedTracker::updateTrackedObjects: j=" + j + " is rejected, because it has correspondence=" + correspondence[j]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (correspondence[j] != (int)TrackedRectState.NEW_RECTANGLE)
|
||||
{
|
||||
if (correspondence [j] != (int)TrackedRectState.NEW_RECTANGLE) {
|
||||
//Debug.Log("DetectionBasedTracker::updateTrackedObjects: j=" + j + " is rejected, because it is intersected with another rectangle");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (IsCollideByRectangle(prevRect, detectedObjects[j], _trackerParameters.coeffRectangleOverlap))
|
||||
{
|
||||
Rect r = Intersect(prevRect, detectedObjects[j]);
|
||||
if ((r.width > 0) && (r.height > 0))
|
||||
{
|
||||
if (IsCollideByRectangle (prevRect, detectedObjects [j], _trackerParameters.coeffRectangleOverlap)) {
|
||||
Rect r = Intersect (prevRect, detectedObjects [j]);
|
||||
if ((r.width > 0) && (r.height > 0)) {
|
||||
//Debug.Log("DetectionBasedTracker::updateTrackedObjects: There is intersection between prevRect and detectedRect r={" + r.x + ", " + r.y + ", " + r.width + ", " + r.height + "]");
|
||||
|
||||
correspondence[j] = (int)TrackedRectState.INTERSECTED_RECTANGLE;
|
||||
correspondence [j] = (int)TrackedRectState.INTERSECTED_RECTANGLE;
|
||||
|
||||
if (r.area() > bestArea)
|
||||
{
|
||||
if (r.area () > bestArea) {
|
||||
//Debug.Log("DetectionBasedTracker::updateTrackedObjects: The area of intersection is " + r.area() + " it is better than bestArea= " + bestArea);
|
||||
|
||||
bestIndex = j;
|
||||
bestArea = (int)r.area();
|
||||
bestArea = (int)r.area ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bestIndex >= 0)
|
||||
{
|
||||
if (bestIndex >= 0) {
|
||||
//Debug.Log("DetectionBasedTracker::updateTrackedObjects: The best correspondence for i=" + i + " is j=" + bestIndex);
|
||||
|
||||
correspondence[bestIndex] = i;
|
||||
correspondence [bestIndex] = i;
|
||||
|
||||
Rect bestRect = detectedObjects[bestIndex];
|
||||
Rect bestRect = detectedObjects [bestIndex];
|
||||
|
||||
for (int j = 0; j < N2; j++)
|
||||
{
|
||||
if (correspondence[j] >= 0)
|
||||
for (int j = 0; j < N2; j++) {
|
||||
if (correspondence [j] >= 0)
|
||||
continue;
|
||||
|
||||
if (IsCollideByRectangle(detectedObjects[j], bestRect, _trackerParameters.coeffRectangleOverlap))
|
||||
{
|
||||
Rect r = Intersect(detectedObjects[j], bestRect);
|
||||
if (IsCollideByRectangle (detectedObjects [j], bestRect, _trackerParameters.coeffRectangleOverlap)) {
|
||||
Rect r = Intersect (detectedObjects [j], bestRect);
|
||||
|
||||
if ((r.width > 0) && (r.height > 0))
|
||||
{
|
||||
if ((r.width > 0) && (r.height > 0)) {
|
||||
//Debug.Log("DetectionBasedTracker::updateTrackedObjects: Found intersection between rectangles j= " + j + " and bestIndex= " + bestIndex + " rectangle j= " + j + " is marked as intersected");
|
||||
|
||||
correspondence[j] = (int)TrackedRectState.INTERSECTED_RECTANGLE;
|
||||
correspondence [j] = (int)TrackedRectState.INTERSECTED_RECTANGLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
//Debug.Log("DetectionBasedTracker::updateTrackedObjects: There is no correspondence for i= " + i);
|
||||
curObject.numFramesNotDetected++;
|
||||
}
|
||||
}
|
||||
|
||||
//Debug.Log("DetectionBasedTracker::updateTrackedObjects: start second cycle");
|
||||
for (int j = 0; j < N2; j++)
|
||||
{
|
||||
int i = correspondence[j];
|
||||
if (i >= 0)
|
||||
{//add position
|
||||
for (int j = 0; j < N2; j++) {
|
||||
int i = correspondence [j];
|
||||
if (i >= 0) {//add position
|
||||
//Debug.Log("DetectionBasedTracker::updateTrackedObjects: add position");
|
||||
|
||||
_trackedObjects[i].lastPositions.Add(detectedObjects[j]);
|
||||
while ((int)_trackedObjects[i].lastPositions.Count > (int)_trackerParameters.numLastPositionsToTrack)
|
||||
{
|
||||
_trackedObjects[i].lastPositions.Remove(_trackedObjects[i].lastPositions[0]);
|
||||
_trackedObjects [i].lastPositions.Add (detectedObjects [j]);
|
||||
while ((int)_trackedObjects [i].lastPositions.Count > (int)_trackerParameters.numLastPositionsToTrack) {
|
||||
_trackedObjects [i].lastPositions.Remove (_trackedObjects [i].lastPositions [0]);
|
||||
}
|
||||
_trackedObjects[i].numFramesNotDetected = 0;
|
||||
if (_trackedObjects[i].state != TrackedState.DELETED) _trackedObjects[i].state = TrackedState.DISPLAYED;
|
||||
}
|
||||
else if (i == (int)TrackedRectState.NEW_RECTANGLE)
|
||||
{ //new object
|
||||
_trackedObjects [i].numFramesNotDetected = 0;
|
||||
if (_trackedObjects [i].state != TrackedState.DELETED)
|
||||
_trackedObjects [i].state = TrackedState.DISPLAYED;
|
||||
} else if (i == (int)TrackedRectState.NEW_RECTANGLE) { //new object
|
||||
//Debug.Log("DetectionBasedTracker::updateTrackedObjects: new object");
|
||||
|
||||
_trackedObjects.Add(new TrackedObject(detectedObjects[j]));
|
||||
}
|
||||
else
|
||||
{
|
||||
_trackedObjects.Add (new TrackedObject (detectedObjects [j]));
|
||||
} else {
|
||||
//Debug.Log("DetectionBasedTracker::updateTrackedObjects: was auxiliary intersection");
|
||||
}
|
||||
}
|
||||
|
@ -267,66 +232,49 @@ namespace OpenCVForUnity.RectangleTrack
|
|||
|
||||
int t = 0;
|
||||
TrackedObject it;
|
||||
while (t < _trackedObjects.Count)
|
||||
{
|
||||
it = _trackedObjects[t];
|
||||
while (t < _trackedObjects.Count) {
|
||||
it = _trackedObjects [t];
|
||||
|
||||
if (it.state == TrackedState.DELETED)
|
||||
{
|
||||
_trackedObjects.Remove(it);
|
||||
}
|
||||
else if ((it.numFramesNotDetected > _trackerParameters.maxTrackLifetime)//ALL
|
||||
||
|
||||
((it.numDetectedFrames <= _trackerParameters.numStepsToWaitBeforeFirstShow)
|
||||
&&
|
||||
(it.numFramesNotDetected > _trackerParameters.numStepsToTrackWithoutDetectingIfObjectHasNotBeenShown))
|
||||
)
|
||||
{
|
||||
if (it.state == TrackedState.DELETED) {
|
||||
_trackedObjects.Remove (it);
|
||||
} else if ((it.numFramesNotDetected > _trackerParameters.maxTrackLifetime)//ALL
|
||||
||
|
||||
((it.numDetectedFrames <= _trackerParameters.numStepsToWaitBeforeFirstShow)
|
||||
&&
|
||||
(it.numFramesNotDetected > _trackerParameters.numStepsToTrackWithoutDetectingIfObjectHasNotBeenShown))) {
|
||||
it.state = TrackedState.DELETED;
|
||||
t++;
|
||||
}
|
||||
else if (it.state >= TrackedState.DISPLAYED)//DISPLAYED, NEW_DISPLAYED, HIDED
|
||||
{
|
||||
} else if (it.state >= TrackedState.DISPLAYED) {//DISPLAYED, NEW_DISPLAYED, HIDED
|
||||
|
||||
if (it.numDetectedFrames < _trackerParameters.numStepsToWaitBeforeFirstShow)
|
||||
{
|
||||
if (it.numDetectedFrames < _trackerParameters.numStepsToWaitBeforeFirstShow) {
|
||||
it.state = TrackedState.PENDING;
|
||||
}
|
||||
else if (it.numDetectedFrames == _trackerParameters.numStepsToWaitBeforeFirstShow)
|
||||
{
|
||||
} else if (it.numDetectedFrames == _trackerParameters.numStepsToWaitBeforeFirstShow) {
|
||||
//i, trackedObjects[i].numDetectedFrames, innerParameters.numStepsToWaitBeforeFirstShow);
|
||||
it.state = TrackedState.NEW_DISPLAYED;
|
||||
}
|
||||
else if (it.numFramesNotDetected == _trackerParameters.numStepsToShowWithoutDetecting)
|
||||
{
|
||||
} else if (it.numFramesNotDetected == _trackerParameters.numStepsToShowWithoutDetecting) {
|
||||
it.state = TrackedState.NEW_HIDED;
|
||||
}
|
||||
else if (it.numFramesNotDetected > _trackerParameters.numStepsToShowWithoutDetecting)
|
||||
{
|
||||
} else if (it.numFramesNotDetected > _trackerParameters.numStepsToShowWithoutDetecting) {
|
||||
it.state = TrackedState.HIDED;
|
||||
}
|
||||
|
||||
t++;
|
||||
}
|
||||
else//NEW
|
||||
{
|
||||
} else {//NEW
|
||||
t++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Rect[] CreateCorrectionBySpeedOfRects()
|
||||
public Rect[] CreateCorrectionBySpeedOfRects ()
|
||||
{
|
||||
//Debug.Log("DetectionBasedTracker::process: get _rectsWhereRegions from previous positions");
|
||||
Rect[] rectsWhereRegions = new Rect[_trackedObjects.Count];
|
||||
|
||||
int count = _trackedObjects.Count;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
int n = _trackedObjects[i].lastPositions.Count;
|
||||
for (int i = 0; i < count; i++) {
|
||||
int n = _trackedObjects [i].lastPositions.Count;
|
||||
//if (n > 0) UnityEngine.Debug.LogError("n > 0 is false");
|
||||
|
||||
Rect r = _trackedObjects[i].lastPositions[n - 1].clone();
|
||||
Rect r = _trackedObjects [i].lastPositions [n - 1].clone ();
|
||||
/*
|
||||
if (r.area() == 0)
|
||||
{
|
||||
|
@ -336,127 +284,117 @@ namespace OpenCVForUnity.RectangleTrack
|
|||
*/
|
||||
|
||||
//correction by speed of rectangle
|
||||
if (n > 1)
|
||||
{
|
||||
Point center = CenterRect(r);
|
||||
Point center_prev = CenterRect(_trackedObjects[i].lastPositions[n - 2]);
|
||||
Point shift = new Point((center.x - center_prev.x) * _trackerParameters.coeffObjectSpeedUsingInPrediction,
|
||||
(center.y - center_prev.y) * _trackerParameters.coeffObjectSpeedUsingInPrediction);
|
||||
if (n > 1) {
|
||||
Point center = CenterRect (r);
|
||||
Point center_prev = CenterRect (_trackedObjects [i].lastPositions [n - 2]);
|
||||
Point shift = new Point ((center.x - center_prev.x) * _trackerParameters.coeffObjectSpeedUsingInPrediction,
|
||||
(center.y - center_prev.y) * _trackerParameters.coeffObjectSpeedUsingInPrediction);
|
||||
|
||||
r.x += (int)Math.Round(shift.x);
|
||||
r.y += (int)Math.Round(shift.y);
|
||||
r.x += (int)Math.Round (shift.x);
|
||||
r.y += (int)Math.Round (shift.y);
|
||||
}
|
||||
|
||||
rectsWhereRegions[i] = r;
|
||||
rectsWhereRegions [i] = r;
|
||||
}
|
||||
|
||||
return rectsWhereRegions;
|
||||
}
|
||||
|
||||
private Point CenterRect(Rect r)
|
||||
private Point CenterRect (Rect r)
|
||||
{
|
||||
return new Point(r.x + (r.width / 2), r.y + (r.height / 2));
|
||||
return new Point (r.x + (r.width / 2), r.y + (r.height / 2));
|
||||
}
|
||||
|
||||
private Rect GetSmoothingRect(int i)
|
||||
private Rect GetSmoothingRect (int i)
|
||||
{
|
||||
//Debug.Log("trackedObjects[i].numFramesNotDetected: " + trackedObjects[i].numFramesNotDetected);
|
||||
|
||||
List<float> weightsSizesSmoothing = _weightsSizesSmoothing;
|
||||
List<float> weightsPositionsSmoothing = _weightsPositionsSmoothing;
|
||||
|
||||
List<Rect> lastPositions = _trackedObjects[i].lastPositions;
|
||||
List<Rect> lastPositions = _trackedObjects [i].lastPositions;
|
||||
|
||||
int N = lastPositions.Count;
|
||||
if (N <= 0)
|
||||
{
|
||||
Debug.Log("DetectionBasedTracker::calcTrackedObjectPositionToShow: ERROR: no positions for i=" + i);
|
||||
return new Rect();
|
||||
if (N <= 0) {
|
||||
Debug.Log ("DetectionBasedTracker::calcTrackedObjectPositionToShow: ERROR: no positions for i=" + i);
|
||||
return new Rect ();
|
||||
}
|
||||
|
||||
int Nsize = Math.Min(N, (int)weightsSizesSmoothing.Count);
|
||||
int Ncenter = Math.Min(N, (int)weightsPositionsSmoothing.Count);
|
||||
int Nsize = Math.Min (N, (int)weightsSizesSmoothing.Count);
|
||||
int Ncenter = Math.Min (N, (int)weightsPositionsSmoothing.Count);
|
||||
|
||||
Point center = new Point();
|
||||
Point center = new Point ();
|
||||
double w = 0, h = 0;
|
||||
if (Nsize > 0)
|
||||
{
|
||||
if (Nsize > 0) {
|
||||
double sum = 0;
|
||||
for (int j = 0; j < Nsize; j++)
|
||||
{
|
||||
for (int j = 0; j < Nsize; j++) {
|
||||
int k = N - j - 1;
|
||||
w += lastPositions[k].width * weightsSizesSmoothing[j];
|
||||
h += lastPositions[k].height * weightsSizesSmoothing[j];
|
||||
sum += weightsSizesSmoothing[j];
|
||||
w += lastPositions [k].width * weightsSizesSmoothing [j];
|
||||
h += lastPositions [k].height * weightsSizesSmoothing [j];
|
||||
sum += weightsSizesSmoothing [j];
|
||||
}
|
||||
w /= sum;
|
||||
h /= sum;
|
||||
}
|
||||
else
|
||||
{
|
||||
w = lastPositions[N - 1].width;
|
||||
h = lastPositions[N - 1].height;
|
||||
} else {
|
||||
w = lastPositions [N - 1].width;
|
||||
h = lastPositions [N - 1].height;
|
||||
}
|
||||
|
||||
if (Ncenter > 0)
|
||||
{
|
||||
if (Ncenter > 0) {
|
||||
double sum = 0;
|
||||
for (int j = 0; j < Ncenter; j++)
|
||||
{
|
||||
for (int j = 0; j < Ncenter; j++) {
|
||||
int k = N - j - 1;
|
||||
Point tl = lastPositions[k].tl();
|
||||
Point br = lastPositions[k].br();
|
||||
Point tl = lastPositions [k].tl ();
|
||||
Point br = lastPositions [k].br ();
|
||||
Point c1;
|
||||
|
||||
c1 = new Point(tl.x * 0.5f, tl.y * 0.5f);
|
||||
c1 = new Point (tl.x * 0.5f, tl.y * 0.5f);
|
||||
Point c2;
|
||||
|
||||
c2 = new Point(br.x * 0.5f, br.y * 0.5f);
|
||||
c1 = new Point(c1.x + c2.x, c1.y + c2.y);
|
||||
c2 = new Point (br.x * 0.5f, br.y * 0.5f);
|
||||
c1 = new Point (c1.x + c2.x, c1.y + c2.y);
|
||||
|
||||
center = new Point(center.x + (c1.x * weightsPositionsSmoothing[j]), center.y + (c1.y * weightsPositionsSmoothing[j]));
|
||||
sum += weightsPositionsSmoothing[j];
|
||||
center = new Point (center.x + (c1.x * weightsPositionsSmoothing [j]), center.y + (c1.y * weightsPositionsSmoothing [j]));
|
||||
sum += weightsPositionsSmoothing [j];
|
||||
}
|
||||
center = new Point(center.x * (1 / sum), center.y * (1 / sum));
|
||||
}
|
||||
else
|
||||
{
|
||||
center = new Point (center.x * (1 / sum), center.y * (1 / sum));
|
||||
} else {
|
||||
int k = N - 1;
|
||||
Point tl = lastPositions[k].tl();
|
||||
Point br = lastPositions[k].br();
|
||||
Point tl = lastPositions [k].tl ();
|
||||
Point br = lastPositions [k].br ();
|
||||
Point c1;
|
||||
|
||||
c1 = new Point(tl.x * 0.5f, tl.y * 0.5f);
|
||||
c1 = new Point (tl.x * 0.5f, tl.y * 0.5f);
|
||||
Point c2;
|
||||
|
||||
c2 = new Point(br.x * 0.5f, br.y * 0.5f);
|
||||
c2 = new Point (br.x * 0.5f, br.y * 0.5f);
|
||||
|
||||
center = new Point(c1.x + c2.x, c1.y + c2.y);
|
||||
center = new Point (c1.x + c2.x, c1.y + c2.y);
|
||||
}
|
||||
Point tl2 = new Point(center.x - (w * 0.5f), center.y - (h * 0.5f));
|
||||
Rect res = new Rect((int)Math.Round(tl2.x), (int)Math.Round(tl2.y), (int)Math.Round(w), (int)Math.Round(h));
|
||||
Point tl2 = new Point (center.x - (w * 0.5f), center.y - (h * 0.5f));
|
||||
Rect res = new Rect ((int)Math.Round (tl2.x), (int)Math.Round (tl2.y), (int)Math.Round (w), (int)Math.Round (h));
|
||||
|
||||
//Debug.Log("DetectionBasedTracker::calcTrackedObjectPositionToShow: Result for i=" + i + ": {" + res.x + ", " + res.y + ", " + res.width + ", " + res.height + "}");
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
public void Reset ()
|
||||
{
|
||||
_trackedObjects.Clear();
|
||||
_trackedObjects.Clear ();
|
||||
}
|
||||
|
||||
private Rect Intersect(Rect a, Rect b)
|
||||
private Rect Intersect (Rect a, Rect b)
|
||||
{
|
||||
int x1 = Math.Max(a.x, b.x);
|
||||
int x2 = Math.Min(a.x + a.width, b.x + b.width);
|
||||
int y1 = Math.Max(a.y, b.y);
|
||||
int y2 = Math.Min(a.y + a.height, b.y + b.height);
|
||||
int x1 = Math.Max (a.x, b.x);
|
||||
int x2 = Math.Min (a.x + a.width, b.x + b.width);
|
||||
int y1 = Math.Max (a.y, b.y);
|
||||
int y2 = Math.Min (a.y + a.height, b.y + b.height);
|
||||
|
||||
if (x2 >= x1 && y2 >= y1)
|
||||
return new Rect(x1, y1, x2 - x1, y2 - y1);
|
||||
return new Rect (x1, y1, x2 - x1, y2 - y1);
|
||||
else
|
||||
return new Rect();
|
||||
return new Rect ();
|
||||
}
|
||||
/*
|
||||
private bool IsCollideByCircle(Rect a, Rect b, float coeffRectangleOverlap)
|
||||
|
@ -474,7 +412,7 @@ namespace OpenCVForUnity.RectangleTrack
|
|||
return false;
|
||||
}
|
||||
*/
|
||||
private bool IsCollideByRectangle(Rect a, Rect b, float coeffRectangleOverlap)
|
||||
private bool IsCollideByRectangle (Rect a, Rect b, float coeffRectangleOverlap)
|
||||
{
|
||||
int mw = (int)(a.width * coeffRectangleOverlap);
|
||||
int mh = (int)(a.height * coeffRectangleOverlap);
|
||||
|
@ -496,9 +434,9 @@ namespace OpenCVForUnity.RectangleTrack
|
|||
return false;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
public void Dispose ()
|
||||
{
|
||||
Reset();
|
||||
Reset ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using PositionsVector = System.Collections.Generic.List<OpenCVForUnity.Rect>;
|
||||
using OpenCVForUnity.CoreModule;
|
||||
using PositionsVector = System.Collections.Generic.List<OpenCVForUnity.CoreModule.Rect>;
|
||||
|
||||
namespace OpenCVForUnity.RectangleTrack
|
||||
{
|
||||
|
@ -21,31 +22,30 @@ namespace OpenCVForUnity.RectangleTrack
|
|||
public int id;
|
||||
public TrackedState state;
|
||||
|
||||
public OpenCVForUnity.Rect position
|
||||
{
|
||||
get { return lastPositions [lastPositions.Count - 1].clone(); }
|
||||
public Rect position {
|
||||
get { return lastPositions [lastPositions.Count - 1].clone (); }
|
||||
}
|
||||
|
||||
static private int _id = 0;
|
||||
|
||||
public TrackedObject(OpenCVForUnity.Rect rect)
|
||||
public TrackedObject (Rect rect)
|
||||
{
|
||||
lastPositions = new PositionsVector();
|
||||
lastPositions = new PositionsVector ();
|
||||
|
||||
numDetectedFrames = 1;
|
||||
numFramesNotDetected = 0;
|
||||
state = TrackedState.NEW;
|
||||
|
||||
lastPositions.Add(rect.clone());
|
||||
lastPositions.Add (rect.clone ());
|
||||
|
||||
_id = GetNextId();
|
||||
_id = GetNextId ();
|
||||
id = _id;
|
||||
}
|
||||
|
||||
static int GetNextId()
|
||||
static int GetNextId ()
|
||||
{
|
||||
_id++;
|
||||
return _id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
namespace OpenCVForUnity.RectangleTrack
|
||||
using OpenCVForUnity.CoreModule;
|
||||
|
||||
namespace OpenCVForUnity.RectangleTrack
|
||||
{
|
||||
public class TrackedRect : Rect
|
||||
{
|
||||
|
@ -7,8 +9,8 @@
|
|||
public int id;
|
||||
public TrackedState state;
|
||||
|
||||
public TrackedRect(int id, Rect rect, TrackedState state, int numDetectedFrames, int numFramesNotDetected)
|
||||
: base(rect.x, rect.y, rect.width, rect.height)
|
||||
public TrackedRect (int id, Rect rect, TrackedState state, int numDetectedFrames, int numFramesNotDetected)
|
||||
: base (rect.x, rect.y, rect.width, rect.height)
|
||||
{
|
||||
this.numDetectedFrames = numDetectedFrames;
|
||||
this.numFramesNotDetected = numFramesNotDetected;
|
||||
|
@ -16,4 +18,4 @@
|
|||
this.state = state;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,12 +12,13 @@
|
|||
public float coeffObjectSpeedUsingInPrediction = 0.8f;
|
||||
public float coeffRectangleOverlap = 0.7f;
|
||||
|
||||
public TrackerParameters() {
|
||||
public TrackerParameters ()
|
||||
{
|
||||
}
|
||||
|
||||
public TrackerParameters Clone()
|
||||
public TrackerParameters Clone ()
|
||||
{
|
||||
TrackerParameters trackerParameters = new TrackerParameters();
|
||||
TrackerParameters trackerParameters = new TrackerParameters ();
|
||||
trackerParameters.numLastPositionsToTrack = numLastPositionsToTrack;
|
||||
trackerParameters.numStepsToWaitBeforeFirstShow = numStepsToWaitBeforeFirstShow;
|
||||
trackerParameters.numStepsToTrackWithoutDetectingIfObjectHasNotBeenShown = numStepsToTrackWithoutDetectingIfObjectHasNotBeenShown;
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
using UnityEngine;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using OpenCVForUnity;
|
||||
using System;
|
||||
using OpenCVForUnity.CoreModule;
|
||||
using OpenCVForUnity.ImgprocModule;
|
||||
using Rect = OpenCVForUnity.CoreModule.Rect;
|
||||
|
||||
namespace FaceMaskExample
|
||||
{
|
||||
|
@ -42,23 +44,23 @@ namespace FaceMaskExample
|
|||
src_mask.Dispose ();
|
||||
src_mask = null;
|
||||
}
|
||||
src_mask = src_mask ?? new Mat (src.rows(), src.cols(), CvType.CV_8UC1, Scalar.all(0));
|
||||
src_mask = src_mask ?? new Mat (src.rows (), src.cols (), CvType.CV_8UC1, Scalar.all (0));
|
||||
|
||||
if (dst_mask != null && (dst.width () != dst_mask.width () || dst.height () != dst_mask.height ())) {
|
||||
dst_mask.Dispose ();
|
||||
dst_mask = null;
|
||||
}
|
||||
dst_mask = dst_mask ?? new Mat (dst.rows(), dst.cols(), CvType.CV_8UC1, Scalar.all(0));
|
||||
dst_mask = dst_mask ?? new Mat (dst.rows (), dst.cols (), CvType.CV_8UC1, Scalar.all (0));
|
||||
|
||||
// Get facial contour points.
|
||||
GetFacialContourPoints (src_landmarkPoints, src_facialContourPoints);
|
||||
GetFacialContourPoints (dst_landmarkPoints, dst_facialContourPoints);
|
||||
|
||||
// Get facial contour rect.
|
||||
OpenCVForUnity.Rect src_facialContourRect = Imgproc.boundingRect(new MatOfPoint(src_facialContourPoints));
|
||||
OpenCVForUnity.Rect dst_facialContourRect = Imgproc.boundingRect(new MatOfPoint(dst_facialContourPoints));
|
||||
src_facialContourRect = src_facialContourRect.intersect (new OpenCVForUnity.Rect(0, 0, src.width(), src.height()));
|
||||
dst_facialContourRect = dst_facialContourRect.intersect (new OpenCVForUnity.Rect(0, 0, dst.width(), dst.height()));
|
||||
Rect src_facialContourRect = Imgproc.boundingRect (new MatOfPoint (src_facialContourPoints));
|
||||
Rect dst_facialContourRect = Imgproc.boundingRect (new MatOfPoint (dst_facialContourPoints));
|
||||
src_facialContourRect = src_facialContourRect.intersect (new Rect (0, 0, src.width (), src.height ()));
|
||||
dst_facialContourRect = dst_facialContourRect.intersect (new Rect (0, 0, dst.width (), dst.height ()));
|
||||
|
||||
Mat src_ROI = new Mat (src, src_facialContourRect);
|
||||
Mat dst_ROI = new Mat (dst, dst_facialContourRect);
|
||||
|
@ -68,17 +70,17 @@ namespace FaceMaskExample
|
|||
GetPointsInFrame (src_mask_ROI, src_facialContourPoints, src_facialContourPoints);
|
||||
GetPointsInFrame (dst_mask_ROI, dst_facialContourPoints, dst_facialContourPoints);
|
||||
|
||||
src_mask_ROI.setTo (new Scalar(0));
|
||||
dst_mask_ROI.setTo (new Scalar(0));
|
||||
Imgproc.fillConvexPoly(src_mask_ROI, new MatOfPoint(src_facialContourPoints), new Scalar(255));
|
||||
Imgproc.fillConvexPoly(dst_mask_ROI, new MatOfPoint(dst_facialContourPoints), new Scalar(255));
|
||||
src_mask_ROI.setTo (new Scalar (0));
|
||||
dst_mask_ROI.setTo (new Scalar (0));
|
||||
Imgproc.fillConvexPoly (src_mask_ROI, new MatOfPoint (src_facialContourPoints), new Scalar (255));
|
||||
Imgproc.fillConvexPoly (dst_mask_ROI, new MatOfPoint (dst_facialContourPoints), new Scalar (255));
|
||||
|
||||
Texture2D LUTTex;
|
||||
if (LUTTexDict.ContainsKey (id)) {
|
||||
LUTTex = LUTTexDict[id];
|
||||
LUTTex = LUTTexDict [id];
|
||||
} else {
|
||||
LUTTex = new Texture2D (256, 1, TextureFormat.RGB24, false);
|
||||
LUTTexDict.Add (id ,LUTTex);
|
||||
LUTTexDict.Add (id, LUTTex);
|
||||
}
|
||||
|
||||
FaceMaskShaderUtils.CalculateLUT (src_ROI, dst_ROI, src_mask_ROI, dst_mask_ROI, LUTTex);
|
||||
|
@ -89,7 +91,7 @@ namespace FaceMaskExample
|
|||
public virtual void DeleteLUTTex (int id)
|
||||
{
|
||||
if (LUTTexDict.ContainsKey (id)) {
|
||||
Texture2D.Destroy(LUTTexDict [id]);
|
||||
Texture2D.Destroy (LUTTexDict [id]);
|
||||
LUTTexDict.Remove (id);
|
||||
}
|
||||
}
|
||||
|
@ -102,38 +104,46 @@ namespace FaceMaskExample
|
|||
return null;
|
||||
}
|
||||
|
||||
protected virtual void GetFacialContourPoints(List<Vector2> landmark_points, Point[] dst_points)
|
||||
protected virtual void GetFacialContourPoints (List<Vector2> landmark_points, Point[] dst_points)
|
||||
{
|
||||
if (landmark_points.Count < 9)
|
||||
throw new ArgumentException("Invalid landmark_points.");
|
||||
throw new ArgumentException ("Invalid landmark_points.");
|
||||
|
||||
if (dst_points.Length != 9)
|
||||
throw new ArgumentException("Invalid points.");
|
||||
throw new ArgumentException ("Invalid points.");
|
||||
|
||||
dst_points[0].x = landmark_points[0].x; dst_points[0].y = landmark_points[0].y;
|
||||
dst_points[1].x = landmark_points[3].x; dst_points[1].y = landmark_points[3].y;
|
||||
dst_points[2].x = landmark_points[5].x; dst_points[2].y = landmark_points[5].y;
|
||||
dst_points[3].x = landmark_points[8].x; dst_points[3].y = landmark_points[8].y;
|
||||
dst_points[4].x = landmark_points[11].x; dst_points[4].y = landmark_points[11].y;
|
||||
dst_points[5].x = landmark_points[13].x; dst_points[5].y = landmark_points[13].y;
|
||||
dst_points[6].x = landmark_points[16].x; dst_points[6].y = landmark_points[16].y;
|
||||
float nose_length_x = landmark_points[27].x - landmark_points[30].x;
|
||||
float nose_length_y = landmark_points[27].y - landmark_points[30].y;
|
||||
dst_points [7].x = landmark_points [26].x + nose_length_x; dst_points [7].y = landmark_points [26].y + nose_length_y;
|
||||
dst_points [8].x = landmark_points [17].x + nose_length_x; dst_points [8].y = landmark_points [17].y + nose_length_y;
|
||||
dst_points [0].x = landmark_points [0].x;
|
||||
dst_points [0].y = landmark_points [0].y;
|
||||
dst_points [1].x = landmark_points [3].x;
|
||||
dst_points [1].y = landmark_points [3].y;
|
||||
dst_points [2].x = landmark_points [5].x;
|
||||
dst_points [2].y = landmark_points [5].y;
|
||||
dst_points [3].x = landmark_points [8].x;
|
||||
dst_points [3].y = landmark_points [8].y;
|
||||
dst_points [4].x = landmark_points [11].x;
|
||||
dst_points [4].y = landmark_points [11].y;
|
||||
dst_points [5].x = landmark_points [13].x;
|
||||
dst_points [5].y = landmark_points [13].y;
|
||||
dst_points [6].x = landmark_points [16].x;
|
||||
dst_points [6].y = landmark_points [16].y;
|
||||
float nose_length_x = landmark_points [27].x - landmark_points [30].x;
|
||||
float nose_length_y = landmark_points [27].y - landmark_points [30].y;
|
||||
dst_points [7].x = landmark_points [26].x + nose_length_x;
|
||||
dst_points [7].y = landmark_points [26].y + nose_length_y;
|
||||
dst_points [8].x = landmark_points [17].x + nose_length_x;
|
||||
dst_points [8].y = landmark_points [17].y + nose_length_y;
|
||||
}
|
||||
|
||||
protected virtual void GetPointsInFrame(Mat frame, Point[] points, Point[] dst_points)
|
||||
protected virtual void GetPointsInFrame (Mat frame, Point[] points, Point[] dst_points)
|
||||
{
|
||||
if (points.Length != dst_points.Length)
|
||||
throw new ArgumentException("points.Length != dst_points.Length");
|
||||
throw new ArgumentException ("points.Length != dst_points.Length");
|
||||
|
||||
Size wholesize = new Size();
|
||||
Point ofs = new Point();
|
||||
frame.locateROI(wholesize, ofs);
|
||||
Size wholesize = new Size ();
|
||||
Point ofs = new Point ();
|
||||
frame.locateROI (wholesize, ofs);
|
||||
|
||||
for (int i = 0; i < points.Length; i++)
|
||||
{
|
||||
for (int i = 0; i < points.Length; i++) {
|
||||
dst_points [i].x = points [i].x - ofs.x;
|
||||
dst_points [i].y = points [i].y - ofs.y;
|
||||
}
|
||||
|
@ -142,7 +152,7 @@ namespace FaceMaskExample
|
|||
public virtual void Reset ()
|
||||
{
|
||||
foreach (var key in LUTTexDict.Keys) {
|
||||
Texture2D.Destroy(LUTTexDict [key]);
|
||||
Texture2D.Destroy (LUTTexDict [key]);
|
||||
}
|
||||
LUTTexDict.Clear ();
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using OpenCVForUnity;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections;
|
||||
using OpenCVForUnity.CoreModule;
|
||||
using OpenCVForUnity.UnityUtils;
|
||||
|
||||
namespace FaceMaskExample
|
||||
{
|
||||
|
@ -11,32 +12,44 @@ namespace FaceMaskExample
|
|||
// Match histograms of 'src' to that of 'dst', according to both masks.
|
||||
public static void CalculateLUT (Mat src, Mat dst, Mat src_mask, Mat dst_mask, Texture2D LUTTex)
|
||||
{
|
||||
if (src.channels() < 3)
|
||||
if (src.channels () < 3)
|
||||
throw new ArgumentException ("src.channels() < 3");
|
||||
|
||||
if (dst.channels() < 3)
|
||||
if (dst.channels () < 3)
|
||||
throw new ArgumentException ("dst.channels() < 3");
|
||||
|
||||
if (src_mask.channels() != 1)
|
||||
if (src_mask.channels () != 1)
|
||||
throw new ArgumentException ("src_mask.channels() != 1");
|
||||
|
||||
if (dst_mask.channels() != 1)
|
||||
if (dst_mask.channels () != 1)
|
||||
throw new ArgumentException ("dst_mask.channels() != 1");
|
||||
|
||||
if (src_mask != null && src.total() != src_mask.total())
|
||||
if (src_mask != null && src.total () != src_mask.total ())
|
||||
throw new ArgumentException ("src.total() != src_mask.total()");
|
||||
|
||||
if (dst_mask != null && dst.total() != dst_mask.total())
|
||||
if (dst_mask != null && dst.total () != dst_mask.total ())
|
||||
throw new ArgumentException ("dst.total() != dst_mask.total()");
|
||||
|
||||
if (LUTTex.width != 256 || LUTTex.height != 1 || LUTTex.format != TextureFormat.RGB24)
|
||||
throw new ArgumentException ("Invalid LUTTex.");
|
||||
|
||||
byte[] LUT = new byte[3 * 256];
|
||||
double[][] src_hist = new double[3][]; for(int i=0; i<src_hist.Length; i++ ){ src_hist[i] = new double[256];}
|
||||
double[][] dst_hist = new double[3][]; for(int i=0; i<dst_hist.Length; i++ ){ dst_hist[i] = new double[256];}
|
||||
double[][] src_cdf = new double[3][]; for(int i=0; i<src_cdf.Length; i++ ){ src_cdf[i] = new double[256];}
|
||||
double[][] dst_cdf = new double[3][]; for(int i=0; i<dst_cdf.Length; i++ ){ dst_cdf[i] = new double[256];}
|
||||
double[][] src_hist = new double[3][];
|
||||
for (int i = 0; i < src_hist.Length; i++) {
|
||||
src_hist [i] = new double[256];
|
||||
}
|
||||
double[][] dst_hist = new double[3][];
|
||||
for (int i = 0; i < dst_hist.Length; i++) {
|
||||
dst_hist [i] = new double[256];
|
||||
}
|
||||
double[][] src_cdf = new double[3][];
|
||||
for (int i = 0; i < src_cdf.Length; i++) {
|
||||
src_cdf [i] = new double[256];
|
||||
}
|
||||
double[][] dst_cdf = new double[3][];
|
||||
for (int i = 0; i < dst_cdf.Length; i++) {
|
||||
dst_cdf [i] = new double[256];
|
||||
}
|
||||
|
||||
double[] src_histMax = new double[3];
|
||||
double[] dst_histMax = new double[3];
|
||||
|
@ -44,22 +57,22 @@ namespace FaceMaskExample
|
|||
byte[] src_mask_byte = null;
|
||||
byte[] dst_mask_byte = null;
|
||||
if (src_mask != null) {
|
||||
src_mask_byte = new byte[src_mask.total() * src_mask.channels()];
|
||||
Utils.copyFromMat<byte>(src_mask, src_mask_byte);
|
||||
src_mask_byte = new byte[src_mask.total () * src_mask.channels ()];
|
||||
Utils.copyFromMat<byte> (src_mask, src_mask_byte);
|
||||
}
|
||||
if (dst_mask != null) {
|
||||
dst_mask_byte = new byte[dst_mask.total () * dst_mask.channels ()];
|
||||
Utils.copyFromMat<byte> (dst_mask, dst_mask_byte);
|
||||
}
|
||||
|
||||
byte[] src_byte = new byte[src.total() * src.channels()];
|
||||
Utils.copyFromMat<byte>(src, src_byte);
|
||||
byte[] dst_byte = new byte[dst.total() * dst.channels()];
|
||||
Utils.copyFromMat<byte>(dst, dst_byte);
|
||||
byte[] src_byte = new byte[src.total () * src.channels ()];
|
||||
Utils.copyFromMat<byte> (src, src_byte);
|
||||
byte[] dst_byte = new byte[dst.total () * dst.channels ()];
|
||||
Utils.copyFromMat<byte> (dst, dst_byte);
|
||||
|
||||
int pixel_i = 0;
|
||||
int channels = src.channels();
|
||||
int total = (int)src.total();
|
||||
int channels = src.channels ();
|
||||
int total = (int)src.total ();
|
||||
if (src_mask_byte != null) {
|
||||
for (int i = 0; i < total; i++) {
|
||||
if (src_mask_byte [i] != 0) {
|
||||
|
@ -152,43 +165,41 @@ namespace FaceMaskExample
|
|||
|
||||
//normalize hist
|
||||
for (int i = 0; i < 256; i++) {
|
||||
src_hist [0][i] /= src_histMax[0];
|
||||
src_hist [1][i] /= src_histMax[1];
|
||||
src_hist [2][i] /= src_histMax[2];
|
||||
src_hist [0] [i] /= src_histMax [0];
|
||||
src_hist [1] [i] /= src_histMax [1];
|
||||
src_hist [2] [i] /= src_histMax [2];
|
||||
|
||||
dst_hist [0][i] /= dst_histMax[0];
|
||||
dst_hist [1][i] /= dst_histMax[1];
|
||||
dst_hist [2][i] /= dst_histMax[2];
|
||||
dst_hist [0] [i] /= dst_histMax [0];
|
||||
dst_hist [1] [i] /= dst_histMax [1];
|
||||
dst_hist [2] [i] /= dst_histMax [2];
|
||||
}
|
||||
|
||||
// Calc cumulative distribution function (CDF)
|
||||
src_cdf[0][0] = src_hist[0][0];
|
||||
src_cdf[1][0] = src_hist[1][0];
|
||||
src_cdf[2][0] = src_hist[2][0];
|
||||
dst_cdf[0][0] = dst_hist[0][0];
|
||||
dst_cdf[1][0] = dst_hist[1][0];
|
||||
dst_cdf[2][0] = dst_hist[2][0];
|
||||
for (int i = 1; i < 256; i++)
|
||||
{
|
||||
src_cdf[0][i] = src_cdf[0][i - 1] + src_hist[0][i];
|
||||
src_cdf[1][i] = src_cdf[1][i - 1] + src_hist[1][i];
|
||||
src_cdf[2][i] = src_cdf[2][i - 1] + src_hist[2][i];
|
||||
src_cdf [0] [0] = src_hist [0] [0];
|
||||
src_cdf [1] [0] = src_hist [1] [0];
|
||||
src_cdf [2] [0] = src_hist [2] [0];
|
||||
dst_cdf [0] [0] = dst_hist [0] [0];
|
||||
dst_cdf [1] [0] = dst_hist [1] [0];
|
||||
dst_cdf [2] [0] = dst_hist [2] [0];
|
||||
for (int i = 1; i < 256; i++) {
|
||||
src_cdf [0] [i] = src_cdf [0] [i - 1] + src_hist [0] [i];
|
||||
src_cdf [1] [i] = src_cdf [1] [i - 1] + src_hist [1] [i];
|
||||
src_cdf [2] [i] = src_cdf [2] [i - 1] + src_hist [2] [i];
|
||||
|
||||
dst_cdf[0][i] = dst_cdf[0][i - 1] + dst_hist[0][i];
|
||||
dst_cdf[1][i] = dst_cdf[1][i - 1] + dst_hist[1][i];
|
||||
dst_cdf[2][i] = dst_cdf[2][i - 1] + dst_hist[2][i];
|
||||
dst_cdf [0] [i] = dst_cdf [0] [i - 1] + dst_hist [0] [i];
|
||||
dst_cdf [1] [i] = dst_cdf [1] [i - 1] + dst_hist [1] [i];
|
||||
dst_cdf [2] [i] = dst_cdf [2] [i - 1] + dst_hist [2] [i];
|
||||
}
|
||||
|
||||
// Normalize CDF
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
src_cdf[0][i] /= src_cdf[0][255];
|
||||
src_cdf[1][i] /= src_cdf[1][255];
|
||||
src_cdf[2][i] /= src_cdf[2][255];
|
||||
for (int i = 0; i < 256; i++) {
|
||||
src_cdf [0] [i] /= src_cdf [0] [255];
|
||||
src_cdf [1] [i] /= src_cdf [1] [255];
|
||||
src_cdf [2] [i] /= src_cdf [2] [255];
|
||||
|
||||
dst_cdf[0][i] /= dst_cdf[0][255];
|
||||
dst_cdf[1][i] /= dst_cdf[1][255];
|
||||
dst_cdf[2][i] /= dst_cdf[2][255];
|
||||
dst_cdf [0] [i] /= dst_cdf [0] [255];
|
||||
dst_cdf [1] [i] /= dst_cdf [1] [255];
|
||||
dst_cdf [2] [i] /= dst_cdf [2] [255];
|
||||
}
|
||||
|
||||
// Create lookup table
|
||||
|
@ -196,10 +207,10 @@ namespace FaceMaskExample
|
|||
for (int i = 0; i < 3; i++) {
|
||||
int last = 0;
|
||||
for (int j = 0; j < 256; j++) {
|
||||
double F1j = src_cdf [i][j];
|
||||
double F1j = src_cdf [i] [j];
|
||||
|
||||
for (int k = last; k < 256; k++) {
|
||||
double F2k = dst_cdf [i][k];
|
||||
double F2k = dst_cdf [i] [k];
|
||||
if (Math.Abs (F2k - F1j) < HISTMATCH_EPSILON || F2k > F1j) {
|
||||
LUT [(j * 3) + i] = (byte)k;
|
||||
last = k;
|
||||
|
|
|
@ -6,8 +6,8 @@ public class FaceMaskData : MonoBehaviour
|
|||
{
|
||||
[SerializeField]
|
||||
private Texture2D _image;
|
||||
public Texture2D image
|
||||
{
|
||||
|
||||
public Texture2D image {
|
||||
get { return this._image; }
|
||||
set { this._image = value; }
|
||||
}
|
||||
|
@ -25,87 +25,86 @@ public class FaceMaskData : MonoBehaviour
|
|||
public bool enableColorCorrection = true;
|
||||
|
||||
[SerializeField]
|
||||
private Rect _faceRect = new Rect(78, 95, 151, 150);
|
||||
public Rect faceRect
|
||||
{
|
||||
private Rect _faceRect = new Rect (78, 95, 151, 150);
|
||||
|
||||
public Rect faceRect {
|
||||
get { return this._faceRect; }
|
||||
set { this._faceRect = value; }
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private List<Vector2> _landmarkPoints = new List<Vector2> ()
|
||||
{
|
||||
new Vector2(84, 148),
|
||||
new Vector2(84, 167),
|
||||
new Vector2(86, 187),
|
||||
new Vector2(89, 206),
|
||||
new Vector2(96, 224),
|
||||
new Vector2(106, 240),
|
||||
new Vector2(119, 253),
|
||||
new Vector2(134, 264),
|
||||
new Vector2(151, 266),
|
||||
new Vector2(168, 264),
|
||||
new Vector2(184, 254),
|
||||
new Vector2(197, 241),
|
||||
new Vector2(207, 226),
|
||||
new Vector2(214, 209),
|
||||
new Vector2(218, 190),
|
||||
new Vector2(221, 170),
|
||||
new Vector2(221, 150),
|
||||
new Vector2(100, 125),
|
||||
new Vector2(108, 117),
|
||||
new Vector2(119, 114),
|
||||
new Vector2(130, 116),
|
||||
new Vector2(141, 120),
|
||||
new Vector2(164, 120),
|
||||
new Vector2(176, 116),
|
||||
new Vector2(187, 115),
|
||||
new Vector2(199, 118),
|
||||
new Vector2(206, 126),
|
||||
new Vector2(153, 133),
|
||||
new Vector2(153, 144),
|
||||
new Vector2(154, 156),
|
||||
new Vector2(154, 168),
|
||||
new Vector2(142, 181),
|
||||
new Vector2(148, 182),
|
||||
new Vector2(154, 184),
|
||||
new Vector2(160, 182),
|
||||
new Vector2(165, 181),
|
||||
new Vector2(113, 134),
|
||||
new Vector2(120, 127),
|
||||
new Vector2(129, 127),
|
||||
new Vector2(136, 136),
|
||||
new Vector2(128, 137),
|
||||
new Vector2(119, 137),
|
||||
new Vector2(170, 137),
|
||||
new Vector2(177, 128),
|
||||
new Vector2(187, 128),
|
||||
new Vector2(193, 136),
|
||||
new Vector2(188, 139),
|
||||
new Vector2(178, 138),
|
||||
new Vector2(127, 215),
|
||||
new Vector2(135, 204),
|
||||
new Vector2(145, 199),
|
||||
new Vector2(154, 201),
|
||||
new Vector2(163, 199),
|
||||
new Vector2(173, 205),
|
||||
new Vector2(178, 218),
|
||||
new Vector2(173, 225),
|
||||
new Vector2(163, 229),
|
||||
new Vector2(154, 230),
|
||||
new Vector2(144, 228),
|
||||
new Vector2(134, 224),
|
||||
new Vector2(131, 215),
|
||||
new Vector2(145, 206),
|
||||
new Vector2(154, 207),
|
||||
new Vector2(163, 207),
|
||||
new Vector2(175, 217),
|
||||
new Vector2(163, 219),
|
||||
new Vector2(154, 220),
|
||||
new Vector2(144, 218)
|
||||
private List<Vector2> _landmarkPoints = new List<Vector2> () {
|
||||
new Vector2 (84, 148),
|
||||
new Vector2 (84, 167),
|
||||
new Vector2 (86, 187),
|
||||
new Vector2 (89, 206),
|
||||
new Vector2 (96, 224),
|
||||
new Vector2 (106, 240),
|
||||
new Vector2 (119, 253),
|
||||
new Vector2 (134, 264),
|
||||
new Vector2 (151, 266),
|
||||
new Vector2 (168, 264),
|
||||
new Vector2 (184, 254),
|
||||
new Vector2 (197, 241),
|
||||
new Vector2 (207, 226),
|
||||
new Vector2 (214, 209),
|
||||
new Vector2 (218, 190),
|
||||
new Vector2 (221, 170),
|
||||
new Vector2 (221, 150),
|
||||
new Vector2 (100, 125),
|
||||
new Vector2 (108, 117),
|
||||
new Vector2 (119, 114),
|
||||
new Vector2 (130, 116),
|
||||
new Vector2 (141, 120),
|
||||
new Vector2 (164, 120),
|
||||
new Vector2 (176, 116),
|
||||
new Vector2 (187, 115),
|
||||
new Vector2 (199, 118),
|
||||
new Vector2 (206, 126),
|
||||
new Vector2 (153, 133),
|
||||
new Vector2 (153, 144),
|
||||
new Vector2 (154, 156),
|
||||
new Vector2 (154, 168),
|
||||
new Vector2 (142, 181),
|
||||
new Vector2 (148, 182),
|
||||
new Vector2 (154, 184),
|
||||
new Vector2 (160, 182),
|
||||
new Vector2 (165, 181),
|
||||
new Vector2 (113, 134),
|
||||
new Vector2 (120, 127),
|
||||
new Vector2 (129, 127),
|
||||
new Vector2 (136, 136),
|
||||
new Vector2 (128, 137),
|
||||
new Vector2 (119, 137),
|
||||
new Vector2 (170, 137),
|
||||
new Vector2 (177, 128),
|
||||
new Vector2 (187, 128),
|
||||
new Vector2 (193, 136),
|
||||
new Vector2 (188, 139),
|
||||
new Vector2 (178, 138),
|
||||
new Vector2 (127, 215),
|
||||
new Vector2 (135, 204),
|
||||
new Vector2 (145, 199),
|
||||
new Vector2 (154, 201),
|
||||
new Vector2 (163, 199),
|
||||
new Vector2 (173, 205),
|
||||
new Vector2 (178, 218),
|
||||
new Vector2 (173, 225),
|
||||
new Vector2 (163, 229),
|
||||
new Vector2 (154, 230),
|
||||
new Vector2 (144, 228),
|
||||
new Vector2 (134, 224),
|
||||
new Vector2 (131, 215),
|
||||
new Vector2 (145, 206),
|
||||
new Vector2 (154, 207),
|
||||
new Vector2 (163, 207),
|
||||
new Vector2 (175, 217),
|
||||
new Vector2 (163, 219),
|
||||
new Vector2 (154, 220),
|
||||
new Vector2 (144, 218)
|
||||
};
|
||||
public List<Vector2> landmarkPoints
|
||||
{
|
||||
|
||||
public List<Vector2> landmarkPoints {
|
||||
get { return this._landmarkPoints; }
|
||||
set { this._landmarkPoints = value; }
|
||||
}
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
using OpenCVForUnity;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using OpenCVForUnity.CoreModule;
|
||||
using OpenCVForUnity.ImgprocModule;
|
||||
|
||||
namespace FaceMaskExample
|
||||
{
|
||||
/// <summary>
|
||||
/// Low Pass Points Filter.
|
||||
/// v 1.0.1
|
||||
/// v 1.0.2
|
||||
/// </summary>
|
||||
public class LowPassPointsFilter : PointsFilterBase
|
||||
{
|
||||
|
@ -89,7 +90,7 @@ namespace FaceMaskExample
|
|||
{
|
||||
flag = false;
|
||||
for (int i = 0; i < lastPoints.Count; i++) {
|
||||
lastPoints[i] = new Vector2 ();
|
||||
lastPoints [i] = new Vector2 ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
using OpenCVForUnity;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using OpenCVForUnity.CoreModule;
|
||||
using OpenCVForUnity.ImgprocModule;
|
||||
using OpenCVForUnity.VideoModule;
|
||||
|
||||
namespace FaceMaskExample
|
||||
{
|
||||
/// <summary>
|
||||
/// Optical Flow Points Filter.
|
||||
/// v 1.0.2
|
||||
/// v 1.0.3
|
||||
/// </summary>
|
||||
public class OFPointsFilter : PointsFilterBase
|
||||
{
|
||||
|
@ -67,7 +69,7 @@ namespace FaceMaskExample
|
|||
}
|
||||
|
||||
for (int i = 0; i < numberOfElements; i++) {
|
||||
prevTrackPts[i] = new Point (srcPoints [i].x, srcPoints [i].y);
|
||||
prevTrackPts [i] = new Point (srcPoints [i].x, srcPoints [i].y);
|
||||
}
|
||||
|
||||
flag = true;
|
||||
|
@ -106,7 +108,7 @@ namespace FaceMaskExample
|
|||
|
||||
// clac diffDlib
|
||||
prevTrackPtsMat.fromList (prevTrackPts);
|
||||
OpenCVForUnity.Rect rect = Imgproc.boundingRect (prevTrackPtsMat);
|
||||
OpenCVForUnity.CoreModule.Rect rect = Imgproc.boundingRect (prevTrackPtsMat);
|
||||
double diffDlib = this.diffDlib * rect.area () / 40000.0 * diffCheckSensitivity;
|
||||
|
||||
// if the face is moving so fast, use dlib to detect the face
|
||||
|
@ -156,21 +158,21 @@ namespace FaceMaskExample
|
|||
|
||||
// Reset Optical Flow
|
||||
for (int i = 0; i < numberOfElements; i++) {
|
||||
prevTrackPts[i].x = 0.0;
|
||||
prevTrackPts[i].y = 0.0;
|
||||
prevTrackPts [i].x = 0.0;
|
||||
prevTrackPts [i].y = 0.0;
|
||||
}
|
||||
for (int i = 0; i < numberOfElements; i++) {
|
||||
nextTrackPts[i].x = 0.0;
|
||||
nextTrackPts[i].y = 0.0;
|
||||
nextTrackPts [i].x = 0.0;
|
||||
nextTrackPts [i].y = 0.0;
|
||||
}
|
||||
|
||||
if (prevgray != null) {
|
||||
prevgray.Dispose ();
|
||||
prevgray = new Mat();
|
||||
prevgray = new Mat ();
|
||||
}
|
||||
if (gray != null) {
|
||||
gray.Dispose ();
|
||||
gray = new Mat();
|
||||
gray = new Mat ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
using OpenCVForUnity;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using OpenCVForUnity.CoreModule;
|
||||
|
||||
namespace FaceMaskExample
|
||||
{
|
||||
/// <summary>
|
||||
/// Points Filter Base.
|
||||
/// v 1.0.0
|
||||
/// v 1.0.1
|
||||
/// </summary>
|
||||
public abstract class PointsFilterBase
|
||||
{
|
||||
|
|
|
@ -13,114 +13,102 @@ namespace FaceMaskExample
|
|||
[SerializeField]
|
||||
private int interval = 1;
|
||||
|
||||
private List<GameObject> pooledObjectList = new List<GameObject>();
|
||||
private List<GameObject> pooledObjectList = new List<GameObject> ();
|
||||
private IEnumerator removeObjectCheckCoroutine;
|
||||
|
||||
void OnEnable()
|
||||
void OnEnable ()
|
||||
{
|
||||
if (interval > 0){
|
||||
removeObjectCheckCoroutine = RemoveObjectCheck();
|
||||
StartCoroutine(removeObjectCheckCoroutine);
|
||||
if (interval > 0) {
|
||||
removeObjectCheckCoroutine = RemoveObjectCheck ();
|
||||
StartCoroutine (removeObjectCheckCoroutine);
|
||||
}
|
||||
}
|
||||
|
||||
void OnDisable()
|
||||
void OnDisable ()
|
||||
{
|
||||
if (removeObjectCheckCoroutine != null){
|
||||
StopCoroutine(removeObjectCheckCoroutine);
|
||||
if (removeObjectCheckCoroutine != null) {
|
||||
StopCoroutine (removeObjectCheckCoroutine);
|
||||
removeObjectCheckCoroutine = null;
|
||||
}
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
void OnDestroy ()
|
||||
{
|
||||
DestroyAllObjects ();
|
||||
}
|
||||
|
||||
public int Interval
|
||||
{
|
||||
get
|
||||
{
|
||||
public int Interval {
|
||||
get {
|
||||
return interval;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (interval != value)
|
||||
{
|
||||
set {
|
||||
if (interval != value) {
|
||||
interval = value;
|
||||
|
||||
if (removeObjectCheckCoroutine != null){
|
||||
StopCoroutine(removeObjectCheckCoroutine);
|
||||
if (removeObjectCheckCoroutine != null) {
|
||||
StopCoroutine (removeObjectCheckCoroutine);
|
||||
removeObjectCheckCoroutine = null;
|
||||
}
|
||||
if (interval > 0){
|
||||
removeObjectCheckCoroutine = RemoveObjectCheck();
|
||||
StartCoroutine(removeObjectCheckCoroutine);
|
||||
if (interval > 0) {
|
||||
removeObjectCheckCoroutine = RemoveObjectCheck ();
|
||||
StartCoroutine (removeObjectCheckCoroutine);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public GameObject GetInstance()
|
||||
public GameObject GetInstance ()
|
||||
{
|
||||
return GetInstance(transform);
|
||||
return GetInstance (transform);
|
||||
}
|
||||
|
||||
public GameObject GetInstance(Transform parent)
|
||||
public GameObject GetInstance (Transform parent)
|
||||
{
|
||||
if (prefab == null){
|
||||
Debug.LogWarning("prefab object is not set.");
|
||||
if (prefab == null) {
|
||||
Debug.LogWarning ("prefab object is not set.");
|
||||
return null;
|
||||
}
|
||||
|
||||
pooledObjectList.RemoveAll((obj) => obj == null);
|
||||
pooledObjectList.RemoveAll ((obj) => obj == null);
|
||||
|
||||
foreach (GameObject obj in pooledObjectList)
|
||||
{
|
||||
if (obj.activeSelf == false)
|
||||
{
|
||||
obj.SetActive(true);
|
||||
foreach (GameObject obj in pooledObjectList) {
|
||||
if (obj.activeSelf == false) {
|
||||
obj.SetActive (true);
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
if (pooledObjectList.Count < maxCount)
|
||||
{
|
||||
GameObject obj = (GameObject)GameObject.Instantiate(prefab);
|
||||
obj.SetActive(true);
|
||||
obj.transform.SetParent(parent, false);
|
||||
pooledObjectList.Add(obj);
|
||||
if (pooledObjectList.Count < maxCount) {
|
||||
GameObject obj = (GameObject)GameObject.Instantiate (prefab);
|
||||
obj.SetActive (true);
|
||||
obj.transform.SetParent (parent, false);
|
||||
pooledObjectList.Add (obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
IEnumerator RemoveObjectCheck()
|
||||
IEnumerator RemoveObjectCheck ()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
RemoveObject(prepareCount);
|
||||
yield return new WaitForSeconds(interval);
|
||||
while (true) {
|
||||
RemoveObject (prepareCount);
|
||||
yield return new WaitForSeconds (interval);
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveObject(int max)
|
||||
public void RemoveObject (int max)
|
||||
{
|
||||
if (pooledObjectList.Count > max)
|
||||
{
|
||||
if (pooledObjectList.Count > max) {
|
||||
|
||||
int needRemoveCount = pooledObjectList.Count - max;
|
||||
foreach (GameObject obj in pooledObjectList.ToArray())
|
||||
{
|
||||
if (needRemoveCount == 0)
|
||||
{
|
||||
foreach (GameObject obj in pooledObjectList.ToArray()) {
|
||||
if (needRemoveCount == 0) {
|
||||
break;
|
||||
}
|
||||
if (obj.activeSelf == false)
|
||||
{
|
||||
pooledObjectList.Remove(obj);
|
||||
Destroy(obj);
|
||||
if (obj.activeSelf == false) {
|
||||
pooledObjectList.Remove (obj);
|
||||
Destroy (obj);
|
||||
needRemoveCount--;
|
||||
}
|
||||
}
|
||||
|
@ -129,11 +117,10 @@ namespace FaceMaskExample
|
|||
|
||||
public void DestroyAllObjects ()
|
||||
{
|
||||
foreach (var obj in pooledObjectList)
|
||||
{
|
||||
Destroy(obj);
|
||||
foreach (var obj in pooledObjectList) {
|
||||
Destroy (obj);
|
||||
}
|
||||
pooledObjectList.Clear();
|
||||
pooledObjectList.Clear ();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,63 +3,62 @@ using UnityEngine;
|
|||
|
||||
namespace FaceMaskExample
|
||||
{
|
||||
[RequireComponent(typeof(MeshRenderer), typeof(MeshFilter), typeof(MeshCollider))]
|
||||
[RequireComponent (typeof(MeshRenderer), typeof(MeshFilter), typeof(MeshCollider))]
|
||||
public class TrackedMesh : MonoBehaviour
|
||||
{
|
||||
public MeshFilter meshFilter
|
||||
{
|
||||
public MeshFilter meshFilter {
|
||||
get { return _meshFilter; }
|
||||
}
|
||||
|
||||
protected MeshFilter _meshFilter;
|
||||
|
||||
public MeshRenderer meshRenderer
|
||||
{
|
||||
public MeshRenderer meshRenderer {
|
||||
get { return _meshRenderer; }
|
||||
}
|
||||
|
||||
protected MeshRenderer _meshRenderer;
|
||||
|
||||
public MeshCollider meshCollider
|
||||
{
|
||||
public MeshCollider meshCollider {
|
||||
get { return _meshCollider; }
|
||||
}
|
||||
|
||||
protected MeshCollider _meshCollider;
|
||||
|
||||
public int id
|
||||
{
|
||||
public int id {
|
||||
get { return _id; }
|
||||
set { _id = value; }
|
||||
}
|
||||
|
||||
protected int _id = 0;
|
||||
|
||||
public Material material
|
||||
{
|
||||
public Material material {
|
||||
get { return _meshRenderer.material; }
|
||||
}
|
||||
|
||||
public Material sharedMaterial
|
||||
{
|
||||
public Material sharedMaterial {
|
||||
get { return _meshRenderer.sharedMaterial; }
|
||||
}
|
||||
|
||||
void Awake()
|
||||
void Awake ()
|
||||
{
|
||||
_meshFilter = this.GetComponent<MeshFilter>();
|
||||
_meshRenderer = this.GetComponent<MeshRenderer>();
|
||||
_meshCollider = this.GetComponent<MeshCollider>();
|
||||
_meshFilter = this.GetComponent<MeshFilter> ();
|
||||
_meshRenderer = this.GetComponent<MeshRenderer> ();
|
||||
_meshCollider = this.GetComponent<MeshCollider> ();
|
||||
|
||||
if (_meshRenderer.material == null)
|
||||
throw new Exception("material does not exist.");
|
||||
throw new Exception ("material does not exist.");
|
||||
|
||||
_meshRenderer.sortingOrder = 32767;
|
||||
}
|
||||
|
||||
void OnDestroy(){
|
||||
if(_meshFilter != null && _meshFilter.mesh != null){
|
||||
DestroyImmediate(_meshFilter.mesh);
|
||||
void OnDestroy ()
|
||||
{
|
||||
if (_meshFilter != null && _meshFilter.mesh != null) {
|
||||
DestroyImmediate (_meshFilter.mesh);
|
||||
}
|
||||
if(_meshRenderer != null && _meshRenderer.materials != null){
|
||||
foreach(var m in _meshRenderer.materials){
|
||||
DestroyImmediate(m);
|
||||
if (_meshRenderer != null && _meshRenderer.materials != null) {
|
||||
foreach (var m in _meshRenderer.materials) {
|
||||
DestroyImmediate (m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,26 +12,24 @@ namespace FaceMaskExample
|
|||
|
||||
[SerializeField]
|
||||
protected GameObject _baseObject;
|
||||
public GameObject baseObject
|
||||
{
|
||||
|
||||
public GameObject baseObject {
|
||||
get {
|
||||
return _baseObject;
|
||||
}
|
||||
set {
|
||||
_baseObject = value;
|
||||
SetBaseObject(_baseObject);
|
||||
SetBaseObject (_baseObject);
|
||||
}
|
||||
}
|
||||
|
||||
public float width
|
||||
{
|
||||
public float width {
|
||||
get {
|
||||
return targetWidth;
|
||||
}
|
||||
}
|
||||
|
||||
public float height
|
||||
{
|
||||
public float height {
|
||||
get {
|
||||
return targetHeight;
|
||||
}
|
||||
|
@ -42,73 +40,71 @@ namespace FaceMaskExample
|
|||
protected float targetHeight = 0;
|
||||
protected Transform overlayTransform;
|
||||
protected ObjectPool objectPool;
|
||||
protected Dictionary<int, TrackedMesh> showingObjects = new Dictionary<int, TrackedMesh>();
|
||||
protected Dictionary<int, TrackedMesh> showingObjects = new Dictionary<int, TrackedMesh> ();
|
||||
|
||||
void Awake()
|
||||
void Awake ()
|
||||
{
|
||||
Initialize("TrackedMeshOverlay");
|
||||
Initialize ("TrackedMeshOverlay");
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
void OnDestroy ()
|
||||
{
|
||||
overlayTransform = null;
|
||||
targetTransform = null;
|
||||
targetWidth = 0;
|
||||
targetHeight = 0;
|
||||
showingObjects.Clear();
|
||||
if(objectPool != null)
|
||||
{
|
||||
Destroy(objectPool.gameObject);
|
||||
showingObjects.Clear ();
|
||||
if (objectPool != null) {
|
||||
Destroy (objectPool.gameObject);
|
||||
objectPool = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual GameObject GetPoolObject(Transform parent)
|
||||
protected virtual GameObject GetPoolObject (Transform parent)
|
||||
{
|
||||
if(objectPool == null) return null;
|
||||
if (objectPool == null)
|
||||
return null;
|
||||
|
||||
GameObject newObj = objectPool.GetInstance(parent);
|
||||
if(newObj != null){
|
||||
newObj.transform.SetParent(parent, false);
|
||||
GameObject newObj = objectPool.GetInstance (parent);
|
||||
if (newObj != null) {
|
||||
newObj.transform.SetParent (parent, false);
|
||||
return newObj;
|
||||
}else{
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void Initialize(String name)
|
||||
protected virtual void Initialize (String name)
|
||||
{
|
||||
GameObject obj = new GameObject(name);
|
||||
GameObject obj = new GameObject (name);
|
||||
overlayTransform = obj.transform;
|
||||
overlayTransform.parent = gameObject.transform.parent;
|
||||
|
||||
if(_baseObject != null)
|
||||
if (_baseObject != null)
|
||||
SetBaseObject (_baseObject);
|
||||
}
|
||||
|
||||
protected virtual void SetBaseObject (GameObject obj)
|
||||
{
|
||||
if (obj.GetComponent<TrackedMesh>() == null)
|
||||
{
|
||||
Debug.LogWarning("This gameObject is not TrackedMesh.");
|
||||
if (obj.GetComponent<TrackedMesh> () == null) {
|
||||
Debug.LogWarning ("This gameObject is not TrackedMesh.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(objectPool != null){
|
||||
Destroy(objectPool);
|
||||
if (objectPool != null) {
|
||||
Destroy (objectPool);
|
||||
}
|
||||
|
||||
objectPool = overlayTransform.gameObject.AddComponent<ObjectPool>();
|
||||
objectPool = overlayTransform.gameObject.AddComponent<ObjectPool> ();
|
||||
objectPool.prefab = obj;
|
||||
objectPool.maxCount = poolSize;
|
||||
objectPool.prepareCount = (int)poolSize / 2;
|
||||
objectPool.Interval = interval;
|
||||
}
|
||||
|
||||
public virtual void UpdateOverlayTransform(Transform targetTransform)
|
||||
public virtual void UpdateOverlayTransform (Transform targetTransform)
|
||||
{
|
||||
if (targetTransform == null)
|
||||
{
|
||||
if (targetTransform == null) {
|
||||
this.targetTransform = null;
|
||||
return;
|
||||
}
|
||||
|
@ -121,89 +117,83 @@ namespace FaceMaskExample
|
|||
overlayTransform.localScale = targetTransform.localScale;
|
||||
}
|
||||
|
||||
public virtual TrackedMesh GetObjectById(int id)
|
||||
public virtual TrackedMesh GetObjectById (int id)
|
||||
{
|
||||
if (showingObjects.ContainsKey(id))
|
||||
{
|
||||
return showingObjects[id];
|
||||
if (showingObjects.ContainsKey (id)) {
|
||||
return showingObjects [id];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual TrackedMesh CreateObject(int id, Texture2D tex = null)
|
||||
public virtual TrackedMesh CreateObject (int id, Texture2D tex = null)
|
||||
{
|
||||
if (_baseObject == null) Debug.LogError("The baseObject does not exist.");
|
||||
if (_baseObject == null)
|
||||
Debug.LogError ("The baseObject does not exist.");
|
||||
|
||||
if (!showingObjects.ContainsKey(id)){
|
||||
GameObject obj = GetPoolObject(overlayTransform);
|
||||
if (obj == null) return null;
|
||||
TrackedMesh tm = obj.GetComponent<TrackedMesh>();
|
||||
if (tm != null)
|
||||
{
|
||||
if (!showingObjects.ContainsKey (id)) {
|
||||
GameObject obj = GetPoolObject (overlayTransform);
|
||||
if (obj == null)
|
||||
return null;
|
||||
TrackedMesh tm = obj.GetComponent<TrackedMesh> ();
|
||||
if (tm != null) {
|
||||
tm.id = id;
|
||||
tm.transform.localPosition = Vector3.zero;
|
||||
tm.transform.localRotation = new Quaternion();
|
||||
tm.transform.localRotation = new Quaternion ();
|
||||
tm.transform.localScale = Vector3.one;
|
||||
if (tex != null)
|
||||
{
|
||||
Renderer tmRenderer = tm.transform.GetComponent<Renderer>();
|
||||
if (tex != null) {
|
||||
Renderer tmRenderer = tm.transform.GetComponent<Renderer> ();
|
||||
tmRenderer.sharedMaterial.SetTexture ("_MainTex", tex);
|
||||
}
|
||||
showingObjects.Add(id, tm);
|
||||
showingObjects.Add (id, tm);
|
||||
}
|
||||
return tm;
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void UpdateObject(int id, Vector3[] vertices, int[] triangles = null, Vector2[] uv = null, Vector2[] uv2 = null)
|
||||
public virtual void UpdateObject (int id, Vector3[] vertices, int[] triangles = null, Vector2[] uv = null, Vector2[] uv2 = null)
|
||||
{
|
||||
if (showingObjects.ContainsKey(id)){
|
||||
TrackedMesh tm = showingObjects[id];
|
||||
if (showingObjects.ContainsKey (id)) {
|
||||
TrackedMesh tm = showingObjects [id];
|
||||
|
||||
if(vertices.Length != tm.meshFilter.mesh.vertices.Length) Debug.LogError("The number of vertices does not match.");
|
||||
if (vertices.Length != tm.meshFilter.mesh.vertices.Length)
|
||||
Debug.LogError ("The number of vertices does not match.");
|
||||
tm.meshFilter.mesh.vertices = vertices;
|
||||
|
||||
if (triangles != null)
|
||||
{
|
||||
if (triangles != null) {
|
||||
tm.meshFilter.mesh.triangles = triangles;
|
||||
}
|
||||
if (uv != null)
|
||||
{
|
||||
if (uv != null) {
|
||||
tm.meshFilter.mesh.uv = uv;
|
||||
}
|
||||
|
||||
if (uv2 != null)
|
||||
{
|
||||
if (uv2 != null) {
|
||||
tm.meshFilter.mesh.uv2 = uv2;
|
||||
}
|
||||
|
||||
tm.meshFilter.mesh.RecalculateBounds();
|
||||
tm.meshFilter.mesh.RecalculateNormals();
|
||||
tm.meshFilter.mesh.RecalculateBounds ();
|
||||
tm.meshFilter.mesh.RecalculateNormals ();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void DeleteObject(int id)
|
||||
public virtual void DeleteObject (int id)
|
||||
{
|
||||
if (showingObjects.ContainsKey(id))
|
||||
{
|
||||
if(showingObjects[id] != null)
|
||||
showingObjects[id].gameObject.SetActive(false);
|
||||
showingObjects.Remove(id);
|
||||
if (showingObjects.ContainsKey (id)) {
|
||||
if (showingObjects [id] != null)
|
||||
showingObjects [id].gameObject.SetActive (false);
|
||||
showingObjects.Remove (id);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
public virtual void Reset ()
|
||||
{
|
||||
foreach (int key in showingObjects.Keys)
|
||||
{
|
||||
if(showingObjects[key] != null)
|
||||
showingObjects[key].gameObject.SetActive(false);
|
||||
foreach (int key in showingObjects.Keys) {
|
||||
if (showingObjects [key] != null)
|
||||
showingObjects [key].gameObject.SetActive (false);
|
||||
}
|
||||
|
||||
showingObjects.Clear();
|
||||
showingObjects.Clear ();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using OpenCVForUnity;
|
||||
using OpenCVForUnity.CoreModule;
|
||||
using OpenCVForUnity.ImgprocModule;
|
||||
using OpenCVForUnity.UnityUtils;
|
||||
|
||||
namespace FaceMaskExample
|
||||
{
|
||||
|
@ -22,8 +24,8 @@ namespace FaceMaskExample
|
|||
for (int i = 0; i < baseArea.Length; i++) {
|
||||
baseAreaPoints [i] = new Point (baseArea [i].x * width, height - baseArea [i].y * height);
|
||||
}
|
||||
Imgproc.fillConvexPoly (baseAreaMaskMat, new MatOfPoint (baseAreaPoints), Scalar.all (255), Core.LINE_AA, 0);
|
||||
// Imgproc.erode(baseAreaMaskMat, baseAreaMaskMat, Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size (width * 0.01, height * 0.01)), new Point(-1, -1), 1, Core.BORDER_CONSTANT, new Scalar(0, 0, 0, 255));
|
||||
Imgproc.fillConvexPoly (baseAreaMaskMat, new MatOfPoint (baseAreaPoints), Scalar.all (255), Imgproc.LINE_AA, 0);
|
||||
// Imgproc.erode(baseAreaMaskMat, baseAreaMaskMat, Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size (width * 0.01, height * 0.01)), new Point(-1, -1), 1, Core.BORDER_CONSTANT, new Scalar(0, 0, 0, 255));
|
||||
Imgproc.blur (baseAreaMaskMat, baseAreaMaskMat, new Size (width * 0.03, height * 0.03));
|
||||
|
||||
|
||||
|
@ -34,9 +36,9 @@ namespace FaceMaskExample
|
|||
for (int i = 0; i < exclusionArea.Length; i++) {
|
||||
points [i] = new Point (exclusionArea [i].x * width, height - exclusionArea [i].y * height);
|
||||
}
|
||||
Imgproc.fillConvexPoly (exclusionAreaMaskMat, new MatOfPoint (points), Scalar.all (255), Core.LINE_AA, 0);
|
||||
Imgproc.fillConvexPoly (exclusionAreaMaskMat, new MatOfPoint (points), Scalar.all (255), Imgproc.LINE_AA, 0);
|
||||
}
|
||||
// Imgproc.dilate(exclusionAreaMaskMat, exclusionAreaMaskMat, Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size (width * 0.002, height * 0.002)), new Point(-1, -1), 1, Core.BORDER_CONSTANT, new Scalar(0));
|
||||
// Imgproc.dilate(exclusionAreaMaskMat, exclusionAreaMaskMat, Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size (width * 0.002, height * 0.002)), new Point(-1, -1), 1, Core.BORDER_CONSTANT, new Scalar(0));
|
||||
Imgproc.blur (exclusionAreaMaskMat, exclusionAreaMaskMat, new Size (width * 0.01, height * 0.01), new Point (-1, -1), Core.BORDER_CONSTANT);
|
||||
|
||||
|
||||
|
@ -44,7 +46,7 @@ namespace FaceMaskExample
|
|||
Core.bitwise_xor (baseAreaMaskMat, exclusionAreaMaskMat, maskMat);
|
||||
|
||||
Texture2D texture = new Texture2D ((int)width, (int)height, TextureFormat.RGBA32, false);
|
||||
OpenCVForUnity.Utils.matToTexture2D (maskMat, texture);
|
||||
Utils.matToTexture2D (maskMat, texture);
|
||||
|
||||
maskMat.Dispose ();
|
||||
baseAreaMaskMat.Dispose ();
|
||||
|
|
|
@ -28,11 +28,11 @@ namespace FaceMaskExample
|
|||
const float INNER_Y = 5f;
|
||||
const float GUI_CONSOLE_HEIGHT = 50f;
|
||||
|
||||
public Vector2 offset = new Vector2(MARGIN_X, MARGIN_Y);
|
||||
public Vector2 offset = new Vector2 (MARGIN_X, MARGIN_Y);
|
||||
public bool boxVisible = true;
|
||||
public float boxWidth = GUI_WIDTH;
|
||||
public float boxHeight = GUI_HEIGHT;
|
||||
public Vector2 padding = new Vector2(INNER_X, INNER_Y);
|
||||
public Vector2 padding = new Vector2 (INNER_X, INNER_Y);
|
||||
public float consoleHeight = GUI_CONSOLE_HEIGHT;
|
||||
|
||||
GUIStyle console_labelStyle;
|
||||
|
@ -52,7 +52,8 @@ namespace FaceMaskExample
|
|||
public string consoleText;
|
||||
|
||||
// Use this for initialization
|
||||
void Start () {
|
||||
void Start ()
|
||||
{
|
||||
console_labelStyle = new GUIStyle ();
|
||||
console_labelStyle.fontSize = 32;
|
||||
console_labelStyle.fontStyle = FontStyle.Normal;
|
||||
|
@ -61,11 +62,12 @@ namespace FaceMaskExample
|
|||
|
||||
oldScrWidth = Screen.width;
|
||||
oldScrHeight = Screen.height;
|
||||
LocateGUI();
|
||||
LocateGUI ();
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update () {
|
||||
void Update ()
|
||||
{
|
||||
tick++;
|
||||
elapsed += Time.deltaTime;
|
||||
if (elapsed >= 1f) {
|
||||
|
@ -75,29 +77,30 @@ namespace FaceMaskExample
|
|||
}
|
||||
}
|
||||
|
||||
void OnGUI () {
|
||||
void OnGUI ()
|
||||
{
|
||||
if (oldScrWidth != Screen.width || oldScrHeight != Screen.height) {
|
||||
LocateGUI();
|
||||
LocateGUI ();
|
||||
}
|
||||
oldScrWidth = Screen.width;
|
||||
oldScrHeight = Screen.height;
|
||||
|
||||
if (boxVisible) {
|
||||
GUI.Box(outer, "");
|
||||
GUI.Box (outer, "");
|
||||
}
|
||||
|
||||
GUILayout.BeginArea(inner);
|
||||
GUILayout.BeginArea (inner);
|
||||
{
|
||||
GUILayout.BeginVertical();
|
||||
GUILayout.Label("fps : " + fps.ToString("F1"));
|
||||
GUILayout.BeginVertical ();
|
||||
GUILayout.Label ("fps : " + fps.ToString ("F1"));
|
||||
foreach (KeyValuePair<string, string> pair in outputDict) {
|
||||
GUILayout.Label(pair.Key + " : " + pair.Value);
|
||||
GUILayout.Label (pair.Key + " : " + pair.Value);
|
||||
}
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.EndVertical ();
|
||||
}
|
||||
GUILayout.EndArea ();
|
||||
|
||||
if (!string.IsNullOrEmpty(consoleText)) {
|
||||
if (!string.IsNullOrEmpty (consoleText)) {
|
||||
if (boxVisible) {
|
||||
GUI.Box (console_outer, "");
|
||||
}
|
||||
|
@ -112,7 +115,8 @@ namespace FaceMaskExample
|
|||
}
|
||||
}
|
||||
|
||||
public void Add (string key, string value) {
|
||||
public void Add (string key, string value)
|
||||
{
|
||||
if (outputDict.ContainsKey (key)) {
|
||||
outputDict [key] = value;
|
||||
} else {
|
||||
|
@ -120,27 +124,31 @@ namespace FaceMaskExample
|
|||
}
|
||||
}
|
||||
|
||||
public void Remove (string key) {
|
||||
public void Remove (string key)
|
||||
{
|
||||
outputDict.Remove (key);
|
||||
}
|
||||
|
||||
public void Clear () {
|
||||
public void Clear ()
|
||||
{
|
||||
outputDict.Clear ();
|
||||
}
|
||||
|
||||
public void LocateGUI() {
|
||||
x = GetAlignedX(alignment, boxWidth);
|
||||
y = GetAlignedY(alignment, boxHeight);
|
||||
outer = new Rect(x, y, boxWidth, boxHeight);
|
||||
inner = new Rect(x + padding.x, y + padding.y, boxWidth, boxHeight);
|
||||
|
||||
console_x = GetAlignedX(Alignment.LeftBottom, Screen.width);
|
||||
console_y = GetAlignedY(Alignment.LeftBottom, consoleHeight);
|
||||
console_outer = new Rect(console_x, console_y, Screen.width - offset.x*2, consoleHeight);
|
||||
console_inner = new Rect(console_x + padding.x, console_y + padding.y, Screen.width - offset.x*2 - padding.x, consoleHeight);
|
||||
public void LocateGUI ()
|
||||
{
|
||||
x = GetAlignedX (alignment, boxWidth);
|
||||
y = GetAlignedY (alignment, boxHeight);
|
||||
outer = new Rect (x, y, boxWidth, boxHeight);
|
||||
inner = new Rect (x + padding.x, y + padding.y, boxWidth, boxHeight);
|
||||
|
||||
console_x = GetAlignedX (Alignment.LeftBottom, Screen.width);
|
||||
console_y = GetAlignedY (Alignment.LeftBottom, consoleHeight);
|
||||
console_outer = new Rect (console_x, console_y, Screen.width - offset.x * 2, consoleHeight);
|
||||
console_inner = new Rect (console_x + padding.x, console_y + padding.y, Screen.width - offset.x * 2 - padding.x, consoleHeight);
|
||||
}
|
||||
|
||||
float GetAlignedX(Alignment anchor, float w) {
|
||||
|
||||
float GetAlignedX (Alignment anchor, float w)
|
||||
{
|
||||
switch (anchor) {
|
||||
default:
|
||||
case Alignment.LeftTop:
|
||||
|
@ -153,7 +161,8 @@ namespace FaceMaskExample
|
|||
}
|
||||
}
|
||||
|
||||
float GetAlignedY(Alignment anchor, float h) {
|
||||
float GetAlignedY (Alignment anchor, float h)
|
||||
{
|
||||
switch (anchor) {
|
||||
default:
|
||||
case Alignment.LeftTop:
|
||||
|
|
|
@ -2,16 +2,16 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
using OpenCVForUnity;
|
||||
using OpenCVForUnity.CoreModule;
|
||||
using OpenCVForUnity.Calib3dModule;
|
||||
|
||||
namespace FaceMaskExample
|
||||
{
|
||||
/// <summary>
|
||||
/// Frontal face checker. (Calculates from points of face landmark which was detected by using Dlib Face Landmark Detector)
|
||||
/// v 1.0.0
|
||||
/// v 1.0.1
|
||||
/// </summary>
|
||||
public class FrontalFaceChecker : IDisposable
|
||||
public class FrontalFaceChecker
|
||||
{
|
||||
float imageWidth;
|
||||
float imageHeight;
|
||||
|
@ -38,7 +38,7 @@ namespace FaceMaskExample
|
|||
imageHeight = height;
|
||||
|
||||
for (int i = 0; i < landmarkPoints.Length; i++) {
|
||||
landmarkPoints[i] = new Point (0, 0);
|
||||
landmarkPoints [i] = new Point (0, 0);
|
||||
}
|
||||
|
||||
objectPoints = new MatOfPoint3f (
|
||||
|
@ -49,7 +49,7 @@ namespace FaceMaskExample
|
|||
new Point3 (26, 15, 83),//r mouse (Mouth breadth)
|
||||
new Point3 (-79, 90, 0.0),//l ear (Bitragion breadth)
|
||||
new Point3 (79, 90, 0.0)//r ear (Bitragion breadth)
|
||||
);
|
||||
);
|
||||
|
||||
imagePoints = new MatOfPoint2f ();
|
||||
|
||||
|
@ -78,25 +78,25 @@ namespace FaceMaskExample
|
|||
|
||||
public void Dispose ()
|
||||
{
|
||||
if(objectPoints != null && !objectPoints.IsDisposed)
|
||||
if (objectPoints != null && !objectPoints.IsDisposed)
|
||||
objectPoints.Dispose ();
|
||||
|
||||
if(imagePoints != null && !imagePoints.IsDisposed)
|
||||
if (imagePoints != null && !imagePoints.IsDisposed)
|
||||
imagePoints.Dispose ();
|
||||
|
||||
if(rvec != null && !rvec.IsDisposed)
|
||||
if (rvec != null && !rvec.IsDisposed)
|
||||
rvec.Dispose ();
|
||||
|
||||
if(tvec != null && !tvec.IsDisposed)
|
||||
if (tvec != null && !tvec.IsDisposed)
|
||||
tvec.Dispose ();
|
||||
|
||||
if(rotM != null && !rotM.IsDisposed)
|
||||
if (rotM != null && !rotM.IsDisposed)
|
||||
rotM.Dispose ();
|
||||
|
||||
if(camMatrix != null && !camMatrix.IsDisposed)
|
||||
if (camMatrix != null && !camMatrix.IsDisposed)
|
||||
camMatrix.Dispose ();
|
||||
|
||||
if(distCoeffs != null && !distCoeffs.IsDisposed)
|
||||
if (distCoeffs != null && !distCoeffs.IsDisposed)
|
||||
distCoeffs.Dispose ();
|
||||
}
|
||||
|
||||
|
@ -160,15 +160,15 @@ namespace FaceMaskExample
|
|||
float rotationY = (angles.y > 180) ? angles.y - 360 : angles.y;
|
||||
float rotationZ = (tvec_z >= 0) ? (angles.z > 180) ? angles.z - 360 : angles.z : 180 - angles.z;
|
||||
|
||||
if(tvec_z < 0){
|
||||
if (tvec_z < 0) {
|
||||
rotationX = -rotationX;
|
||||
rotationY = -rotationY;
|
||||
rotationZ = -rotationZ;
|
||||
}
|
||||
|
||||
return new Vector3(rotationX, rotationY, rotationZ);
|
||||
return new Vector3 (rotationX, rotationY, rotationZ);
|
||||
} else {
|
||||
return new Vector3(0, 0, 0);
|
||||
return new Vector3 (0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -190,7 +190,7 @@ namespace FaceMaskExample
|
|||
|
||||
return 1.0f - rate;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Extract rotation quaternion from transform matrix.
|
||||
/// </summary>
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
using UnityEngine;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using OpenCVForUnity;
|
||||
using UnityEngine;
|
||||
using DlibFaceLandmarkDetector;
|
||||
using OpenCVForUnity.CoreModule;
|
||||
using OpenCVForUnity.ImgprocModule;
|
||||
|
||||
namespace FaceMaskExample
|
||||
{
|
||||
|
@ -48,8 +48,8 @@ namespace FaceMaskExample
|
|||
public static void DrawFaceRect (Mat imgMat, DlibFaceLandmarkDetector.FaceLandmarkDetector.RectDetection rect, Scalar color, int thickness)
|
||||
{
|
||||
UnityEngine.Rect _rect = rect.rect;
|
||||
Imgproc.putText (imgMat, "detection_confidence : " + rect.detection_confidence, new Point (_rect.xMin, _rect.yMin - 20), Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 1, Imgproc.LINE_AA, false);
|
||||
Imgproc.putText (imgMat, "weight_index : " + rect.weight_index, new Point (_rect.xMin, _rect.yMin - 5), Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 1, Imgproc.LINE_AA, false);
|
||||
Imgproc.putText (imgMat, "detection_confidence : " + rect.detection_confidence, new Point (_rect.xMin, _rect.yMin - 20), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 1, Imgproc.LINE_AA, false);
|
||||
Imgproc.putText (imgMat, "weight_index : " + rect.weight_index, new Point (_rect.xMin, _rect.yMin - 5), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 1, Imgproc.LINE_AA, false);
|
||||
Imgproc.rectangle (imgMat, new Point (_rect.xMin, _rect.yMin), new Point (_rect.xMax, _rect.yMax), color, thickness);
|
||||
}
|
||||
|
||||
|
@ -63,10 +63,10 @@ namespace FaceMaskExample
|
|||
public static void DrawFaceRect (Mat imgMat, double[] rect, Scalar color, int thickness)
|
||||
{
|
||||
if (rect.Length > 4)
|
||||
Imgproc.putText (imgMat, "detection_confidence : " + rect[4], new Point (rect[0], rect[1] - 20), Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 1, Imgproc.LINE_AA, false);
|
||||
Imgproc.putText (imgMat, "detection_confidence : " + rect [4], new Point (rect [0], rect [1] - 20), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 1, Imgproc.LINE_AA, false);
|
||||
if (rect.Length > 5)
|
||||
Imgproc.putText (imgMat, "weight_index : " + rect[5], new Point (rect[0], rect[1] - 5), Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 1, Imgproc.LINE_AA, false);
|
||||
Imgproc.rectangle (imgMat, new Point (rect[0], rect[1]), new Point (rect[0] + rect[2], rect[1] + rect[3]), color, thickness);
|
||||
Imgproc.putText (imgMat, "weight_index : " + rect [5], new Point (rect [0], rect [1] - 5), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 1, Imgproc.LINE_AA, false);
|
||||
Imgproc.rectangle (imgMat, new Point (rect [0], rect [1]), new Point (rect [0] + rect [2], rect [1] + rect [3]), color, thickness);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -127,7 +127,7 @@ namespace FaceMaskExample
|
|||
// Draw the index number of facelandmark points.
|
||||
if (drawIndexNumbers) {
|
||||
for (int i = 0; i < points.Count; ++i)
|
||||
Imgproc.putText (imgMat, i.ToString (), new Point (points [i].x, points [i].y), Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 1, Imgproc.LINE_AA, false);
|
||||
Imgproc.putText (imgMat, i.ToString (), new Point (points [i].x, points [i].y), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 1, Imgproc.LINE_AA, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -189,7 +189,7 @@ namespace FaceMaskExample
|
|||
// Draw the index number of facelandmark points.
|
||||
if (drawIndexNumbers) {
|
||||
for (int i = 0; i < points.Count; ++i)
|
||||
Imgproc.putText (imgMat, i.ToString (), points [i], Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 1, Imgproc.LINE_AA, false);
|
||||
Imgproc.putText (imgMat, i.ToString (), points [i], Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 1, Imgproc.LINE_AA, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -278,7 +278,7 @@ namespace FaceMaskExample
|
|||
}
|
||||
|
||||
for (int i = 0; i < pts.Count; ++i) {
|
||||
vecs.Add (new Vector2((float)pts[i].x, (float)pts[i].y));
|
||||
vecs.Add (new Vector2 ((float)pts [i].x, (float)pts [i].y));
|
||||
}
|
||||
|
||||
return vecs;
|
||||
|
@ -324,7 +324,7 @@ namespace FaceMaskExample
|
|||
}
|
||||
|
||||
for (int i = 0; i < vecs.Count; ++i) {
|
||||
vecs [i] = new Vector2((float)arr [i * 2], (float)arr [i * 2 + 1]);
|
||||
vecs [i] = new Vector2 ((float)arr [i * 2], (float)arr [i * 2 + 1]);
|
||||
}
|
||||
|
||||
return vecs;
|
||||
|
|
|
@ -1,887 +0,0 @@
|
|||
using OpenCVForUnity;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace FaceMaskExample
|
||||
{
|
||||
/// <summary>
|
||||
/// WebcamTexture to mat helper.
|
||||
/// v 1.0.8
|
||||
/// </summary>
|
||||
public class WebCamTextureToMatHelper : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// Set the name of the camera device to use. (or device index number)
|
||||
/// </summary>
|
||||
[SerializeField, FormerlySerializedAs("requestedDeviceName"), TooltipAttribute ("Set the name of the device to use. (or device index number)")]
|
||||
protected string _requestedDeviceName = null;
|
||||
public virtual string requestedDeviceName {
|
||||
get { return _requestedDeviceName; }
|
||||
set {
|
||||
_requestedDeviceName = value;
|
||||
if (hasInitDone) {
|
||||
Initialize ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the width of camera.
|
||||
/// </summary>
|
||||
[SerializeField, FormerlySerializedAs("requestedWidth"), TooltipAttribute ("Set the width of camera.")]
|
||||
protected int _requestedWidth = 640;
|
||||
public virtual int requestedWidth {
|
||||
get { return _requestedWidth; }
|
||||
set {
|
||||
_requestedWidth = (int)Mathf.Clamp(value, 0f, float.MaxValue);
|
||||
if (hasInitDone) {
|
||||
Initialize ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the height of camera.
|
||||
/// </summary>
|
||||
[SerializeField, FormerlySerializedAs("requestedHeight"), TooltipAttribute ("Set the height of camera.")]
|
||||
protected int _requestedHeight = 480;
|
||||
public virtual int requestedHeight {
|
||||
get { return _requestedHeight; }
|
||||
set {
|
||||
_requestedHeight = (int)Mathf.Clamp(value, 0f, float.MaxValue);
|
||||
if (hasInitDone) {
|
||||
Initialize ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set whether to use the front facing camera.
|
||||
/// </summary>
|
||||
[SerializeField, FormerlySerializedAs("requestedIsFrontFacing"), TooltipAttribute ("Set whether to use the front facing camera.")]
|
||||
protected bool _requestedIsFrontFacing = false;
|
||||
public virtual bool requestedIsFrontFacing {
|
||||
get { return _requestedIsFrontFacing; }
|
||||
set {
|
||||
_requestedIsFrontFacing = value;
|
||||
if (hasInitDone) {
|
||||
Initialize (_requestedIsFrontFacing, requestedFPS, rotate90Degree);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the frame rate of camera.
|
||||
/// </summary>
|
||||
[SerializeField, FormerlySerializedAs("requestedFPS"), TooltipAttribute ("Set the frame rate of camera.")]
|
||||
protected float _requestedFPS = 30f;
|
||||
public virtual float requestedFPS {
|
||||
get { return _requestedFPS; }
|
||||
set {
|
||||
_requestedFPS = Mathf.Clamp(value, -1f, float.MaxValue);
|
||||
if (hasInitDone) {
|
||||
bool isPlaying = IsPlaying ();
|
||||
Stop ();
|
||||
webCamTexture.requestedFPS = _requestedFPS;
|
||||
if (isPlaying) Play ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets whether to rotate camera frame 90 degrees. (clockwise)
|
||||
/// </summary>
|
||||
[SerializeField, FormerlySerializedAs("rotate90Degree"), TooltipAttribute ("Sets whether to rotate camera frame 90 degrees. (clockwise)")]
|
||||
protected bool _rotate90Degree = false;
|
||||
public virtual bool rotate90Degree {
|
||||
get { return _rotate90Degree; }
|
||||
set {
|
||||
_rotate90Degree = value;
|
||||
if (hasInitDone) {
|
||||
Initialize ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if flips vertically.
|
||||
/// </summary>
|
||||
[SerializeField, FormerlySerializedAs("flipVertical"), TooltipAttribute ("Determines if flips vertically.")]
|
||||
protected bool _flipVertical = false;
|
||||
public virtual bool flipVertical {
|
||||
get { return _flipVertical; }
|
||||
set { _flipVertical = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if flips horizontal.
|
||||
/// </summary>
|
||||
[SerializeField, FormerlySerializedAs("flipHorizontal"), TooltipAttribute ("Determines if flips horizontal.")]
|
||||
protected bool _flipHorizontal = false;
|
||||
public virtual bool flipHorizontal {
|
||||
get { return _flipHorizontal; }
|
||||
set { _flipHorizontal = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The number of frames before the initialization process times out.
|
||||
/// </summary>
|
||||
[SerializeField, FormerlySerializedAs("timeoutFrameCount"), TooltipAttribute ("The number of frames before the initialization process times out.")]
|
||||
protected int _timeoutFrameCount = 300;
|
||||
public virtual int timeoutFrameCount {
|
||||
get { return _timeoutFrameCount; }
|
||||
set { _timeoutFrameCount = (int)Mathf.Clamp(value, 0f, float.MaxValue); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// UnityEvent that is triggered when this instance is initialized.
|
||||
/// </summary>
|
||||
public UnityEvent onInitialized;
|
||||
|
||||
/// <summary>
|
||||
/// UnityEvent that is triggered when this instance is disposed.
|
||||
/// </summary>
|
||||
public UnityEvent onDisposed;
|
||||
|
||||
/// <summary>
|
||||
/// UnityEvent that is triggered when this instance is error Occurred.
|
||||
/// </summary>
|
||||
public ErrorUnityEvent onErrorOccurred;
|
||||
|
||||
/// <summary>
|
||||
/// The active WebcamTexture.
|
||||
/// </summary>
|
||||
protected WebCamTexture webCamTexture;
|
||||
|
||||
/// <summary>
|
||||
/// The active WebcamDevice.
|
||||
/// </summary>
|
||||
protected WebCamDevice webCamDevice;
|
||||
|
||||
/// <summary>
|
||||
/// The frame mat.
|
||||
/// </summary>
|
||||
protected Mat frameMat;
|
||||
|
||||
/// <summary>
|
||||
/// The rotated frame mat
|
||||
/// </summary>
|
||||
protected Mat rotatedFrameMat;
|
||||
|
||||
/// <summary>
|
||||
/// The buffer colors.
|
||||
/// </summary>
|
||||
protected Color32[] colors;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether this instance is waiting for initialization to complete.
|
||||
/// </summary>
|
||||
protected bool isInitWaiting = false;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether this instance has been initialized.
|
||||
/// </summary>
|
||||
protected bool hasInitDone = false;
|
||||
|
||||
/// <summary>
|
||||
/// The initialization coroutine.
|
||||
/// </summary>
|
||||
protected IEnumerator initCoroutine;
|
||||
|
||||
/// <summary>
|
||||
/// The orientation of the screen.
|
||||
/// </summary>
|
||||
protected ScreenOrientation screenOrientation;
|
||||
|
||||
/// <summary>
|
||||
/// The width of the screen.
|
||||
/// </summary>
|
||||
protected int screenWidth;
|
||||
|
||||
/// <summary>
|
||||
/// The height of the screen.
|
||||
/// </summary>
|
||||
protected int screenHeight;
|
||||
|
||||
|
||||
[System.Serializable]
|
||||
public enum ErrorCode :int
|
||||
{
|
||||
UNKNOWN = 0,
|
||||
CAMERA_DEVICE_NOT_EXIST = 1,
|
||||
TIMEOUT = 2,
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class ErrorUnityEvent : UnityEngine.Events.UnityEvent<ErrorCode>
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected virtual void OnValidate()
|
||||
{
|
||||
_requestedWidth = (int)Mathf.Clamp(_requestedWidth, 0f, float.MaxValue);
|
||||
_requestedHeight = (int)Mathf.Clamp(_requestedHeight, 0f, float.MaxValue);
|
||||
_requestedFPS = Mathf.Clamp(_requestedFPS, -1f, float.MaxValue);
|
||||
_timeoutFrameCount = (int)Mathf.Clamp(_timeoutFrameCount, 0f, float.MaxValue);
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
protected virtual void Update ()
|
||||
{
|
||||
if (hasInitDone) {
|
||||
// Catch the orientation change of the screen and correct the mat image to the correct direction.
|
||||
if (screenOrientation != Screen.orientation && (screenWidth != Screen.width || screenHeight != Screen.height)) {
|
||||
|
||||
if (onDisposed != null)
|
||||
onDisposed.Invoke ();
|
||||
|
||||
if (frameMat != null) {
|
||||
frameMat.Dispose ();
|
||||
frameMat = null;
|
||||
}
|
||||
if (rotatedFrameMat != null) {
|
||||
rotatedFrameMat.Dispose ();
|
||||
rotatedFrameMat = null;
|
||||
}
|
||||
|
||||
frameMat = new Mat (webCamTexture.height, webCamTexture.width, CvType.CV_8UC4);
|
||||
screenOrientation = Screen.orientation;
|
||||
screenWidth = Screen.width;
|
||||
screenHeight = Screen.height;
|
||||
|
||||
bool isRotatedFrame = false;
|
||||
#if !UNITY_EDITOR && !(UNITY_STANDALONE || UNITY_WEBGL)
|
||||
if (screenOrientation == ScreenOrientation.Portrait || screenOrientation == ScreenOrientation.PortraitUpsideDown) {
|
||||
if (!rotate90Degree)
|
||||
isRotatedFrame = true;
|
||||
} else if (rotate90Degree) {
|
||||
isRotatedFrame = true;
|
||||
}
|
||||
#else
|
||||
if (rotate90Degree)
|
||||
isRotatedFrame = true;
|
||||
#endif
|
||||
if (isRotatedFrame)
|
||||
rotatedFrameMat = new Mat (webCamTexture.width, webCamTexture.height, CvType.CV_8UC4);
|
||||
|
||||
if (onInitialized != null)
|
||||
onInitialized.Invoke ();
|
||||
} else {
|
||||
screenWidth = Screen.width;
|
||||
screenHeight = Screen.height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raises the destroy event.
|
||||
/// </summary>
|
||||
protected virtual void OnDestroy ()
|
||||
{
|
||||
Dispose ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes this instance.
|
||||
/// </summary>
|
||||
public virtual void Initialize ()
|
||||
{
|
||||
if (isInitWaiting)
|
||||
{
|
||||
CancelInitCoroutine ();
|
||||
ReleaseResources ();
|
||||
}
|
||||
|
||||
if (onInitialized == null)
|
||||
onInitialized = new UnityEvent ();
|
||||
if (onDisposed == null)
|
||||
onDisposed = new UnityEvent ();
|
||||
if (onErrorOccurred == null)
|
||||
onErrorOccurred = new ErrorUnityEvent ();
|
||||
|
||||
initCoroutine = _Initialize ();
|
||||
StartCoroutine (initCoroutine);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes this instance.
|
||||
/// </summary>
|
||||
/// <param name="requestedWidth">Requested width.</param>
|
||||
/// <param name="requestedHeight">Requested height.</param>
|
||||
public virtual void Initialize (int requestedWidth, int requestedHeight)
|
||||
{
|
||||
if (isInitWaiting)
|
||||
{
|
||||
CancelInitCoroutine ();
|
||||
ReleaseResources ();
|
||||
}
|
||||
|
||||
this._requestedWidth = requestedWidth;
|
||||
this._requestedHeight = requestedHeight;
|
||||
if (onInitialized == null)
|
||||
onInitialized = new UnityEvent ();
|
||||
if (onDisposed == null)
|
||||
onDisposed = new UnityEvent ();
|
||||
if (onErrorOccurred == null)
|
||||
onErrorOccurred = new ErrorUnityEvent ();
|
||||
|
||||
initCoroutine = _Initialize ();
|
||||
StartCoroutine (initCoroutine);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes this instance.
|
||||
/// </summary>
|
||||
/// <param name="requestedIsFrontFacing">If set to <c>true</c> requested to using the front camera.</param>
|
||||
/// <param name="requestedFPS">Requested FPS.</param>
|
||||
/// <param name="rotate90Degree">If set to <c>true</c> requested to rotate camera frame 90 degrees. (clockwise)</param>
|
||||
public virtual void Initialize (bool requestedIsFrontFacing, float requestedFPS = 30f, bool rotate90Degree = false)
|
||||
{
|
||||
if (isInitWaiting)
|
||||
{
|
||||
CancelInitCoroutine ();
|
||||
ReleaseResources ();
|
||||
}
|
||||
|
||||
_requestedDeviceName = null;
|
||||
this._requestedIsFrontFacing = requestedIsFrontFacing;
|
||||
this._requestedFPS = requestedFPS;
|
||||
this._rotate90Degree = rotate90Degree;
|
||||
if (onInitialized == null)
|
||||
onInitialized = new UnityEvent ();
|
||||
if (onDisposed == null)
|
||||
onDisposed = new UnityEvent ();
|
||||
if (onErrorOccurred == null)
|
||||
onErrorOccurred = new ErrorUnityEvent ();
|
||||
|
||||
initCoroutine = _Initialize ();
|
||||
StartCoroutine (initCoroutine);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes this instance.
|
||||
/// </summary>
|
||||
/// <param name="deviceName">Device name.</param>
|
||||
/// <param name="requestedWidth">Requested width.</param>
|
||||
/// <param name="requestedHeight">Requested height.</param>
|
||||
/// <param name="requestedIsFrontFacing">If set to <c>true</c> requested to using the front camera.</param>
|
||||
/// <param name="requestedFPS">Requested FPS.</param>
|
||||
/// <param name="rotate90Degree">If set to <c>true</c> requested to rotate camera frame 90 degrees. (clockwise)</param>
|
||||
public virtual void Initialize (string deviceName, int requestedWidth, int requestedHeight, bool requestedIsFrontFacing = false, float requestedFPS = 30f, bool rotate90Degree = false)
|
||||
{
|
||||
if (isInitWaiting)
|
||||
{
|
||||
CancelInitCoroutine ();
|
||||
ReleaseResources ();
|
||||
}
|
||||
|
||||
this._requestedDeviceName = deviceName;
|
||||
this._requestedWidth = requestedWidth;
|
||||
this._requestedHeight = requestedHeight;
|
||||
this._requestedIsFrontFacing = requestedIsFrontFacing;
|
||||
this._requestedFPS = requestedFPS;
|
||||
this._rotate90Degree = rotate90Degree;
|
||||
if (onInitialized == null)
|
||||
onInitialized = new UnityEvent ();
|
||||
if (onDisposed == null)
|
||||
onDisposed = new UnityEvent ();
|
||||
if (onErrorOccurred == null)
|
||||
onErrorOccurred = new ErrorUnityEvent ();
|
||||
|
||||
initCoroutine = _Initialize ();
|
||||
StartCoroutine (initCoroutine);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes this instance by coroutine.
|
||||
/// </summary>
|
||||
protected virtual IEnumerator _Initialize ()
|
||||
{
|
||||
if (hasInitDone)
|
||||
{
|
||||
ReleaseResources ();
|
||||
|
||||
if (onDisposed != null)
|
||||
onDisposed.Invoke ();
|
||||
}
|
||||
|
||||
isInitWaiting = true;
|
||||
|
||||
// Creates the camera
|
||||
if (!String.IsNullOrEmpty (requestedDeviceName)) {
|
||||
int requestedDeviceIndex = -1;
|
||||
if (Int32.TryParse (requestedDeviceName, out requestedDeviceIndex)) {
|
||||
if (requestedDeviceIndex >= 0 && requestedDeviceIndex < WebCamTexture.devices.Length) {
|
||||
webCamDevice = WebCamTexture.devices [requestedDeviceIndex];
|
||||
if (requestedFPS < 0) {
|
||||
webCamTexture = new WebCamTexture (webCamDevice.name, requestedWidth, requestedHeight);
|
||||
} else {
|
||||
webCamTexture = new WebCamTexture (webCamDevice.name, requestedWidth, requestedHeight, (int)requestedFPS);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int cameraIndex = 0; cameraIndex < WebCamTexture.devices.Length; cameraIndex++) {
|
||||
if (WebCamTexture.devices [cameraIndex].name == requestedDeviceName) {
|
||||
webCamDevice = WebCamTexture.devices [cameraIndex];
|
||||
if (requestedFPS < 0) {
|
||||
webCamTexture = new WebCamTexture (webCamDevice.name, requestedWidth, requestedHeight);
|
||||
} else {
|
||||
webCamTexture = new WebCamTexture (webCamDevice.name, requestedWidth, requestedHeight, (int)requestedFPS);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (webCamTexture == null)
|
||||
Debug.Log ("Cannot find camera device " + requestedDeviceName + ".");
|
||||
}
|
||||
|
||||
if (webCamTexture == null) {
|
||||
// Checks how many and which cameras are available on the device
|
||||
for (int cameraIndex = 0; cameraIndex < WebCamTexture.devices.Length; cameraIndex++) {
|
||||
if (WebCamTexture.devices [cameraIndex].isFrontFacing == requestedIsFrontFacing) {
|
||||
webCamDevice = WebCamTexture.devices [cameraIndex];
|
||||
if (requestedFPS < 0) {
|
||||
webCamTexture = new WebCamTexture (webCamDevice.name, requestedWidth, requestedHeight);
|
||||
} else {
|
||||
webCamTexture = new WebCamTexture (webCamDevice.name, requestedWidth, requestedHeight, (int)requestedFPS);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (webCamTexture == null) {
|
||||
if (WebCamTexture.devices.Length > 0) {
|
||||
webCamDevice = WebCamTexture.devices [0];
|
||||
if (requestedFPS < 0) {
|
||||
webCamTexture = new WebCamTexture (webCamDevice.name, requestedWidth, requestedHeight);
|
||||
} else {
|
||||
webCamTexture = new WebCamTexture (webCamDevice.name, requestedWidth, requestedHeight, (int)requestedFPS);
|
||||
}
|
||||
} else {
|
||||
isInitWaiting = false;
|
||||
|
||||
if (onErrorOccurred != null)
|
||||
onErrorOccurred.Invoke (ErrorCode.CAMERA_DEVICE_NOT_EXIST);
|
||||
|
||||
yield break;
|
||||
}
|
||||
}
|
||||
|
||||
// Starts the camera
|
||||
webCamTexture.Play ();
|
||||
|
||||
int initFrameCount = 0;
|
||||
bool isTimeout = false;
|
||||
|
||||
while (true) {
|
||||
if (initFrameCount > timeoutFrameCount) {
|
||||
isTimeout = true;
|
||||
break;
|
||||
}
|
||||
// If you want to use webcamTexture.width and webcamTexture.height on iOS, you have to wait until webcamTexture.didUpdateThisFrame == 1, otherwise these two values will be equal to 16. (http://forum.unity3d.com/threads/webcamtexture-and-error-0x0502.123922/)
|
||||
#if UNITY_IOS && !UNITY_EDITOR && (UNITY_4_6_3 || UNITY_4_6_4 || UNITY_5_0_0 || UNITY_5_0_1)
|
||||
else if (webCamTexture.width > 16 && webCamTexture.height > 16) {
|
||||
#else
|
||||
else if (webCamTexture.didUpdateThisFrame) {
|
||||
#if UNITY_IOS && !UNITY_EDITOR && UNITY_5_2
|
||||
while (webCamTexture.width <= 16) {
|
||||
if (initFrameCount > timeoutFrameCount) {
|
||||
isTimeout = true;
|
||||
break;
|
||||
}else {
|
||||
initFrameCount++;
|
||||
}
|
||||
webCamTexture.GetPixels32 ();
|
||||
yield return new WaitForEndOfFrame ();
|
||||
}
|
||||
if (isTimeout) break;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Debug.Log ("WebCamTextureToMatHelper:: " + "devicename:" + webCamTexture.deviceName + " name:" + webCamTexture.name + " width:" + webCamTexture.width + " height:" + webCamTexture.height + " fps:" + webCamTexture.requestedFPS
|
||||
+ " videoRotationAngle:" + webCamTexture.videoRotationAngle + " videoVerticallyMirrored:" + webCamTexture.videoVerticallyMirrored + " isFrongFacing:" + webCamDevice.isFrontFacing);
|
||||
|
||||
if (colors == null || colors.Length != webCamTexture.width * webCamTexture.height)
|
||||
colors = new Color32[webCamTexture.width * webCamTexture.height];
|
||||
|
||||
frameMat = new Mat (webCamTexture.height, webCamTexture.width, CvType.CV_8UC4);
|
||||
screenOrientation = Screen.orientation;
|
||||
screenWidth = Screen.width;
|
||||
screenHeight = Screen.height;
|
||||
|
||||
bool isRotatedFrame = false;
|
||||
#if !UNITY_EDITOR && !(UNITY_STANDALONE || UNITY_WEBGL)
|
||||
if (screenOrientation == ScreenOrientation.Portrait || screenOrientation == ScreenOrientation.PortraitUpsideDown) {
|
||||
if (!rotate90Degree)
|
||||
isRotatedFrame = true;
|
||||
} else if (rotate90Degree) {
|
||||
isRotatedFrame = true;
|
||||
}
|
||||
#else
|
||||
if (rotate90Degree)
|
||||
isRotatedFrame = true;
|
||||
#endif
|
||||
if (isRotatedFrame)
|
||||
rotatedFrameMat = new Mat (webCamTexture.width, webCamTexture.height, CvType.CV_8UC4);
|
||||
|
||||
isInitWaiting = false;
|
||||
hasInitDone = true;
|
||||
initCoroutine = null;
|
||||
|
||||
if (onInitialized != null)
|
||||
onInitialized.Invoke ();
|
||||
|
||||
break;
|
||||
} else {
|
||||
initFrameCount++;
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (isTimeout) {
|
||||
webCamTexture.Stop ();
|
||||
webCamTexture = null;
|
||||
isInitWaiting = false;
|
||||
initCoroutine = null;
|
||||
|
||||
if (onErrorOccurred != null)
|
||||
onErrorOccurred.Invoke (ErrorCode.TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether this instance has been initialized.
|
||||
/// </summary>
|
||||
/// <returns><c>true</c>, if this instance has been initialized, <c>false</c> otherwise.</returns>
|
||||
public virtual bool IsInitialized ()
|
||||
{
|
||||
return hasInitDone;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts the camera.
|
||||
/// </summary>
|
||||
public virtual void Play ()
|
||||
{
|
||||
if (hasInitDone)
|
||||
webCamTexture.Play ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pauses the active camera.
|
||||
/// </summary>
|
||||
public virtual void Pause ()
|
||||
{
|
||||
if (hasInitDone)
|
||||
webCamTexture.Pause ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops the active camera.
|
||||
/// </summary>
|
||||
public virtual void Stop ()
|
||||
{
|
||||
if (hasInitDone)
|
||||
webCamTexture.Stop ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the active camera is currently playing.
|
||||
/// </summary>
|
||||
/// <returns><c>true</c>, if the active camera is playing, <c>false</c> otherwise.</returns>
|
||||
public virtual bool IsPlaying ()
|
||||
{
|
||||
return hasInitDone ? webCamTexture.isPlaying : false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the active camera device is currently front facng.
|
||||
/// </summary>
|
||||
/// <returns><c>true</c>, if the active camera device is front facng, <c>false</c> otherwise.</returns>
|
||||
public virtual bool IsFrontFacing ()
|
||||
{
|
||||
return hasInitDone ? webCamDevice.isFrontFacing : false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the active camera device name.
|
||||
/// </summary>
|
||||
/// <returns>The active camera device name.</returns>
|
||||
public virtual string GetDeviceName ()
|
||||
{
|
||||
return hasInitDone ? webCamTexture.deviceName : "";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the active camera width.
|
||||
/// </summary>
|
||||
/// <returns>The active camera width.</returns>
|
||||
public virtual int GetWidth ()
|
||||
{
|
||||
if (!hasInitDone)
|
||||
return -1;
|
||||
return (rotatedFrameMat != null) ? frameMat.height () : frameMat.width ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the active camera height.
|
||||
/// </summary>
|
||||
/// <returns>The active camera height.</returns>
|
||||
public virtual int GetHeight ()
|
||||
{
|
||||
if (!hasInitDone)
|
||||
return -1;
|
||||
return (rotatedFrameMat != null) ? frameMat.width () : frameMat.height ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the active camera framerate.
|
||||
/// </summary>
|
||||
/// <returns>The active camera framerate.</returns>
|
||||
public virtual float GetFPS ()
|
||||
{
|
||||
return hasInitDone ? webCamTexture.requestedFPS : -1f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the active WebcamTexture.
|
||||
/// </summary>
|
||||
/// <returns>The active WebcamTexture.</returns>
|
||||
public virtual WebCamTexture GetWebCamTexture ()
|
||||
{
|
||||
return hasInitDone ? webCamTexture : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the active WebcamDevice.
|
||||
/// </summary>
|
||||
/// <returns>The active WebcamDevice.</returns>
|
||||
public virtual WebCamDevice GetWebCamDevice ()
|
||||
{
|
||||
return webCamDevice;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the camera to world matrix.
|
||||
/// </summary>
|
||||
/// <returns>The camera to world matrix.</returns>
|
||||
public virtual Matrix4x4 GetCameraToWorldMatrix ()
|
||||
{
|
||||
return Camera.main.cameraToWorldMatrix;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the projection matrix matrix.
|
||||
/// </summary>
|
||||
/// <returns>The projection matrix.</returns>
|
||||
public virtual Matrix4x4 GetProjectionMatrix ()
|
||||
{
|
||||
return Camera.main.projectionMatrix;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the video buffer of the frame has been updated.
|
||||
/// </summary>
|
||||
/// <returns><c>true</c>, if the video buffer has been updated <c>false</c> otherwise.</returns>
|
||||
public virtual bool DidUpdateThisFrame ()
|
||||
{
|
||||
if (!hasInitDone)
|
||||
return false;
|
||||
|
||||
#if UNITY_IOS && !UNITY_EDITOR && (UNITY_4_6_3 || UNITY_4_6_4 || UNITY_5_0_0 || UNITY_5_0_1)
|
||||
if (webCamTexture.width > 16 && webCamTexture.height > 16) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
return webCamTexture.didUpdateThisFrame;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the mat of the current frame.
|
||||
/// The Mat object's type is 'CV_8UC4' (RGBA).
|
||||
/// </summary>
|
||||
/// <returns>The mat of the current frame.</returns>
|
||||
public virtual Mat GetMat ()
|
||||
{
|
||||
if (!hasInitDone || !webCamTexture.isPlaying) {
|
||||
return (rotatedFrameMat != null) ? rotatedFrameMat : frameMat;
|
||||
}
|
||||
|
||||
Utils.webCamTextureToMat (webCamTexture, frameMat, colors);
|
||||
|
||||
#if !UNITY_EDITOR && !(UNITY_STANDALONE || UNITY_WEBGL)
|
||||
if (rotatedFrameMat != null) {
|
||||
if (screenOrientation == ScreenOrientation.Portrait || screenOrientation == ScreenOrientation.PortraitUpsideDown) {
|
||||
// (Orientation is Portrait, rotate90Degree is false)
|
||||
if (webCamDevice.isFrontFacing){
|
||||
FlipMat (frameMat, !flipHorizontal, !flipVertical);
|
||||
}else{
|
||||
FlipMat (frameMat, flipHorizontal, flipVertical);
|
||||
}
|
||||
} else {
|
||||
// (Orientation is Landscape, rotate90Degrees=true)
|
||||
FlipMat (frameMat, flipVertical, flipHorizontal);
|
||||
}
|
||||
Core.rotate (frameMat, rotatedFrameMat, Core.ROTATE_90_CLOCKWISE);
|
||||
return rotatedFrameMat;
|
||||
} else {
|
||||
if (screenOrientation == ScreenOrientation.Portrait || screenOrientation == ScreenOrientation.PortraitUpsideDown) {
|
||||
// (Orientation is Portrait, rotate90Degree is ture)
|
||||
if (webCamDevice.isFrontFacing){
|
||||
FlipMat (frameMat, flipHorizontal, flipVertical);
|
||||
}else{
|
||||
FlipMat (frameMat, !flipHorizontal, !flipVertical);
|
||||
}
|
||||
} else {
|
||||
// (Orientation is Landscape, rotate90Degree is false)
|
||||
FlipMat (frameMat, flipVertical, flipHorizontal);
|
||||
}
|
||||
return frameMat;
|
||||
}
|
||||
#else
|
||||
FlipMat (frameMat, flipVertical, flipHorizontal);
|
||||
if (rotatedFrameMat != null) {
|
||||
Core.rotate (frameMat, rotatedFrameMat, Core.ROTATE_90_CLOCKWISE);
|
||||
return rotatedFrameMat;
|
||||
} else {
|
||||
return frameMat;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Flips the mat.
|
||||
/// </summary>
|
||||
/// <param name="mat">Mat.</param>
|
||||
protected virtual void FlipMat (Mat mat, bool flipVertical, bool flipHorizontal)
|
||||
{
|
||||
int flipCode = int.MinValue;
|
||||
|
||||
if (webCamDevice.isFrontFacing) {
|
||||
if (webCamTexture.videoRotationAngle == 0) {
|
||||
flipCode = 1;
|
||||
} else if (webCamTexture.videoRotationAngle == 90) {
|
||||
flipCode = 1;
|
||||
}
|
||||
if (webCamTexture.videoRotationAngle == 180) {
|
||||
flipCode = 0;
|
||||
} else if (webCamTexture.videoRotationAngle == 270) {
|
||||
flipCode = 0;
|
||||
}
|
||||
} else {
|
||||
if (webCamTexture.videoRotationAngle == 180) {
|
||||
flipCode = -1;
|
||||
} else if (webCamTexture.videoRotationAngle == 270) {
|
||||
flipCode = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (flipVertical) {
|
||||
if (flipCode == int.MinValue) {
|
||||
flipCode = 0;
|
||||
} else if (flipCode == 0) {
|
||||
flipCode = int.MinValue;
|
||||
} else if (flipCode == 1) {
|
||||
flipCode = -1;
|
||||
} else if (flipCode == -1) {
|
||||
flipCode = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (flipHorizontal) {
|
||||
if (flipCode == int.MinValue) {
|
||||
flipCode = 1;
|
||||
} else if (flipCode == 0) {
|
||||
flipCode = -1;
|
||||
} else if (flipCode == 1) {
|
||||
flipCode = int.MinValue;
|
||||
} else if (flipCode == -1) {
|
||||
flipCode = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (flipCode > int.MinValue) {
|
||||
Core.flip (mat, mat, flipCode);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the buffer colors.
|
||||
/// </summary>
|
||||
/// <returns>The buffer colors.</returns>
|
||||
public virtual Color32[] GetBufferColors ()
|
||||
{
|
||||
return colors;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cancel Init Coroutine.
|
||||
/// </summary>
|
||||
protected virtual void CancelInitCoroutine ()
|
||||
{
|
||||
if (initCoroutine != null) {
|
||||
StopCoroutine (initCoroutine);
|
||||
((IDisposable)initCoroutine).Dispose ();
|
||||
initCoroutine = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// To release the resources.
|
||||
/// </summary>
|
||||
protected virtual void ReleaseResources ()
|
||||
{
|
||||
isInitWaiting = false;
|
||||
hasInitDone = false;
|
||||
|
||||
if (webCamTexture != null) {
|
||||
webCamTexture.Stop ();
|
||||
WebCamTexture.Destroy (webCamTexture);
|
||||
webCamTexture = null;
|
||||
}
|
||||
if (frameMat != null) {
|
||||
frameMat.Dispose ();
|
||||
frameMat = null;
|
||||
}
|
||||
if (rotatedFrameMat != null) {
|
||||
rotatedFrameMat.Dispose ();
|
||||
rotatedFrameMat = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Releases all resource used by the <see cref="WebCamTextureToMatHelper"/> object.
|
||||
/// </summary>
|
||||
/// <remarks>Call <see cref="Dispose"/> when you are finished using the <see cref="WebCamTextureToMatHelper"/>. The
|
||||
/// <see cref="Dispose"/> method leaves the <see cref="WebCamTextureToMatHelper"/> in an unusable state. After
|
||||
/// calling <see cref="Dispose"/>, you must release all references to the <see cref="WebCamTextureToMatHelper"/> so
|
||||
/// the garbage collector can reclaim the memory that the <see cref="WebCamTextureToMatHelper"/> was occupying.</remarks>
|
||||
public virtual void Dispose ()
|
||||
{
|
||||
if (colors != null)
|
||||
colors = null;
|
||||
|
||||
if (isInitWaiting)
|
||||
{
|
||||
CancelInitCoroutine ();
|
||||
ReleaseResources ();
|
||||
}
|
||||
else if (hasInitDone)
|
||||
{
|
||||
ReleaseResources ();
|
||||
|
||||
if (onDisposed != null)
|
||||
onDisposed.Invoke ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: bafc15da02fe850489635791dda2bbdf
|
||||
timeCreated: 1481920838
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,14 +1,11 @@
|
|||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
|
||||
using UnityEngine.SceneManagement;
|
||||
#endif
|
||||
using System.Collections;
|
||||
|
||||
namespace FaceMaskExample
|
||||
{
|
||||
/// <summary>
|
||||
/// Show license.
|
||||
/// Show License
|
||||
/// </summary>
|
||||
public class ShowLicense : MonoBehaviour
|
||||
{
|
||||
|
@ -26,11 +23,7 @@ namespace FaceMaskExample
|
|||
|
||||
public void OnBackButtonClick ()
|
||||
{
|
||||
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
|
||||
SceneManager.LoadScene ("FaceMaskExample");
|
||||
#else
|
||||
Application.LoadLevel ("FaceMaskExample");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,12 +5,12 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using DlibFaceLandmarkDetector;
|
||||
using OpenCVForUnity;
|
||||
|
||||
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
|
||||
using UnityEngine.SceneManagement;
|
||||
#endif
|
||||
using DlibFaceLandmarkDetector;
|
||||
using OpenCVForUnity.ObjdetectModule;
|
||||
using OpenCVForUnity.CoreModule;
|
||||
using OpenCVForUnity.ImgprocModule;
|
||||
using Rect = OpenCVForUnity.CoreModule.Rect;
|
||||
|
||||
namespace FaceMaskExample
|
||||
{
|
||||
|
@ -112,19 +112,18 @@ namespace FaceMaskExample
|
|||
string sp_human_face_68_dat_filepath;
|
||||
|
||||
#if UNITY_WEBGL && !UNITY_EDITOR
|
||||
Stack<IEnumerator> coroutines = new Stack<IEnumerator> ();
|
||||
IEnumerator getFilePath_Coroutine;
|
||||
#endif
|
||||
|
||||
// Use this for initialization
|
||||
void Start ()
|
||||
{
|
||||
#if UNITY_WEBGL && !UNITY_EDITOR
|
||||
var getFilePath_Coroutine = GetFilePath ();
|
||||
coroutines.Push (getFilePath_Coroutine);
|
||||
getFilePath_Coroutine = GetFilePath ();
|
||||
StartCoroutine (getFilePath_Coroutine);
|
||||
#else
|
||||
haarcascade_frontalface_alt_xml_filepath = OpenCVForUnity.Utils.getFilePath ("haarcascade_frontalface_alt.xml");
|
||||
sp_human_face_68_dat_filepath = DlibFaceLandmarkDetector.Utils.getFilePath ("sp_human_face_68.dat");
|
||||
haarcascade_frontalface_alt_xml_filepath = OpenCVForUnity.UnityUtils.Utils.getFilePath ("haarcascade_frontalface_alt.xml");
|
||||
sp_human_face_68_dat_filepath = DlibFaceLandmarkDetector.UnityUtils.Utils.getFilePath ("sp_human_face_68.dat");
|
||||
Run ();
|
||||
#endif
|
||||
}
|
||||
|
@ -132,19 +131,17 @@ namespace FaceMaskExample
|
|||
#if UNITY_WEBGL && !UNITY_EDITOR
|
||||
private IEnumerator GetFilePath ()
|
||||
{
|
||||
var getFilePathAsync_0_Coroutine = OpenCVForUnity.Utils.getFilePathAsync ("haarcascade_frontalface_alt.xml", (result) => {
|
||||
var getFilePathAsync_0_Coroutine = OpenCVForUnity.UnityUtils.Utils.getFilePathAsync ("haarcascade_frontalface_alt.xml", (result) => {
|
||||
haarcascade_frontalface_alt_xml_filepath = result;
|
||||
});
|
||||
coroutines.Push (getFilePathAsync_0_Coroutine);
|
||||
yield return StartCoroutine (getFilePathAsync_0_Coroutine);
|
||||
yield return getFilePathAsync_0_Coroutine;
|
||||
|
||||
var getFilePathAsync_1_Coroutine = DlibFaceLandmarkDetector.Utils.getFilePathAsync ("sp_human_face_68.dat", (result) => {
|
||||
var getFilePathAsync_1_Coroutine = DlibFaceLandmarkDetector.UnityUtils.Utils.getFilePathAsync ("sp_human_face_68.dat", (result) => {
|
||||
sp_human_face_68_dat_filepath = result;
|
||||
});
|
||||
coroutines.Push (getFilePathAsync_1_Coroutine);
|
||||
yield return StartCoroutine (getFilePathAsync_1_Coroutine);
|
||||
yield return getFilePathAsync_1_Coroutine;
|
||||
|
||||
coroutines.Clear ();
|
||||
getFilePath_Coroutine = null;
|
||||
|
||||
Run ();
|
||||
}
|
||||
|
@ -185,7 +182,7 @@ namespace FaceMaskExample
|
|||
|
||||
Mat rgbaMat = new Mat (imgTexture.height, imgTexture.width, CvType.CV_8UC4);
|
||||
|
||||
OpenCVForUnity.Utils.texture2DToMat (imgTexture, rgbaMat);
|
||||
OpenCVForUnity.UnityUtils.Utils.texture2DToMat (imgTexture, rgbaMat);
|
||||
Debug.Log ("rgbaMat ToString " + rgbaMat.ToString ());
|
||||
|
||||
if (faceLandmarkDetector == null)
|
||||
|
@ -195,13 +192,13 @@ namespace FaceMaskExample
|
|||
FrontalFaceChecker frontalFaceChecker = new FrontalFaceChecker (width, height);
|
||||
|
||||
// detect faces.
|
||||
List<OpenCVForUnity.Rect> detectResult = new List<OpenCVForUnity.Rect> ();
|
||||
List<Rect> detectResult = new List<Rect> ();
|
||||
if (useDlibFaceDetecter) {
|
||||
OpenCVForUnityUtils.SetImage (faceLandmarkDetector, rgbaMat);
|
||||
List<UnityEngine.Rect> result = faceLandmarkDetector.Detect ();
|
||||
|
||||
foreach (var unityRect in result) {
|
||||
detectResult.Add (new OpenCVForUnity.Rect ((int)unityRect.x, (int)unityRect.y, (int)unityRect.width, (int)unityRect.height));
|
||||
detectResult.Add (new Rect ((int)unityRect.x, (int)unityRect.y, (int)unityRect.width, (int)unityRect.height));
|
||||
}
|
||||
} else {
|
||||
if (cascade == null)
|
||||
|
@ -216,13 +213,13 @@ namespace FaceMaskExample
|
|||
|
||||
MatOfRect faces = new MatOfRect ();
|
||||
Imgproc.equalizeHist (gray, gray);
|
||||
cascade.detectMultiScale (gray, faces, 1.1f, 2, 0 | Objdetect.CASCADE_SCALE_IMAGE, new OpenCVForUnity.Size (gray.cols () * 0.05, gray.cols () * 0.05), new Size ());
|
||||
cascade.detectMultiScale (gray, faces, 1.1f, 2, 0 | Objdetect.CASCADE_SCALE_IMAGE, new Size (gray.cols () * 0.05, gray.cols () * 0.05), new Size ());
|
||||
//Debug.Log ("faces " + faces.dump ());
|
||||
|
||||
detectResult = faces.toList ();
|
||||
|
||||
// adjust to Dilb's result.
|
||||
foreach (OpenCVForUnity.Rect r in detectResult) {
|
||||
// corrects the deviation of a detection result between OpenCV and Dlib.
|
||||
foreach (Rect r in detectResult) {
|
||||
r.y += (int)(r.height * 0.1f);
|
||||
}
|
||||
|
||||
|
@ -296,12 +293,12 @@ namespace FaceMaskExample
|
|||
|
||||
// draw face rects.
|
||||
if (displayFaceRects) {
|
||||
int ann = face_nums[0];
|
||||
int ann = face_nums [0];
|
||||
UnityEngine.Rect rect_ann = new UnityEngine.Rect (detectResult [ann].x, detectResult [ann].y, detectResult [ann].width, detectResult [ann].height);
|
||||
OpenCVForUnityUtils.DrawFaceRect (rgbaMat, rect_ann, new Scalar (255, 255, 0, 255), 2);
|
||||
|
||||
int bob = 0;
|
||||
for (int i = 1; i < face_nums.Length; i ++) {
|
||||
for (int i = 1; i < face_nums.Length; i++) {
|
||||
bob = face_nums [i];
|
||||
UnityEngine.Rect rect_bob = new UnityEngine.Rect (detectResult [bob].x, detectResult [bob].y, detectResult [bob].width, detectResult [bob].height);
|
||||
OpenCVForUnityUtils.DrawFaceRect (rgbaMat, rect_bob, new Scalar (255, 0, 0, 255), 2);
|
||||
|
@ -317,7 +314,7 @@ namespace FaceMaskExample
|
|||
|
||||
|
||||
Texture2D texture = new Texture2D (rgbaMat.cols (), rgbaMat.rows (), TextureFormat.RGBA32, false);
|
||||
OpenCVForUnity.Utils.matToTexture2D (rgbaMat, texture);
|
||||
OpenCVForUnity.UnityUtils.Utils.matToTexture2D (rgbaMat, texture);
|
||||
gameObject.transform.GetComponent<Renderer> ().material.mainTexture = texture;
|
||||
|
||||
frontalFaceChecker.Dispose ();
|
||||
|
@ -339,9 +336,9 @@ namespace FaceMaskExample
|
|||
cascade.Dispose ();
|
||||
|
||||
#if UNITY_WEBGL && !UNITY_EDITOR
|
||||
foreach (var coroutine in coroutines) {
|
||||
StopCoroutine (coroutine);
|
||||
((IDisposable)coroutine).Dispose ();
|
||||
if (getFilePath_Coroutine != null) {
|
||||
StopCoroutine (getFilePath_Coroutine);
|
||||
((IDisposable)getFilePath_Coroutine).Dispose ();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -351,11 +348,7 @@ namespace FaceMaskExample
|
|||
/// </summary>
|
||||
public void OnBackButtonClick ()
|
||||
{
|
||||
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
|
||||
SceneManager.LoadScene ("FaceMaskExample");
|
||||
#else
|
||||
Application.LoadLevel ("FaceMaskExample");
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -411,7 +404,7 @@ namespace FaceMaskExample
|
|||
if (imgTexture != null)
|
||||
Run ();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Raises the display face rects toggle value changed event.
|
||||
/// </summary>
|
||||
|
|
|
@ -2563,7 +2563,7 @@ MonoBehaviour:
|
|||
m_EditorClassIdentifier:
|
||||
interval: 1
|
||||
poolSize: 10
|
||||
_baseObject: {fileID: 1138294731141240, guid: 8b9701cb9064eeb44b641983696a9e94,
|
||||
_baseObject: {fileID: 1150371196015818, guid: 8b9701cb9064eeb44b641983696a9e94,
|
||||
type: 2}
|
||||
--- !u!1 &2138936149
|
||||
GameObject:
|
||||
|
|
|
@ -4,13 +4,15 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using DlibFaceLandmarkDetector;
|
||||
using OpenCVForUnity;
|
||||
using OpenCVForUnity.RectangleTrack;
|
||||
|
||||
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
|
||||
using UnityEngine.SceneManagement;
|
||||
#endif
|
||||
using DlibFaceLandmarkDetector;
|
||||
using OpenCVForUnity.RectangleTrack;
|
||||
using OpenCVForUnity.CoreModule;
|
||||
using OpenCVForUnity.ObjdetectModule;
|
||||
using OpenCVForUnity.VideoioModule;
|
||||
using OpenCVForUnity.ImgprocModule;
|
||||
using VideoCapture = OpenCVForUnity.VideoioModule.VideoCapture;
|
||||
using Rect = OpenCVForUnity.CoreModule.Rect;
|
||||
|
||||
namespace FaceMaskExample
|
||||
{
|
||||
|
@ -221,7 +223,7 @@ namespace FaceMaskExample
|
|||
string couple_avi_filepath;
|
||||
|
||||
#if UNITY_WEBGL && !UNITY_EDITOR
|
||||
Stack<IEnumerator> coroutines = new Stack<IEnumerator> ();
|
||||
IEnumerator getFilePath_Coroutine;
|
||||
#endif
|
||||
|
||||
// Use this for initialization
|
||||
|
@ -230,13 +232,12 @@ namespace FaceMaskExample
|
|||
capture = new VideoCapture ();
|
||||
|
||||
#if UNITY_WEBGL && !UNITY_EDITOR
|
||||
var getFilePath_Coroutine = GetFilePath ();
|
||||
coroutines.Push (getFilePath_Coroutine);
|
||||
getFilePath_Coroutine = GetFilePath ();
|
||||
StartCoroutine (getFilePath_Coroutine);
|
||||
#else
|
||||
haarcascade_frontalface_alt_xml_filepath = OpenCVForUnity.Utils.getFilePath ("haarcascade_frontalface_alt.xml");
|
||||
sp_human_face_68_dat_filepath = DlibFaceLandmarkDetector.Utils.getFilePath ("sp_human_face_68.dat");
|
||||
couple_avi_filepath = OpenCVForUnity.Utils.getFilePath ("dance.avi");
|
||||
haarcascade_frontalface_alt_xml_filepath = OpenCVForUnity.UnityUtils.Utils.getFilePath ("haarcascade_frontalface_alt.xml");
|
||||
sp_human_face_68_dat_filepath = DlibFaceLandmarkDetector.UnityUtils.Utils.getFilePath ("sp_human_face_68.dat");
|
||||
couple_avi_filepath = OpenCVForUnity.UnityUtils.Utils.getFilePath ("dance.avi");
|
||||
Run ();
|
||||
#endif
|
||||
}
|
||||
|
@ -244,25 +245,22 @@ namespace FaceMaskExample
|
|||
#if UNITY_WEBGL && !UNITY_EDITOR
|
||||
private IEnumerator GetFilePath ()
|
||||
{
|
||||
var getFilePathAsync_0_Coroutine = OpenCVForUnity.Utils.getFilePathAsync ("haarcascade_frontalface_alt.xml", (result) => {
|
||||
var getFilePathAsync_0_Coroutine = OpenCVForUnity.UnityUtils.Utils.getFilePathAsync ("haarcascade_frontalface_alt.xml", (result) => {
|
||||
haarcascade_frontalface_alt_xml_filepath = result;
|
||||
});
|
||||
coroutines.Push (getFilePathAsync_0_Coroutine);
|
||||
yield return StartCoroutine (getFilePathAsync_0_Coroutine);
|
||||
yield return getFilePathAsync_0_Coroutine;
|
||||
|
||||
var getFilePathAsync_1_Coroutine = DlibFaceLandmarkDetector.Utils.getFilePathAsync ("sp_human_face_68.dat", (result) => {
|
||||
var getFilePathAsync_1_Coroutine = DlibFaceLandmarkDetector.UnityUtils.Utils.getFilePathAsync ("sp_human_face_68.dat", (result) => {
|
||||
sp_human_face_68_dat_filepath = result;
|
||||
});
|
||||
coroutines.Push (getFilePathAsync_1_Coroutine);
|
||||
yield return StartCoroutine (getFilePathAsync_1_Coroutine);
|
||||
yield return getFilePathAsync_1_Coroutine;
|
||||
|
||||
var getFilePathAsync_2_Coroutine = OpenCVForUnity.Utils.getFilePathAsync ("dance.avi", (result) => {
|
||||
var getFilePathAsync_2_Coroutine = OpenCVForUnity.UnityUtils.Utils.getFilePathAsync ("dance.avi", (result) => {
|
||||
couple_avi_filepath = result;
|
||||
});
|
||||
coroutines.Push (getFilePathAsync_2_Coroutine);
|
||||
yield return StartCoroutine (getFilePathAsync_2_Coroutine);
|
||||
yield return getFilePathAsync_2_Coroutine;
|
||||
|
||||
coroutines.Clear ();
|
||||
getFilePath_Coroutine = null;
|
||||
|
||||
Run ();
|
||||
}
|
||||
|
@ -272,13 +270,13 @@ namespace FaceMaskExample
|
|||
{
|
||||
meshOverlay = this.GetComponent<TrackedMeshOverlay> ();
|
||||
|
||||
shader_FadeID = Shader.PropertyToID("_Fade");
|
||||
shader_ColorCorrectionID = Shader.PropertyToID("_ColorCorrection");
|
||||
shader_LUTTexID = Shader.PropertyToID("_LUTTex");
|
||||
shader_FadeID = Shader.PropertyToID ("_Fade");
|
||||
shader_ColorCorrectionID = Shader.PropertyToID ("_ColorCorrection");
|
||||
shader_LUTTexID = Shader.PropertyToID ("_LUTTex");
|
||||
|
||||
rectangleTracker = new RectangleTracker ();
|
||||
|
||||
frontalFaceChecker = new FrontalFaceChecker((float)frameWidth, (float)frameHeight);
|
||||
frontalFaceChecker = new FrontalFaceChecker ((float)frameWidth, (float)frameHeight);
|
||||
|
||||
faceLandmarkDetector = new FaceLandmarkDetector (sp_human_face_68_dat_filepath);
|
||||
|
||||
|
@ -299,7 +297,6 @@ namespace FaceMaskExample
|
|||
|
||||
|
||||
Debug.Log ("CAP_PROP_FORMAT: " + capture.get (Videoio.CAP_PROP_FORMAT));
|
||||
Debug.Log ("CV_CAP_PROP_PREVIEW_FORMAT: " + capture.get (Videoio.CV_CAP_PROP_PREVIEW_FORMAT));
|
||||
Debug.Log ("CAP_PROP_POS_MSEC: " + capture.get (Videoio.CAP_PROP_POS_MSEC));
|
||||
Debug.Log ("CAP_PROP_POS_FRAMES: " + capture.get (Videoio.CAP_PROP_POS_FRAMES));
|
||||
Debug.Log ("CAP_PROP_POS_AVI_RATIO: " + capture.get (Videoio.CAP_PROP_POS_AVI_RATIO));
|
||||
|
@ -356,13 +353,13 @@ namespace FaceMaskExample
|
|||
|
||||
|
||||
// detect faces.
|
||||
List<OpenCVForUnity.Rect> detectResult = new List<OpenCVForUnity.Rect> ();
|
||||
List<Rect> detectResult = new List<Rect> ();
|
||||
if (useDlibFaceDetecter) {
|
||||
OpenCVForUnityUtils.SetImage (faceLandmarkDetector, rgbMat);
|
||||
List<UnityEngine.Rect> result = faceLandmarkDetector.Detect ();
|
||||
|
||||
foreach (var unityRect in result) {
|
||||
detectResult.Add (new OpenCVForUnity.Rect ((int)unityRect.x, (int)unityRect.y, (int)unityRect.width, (int)unityRect.height));
|
||||
detectResult.Add (new Rect ((int)unityRect.x, (int)unityRect.y, (int)unityRect.width, (int)unityRect.height));
|
||||
}
|
||||
} else {
|
||||
// convert image to greyscale.
|
||||
|
@ -372,12 +369,12 @@ namespace FaceMaskExample
|
|||
using (MatOfRect faces = new MatOfRect ()) {
|
||||
Imgproc.equalizeHist (grayMat, equalizeHistMat);
|
||||
|
||||
cascade.detectMultiScale (equalizeHistMat, faces, 1.1f, 2, 0 | Objdetect.CASCADE_SCALE_IMAGE, new OpenCVForUnity.Size (equalizeHistMat.cols () * 0.15, equalizeHistMat.cols () * 0.15), new Size ());
|
||||
cascade.detectMultiScale (equalizeHistMat, faces, 1.1f, 2, 0 | Objdetect.CASCADE_SCALE_IMAGE, new Size (equalizeHistMat.cols () * 0.15, equalizeHistMat.cols () * 0.15), new Size ());
|
||||
|
||||
detectResult = faces.toList ();
|
||||
|
||||
// adjust to Dilb's result.
|
||||
foreach (OpenCVForUnity.Rect r in detectResult) {
|
||||
// corrects the deviation of a detection result between OpenCV and Dlib.
|
||||
foreach (Rect r in detectResult) {
|
||||
r.y += (int)(r.height * 0.1f);
|
||||
}
|
||||
}
|
||||
|
@ -391,11 +388,11 @@ namespace FaceMaskExample
|
|||
// create noise filter.
|
||||
foreach (var openCVRect in trackedRects) {
|
||||
if (openCVRect.state == TrackedState.NEW) {
|
||||
if (!lowPassFilterDict.ContainsKey(openCVRect.id))
|
||||
lowPassFilterDict.Add (openCVRect.id, new LowPassPointsFilter((int)faceLandmarkDetector.GetShapePredictorNumParts()));
|
||||
if (!opticalFlowFilterDict.ContainsKey(openCVRect.id))
|
||||
opticalFlowFilterDict.Add (openCVRect.id, new OFPointsFilter((int)faceLandmarkDetector.GetShapePredictorNumParts()));
|
||||
}else if (openCVRect.state == TrackedState.DELETED){
|
||||
if (!lowPassFilterDict.ContainsKey (openCVRect.id))
|
||||
lowPassFilterDict.Add (openCVRect.id, new LowPassPointsFilter ((int)faceLandmarkDetector.GetShapePredictorNumParts ()));
|
||||
if (!opticalFlowFilterDict.ContainsKey (openCVRect.id))
|
||||
opticalFlowFilterDict.Add (openCVRect.id, new OFPointsFilter ((int)faceLandmarkDetector.GetShapePredictorNumParts ()));
|
||||
} else if (openCVRect.state == TrackedState.DELETED) {
|
||||
if (lowPassFilterDict.ContainsKey (openCVRect.id)) {
|
||||
lowPassFilterDict [openCVRect.id].Dispose ();
|
||||
lowPassFilterDict.Remove (openCVRect.id);
|
||||
|
@ -411,7 +408,7 @@ namespace FaceMaskExample
|
|||
foreach (var openCVRect in trackedRects) {
|
||||
if (openCVRect.state == TrackedState.NEW) {
|
||||
faceMaskColorCorrector.CreateLUTTex (openCVRect.id);
|
||||
}else if (openCVRect.state == TrackedState.DELETED) {
|
||||
} else if (openCVRect.state == TrackedState.DELETED) {
|
||||
faceMaskColorCorrector.DeleteLUTTex (openCVRect.id);
|
||||
}
|
||||
}
|
||||
|
@ -496,8 +493,8 @@ namespace FaceMaskExample
|
|||
for (int i = 0; i < trackedRects.Count; i++) {
|
||||
UnityEngine.Rect rect = new UnityEngine.Rect (trackedRects [i].x, trackedRects [i].y, trackedRects [i].width, trackedRects [i].height);
|
||||
OpenCVForUnityUtils.DrawFaceRect (rgbMat, rect, new Scalar (255, 255, 0, 255), 2);
|
||||
//Imgproc.putText (rgbaMat, " " + frontalFaceChecker.GetFrontalFaceAngles (landmarkPoints [i]), new Point (rect.xMin, rect.yMin - 10), Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
|
||||
//Imgproc.putText (rgbaMat, " " + frontalFaceChecker.GetFrontalFaceRate (landmarkPoints [i]), new Point (rect.xMin, rect.yMin - 10), Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
|
||||
// Imgproc.putText (rgbMat, " " + frontalFaceChecker.GetFrontalFaceAngles (landmarkPoints [i]), new Point (rect.xMin, rect.yMin - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
|
||||
// Imgproc.putText (rgbMat, " " + frontalFaceChecker.GetFrontalFaceRate (landmarkPoints [i]), new Point (rect.xMin, rect.yMin - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -532,12 +529,12 @@ namespace FaceMaskExample
|
|||
Imgproc.warpAffine (faceMaskMat, rgbMat, trans, rgbMat.size (), Imgproc.INTER_LINEAR, Core.BORDER_TRANSPARENT, new Scalar (0));
|
||||
|
||||
if (displayFaceRects || displayDebugFacePointsToggle)
|
||||
OpenCVForUnity.Utils.texture2DToMat (faceMaskTexture, faceMaskMat);
|
||||
OpenCVForUnity.UnityUtils.Utils.texture2DToMat (faceMaskTexture, faceMaskMat);
|
||||
}
|
||||
|
||||
// Imgproc.putText (rgbMat, "W:" + rgbMat.width () + " H:" + rgbMat.height () + " SO:" + Screen.orientation, new Point (5, rgbMat.rows () - 10), Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255), 1, Imgproc.LINE_AA, false);
|
||||
// Imgproc.putText (rgbMat, "W:" + rgbMat.width () + " H:" + rgbMat.height () + " SO:" + Screen.orientation, new Point (5, rgbMat.rows () - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255), 1, Imgproc.LINE_AA, false);
|
||||
|
||||
OpenCVForUnity.Utils.fastMatToTexture2D (rgbMat, texture);
|
||||
OpenCVForUnity.UnityUtils.Utils.fastMatToTexture2D (rgbMat, texture);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -557,23 +554,23 @@ namespace FaceMaskExample
|
|||
Vector3[] vertices = tm.meshFilter.mesh.vertices;
|
||||
if (vertices.Length == landmarkPoints.Count) {
|
||||
for (int j = 0; j < vertices.Length; j++) {
|
||||
vertices [j].x = landmarkPoints[j].x / imageWidth - 0.5f;
|
||||
vertices [j].y = 0.5f - landmarkPoints[j].y / imageHeight;
|
||||
vertices [j].x = landmarkPoints [j].x / imageWidth - 0.5f;
|
||||
vertices [j].y = 0.5f - landmarkPoints [j].y / imageHeight;
|
||||
}
|
||||
}
|
||||
Vector2[] uv = tm.meshFilter.mesh.uv;
|
||||
if (uv.Length == landmarkPointsInMaskImage.Count) {
|
||||
for (int jj = 0; jj < uv.Length; jj++) {
|
||||
uv [jj].x = landmarkPointsInMaskImage[jj].x / maskImageWidth;
|
||||
uv [jj].y = (maskImageHeight - landmarkPointsInMaskImage[jj].y) / maskImageHeight;
|
||||
uv [jj].x = landmarkPointsInMaskImage [jj].x / maskImageWidth;
|
||||
uv [jj].y = (maskImageHeight - landmarkPointsInMaskImage [jj].y) / maskImageHeight;
|
||||
}
|
||||
}
|
||||
meshOverlay.UpdateObject (tr.id, vertices, null, uv);
|
||||
|
||||
if (tr.numFramesNotDetected > 3) {
|
||||
tm.sharedMaterial.SetFloat (shader_FadeID, 1f);
|
||||
}else if (tr.numFramesNotDetected > 0 && tr.numFramesNotDetected <= 3) {
|
||||
tm.sharedMaterial.SetFloat (shader_FadeID, 0.3f + (0.7f/4f) * tr.numFramesNotDetected);
|
||||
} else if (tr.numFramesNotDetected > 0 && tr.numFramesNotDetected <= 3) {
|
||||
tm.sharedMaterial.SetFloat (shader_FadeID, 0.3f + (0.7f / 4f) * tr.numFramesNotDetected);
|
||||
} else {
|
||||
tm.sharedMaterial.SetFloat (shader_FadeID, 0.3f);
|
||||
}
|
||||
|
@ -592,7 +589,7 @@ namespace FaceMaskExample
|
|||
|
||||
private void CorrectFaceMaskColor (int id, Mat src, Mat dst, List<Vector2> src_landmarkPoints, List<Vector2> dst_landmarkPoints)
|
||||
{
|
||||
Texture2D LUTTex = faceMaskColorCorrector.UpdateLUTTex(id, src, dst, src_landmarkPoints, dst_landmarkPoints);
|
||||
Texture2D LUTTex = faceMaskColorCorrector.UpdateLUTTex (id, src, dst, src_landmarkPoints, dst_landmarkPoints);
|
||||
TrackedMesh tm = meshOverlay.GetObjectById (id);
|
||||
tm.sharedMaterial.SetTexture (shader_LUTTexID, LUTTex);
|
||||
}
|
||||
|
@ -631,9 +628,9 @@ namespace FaceMaskExample
|
|||
frontalFaceChecker.Dispose ();
|
||||
|
||||
#if UNITY_WEBGL && !UNITY_EDITOR
|
||||
foreach (var coroutine in coroutines) {
|
||||
StopCoroutine (coroutine);
|
||||
((IDisposable)coroutine).Dispose ();
|
||||
if (getFilePath_Coroutine != null) {
|
||||
StopCoroutine (getFilePath_Coroutine);
|
||||
((IDisposable)getFilePath_Coroutine).Dispose ();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -643,11 +640,7 @@ namespace FaceMaskExample
|
|||
/// </summary>
|
||||
public void OnBackButtonClick ()
|
||||
{
|
||||
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
|
||||
SceneManager.LoadScene ("FaceMaskExample");
|
||||
#else
|
||||
Application.LoadLevel ("FaceMaskExample");
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -703,7 +696,7 @@ namespace FaceMaskExample
|
|||
filterNonFrontalFaces = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Raises the display face rects toggle value changed event.
|
||||
/// </summary>
|
||||
|
@ -738,7 +731,7 @@ namespace FaceMaskExample
|
|||
if (faceMaskDatas.Count == 0)
|
||||
return;
|
||||
|
||||
FaceMaskData maskData = faceMaskDatas[faceMaskDataIndex];
|
||||
FaceMaskData maskData = faceMaskDatas [faceMaskDataIndex];
|
||||
faceMaskDataIndex = (faceMaskDataIndex < faceMaskDatas.Count - 1) ? faceMaskDataIndex + 1 : 0;
|
||||
|
||||
if (maskData == null) {
|
||||
|
@ -758,20 +751,20 @@ namespace FaceMaskExample
|
|||
|
||||
faceMaskTexture = maskData.image;
|
||||
faceMaskMat = new Mat (faceMaskTexture.height, faceMaskTexture.width, CvType.CV_8UC3);
|
||||
OpenCVForUnity.Utils.texture2DToMat (faceMaskTexture, faceMaskMat);
|
||||
OpenCVForUnity.UnityUtils.Utils.texture2DToMat (faceMaskTexture, faceMaskMat);
|
||||
|
||||
if(maskData.isDynamicMode){
|
||||
if (maskData.isDynamicMode) {
|
||||
faceRectInMask = DetectFace (faceMaskMat);
|
||||
faceLandmarkPointsInMask = DetectFaceLandmarkPoints (faceMaskMat, faceRectInMask);
|
||||
|
||||
maskData.faceRect = faceRectInMask;
|
||||
maskData.landmarkPoints = faceLandmarkPointsInMask;
|
||||
}else{
|
||||
} else {
|
||||
faceRectInMask = maskData.faceRect;
|
||||
faceLandmarkPointsInMask = maskData.landmarkPoints;
|
||||
}
|
||||
|
||||
if (faceRectInMask.width == 0 && faceRectInMask.height == 0){
|
||||
if (faceRectInMask.width == 0 && faceRectInMask.height == 0) {
|
||||
RemoveFaceMask ();
|
||||
Debug.LogError ("A face could not be detected from the input image.");
|
||||
}
|
||||
|
@ -797,7 +790,7 @@ namespace FaceMaskExample
|
|||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Raises the remove face mask button click event.
|
||||
/// </summary>
|
||||
|
@ -817,7 +810,7 @@ namespace FaceMaskExample
|
|||
rectangleTracker.Reset ();
|
||||
meshOverlay.Reset ();
|
||||
}
|
||||
|
||||
|
||||
private UnityEngine.Rect DetectFace (Mat mat)
|
||||
{
|
||||
if (useDlibFaceDetecter) {
|
||||
|
@ -834,12 +827,12 @@ namespace FaceMaskExample
|
|||
Imgproc.cvtColor (mat, grayMat, Imgproc.COLOR_RGB2GRAY);
|
||||
Imgproc.equalizeHist (grayMat, equalizeHistMat);
|
||||
|
||||
cascade.detectMultiScale (equalizeHistMat, faces, 1.1f, 2, 0 | Objdetect.CASCADE_SCALE_IMAGE, new OpenCVForUnity.Size (equalizeHistMat.cols () * 0.15, equalizeHistMat.cols () * 0.15), new Size ());
|
||||
cascade.detectMultiScale (equalizeHistMat, faces, 1.1f, 2, 0 | Objdetect.CASCADE_SCALE_IMAGE, new Size (equalizeHistMat.cols () * 0.15, equalizeHistMat.cols () * 0.15), new Size ());
|
||||
|
||||
List<OpenCVForUnity.Rect> faceList = faces.toList ();
|
||||
List<Rect> faceList = faces.toList ();
|
||||
if (faceList.Count >= 1) {
|
||||
UnityEngine.Rect r = new UnityEngine.Rect (faceList [0].x, faceList [0].y, faceList [0].width, faceList [0].height);
|
||||
// adjust to Dilb's result.
|
||||
// corrects the deviation of a detection result between OpenCV and Dlib.
|
||||
r.y += (int)(r.height * 0.1f);
|
||||
return r;
|
||||
}
|
||||
|
@ -847,7 +840,7 @@ namespace FaceMaskExample
|
|||
}
|
||||
return new UnityEngine.Rect ();
|
||||
}
|
||||
|
||||
|
||||
private List<Vector2> DetectFaceLandmarkPoints (Mat mat, UnityEngine.Rect rect)
|
||||
{
|
||||
OpenCVForUnityUtils.SetImage (faceLandmarkDetector, mat);
|
||||
|
|
|
@ -38,7 +38,7 @@ RenderSettings:
|
|||
m_ReflectionIntensity: 1
|
||||
m_CustomReflection: {fileID: 0}
|
||||
m_Sun: {fileID: 0}
|
||||
m_IndirectSpecularColor: {r: 0.37311918, g: 0.3807398, b: 0.35872716, a: 1}
|
||||
m_IndirectSpecularColor: {r: 0.37311947, g: 0.38074005, b: 0.35872722, a: 1}
|
||||
--- !u!157 &4
|
||||
LightmapSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
|
@ -2732,7 +2732,7 @@ MonoBehaviour:
|
|||
m_EditorClassIdentifier:
|
||||
interval: 1
|
||||
poolSize: 10
|
||||
_baseObject: {fileID: 1138294731141240, guid: 8b9701cb9064eeb44b641983696a9e94,
|
||||
_baseObject: {fileID: 1150371196015818, guid: 8b9701cb9064eeb44b641983696a9e94,
|
||||
type: 2}
|
||||
--- !u!114 &1425214148
|
||||
MonoBehaviour:
|
||||
|
|
|
@ -4,13 +4,14 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using DlibFaceLandmarkDetector;
|
||||
using OpenCVForUnity;
|
||||
using OpenCVForUnity.RectangleTrack;
|
||||
|
||||
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
|
||||
using UnityEngine.SceneManagement;
|
||||
#endif
|
||||
using DlibFaceLandmarkDetector;
|
||||
using OpenCVForUnity.RectangleTrack;
|
||||
using OpenCVForUnity.UnityUtils.Helper;
|
||||
using OpenCVForUnity.CoreModule;
|
||||
using OpenCVForUnity.ObjdetectModule;
|
||||
using OpenCVForUnity.ImgprocModule;
|
||||
using Rect = OpenCVForUnity.CoreModule.Rect;
|
||||
|
||||
namespace FaceMaskExample
|
||||
{
|
||||
|
@ -37,7 +38,7 @@ namespace FaceMaskExample
|
|||
/// </summary>
|
||||
public bool extendForehead = true;
|
||||
|
||||
[Space(15)]
|
||||
[Space (15)]
|
||||
|
||||
[HeaderAttribute ("FaceMaskData")]
|
||||
|
||||
|
@ -224,12 +225,8 @@ namespace FaceMaskExample
|
|||
/// </summary>
|
||||
FpsMonitor fpsMonitor;
|
||||
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
float rearCameraRequestedFPS;
|
||||
#endif
|
||||
|
||||
#if UNITY_WEBGL && !UNITY_EDITOR
|
||||
Stack<IEnumerator> coroutines = new Stack<IEnumerator> ();
|
||||
IEnumerator getFilePath_Coroutine;
|
||||
#endif
|
||||
|
||||
// Use this for initialization
|
||||
|
@ -240,12 +237,11 @@ namespace FaceMaskExample
|
|||
webCamTextureToMatHelper = gameObject.GetComponent<WebCamTextureToMatHelper> ();
|
||||
|
||||
#if UNITY_WEBGL && !UNITY_EDITOR
|
||||
var getFilePath_Coroutine = GetFilePath ();
|
||||
coroutines.Push (getFilePath_Coroutine);
|
||||
getFilePath_Coroutine = GetFilePath ();
|
||||
StartCoroutine (getFilePath_Coroutine);
|
||||
#else
|
||||
haarcascade_frontalface_alt_xml_filepath = OpenCVForUnity.Utils.getFilePath ("haarcascade_frontalface_alt.xml");
|
||||
sp_human_face_68_dat_filepath = DlibFaceLandmarkDetector.Utils.getFilePath ("sp_human_face_68.dat");
|
||||
haarcascade_frontalface_alt_xml_filepath = OpenCVForUnity.UnityUtils.Utils.getFilePath ("haarcascade_frontalface_alt.xml");
|
||||
sp_human_face_68_dat_filepath = DlibFaceLandmarkDetector.UnityUtils.Utils.getFilePath ("sp_human_face_68.dat");
|
||||
Run ();
|
||||
#endif
|
||||
}
|
||||
|
@ -253,19 +249,17 @@ namespace FaceMaskExample
|
|||
#if UNITY_WEBGL && !UNITY_EDITOR
|
||||
private IEnumerator GetFilePath ()
|
||||
{
|
||||
var getFilePathAsync_0_Coroutine = OpenCVForUnity.Utils.getFilePathAsync ("haarcascade_frontalface_alt.xml", (result) => {
|
||||
var getFilePathAsync_0_Coroutine = OpenCVForUnity.UnityUtils.Utils.getFilePathAsync ("haarcascade_frontalface_alt.xml", (result) => {
|
||||
haarcascade_frontalface_alt_xml_filepath = result;
|
||||
});
|
||||
coroutines.Push (getFilePathAsync_0_Coroutine);
|
||||
yield return StartCoroutine (getFilePathAsync_0_Coroutine);
|
||||
yield return getFilePathAsync_0_Coroutine;
|
||||
|
||||
var getFilePathAsync_1_Coroutine = DlibFaceLandmarkDetector.Utils.getFilePathAsync ("sp_human_face_68.dat", (result) => {
|
||||
var getFilePathAsync_1_Coroutine = DlibFaceLandmarkDetector.UnityUtils.Utils.getFilePathAsync ("sp_human_face_68.dat", (result) => {
|
||||
sp_human_face_68_dat_filepath = result;
|
||||
});
|
||||
coroutines.Push (getFilePathAsync_1_Coroutine);
|
||||
yield return StartCoroutine (getFilePathAsync_1_Coroutine);
|
||||
yield return getFilePathAsync_1_Coroutine;
|
||||
|
||||
coroutines.Clear ();
|
||||
getFilePath_Coroutine = null;
|
||||
|
||||
Run ();
|
||||
}
|
||||
|
@ -276,7 +270,7 @@ namespace FaceMaskExample
|
|||
meshOverlay = this.GetComponent<TrackedMeshOverlay> ();
|
||||
|
||||
// Customize face mask.
|
||||
GameObject newBaseObject = Instantiate(meshOverlay.baseObject);
|
||||
GameObject newBaseObject = Instantiate (meshOverlay.baseObject);
|
||||
newBaseObject.name = "CustomFaceMaskTrackedMesh";
|
||||
TrackedMesh tm = newBaseObject.GetComponent<TrackedMesh> ();
|
||||
|
||||
|
@ -292,9 +286,9 @@ namespace FaceMaskExample
|
|||
meshOverlay.baseObject = newBaseObject;
|
||||
|
||||
|
||||
shader_FadeID = Shader.PropertyToID("_Fade");
|
||||
shader_ColorCorrectionID = Shader.PropertyToID("_ColorCorrection");
|
||||
shader_LUTTexID = Shader.PropertyToID("_LUTTex");
|
||||
shader_FadeID = Shader.PropertyToID ("_Fade");
|
||||
shader_ColorCorrectionID = Shader.PropertyToID ("_ColorCorrection");
|
||||
shader_LUTTexID = Shader.PropertyToID ("_LUTTex");
|
||||
|
||||
rectangleTracker = new RectangleTracker ();
|
||||
|
||||
|
@ -306,19 +300,10 @@ namespace FaceMaskExample
|
|||
faceMaskColorCorrector = new FaceMaskColorCorrector ();
|
||||
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
// Set the requestedFPS parameter to avoid the problem of the WebCamTexture image becoming low light on some Android devices. (Pixel, pixel 2)
|
||||
// https://forum.unity.com/threads/android-webcamtexture-in-low-light-only-some-models.520656/
|
||||
// https://forum.unity.com/threads/released-opencv-for-unity.277080/page-33#post-3445178
|
||||
rearCameraRequestedFPS = webCamTextureToMatHelper.requestedFPS;
|
||||
if (webCamTextureToMatHelper.requestedIsFrontFacing) {
|
||||
webCamTextureToMatHelper.requestedFPS = 15;
|
||||
webCamTextureToMatHelper.Initialize ();
|
||||
} else {
|
||||
webCamTextureToMatHelper.Initialize ();
|
||||
}
|
||||
#else
|
||||
webCamTextureToMatHelper.Initialize ();
|
||||
// Avoids the front camera low light issue that occurs in only some Android devices (e.g. Google Pixel, Pixel2).
|
||||
webCamTextureToMatHelper.avoidAndroidFrontCameraLowLightIssue = true;
|
||||
#endif
|
||||
webCamTextureToMatHelper.Initialize ();
|
||||
|
||||
displayFaceRectsToggle.isOn = displayFaceRects;
|
||||
useDlibFaceDetecterToggle.isOn = useDlibFaceDetecter;
|
||||
|
@ -343,10 +328,10 @@ namespace FaceMaskExample
|
|||
gameObject.transform.localScale = new Vector3 (webCamTextureMat.cols (), webCamTextureMat.rows (), 1);
|
||||
Debug.Log ("Screen.width " + Screen.width + " Screen.height " + Screen.height + " Screen.orientation " + Screen.orientation);
|
||||
|
||||
if (fpsMonitor != null){
|
||||
fpsMonitor.Add ("width", webCamTextureMat.width ().ToString());
|
||||
fpsMonitor.Add ("height", webCamTextureMat.height ().ToString());
|
||||
fpsMonitor.Add ("orientation", Screen.orientation.ToString());
|
||||
if (fpsMonitor != null) {
|
||||
fpsMonitor.Add ("width", webCamTextureMat.width ().ToString ());
|
||||
fpsMonitor.Add ("height", webCamTextureMat.height ().ToString ());
|
||||
fpsMonitor.Add ("orientation", Screen.orientation.ToString ());
|
||||
}
|
||||
|
||||
|
||||
|
@ -386,7 +371,7 @@ namespace FaceMaskExample
|
|||
grayMat.Dispose ();
|
||||
|
||||
if (texture != null) {
|
||||
Texture2D.Destroy(texture);
|
||||
Texture2D.Destroy (texture);
|
||||
texture = null;
|
||||
}
|
||||
|
||||
|
@ -411,7 +396,8 @@ namespace FaceMaskExample
|
|||
/// Raises the web cam texture to mat helper error occurred event.
|
||||
/// </summary>
|
||||
/// <param name="errorCode">Error code.</param>
|
||||
public void OnWebCamTextureToMatHelperErrorOccurred(WebCamTextureToMatHelper.ErrorCode errorCode){
|
||||
public void OnWebCamTextureToMatHelperErrorOccurred (WebCamTextureToMatHelper.ErrorCode errorCode)
|
||||
{
|
||||
Debug.Log ("OnWebCamTextureToMatHelperErrorOccurred " + errorCode);
|
||||
}
|
||||
|
||||
|
@ -423,13 +409,13 @@ namespace FaceMaskExample
|
|||
Mat rgbaMat = webCamTextureToMatHelper.GetMat ();
|
||||
|
||||
// detect faces.
|
||||
List<OpenCVForUnity.Rect> detectResult = new List<OpenCVForUnity.Rect> ();
|
||||
List<Rect> detectResult = new List<Rect> ();
|
||||
if (useDlibFaceDetecter) {
|
||||
OpenCVForUnityUtils.SetImage (faceLandmarkDetector, rgbaMat);
|
||||
List<UnityEngine.Rect> result = faceLandmarkDetector.Detect ();
|
||||
|
||||
foreach (var unityRect in result) {
|
||||
detectResult.Add (new OpenCVForUnity.Rect ((int)unityRect.x, (int)unityRect.y, (int)unityRect.width, (int)unityRect.height));
|
||||
detectResult.Add (new Rect ((int)unityRect.x, (int)unityRect.y, (int)unityRect.width, (int)unityRect.height));
|
||||
}
|
||||
} else {
|
||||
// convert image to greyscale.
|
||||
|
@ -439,13 +425,13 @@ namespace FaceMaskExample
|
|||
using (MatOfRect faces = new MatOfRect ()) {
|
||||
Imgproc.equalizeHist (grayMat, equalizeHistMat);
|
||||
|
||||
cascade.detectMultiScale (equalizeHistMat, faces, 1.1f, 2, 0 | Objdetect.CASCADE_SCALE_IMAGE, new OpenCVForUnity.Size (equalizeHistMat.cols () * 0.15, equalizeHistMat.cols () * 0.15), new Size ());
|
||||
cascade.detectMultiScale (equalizeHistMat, faces, 1.1f, 2, 0 | Objdetect.CASCADE_SCALE_IMAGE, new Size (equalizeHistMat.cols () * 0.15, equalizeHistMat.cols () * 0.15), new Size ());
|
||||
|
||||
detectResult = faces.toList ();
|
||||
}
|
||||
|
||||
// adjust to Dilb's result.
|
||||
foreach (OpenCVForUnity.Rect r in detectResult) {
|
||||
// corrects the deviation of a detection result between OpenCV and Dlib.
|
||||
foreach (Rect r in detectResult) {
|
||||
r.y += (int)(r.height * 0.1f);
|
||||
}
|
||||
}
|
||||
|
@ -458,11 +444,11 @@ namespace FaceMaskExample
|
|||
// create noise filter.
|
||||
foreach (var openCVRect in trackedRects) {
|
||||
if (openCVRect.state == TrackedState.NEW) {
|
||||
if (!lowPassFilterDict.ContainsKey(openCVRect.id))
|
||||
lowPassFilterDict.Add (openCVRect.id, new LowPassPointsFilter((int)faceLandmarkDetector.GetShapePredictorNumParts()));
|
||||
if (!opticalFlowFilterDict.ContainsKey(openCVRect.id))
|
||||
opticalFlowFilterDict.Add (openCVRect.id, new OFPointsFilter((int)faceLandmarkDetector.GetShapePredictorNumParts()));
|
||||
}else if (openCVRect.state == TrackedState.DELETED){
|
||||
if (!lowPassFilterDict.ContainsKey (openCVRect.id))
|
||||
lowPassFilterDict.Add (openCVRect.id, new LowPassPointsFilter ((int)faceLandmarkDetector.GetShapePredictorNumParts ()));
|
||||
if (!opticalFlowFilterDict.ContainsKey (openCVRect.id))
|
||||
opticalFlowFilterDict.Add (openCVRect.id, new OFPointsFilter ((int)faceLandmarkDetector.GetShapePredictorNumParts ()));
|
||||
} else if (openCVRect.state == TrackedState.DELETED) {
|
||||
if (lowPassFilterDict.ContainsKey (openCVRect.id)) {
|
||||
lowPassFilterDict [openCVRect.id].Dispose ();
|
||||
lowPassFilterDict.Remove (openCVRect.id);
|
||||
|
@ -478,7 +464,7 @@ namespace FaceMaskExample
|
|||
foreach (var openCVRect in trackedRects) {
|
||||
if (openCVRect.state == TrackedState.NEW) {
|
||||
faceMaskColorCorrector.CreateLUTTex (openCVRect.id);
|
||||
}else if (openCVRect.state == TrackedState.DELETED) {
|
||||
} else if (openCVRect.state == TrackedState.DELETED) {
|
||||
faceMaskColorCorrector.DeleteLUTTex (openCVRect.id);
|
||||
}
|
||||
}
|
||||
|
@ -500,8 +486,8 @@ namespace FaceMaskExample
|
|||
}
|
||||
}
|
||||
|
||||
if (extendForehead){
|
||||
AddForeheadPoints(points);
|
||||
if (extendForehead) {
|
||||
AddForeheadPoints (points);
|
||||
}
|
||||
|
||||
landmarkPoints.Add (points);
|
||||
|
@ -566,8 +552,8 @@ namespace FaceMaskExample
|
|||
for (int i = 0; i < trackedRects.Count; i++) {
|
||||
UnityEngine.Rect rect = new UnityEngine.Rect (trackedRects [i].x, trackedRects [i].y, trackedRects [i].width, trackedRects [i].height);
|
||||
OpenCVForUnityUtils.DrawFaceRect (rgbaMat, rect, new Scalar (255, 255, 0, 255), 2);
|
||||
//Imgproc.putText (rgbaMat, " " + frontalFaceChecker.GetFrontalFaceAngles (landmarkPoints [i]), new Point (rect.xMin, rect.yMin - 10), Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
|
||||
//Imgproc.putText (rgbaMat, " " + frontalFaceChecker.GetFrontalFaceRate (landmarkPoints [i]), new Point (rect.xMin, rect.yMin - 10), Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
|
||||
// Imgproc.putText (rgbaMat, " " + frontalFaceChecker.GetFrontalFaceAngles (landmarkPoints [i]), new Point (rect.xMin, rect.yMin - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
|
||||
// Imgproc.putText (rgbaMat, " " + frontalFaceChecker.GetFrontalFaceRate (landmarkPoints [i]), new Point (rect.xMin, rect.yMin - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -603,12 +589,12 @@ namespace FaceMaskExample
|
|||
Imgproc.warpAffine (faceMaskMat, rgbaMat, trans, rgbaMat.size (), Imgproc.INTER_LINEAR, Core.BORDER_TRANSPARENT, new Scalar (0));
|
||||
|
||||
if (displayFaceRects || displayDebugFacePointsToggle)
|
||||
OpenCVForUnity.Utils.texture2DToMat (faceMaskTexture, faceMaskMat);
|
||||
OpenCVForUnity.UnityUtils.Utils.texture2DToMat (faceMaskTexture, faceMaskMat);
|
||||
}
|
||||
|
||||
// Imgproc.putText (rgbaMat, "W:" + rgbaMat.width () + " H:" + rgbaMat.height () + " SO:" + Screen.orientation, new Point (5, rgbaMat.rows () - 10), Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 1, Imgproc.LINE_AA, false);
|
||||
// Imgproc.putText (rgbaMat, "W:" + rgbaMat.width () + " H:" + rgbaMat.height () + " SO:" + Screen.orientation, new Point (5, rgbaMat.rows () - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 1, Imgproc.LINE_AA, false);
|
||||
|
||||
OpenCVForUnity.Utils.fastMatToTexture2D (rgbaMat, texture);
|
||||
OpenCVForUnity.UnityUtils.Utils.fastMatToTexture2D (rgbaMat, texture);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -628,23 +614,23 @@ namespace FaceMaskExample
|
|||
Vector3[] vertices = tm.meshFilter.mesh.vertices;
|
||||
if (vertices.Length == landmarkPoints.Count) {
|
||||
for (int j = 0; j < vertices.Length; j++) {
|
||||
vertices [j].x = landmarkPoints[j].x / imageWidth - 0.5f;
|
||||
vertices [j].y = 0.5f - landmarkPoints[j].y / imageHeight;
|
||||
vertices [j].x = landmarkPoints [j].x / imageWidth - 0.5f;
|
||||
vertices [j].y = 0.5f - landmarkPoints [j].y / imageHeight;
|
||||
}
|
||||
}
|
||||
Vector2[] uv = tm.meshFilter.mesh.uv;
|
||||
if (uv.Length == landmarkPointsInMaskImage.Count) {
|
||||
for (int jj = 0; jj < uv.Length; jj++) {
|
||||
uv [jj].x = landmarkPointsInMaskImage[jj].x / maskImageWidth;
|
||||
uv [jj].y = (maskImageHeight - landmarkPointsInMaskImage[jj].y) / maskImageHeight;
|
||||
uv [jj].x = landmarkPointsInMaskImage [jj].x / maskImageWidth;
|
||||
uv [jj].y = (maskImageHeight - landmarkPointsInMaskImage [jj].y) / maskImageHeight;
|
||||
}
|
||||
}
|
||||
meshOverlay.UpdateObject (tr.id, vertices, null, uv);
|
||||
|
||||
if (tr.numFramesNotDetected > 3) {
|
||||
tm.sharedMaterial.SetFloat (shader_FadeID, 1f);
|
||||
}else if (tr.numFramesNotDetected > 0 && tr.numFramesNotDetected <= 3) {
|
||||
tm.sharedMaterial.SetFloat (shader_FadeID, 0.3f + (0.7f/4f) * tr.numFramesNotDetected);
|
||||
} else if (tr.numFramesNotDetected > 0 && tr.numFramesNotDetected <= 3) {
|
||||
tm.sharedMaterial.SetFloat (shader_FadeID, 0.3f + (0.7f / 4f) * tr.numFramesNotDetected);
|
||||
} else {
|
||||
tm.sharedMaterial.SetFloat (shader_FadeID, 0.3f);
|
||||
}
|
||||
|
@ -663,7 +649,7 @@ namespace FaceMaskExample
|
|||
|
||||
private void CorrectFaceMaskColor (int id, Mat src, Mat dst, List<Vector2> src_landmarkPoints, List<Vector2> dst_landmarkPoints)
|
||||
{
|
||||
Texture2D LUTTex = faceMaskColorCorrector.UpdateLUTTex(id, src, dst, src_landmarkPoints, dst_landmarkPoints);
|
||||
Texture2D LUTTex = faceMaskColorCorrector.UpdateLUTTex (id, src, dst, src_landmarkPoints, dst_landmarkPoints);
|
||||
TrackedMesh tm = meshOverlay.GetObjectById (id);
|
||||
tm.sharedMaterial.SetTexture (shader_LUTTexID, LUTTex);
|
||||
}
|
||||
|
@ -697,9 +683,9 @@ namespace FaceMaskExample
|
|||
faceMaskColorCorrector.Dispose ();
|
||||
|
||||
#if UNITY_WEBGL && !UNITY_EDITOR
|
||||
foreach (var coroutine in coroutines) {
|
||||
StopCoroutine (coroutine);
|
||||
((IDisposable)coroutine).Dispose ();
|
||||
if (getFilePath_Coroutine != null) {
|
||||
StopCoroutine (getFilePath_Coroutine);
|
||||
((IDisposable)getFilePath_Coroutine).Dispose ();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -709,11 +695,7 @@ namespace FaceMaskExample
|
|||
/// </summary>
|
||||
public void OnBackButtonClick ()
|
||||
{
|
||||
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
|
||||
SceneManager.LoadScene ("FaceMaskExample");
|
||||
#else
|
||||
Application.LoadLevel ("FaceMaskExample");
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -737,16 +719,7 @@ namespace FaceMaskExample
|
|||
/// </summary>
|
||||
public void OnChangeCameraButtonClick ()
|
||||
{
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
if (!webCamTextureToMatHelper.IsFrontFacing ()) {
|
||||
rearCameraRequestedFPS = webCamTextureToMatHelper.requestedFPS;
|
||||
webCamTextureToMatHelper.Initialize (!webCamTextureToMatHelper.IsFrontFacing (), 15, webCamTextureToMatHelper.rotate90Degree);
|
||||
} else {
|
||||
webCamTextureToMatHelper.Initialize (!webCamTextureToMatHelper.IsFrontFacing (), rearCameraRequestedFPS, webCamTextureToMatHelper.rotate90Degree);
|
||||
}
|
||||
#else
|
||||
webCamTextureToMatHelper.requestedIsFrontFacing = !webCamTextureToMatHelper.IsFrontFacing ();
|
||||
#endif
|
||||
webCamTextureToMatHelper.requestedIsFrontFacing = !webCamTextureToMatHelper.IsFrontFacing ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -802,7 +775,7 @@ namespace FaceMaskExample
|
|||
filterNonFrontalFaces = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Raises the display face rects toggle value changed event.
|
||||
/// </summary>
|
||||
|
@ -837,7 +810,7 @@ namespace FaceMaskExample
|
|||
if (faceMaskDatas.Count == 0)
|
||||
return;
|
||||
|
||||
FaceMaskData maskData = faceMaskDatas[faceMaskDataIndex];
|
||||
FaceMaskData maskData = faceMaskDatas [faceMaskDataIndex];
|
||||
faceMaskDataIndex = (faceMaskDataIndex < faceMaskDatas.Count - 1) ? faceMaskDataIndex + 1 : 0;
|
||||
|
||||
if (maskData == null) {
|
||||
|
@ -857,26 +830,26 @@ namespace FaceMaskExample
|
|||
|
||||
faceMaskTexture = maskData.image;
|
||||
faceMaskMat = new Mat (faceMaskTexture.height, faceMaskTexture.width, CvType.CV_8UC4);
|
||||
OpenCVForUnity.Utils.texture2DToMat (faceMaskTexture, faceMaskMat);
|
||||
OpenCVForUnity.UnityUtils.Utils.texture2DToMat (faceMaskTexture, faceMaskMat);
|
||||
|
||||
if(maskData.isDynamicMode){
|
||||
if (maskData.isDynamicMode) {
|
||||
faceRectInMask = DetectFace (faceMaskMat);
|
||||
faceLandmarkPointsInMask = DetectFaceLandmarkPoints (faceMaskMat, faceRectInMask);
|
||||
|
||||
maskData.faceRect = faceRectInMask;
|
||||
maskData.landmarkPoints = faceLandmarkPointsInMask;
|
||||
}else{
|
||||
} else {
|
||||
faceRectInMask = maskData.faceRect;
|
||||
faceLandmarkPointsInMask = maskData.landmarkPoints;
|
||||
}
|
||||
|
||||
if (extendForehead) {
|
||||
List<Vector2> newLandmarkPointsInMask = new List<Vector2> (faceLandmarkPointsInMask);
|
||||
AddForeheadPoints(newLandmarkPointsInMask);
|
||||
AddForeheadPoints (newLandmarkPointsInMask);
|
||||
faceLandmarkPointsInMask = newLandmarkPointsInMask;
|
||||
}
|
||||
|
||||
if (faceRectInMask.width == 0 && faceRectInMask.height == 0){
|
||||
if (faceRectInMask.width == 0 && faceRectInMask.height == 0) {
|
||||
RemoveFaceMask ();
|
||||
Debug.LogError ("A face could not be detected from the input image.");
|
||||
}
|
||||
|
@ -897,34 +870,34 @@ namespace FaceMaskExample
|
|||
Mat rgbaMat = webCamTextureToMatHelper.GetMat ();
|
||||
|
||||
faceRectInMask = DetectFace (rgbaMat);
|
||||
if (faceRectInMask.width == 0 && faceRectInMask.height == 0){
|
||||
if (faceRectInMask.width == 0 && faceRectInMask.height == 0) {
|
||||
Debug.Log ("A face could not be detected from the input image.");
|
||||
return;
|
||||
}
|
||||
|
||||
OpenCVForUnity.Rect rect = new OpenCVForUnity.Rect((int)faceRectInMask.x, (int)faceRectInMask.y, (int)faceRectInMask.width, (int)faceRectInMask.height);
|
||||
rect.inflate(rect.x/5, rect.y/5);
|
||||
rect = rect.intersect(new OpenCVForUnity.Rect(0,0,rgbaMat.width(),rgbaMat.height()));
|
||||
Rect rect = new Rect ((int)faceRectInMask.x, (int)faceRectInMask.y, (int)faceRectInMask.width, (int)faceRectInMask.height);
|
||||
rect.inflate (rect.x / 5, rect.y / 5);
|
||||
rect = rect.intersect (new Rect (0, 0, rgbaMat.width (), rgbaMat.height ()));
|
||||
|
||||
faceMaskTexture = new Texture2D (rect.width, rect.height, TextureFormat.RGBA32, false);
|
||||
faceMaskMat = new Mat(rgbaMat, rect).clone ();
|
||||
OpenCVForUnity.Utils.matToTexture2D(faceMaskMat, faceMaskTexture);
|
||||
faceMaskMat = new Mat (rgbaMat, rect).clone ();
|
||||
OpenCVForUnity.UnityUtils.Utils.matToTexture2D (faceMaskMat, faceMaskTexture);
|
||||
Debug.Log ("faceMaskMat ToString " + faceMaskMat.ToString ());
|
||||
|
||||
faceRectInMask = DetectFace (faceMaskMat);
|
||||
faceLandmarkPointsInMask = DetectFaceLandmarkPoints (faceMaskMat, faceRectInMask);
|
||||
|
||||
if (extendForehead) {
|
||||
AddForeheadPoints(faceLandmarkPointsInMask);
|
||||
AddForeheadPoints (faceLandmarkPointsInMask);
|
||||
}
|
||||
|
||||
if (faceRectInMask.width == 0 && faceRectInMask.height == 0){
|
||||
if (faceRectInMask.width == 0 && faceRectInMask.height == 0) {
|
||||
RemoveFaceMask ();
|
||||
Debug.Log ("A face could not be detected from the input image.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Raises the remove face mask button click event.
|
||||
/// </summary>
|
||||
|
@ -944,7 +917,7 @@ namespace FaceMaskExample
|
|||
rectangleTracker.Reset ();
|
||||
meshOverlay.Reset ();
|
||||
}
|
||||
|
||||
|
||||
private UnityEngine.Rect DetectFace (Mat mat)
|
||||
{
|
||||
if (useDlibFaceDetecter) {
|
||||
|
@ -961,12 +934,12 @@ namespace FaceMaskExample
|
|||
Imgproc.cvtColor (mat, grayMat, Imgproc.COLOR_RGBA2GRAY);
|
||||
Imgproc.equalizeHist (grayMat, equalizeHistMat);
|
||||
|
||||
cascade.detectMultiScale (equalizeHistMat, faces, 1.1f, 2, 0 | Objdetect.CASCADE_SCALE_IMAGE, new OpenCVForUnity.Size (equalizeHistMat.cols () * 0.15, equalizeHistMat.cols () * 0.15), new Size ());
|
||||
cascade.detectMultiScale (equalizeHistMat, faces, 1.1f, 2, 0 | Objdetect.CASCADE_SCALE_IMAGE, new Size (equalizeHistMat.cols () * 0.15, equalizeHistMat.cols () * 0.15), new Size ());
|
||||
|
||||
List<OpenCVForUnity.Rect> faceList = faces.toList ();
|
||||
List<Rect> faceList = faces.toList ();
|
||||
if (faceList.Count >= 1) {
|
||||
UnityEngine.Rect r = new UnityEngine.Rect (faceList [0].x, faceList [0].y, faceList [0].width, faceList [0].height);
|
||||
// adjust to Dilb's result.
|
||||
// corrects the deviation of a detection result between OpenCV and Dlib.
|
||||
r.y += (int)(r.height * 0.1f);
|
||||
return r;
|
||||
}
|
||||
|
@ -983,41 +956,40 @@ namespace FaceMaskExample
|
|||
return points;
|
||||
}
|
||||
|
||||
private void ExtendForehead(Mesh mesh)
|
||||
private void ExtendForehead (Mesh mesh)
|
||||
{
|
||||
if (mesh.vertices.Length != 68)
|
||||
throw new ArgumentException ("Invalid face mask mesh", "mesh");
|
||||
|
||||
List<Vector2> verticesList = new List<Vector2> (mesh.vertices.Length);
|
||||
foreach (Vector3 v in mesh.vertices) {
|
||||
verticesList.Add(new Vector2(v.x, v.y));
|
||||
verticesList.Add (new Vector2 (v.x, v.y));
|
||||
}
|
||||
|
||||
AddForeheadPoints (verticesList);
|
||||
|
||||
Vector3[] vertices = new Vector3[verticesList.Count];
|
||||
for (int i = 0; i < vertices.Length; i++) {
|
||||
vertices[i] = new Vector3(verticesList[i].x, verticesList[i].y);
|
||||
vertices [i] = new Vector3 (verticesList [i].x, verticesList [i].y);
|
||||
}
|
||||
mesh.vertices = vertices;
|
||||
|
||||
int[] foreheadTriangles = new int[13 * 3]
|
||||
{
|
||||
68,16,26,
|
||||
68,26,25,
|
||||
69,68,25,
|
||||
69,25,24,
|
||||
69,24,23,
|
||||
70,69,23,
|
||||
int[] foreheadTriangles = new int[13 * 3] {
|
||||
68, 16, 26,
|
||||
68, 26, 25,
|
||||
69, 68, 25,
|
||||
69, 25, 24,
|
||||
69, 24, 23,
|
||||
70, 69, 23,
|
||||
|
||||
70,23,20,
|
||||
70, 23, 20,
|
||||
|
||||
71,70,20,
|
||||
71,20,19,
|
||||
71,19,18,
|
||||
72,71,18,
|
||||
72,18,17,
|
||||
72,17,0
|
||||
71, 70, 20,
|
||||
71, 20, 19,
|
||||
71, 19, 18,
|
||||
72, 71, 18,
|
||||
72, 18, 17,
|
||||
72, 17, 0
|
||||
};
|
||||
int[] triangles = new int[mesh.triangles.Length + foreheadTriangles.Length];
|
||||
mesh.triangles.CopyTo (triangles, 0);
|
||||
|
@ -1026,8 +998,8 @@ namespace FaceMaskExample
|
|||
|
||||
Vector2[] uv = new Vector2[mesh.uv.Length];
|
||||
for (int j = 0; j < uv.Length; j++) {
|
||||
uv [j].x = vertices[j].x + 0.5f;
|
||||
uv [j].y = vertices[j].y + 0.5f;
|
||||
uv [j].x = vertices [j].x + 0.5f;
|
||||
uv [j].y = vertices [j].y + 0.5f;
|
||||
}
|
||||
mesh.uv = uv;
|
||||
mesh.uv2 = (Vector2[])uv.Clone ();
|
||||
|
@ -1035,19 +1007,19 @@ namespace FaceMaskExample
|
|||
mesh.RecalculateNormals ();
|
||||
}
|
||||
|
||||
private void AddForeheadPoints(List<Vector2> points)
|
||||
private void AddForeheadPoints (List<Vector2> points)
|
||||
{
|
||||
if (points.Count != 68)
|
||||
throw new ArgumentException ("Invalid face landmark points", "points");
|
||||
|
||||
Vector2 noseLength = new Vector2(points[27].x - points[30].x, points[27].y - points[30].y);
|
||||
Vector2 glabellaPoint = new Vector2((points[19].x + points[24].x)/2f, (points[19].y + points[24].y)/2f);
|
||||
Vector2 noseLength = new Vector2 (points [27].x - points [30].x, points [27].y - points [30].y);
|
||||
Vector2 glabellaPoint = new Vector2 ((points [19].x + points [24].x) / 2f, (points [19].y + points [24].y) / 2f);
|
||||
|
||||
points.Add (new Vector2(points[26].x + noseLength.x*0.8f, points[26].y + noseLength.y*0.8f));
|
||||
points.Add (new Vector2(points[24].x + noseLength.x, points[24].y + noseLength.y));
|
||||
points.Add (new Vector2(glabellaPoint.x + noseLength.x*1.1f, glabellaPoint.y + noseLength.y*1.1f));
|
||||
points.Add (new Vector2(points[19].x + noseLength.x, points[19].y + noseLength.y));
|
||||
points.Add (new Vector2(points[17].x + noseLength.x*0.8f, points[17].y + noseLength.y*0.8f));
|
||||
points.Add (new Vector2 (points [26].x + noseLength.x * 0.8f, points [26].y + noseLength.y * 0.8f));
|
||||
points.Add (new Vector2 (points [24].x + noseLength.x, points [24].y + noseLength.y));
|
||||
points.Add (new Vector2 (glabellaPoint.x + noseLength.x * 1.1f, glabellaPoint.y + noseLength.y * 1.1f));
|
||||
points.Add (new Vector2 (points [19].x + noseLength.x, points [19].y + noseLength.y));
|
||||
points.Add (new Vector2 (points [17].x + noseLength.x * 0.8f, points [17].y + noseLength.y * 0.8f));
|
||||
}
|
||||
|
||||
private static void DrawFaceLandmark (Mat imgMat, List<Vector2> points, Scalar color, int thickness)
|
||||
|
@ -1086,109 +1058,113 @@ namespace FaceMaskExample
|
|||
for (int i = 69; i <= 72; ++i)
|
||||
Imgproc.line (imgMat, new Point (points [i].x, points [i].y), new Point (points [i - 1].x, points [i - 1].y), new Scalar (0, 255, 0, 255), thickness);
|
||||
} else {
|
||||
OpenCVForUnityUtils.DrawFaceLandmark(imgMat, points, color, thickness);
|
||||
OpenCVForUnityUtils.DrawFaceLandmark (imgMat, points, color, thickness);
|
||||
}
|
||||
}
|
||||
|
||||
private Texture2D CreateFaceMaskAlphaMaskTexture(float width, float height, Vector2[] uv, bool makeBothEyesTransparent = true, bool makeMouthTransparent = true)
|
||||
private Texture2D CreateFaceMaskAlphaMaskTexture (float width, float height, Vector2[] uv, bool makeBothEyesTransparent = true, bool makeMouthTransparent = true)
|
||||
{
|
||||
if (uv.Length != 68 && uv.Length != 73)
|
||||
throw new ArgumentException ("Invalid face landmark points", "uv");
|
||||
|
||||
Vector2[] facialContourUVPoints = new Vector2[0];
|
||||
if(uv.Length == 68){
|
||||
facialContourUVPoints = new Vector2[]{
|
||||
uv[0],
|
||||
uv[1],
|
||||
uv[2],
|
||||
uv[3],
|
||||
uv[4],
|
||||
uv[5],
|
||||
uv[6],
|
||||
uv[7],
|
||||
uv[8],
|
||||
uv[9],
|
||||
uv[10],
|
||||
uv[11],
|
||||
uv[12],
|
||||
uv[13],
|
||||
uv[14],
|
||||
uv[15],
|
||||
uv[16],
|
||||
uv[26],
|
||||
uv[25],
|
||||
uv[24],
|
||||
uv[23],
|
||||
uv[20],
|
||||
uv[19],
|
||||
uv[18],
|
||||
uv[17]
|
||||
if (uv.Length == 68) {
|
||||
facialContourUVPoints = new Vector2[] {
|
||||
uv [0],
|
||||
uv [1],
|
||||
uv [2],
|
||||
uv [3],
|
||||
uv [4],
|
||||
uv [5],
|
||||
uv [6],
|
||||
uv [7],
|
||||
uv [8],
|
||||
uv [9],
|
||||
uv [10],
|
||||
uv [11],
|
||||
uv [12],
|
||||
uv [13],
|
||||
uv [14],
|
||||
uv [15],
|
||||
uv [16],
|
||||
uv [26],
|
||||
uv [25],
|
||||
uv [24],
|
||||
uv [23],
|
||||
uv [20],
|
||||
uv [19],
|
||||
uv [18],
|
||||
uv [17]
|
||||
};
|
||||
}else if (uv.Length == 73){ // If landmark points of forehead exists.
|
||||
facialContourUVPoints = new Vector2[]{
|
||||
uv[0],
|
||||
uv[1],
|
||||
uv[2],
|
||||
uv[3],
|
||||
uv[4],
|
||||
uv[5],
|
||||
uv[6],
|
||||
uv[7],
|
||||
uv[8],
|
||||
uv[9],
|
||||
uv[10],
|
||||
uv[11],
|
||||
uv[12],
|
||||
uv[13],
|
||||
uv[14],
|
||||
uv[15],
|
||||
uv[16],
|
||||
uv[68],
|
||||
uv[69],
|
||||
uv[70],
|
||||
uv[71],
|
||||
uv[72]
|
||||
} else if (uv.Length == 73) { // If landmark points of forehead exists.
|
||||
facialContourUVPoints = new Vector2[] {
|
||||
uv [0],
|
||||
uv [1],
|
||||
uv [2],
|
||||
uv [3],
|
||||
uv [4],
|
||||
uv [5],
|
||||
uv [6],
|
||||
uv [7],
|
||||
uv [8],
|
||||
uv [9],
|
||||
uv [10],
|
||||
uv [11],
|
||||
uv [12],
|
||||
uv [13],
|
||||
uv [14],
|
||||
uv [15],
|
||||
uv [16],
|
||||
uv [68],
|
||||
uv [69],
|
||||
uv [70],
|
||||
uv [71],
|
||||
uv [72]
|
||||
};
|
||||
}
|
||||
|
||||
Vector2[] rightEyeContourUVPoints = new Vector2[]{
|
||||
uv[36],
|
||||
uv[37],
|
||||
uv[38],
|
||||
uv[39],
|
||||
uv[40],
|
||||
uv[41]
|
||||
Vector2[] rightEyeContourUVPoints = new Vector2[] {
|
||||
uv [36],
|
||||
uv [37],
|
||||
uv [38],
|
||||
uv [39],
|
||||
uv [40],
|
||||
uv [41]
|
||||
};
|
||||
|
||||
Vector2[] leftEyeContourUVPoints = new Vector2[]{
|
||||
uv[42],
|
||||
uv[43],
|
||||
uv[44],
|
||||
uv[45],
|
||||
uv[46],
|
||||
uv[47]
|
||||
Vector2[] leftEyeContourUVPoints = new Vector2[] {
|
||||
uv [42],
|
||||
uv [43],
|
||||
uv [44],
|
||||
uv [45],
|
||||
uv [46],
|
||||
uv [47]
|
||||
};
|
||||
|
||||
Vector2[] mouthContourUVPoints = new Vector2[]{
|
||||
uv[60],
|
||||
uv[61],
|
||||
uv[62],
|
||||
uv[63],
|
||||
uv[64],
|
||||
uv[65],
|
||||
uv[66],
|
||||
uv[67]
|
||||
Vector2[] mouthContourUVPoints = new Vector2[] {
|
||||
uv [60],
|
||||
uv [61],
|
||||
uv [62],
|
||||
uv [63],
|
||||
uv [64],
|
||||
uv [65],
|
||||
uv [66],
|
||||
uv [67]
|
||||
};
|
||||
|
||||
Vector2[][] exclusionAreas;
|
||||
if (makeBothEyesTransparent == true && makeMouthTransparent == false) {
|
||||
exclusionAreas = new Vector2[][]{rightEyeContourUVPoints, leftEyeContourUVPoints};
|
||||
exclusionAreas = new Vector2[][]{ rightEyeContourUVPoints, leftEyeContourUVPoints };
|
||||
} else if (makeBothEyesTransparent == false && makeMouthTransparent == true) {
|
||||
exclusionAreas = new Vector2[][]{mouthContourUVPoints};
|
||||
exclusionAreas = new Vector2[][]{ mouthContourUVPoints };
|
||||
} else if (makeBothEyesTransparent == true && makeMouthTransparent == true) {
|
||||
exclusionAreas = new Vector2[][]{rightEyeContourUVPoints, leftEyeContourUVPoints, mouthContourUVPoints};
|
||||
exclusionAreas = new Vector2[][] {
|
||||
rightEyeContourUVPoints,
|
||||
leftEyeContourUVPoints,
|
||||
mouthContourUVPoints
|
||||
};
|
||||
} else {
|
||||
exclusionAreas = new Vector2[][]{};
|
||||
exclusionAreas = new Vector2[][]{ };
|
||||
}
|
||||
|
||||
return AlphaMaskTextureCreater.CreateAlphaMaskTexture (width, height, facialContourUVPoints, exclusionAreas);
|
||||
|
|
|
@ -3094,7 +3094,7 @@ MonoBehaviour:
|
|||
m_EditorClassIdentifier:
|
||||
interval: 1
|
||||
poolSize: 10
|
||||
_baseObject: {fileID: 1138294731141240, guid: 8b9701cb9064eeb44b641983696a9e94,
|
||||
_baseObject: {fileID: 1150371196015818, guid: 8b9701cb9064eeb44b641983696a9e94,
|
||||
type: 2}
|
||||
--- !u!114 &1362053830
|
||||
MonoBehaviour:
|
||||
|
@ -3104,7 +3104,7 @@ MonoBehaviour:
|
|||
m_GameObject: {fileID: 1362053823}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: bafc15da02fe850489635791dda2bbdf, type: 3}
|
||||
m_Script: {fileID: 11500000, guid: df35b0c19ca97734e87299a664cea35f, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
_requestedDeviceName:
|
||||
|
@ -3162,8 +3162,9 @@ MonoBehaviour:
|
|||
m_StringArgument:
|
||||
m_BoolArgument: 0
|
||||
m_CallState: 2
|
||||
m_TypeName: FaceMaskExample.WebCamTextureToMatHelper+ErrorUnityEvent, Assembly-CSharp,
|
||||
Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_TypeName: OpenCVForUnity.UnityUtils.Helper.WebCamTextureToMatHelper+ErrorUnityEvent,
|
||||
Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
avoidAndroidFrontCameraLowLightIssue: 0
|
||||
--- !u!114 &1362053831
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
|
|
|
@ -4,13 +4,14 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using DlibFaceLandmarkDetector;
|
||||
using OpenCVForUnity;
|
||||
using OpenCVForUnity.RectangleTrack;
|
||||
|
||||
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
|
||||
using UnityEngine.SceneManagement;
|
||||
#endif
|
||||
using DlibFaceLandmarkDetector;
|
||||
using OpenCVForUnity.RectangleTrack;
|
||||
using OpenCVForUnity.UnityUtils.Helper;
|
||||
using OpenCVForUnity.CoreModule;
|
||||
using OpenCVForUnity.ObjdetectModule;
|
||||
using OpenCVForUnity.ImgprocModule;
|
||||
using Rect = OpenCVForUnity.CoreModule.Rect;
|
||||
|
||||
namespace FaceMaskExample
|
||||
{
|
||||
|
@ -205,12 +206,8 @@ namespace FaceMaskExample
|
|||
/// </summary>
|
||||
FpsMonitor fpsMonitor;
|
||||
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
float rearCameraRequestedFPS;
|
||||
#endif
|
||||
|
||||
#if UNITY_WEBGL && !UNITY_EDITOR
|
||||
Stack<IEnumerator> coroutines = new Stack<IEnumerator> ();
|
||||
IEnumerator getFilePath_Coroutine;
|
||||
#endif
|
||||
|
||||
// Use this for initialization
|
||||
|
@ -221,12 +218,11 @@ namespace FaceMaskExample
|
|||
webCamTextureToMatHelper = gameObject.GetComponent<WebCamTextureToMatHelper> ();
|
||||
|
||||
#if UNITY_WEBGL && !UNITY_EDITOR
|
||||
var getFilePath_Coroutine = GetFilePath ();
|
||||
coroutines.Push (getFilePath_Coroutine);
|
||||
getFilePath_Coroutine = GetFilePath ();
|
||||
StartCoroutine (getFilePath_Coroutine);
|
||||
#else
|
||||
haarcascade_frontalface_alt_xml_filepath = OpenCVForUnity.Utils.getFilePath ("haarcascade_frontalface_alt.xml");
|
||||
sp_human_face_68_dat_filepath = DlibFaceLandmarkDetector.Utils.getFilePath ("sp_human_face_68.dat");
|
||||
haarcascade_frontalface_alt_xml_filepath = OpenCVForUnity.UnityUtils.Utils.getFilePath ("haarcascade_frontalface_alt.xml");
|
||||
sp_human_face_68_dat_filepath = DlibFaceLandmarkDetector.UnityUtils.Utils.getFilePath ("sp_human_face_68.dat");
|
||||
Run ();
|
||||
#endif
|
||||
}
|
||||
|
@ -234,19 +230,17 @@ namespace FaceMaskExample
|
|||
#if UNITY_WEBGL && !UNITY_EDITOR
|
||||
private IEnumerator GetFilePath ()
|
||||
{
|
||||
var getFilePathAsync_0_Coroutine = OpenCVForUnity.Utils.getFilePathAsync ("haarcascade_frontalface_alt.xml", (result) => {
|
||||
var getFilePathAsync_0_Coroutine = OpenCVForUnity.UnityUtils.Utils.getFilePathAsync ("haarcascade_frontalface_alt.xml", (result) => {
|
||||
haarcascade_frontalface_alt_xml_filepath = result;
|
||||
});
|
||||
coroutines.Push (getFilePathAsync_0_Coroutine);
|
||||
yield return StartCoroutine (getFilePathAsync_0_Coroutine);
|
||||
yield return getFilePathAsync_0_Coroutine;
|
||||
|
||||
var getFilePathAsync_1_Coroutine = DlibFaceLandmarkDetector.Utils.getFilePathAsync ("sp_human_face_68.dat", (result) => {
|
||||
var getFilePathAsync_1_Coroutine = DlibFaceLandmarkDetector.UnityUtils.Utils.getFilePathAsync ("sp_human_face_68.dat", (result) => {
|
||||
sp_human_face_68_dat_filepath = result;
|
||||
});
|
||||
coroutines.Push (getFilePathAsync_1_Coroutine);
|
||||
yield return StartCoroutine (getFilePathAsync_1_Coroutine);
|
||||
yield return getFilePathAsync_1_Coroutine;
|
||||
|
||||
coroutines.Clear ();
|
||||
getFilePath_Coroutine = null;
|
||||
|
||||
Run ();
|
||||
}
|
||||
|
@ -256,9 +250,9 @@ namespace FaceMaskExample
|
|||
{
|
||||
meshOverlay = this.GetComponent<TrackedMeshOverlay> ();
|
||||
|
||||
shader_FadeID = Shader.PropertyToID("_Fade");
|
||||
shader_ColorCorrectionID = Shader.PropertyToID("_ColorCorrection");
|
||||
shader_LUTTexID = Shader.PropertyToID("_LUTTex");
|
||||
shader_FadeID = Shader.PropertyToID ("_Fade");
|
||||
shader_ColorCorrectionID = Shader.PropertyToID ("_ColorCorrection");
|
||||
shader_LUTTexID = Shader.PropertyToID ("_LUTTex");
|
||||
|
||||
rectangleTracker = new RectangleTracker ();
|
||||
|
||||
|
@ -270,19 +264,10 @@ namespace FaceMaskExample
|
|||
faceMaskColorCorrector = new FaceMaskColorCorrector ();
|
||||
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
// Set the requestedFPS parameter to avoid the problem of the WebCamTexture image becoming low light on some Android devices. (Pixel, pixel 2)
|
||||
// https://forum.unity.com/threads/android-webcamtexture-in-low-light-only-some-models.520656/
|
||||
// https://forum.unity.com/threads/released-opencv-for-unity.277080/page-33#post-3445178
|
||||
rearCameraRequestedFPS = webCamTextureToMatHelper.requestedFPS;
|
||||
if (webCamTextureToMatHelper.requestedIsFrontFacing) {
|
||||
webCamTextureToMatHelper.requestedFPS = 15;
|
||||
webCamTextureToMatHelper.Initialize ();
|
||||
} else {
|
||||
webCamTextureToMatHelper.Initialize ();
|
||||
}
|
||||
#else
|
||||
webCamTextureToMatHelper.Initialize ();
|
||||
// Avoids the front camera low light issue that occurs in only some Android devices (e.g. Google Pixel, Pixel2).
|
||||
webCamTextureToMatHelper.avoidAndroidFrontCameraLowLightIssue = true;
|
||||
#endif
|
||||
webCamTextureToMatHelper.Initialize ();
|
||||
|
||||
displayFaceRectsToggle.isOn = displayFaceRects;
|
||||
useDlibFaceDetecterToggle.isOn = useDlibFaceDetecter;
|
||||
|
@ -307,10 +292,10 @@ namespace FaceMaskExample
|
|||
gameObject.transform.localScale = new Vector3 (webCamTextureMat.cols (), webCamTextureMat.rows (), 1);
|
||||
Debug.Log ("Screen.width " + Screen.width + " Screen.height " + Screen.height + " Screen.orientation " + Screen.orientation);
|
||||
|
||||
if (fpsMonitor != null){
|
||||
fpsMonitor.Add ("width", webCamTextureMat.width ().ToString());
|
||||
fpsMonitor.Add ("height", webCamTextureMat.height ().ToString());
|
||||
fpsMonitor.Add ("orientation", Screen.orientation.ToString());
|
||||
if (fpsMonitor != null) {
|
||||
fpsMonitor.Add ("width", webCamTextureMat.width ().ToString ());
|
||||
fpsMonitor.Add ("height", webCamTextureMat.height ().ToString ());
|
||||
fpsMonitor.Add ("orientation", Screen.orientation.ToString ());
|
||||
}
|
||||
|
||||
|
||||
|
@ -350,7 +335,7 @@ namespace FaceMaskExample
|
|||
grayMat.Dispose ();
|
||||
|
||||
if (texture != null) {
|
||||
Texture2D.Destroy(texture);
|
||||
Texture2D.Destroy (texture);
|
||||
texture = null;
|
||||
}
|
||||
|
||||
|
@ -375,7 +360,8 @@ namespace FaceMaskExample
|
|||
/// Raises the web cam texture to mat helper error occurred event.
|
||||
/// </summary>
|
||||
/// <param name="errorCode">Error code.</param>
|
||||
public void OnWebCamTextureToMatHelperErrorOccurred(WebCamTextureToMatHelper.ErrorCode errorCode){
|
||||
public void OnWebCamTextureToMatHelperErrorOccurred (WebCamTextureToMatHelper.ErrorCode errorCode)
|
||||
{
|
||||
Debug.Log ("OnWebCamTextureToMatHelperErrorOccurred " + errorCode);
|
||||
}
|
||||
|
||||
|
@ -388,13 +374,13 @@ namespace FaceMaskExample
|
|||
Mat rgbaMat = webCamTextureToMatHelper.GetMat ();
|
||||
|
||||
// detect faces.
|
||||
List<OpenCVForUnity.Rect> detectResult = new List<OpenCVForUnity.Rect> ();
|
||||
List<Rect> detectResult = new List<Rect> ();
|
||||
if (useDlibFaceDetecter) {
|
||||
OpenCVForUnityUtils.SetImage (faceLandmarkDetector, rgbaMat);
|
||||
List<UnityEngine.Rect> result = faceLandmarkDetector.Detect ();
|
||||
|
||||
foreach (var unityRect in result) {
|
||||
detectResult.Add (new OpenCVForUnity.Rect ((int)unityRect.x, (int)unityRect.y, (int)unityRect.width, (int)unityRect.height));
|
||||
detectResult.Add (new Rect ((int)unityRect.x, (int)unityRect.y, (int)unityRect.width, (int)unityRect.height));
|
||||
}
|
||||
} else {
|
||||
// convert image to greyscale.
|
||||
|
@ -404,13 +390,13 @@ namespace FaceMaskExample
|
|||
using (MatOfRect faces = new MatOfRect ()) {
|
||||
Imgproc.equalizeHist (grayMat, equalizeHistMat);
|
||||
|
||||
cascade.detectMultiScale (equalizeHistMat, faces, 1.1f, 2, 0 | Objdetect.CASCADE_SCALE_IMAGE, new OpenCVForUnity.Size (equalizeHistMat.cols () * 0.15, equalizeHistMat.cols () * 0.15), new Size ());
|
||||
cascade.detectMultiScale (equalizeHistMat, faces, 1.1f, 2, 0 | Objdetect.CASCADE_SCALE_IMAGE, new Size (equalizeHistMat.cols () * 0.15, equalizeHistMat.cols () * 0.15), new Size ());
|
||||
|
||||
detectResult = faces.toList ();
|
||||
}
|
||||
|
||||
// adjust to Dilb's result.
|
||||
foreach (OpenCVForUnity.Rect r in detectResult) {
|
||||
// corrects the deviation of a detection result between OpenCV and Dlib.
|
||||
foreach (Rect r in detectResult) {
|
||||
r.y += (int)(r.height * 0.1f);
|
||||
}
|
||||
}
|
||||
|
@ -424,11 +410,11 @@ namespace FaceMaskExample
|
|||
// create noise filter.
|
||||
foreach (var openCVRect in trackedRects) {
|
||||
if (openCVRect.state == TrackedState.NEW) {
|
||||
if (!lowPassFilterDict.ContainsKey(openCVRect.id))
|
||||
lowPassFilterDict.Add (openCVRect.id, new LowPassPointsFilter((int)faceLandmarkDetector.GetShapePredictorNumParts()));
|
||||
if (!opticalFlowFilterDict.ContainsKey(openCVRect.id))
|
||||
opticalFlowFilterDict.Add (openCVRect.id, new OFPointsFilter((int)faceLandmarkDetector.GetShapePredictorNumParts()));
|
||||
}else if (openCVRect.state == TrackedState.DELETED){
|
||||
if (!lowPassFilterDict.ContainsKey (openCVRect.id))
|
||||
lowPassFilterDict.Add (openCVRect.id, new LowPassPointsFilter ((int)faceLandmarkDetector.GetShapePredictorNumParts ()));
|
||||
if (!opticalFlowFilterDict.ContainsKey (openCVRect.id))
|
||||
opticalFlowFilterDict.Add (openCVRect.id, new OFPointsFilter ((int)faceLandmarkDetector.GetShapePredictorNumParts ()));
|
||||
} else if (openCVRect.state == TrackedState.DELETED) {
|
||||
if (lowPassFilterDict.ContainsKey (openCVRect.id)) {
|
||||
lowPassFilterDict [openCVRect.id].Dispose ();
|
||||
lowPassFilterDict.Remove (openCVRect.id);
|
||||
|
@ -444,7 +430,7 @@ namespace FaceMaskExample
|
|||
foreach (var openCVRect in trackedRects) {
|
||||
if (openCVRect.state == TrackedState.NEW) {
|
||||
faceMaskColorCorrector.CreateLUTTex (openCVRect.id);
|
||||
}else if (openCVRect.state == TrackedState.DELETED) {
|
||||
} else if (openCVRect.state == TrackedState.DELETED) {
|
||||
faceMaskColorCorrector.DeleteLUTTex (openCVRect.id);
|
||||
}
|
||||
}
|
||||
|
@ -528,8 +514,8 @@ namespace FaceMaskExample
|
|||
for (int i = 0; i < trackedRects.Count; i++) {
|
||||
UnityEngine.Rect rect = new UnityEngine.Rect (trackedRects [i].x, trackedRects [i].y, trackedRects [i].width, trackedRects [i].height);
|
||||
OpenCVForUnityUtils.DrawFaceRect (rgbaMat, rect, new Scalar (255, 255, 0, 255), 2);
|
||||
//Imgproc.putText (rgbaMat, " " + frontalFaceChecker.GetFrontalFaceAngles (landmarkPoints [i]), new Point (rect.xMin, rect.yMin - 10), Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
|
||||
//Imgproc.putText (rgbaMat, " " + frontalFaceChecker.GetFrontalFaceRate (landmarkPoints [i]), new Point (rect.xMin, rect.yMin - 10), Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
|
||||
// Imgproc.putText (rgbaMat, " " + frontalFaceChecker.GetFrontalFaceAngles (landmarkPoints [i]), new Point (rect.xMin, rect.yMin - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
|
||||
// Imgproc.putText (rgbaMat, " " + frontalFaceChecker.GetFrontalFaceRate (landmarkPoints [i]), new Point (rect.xMin, rect.yMin - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -565,12 +551,12 @@ namespace FaceMaskExample
|
|||
Imgproc.warpAffine (faceMaskMat, rgbaMat, trans, rgbaMat.size (), Imgproc.INTER_LINEAR, Core.BORDER_TRANSPARENT, new Scalar (0));
|
||||
|
||||
if (displayFaceRects || displayDebugFacePointsToggle)
|
||||
OpenCVForUnity.Utils.texture2DToMat (faceMaskTexture, faceMaskMat);
|
||||
OpenCVForUnity.UnityUtils.Utils.texture2DToMat (faceMaskTexture, faceMaskMat);
|
||||
}
|
||||
|
||||
// Imgproc.putText (rgbaMat, "W:" + rgbaMat.width () + " H:" + rgbaMat.height () + " SO:" + Screen.orientation, new Point (5, rgbaMat.rows () - 10), Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 1, Imgproc.LINE_AA, false);
|
||||
// Imgproc.putText (rgbaMat, "W:" + rgbaMat.width () + " H:" + rgbaMat.height () + " SO:" + Screen.orientation, new Point (5, rgbaMat.rows () - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255, 255), 1, Imgproc.LINE_AA, false);
|
||||
|
||||
OpenCVForUnity.Utils.fastMatToTexture2D (rgbaMat, texture);
|
||||
OpenCVForUnity.UnityUtils.Utils.fastMatToTexture2D (rgbaMat, texture);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -590,23 +576,23 @@ namespace FaceMaskExample
|
|||
Vector3[] vertices = tm.meshFilter.mesh.vertices;
|
||||
if (vertices.Length == landmarkPoints.Count) {
|
||||
for (int j = 0; j < vertices.Length; j++) {
|
||||
vertices [j].x = landmarkPoints[j].x / imageWidth - 0.5f;
|
||||
vertices [j].y = 0.5f - landmarkPoints[j].y / imageHeight;
|
||||
vertices [j].x = landmarkPoints [j].x / imageWidth - 0.5f;
|
||||
vertices [j].y = 0.5f - landmarkPoints [j].y / imageHeight;
|
||||
}
|
||||
}
|
||||
Vector2[] uv = tm.meshFilter.mesh.uv;
|
||||
if (uv.Length == landmarkPointsInMaskImage.Count) {
|
||||
for (int jj = 0; jj < uv.Length; jj++) {
|
||||
uv [jj].x = landmarkPointsInMaskImage[jj].x / maskImageWidth;
|
||||
uv [jj].y = (maskImageHeight - landmarkPointsInMaskImage[jj].y) / maskImageHeight;
|
||||
uv [jj].x = landmarkPointsInMaskImage [jj].x / maskImageWidth;
|
||||
uv [jj].y = (maskImageHeight - landmarkPointsInMaskImage [jj].y) / maskImageHeight;
|
||||
}
|
||||
}
|
||||
meshOverlay.UpdateObject (tr.id, vertices, null, uv);
|
||||
|
||||
if (tr.numFramesNotDetected > 3) {
|
||||
tm.sharedMaterial.SetFloat (shader_FadeID, 1f);
|
||||
}else if (tr.numFramesNotDetected > 0 && tr.numFramesNotDetected <= 3) {
|
||||
tm.sharedMaterial.SetFloat (shader_FadeID, 0.3f + (0.7f/4f) * tr.numFramesNotDetected);
|
||||
} else if (tr.numFramesNotDetected > 0 && tr.numFramesNotDetected <= 3) {
|
||||
tm.sharedMaterial.SetFloat (shader_FadeID, 0.3f + (0.7f / 4f) * tr.numFramesNotDetected);
|
||||
} else {
|
||||
tm.sharedMaterial.SetFloat (shader_FadeID, 0.3f);
|
||||
}
|
||||
|
@ -625,7 +611,7 @@ namespace FaceMaskExample
|
|||
|
||||
private void CorrectFaceMaskColor (int id, Mat src, Mat dst, List<Vector2> src_landmarkPoints, List<Vector2> dst_landmarkPoints)
|
||||
{
|
||||
Texture2D LUTTex = faceMaskColorCorrector.UpdateLUTTex(id, src, dst, src_landmarkPoints, dst_landmarkPoints);
|
||||
Texture2D LUTTex = faceMaskColorCorrector.UpdateLUTTex (id, src, dst, src_landmarkPoints, dst_landmarkPoints);
|
||||
TrackedMesh tm = meshOverlay.GetObjectById (id);
|
||||
tm.sharedMaterial.SetTexture (shader_LUTTexID, LUTTex);
|
||||
}
|
||||
|
@ -659,9 +645,9 @@ namespace FaceMaskExample
|
|||
faceMaskColorCorrector.Dispose ();
|
||||
|
||||
#if UNITY_WEBGL && !UNITY_EDITOR
|
||||
foreach (var coroutine in coroutines) {
|
||||
StopCoroutine (coroutine);
|
||||
((IDisposable)coroutine).Dispose ();
|
||||
if (getFilePath_Coroutine != null) {
|
||||
StopCoroutine (getFilePath_Coroutine);
|
||||
((IDisposable)getFilePath_Coroutine).Dispose ();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -671,11 +657,7 @@ namespace FaceMaskExample
|
|||
/// </summary>
|
||||
public void OnBackButtonClick ()
|
||||
{
|
||||
#if UNITY_5_3 || UNITY_5_3_OR_NEWER
|
||||
SceneManager.LoadScene ("FaceMaskExample");
|
||||
#else
|
||||
Application.LoadLevel ("FaceMaskExample");
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -699,16 +681,7 @@ namespace FaceMaskExample
|
|||
/// </summary>
|
||||
public void OnChangeCameraButtonClick ()
|
||||
{
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
if (!webCamTextureToMatHelper.IsFrontFacing ()) {
|
||||
rearCameraRequestedFPS = webCamTextureToMatHelper.requestedFPS;
|
||||
webCamTextureToMatHelper.Initialize (!webCamTextureToMatHelper.IsFrontFacing (), 15, webCamTextureToMatHelper.rotate90Degree);
|
||||
} else {
|
||||
webCamTextureToMatHelper.Initialize (!webCamTextureToMatHelper.IsFrontFacing (), rearCameraRequestedFPS, webCamTextureToMatHelper.rotate90Degree);
|
||||
}
|
||||
#else
|
||||
webCamTextureToMatHelper.requestedIsFrontFacing = !webCamTextureToMatHelper.IsFrontFacing ();
|
||||
#endif
|
||||
webCamTextureToMatHelper.requestedIsFrontFacing = !webCamTextureToMatHelper.IsFrontFacing ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -764,7 +737,7 @@ namespace FaceMaskExample
|
|||
filterNonFrontalFaces = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Raises the display face rects toggle value changed event.
|
||||
/// </summary>
|
||||
|
@ -799,7 +772,7 @@ namespace FaceMaskExample
|
|||
if (faceMaskDatas.Count == 0)
|
||||
return;
|
||||
|
||||
FaceMaskData maskData = faceMaskDatas[faceMaskDataIndex];
|
||||
FaceMaskData maskData = faceMaskDatas [faceMaskDataIndex];
|
||||
faceMaskDataIndex = (faceMaskDataIndex < faceMaskDatas.Count - 1) ? faceMaskDataIndex + 1 : 0;
|
||||
|
||||
if (maskData == null) {
|
||||
|
@ -819,20 +792,20 @@ namespace FaceMaskExample
|
|||
|
||||
faceMaskTexture = maskData.image;
|
||||
faceMaskMat = new Mat (faceMaskTexture.height, faceMaskTexture.width, CvType.CV_8UC4);
|
||||
OpenCVForUnity.Utils.texture2DToMat (faceMaskTexture, faceMaskMat);
|
||||
OpenCVForUnity.UnityUtils.Utils.texture2DToMat (faceMaskTexture, faceMaskMat);
|
||||
|
||||
if(maskData.isDynamicMode){
|
||||
if (maskData.isDynamicMode) {
|
||||
faceRectInMask = DetectFace (faceMaskMat);
|
||||
faceLandmarkPointsInMask = DetectFaceLandmarkPoints (faceMaskMat, faceRectInMask);
|
||||
|
||||
maskData.faceRect = faceRectInMask;
|
||||
maskData.landmarkPoints = faceLandmarkPointsInMask;
|
||||
}else{
|
||||
} else {
|
||||
faceRectInMask = maskData.faceRect;
|
||||
faceLandmarkPointsInMask = maskData.landmarkPoints;
|
||||
}
|
||||
|
||||
if (faceRectInMask.width == 0 && faceRectInMask.height == 0){
|
||||
if (faceRectInMask.width == 0 && faceRectInMask.height == 0) {
|
||||
RemoveFaceMask ();
|
||||
Debug.LogError ("A face could not be detected from the input image.");
|
||||
}
|
||||
|
@ -853,30 +826,30 @@ namespace FaceMaskExample
|
|||
Mat rgbaMat = webCamTextureToMatHelper.GetMat ();
|
||||
|
||||
faceRectInMask = DetectFace (rgbaMat);
|
||||
if (faceRectInMask.width == 0 && faceRectInMask.height == 0){
|
||||
if (faceRectInMask.width == 0 && faceRectInMask.height == 0) {
|
||||
Debug.Log ("A face could not be detected from the input image.");
|
||||
return;
|
||||
}
|
||||
|
||||
OpenCVForUnity.Rect rect = new OpenCVForUnity.Rect((int)faceRectInMask.x, (int)faceRectInMask.y, (int)faceRectInMask.width, (int)faceRectInMask.height);
|
||||
rect.inflate(rect.x/5, rect.y/5);
|
||||
rect = rect.intersect(new OpenCVForUnity.Rect(0,0,rgbaMat.width(),rgbaMat.height()));
|
||||
Rect rect = new Rect ((int)faceRectInMask.x, (int)faceRectInMask.y, (int)faceRectInMask.width, (int)faceRectInMask.height);
|
||||
rect.inflate (rect.x / 5, rect.y / 5);
|
||||
rect = rect.intersect (new Rect (0, 0, rgbaMat.width (), rgbaMat.height ()));
|
||||
|
||||
faceMaskTexture = new Texture2D (rect.width, rect.height, TextureFormat.RGBA32, false);
|
||||
faceMaskMat = new Mat(rgbaMat, rect).clone ();
|
||||
OpenCVForUnity.Utils.matToTexture2D(faceMaskMat, faceMaskTexture);
|
||||
faceMaskMat = new Mat (rgbaMat, rect).clone ();
|
||||
OpenCVForUnity.UnityUtils.Utils.matToTexture2D (faceMaskMat, faceMaskTexture);
|
||||
Debug.Log ("faceMaskMat ToString " + faceMaskMat.ToString ());
|
||||
|
||||
faceRectInMask = DetectFace (faceMaskMat);
|
||||
faceLandmarkPointsInMask = DetectFaceLandmarkPoints (faceMaskMat, faceRectInMask);
|
||||
|
||||
if (faceRectInMask.width == 0 && faceRectInMask.height == 0){
|
||||
if (faceRectInMask.width == 0 && faceRectInMask.height == 0) {
|
||||
RemoveFaceMask ();
|
||||
Debug.Log ("A face could not be detected from the input image.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Raises the remove face mask button click event.
|
||||
/// </summary>
|
||||
|
@ -896,7 +869,7 @@ namespace FaceMaskExample
|
|||
rectangleTracker.Reset ();
|
||||
meshOverlay.Reset ();
|
||||
}
|
||||
|
||||
|
||||
private UnityEngine.Rect DetectFace (Mat mat)
|
||||
{
|
||||
if (useDlibFaceDetecter) {
|
||||
|
@ -913,12 +886,12 @@ namespace FaceMaskExample
|
|||
Imgproc.cvtColor (mat, grayMat, Imgproc.COLOR_RGBA2GRAY);
|
||||
Imgproc.equalizeHist (grayMat, equalizeHistMat);
|
||||
|
||||
cascade.detectMultiScale (equalizeHistMat, faces, 1.1f, 2, 0 | Objdetect.CASCADE_SCALE_IMAGE, new OpenCVForUnity.Size (equalizeHistMat.cols () * 0.15, equalizeHistMat.cols () * 0.15), new Size ());
|
||||
cascade.detectMultiScale (equalizeHistMat, faces, 1.1f, 2, 0 | Objdetect.CASCADE_SCALE_IMAGE, new Size (equalizeHistMat.cols () * 0.15, equalizeHistMat.cols () * 0.15), new Size ());
|
||||
|
||||
List<OpenCVForUnity.Rect> faceList = faces.toList ();
|
||||
List<Rect> faceList = faces.toList ();
|
||||
if (faceList.Count >= 1) {
|
||||
UnityEngine.Rect r = new UnityEngine.Rect (faceList [0].x, faceList [0].y, faceList [0].width, faceList [0].height);
|
||||
// adjust to Dilb's result.
|
||||
// corrects the deviation of a detection result between OpenCV and Dlib.
|
||||
r.y += (int)(r.height * 0.1f);
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -3032,7 +3032,7 @@ MonoBehaviour:
|
|||
m_EditorClassIdentifier:
|
||||
interval: 1
|
||||
poolSize: 10
|
||||
_baseObject: {fileID: 1138294731141240, guid: 8b9701cb9064eeb44b641983696a9e94,
|
||||
_baseObject: {fileID: 1150371196015818, guid: 8b9701cb9064eeb44b641983696a9e94,
|
||||
type: 2}
|
||||
--- !u!114 &1362053830
|
||||
MonoBehaviour:
|
||||
|
@ -3042,7 +3042,7 @@ MonoBehaviour:
|
|||
m_GameObject: {fileID: 1362053823}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: bafc15da02fe850489635791dda2bbdf, type: 3}
|
||||
m_Script: {fileID: 11500000, guid: df35b0c19ca97734e87299a664cea35f, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
_requestedDeviceName:
|
||||
|
@ -3100,8 +3100,9 @@ MonoBehaviour:
|
|||
m_StringArgument:
|
||||
m_BoolArgument: 0
|
||||
m_CallState: 2
|
||||
m_TypeName: FaceMaskExample.WebCamTextureToMatHelper+ErrorUnityEvent, Assembly-CSharp,
|
||||
Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_TypeName: OpenCVForUnity.UnityUtils.Helper.WebCamTextureToMatHelper+ErrorUnityEvent,
|
||||
Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
avoidAndroidFrontCameraLowLightIssue: 0
|
||||
--- !u!114 &1362053831
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
|
|
|
@ -3,7 +3,12 @@ FaceMask Example
|
|||
|
||||
Overview
|
||||
-----
|
||||
<https://www.assetstore.unity3d.com/#!/content/79999>
|
||||
[https://assetstore.unity.com/packages/templates/tutorials/facemask-example-79999](https://assetstore.unity.com/packages/templates/tutorials/facemask-example-79999?aid=1011l4ehR)
|
||||
|
||||
Environment
|
||||
-----
|
||||
[OpenCVForUnity](https://assetstore.unity.com/packages/tools/integration/opencv-for-unity-21088?aid=1011l4ehR)
|
||||
[DlibFaceLandmarkDetector](https://assetstore.unity.com/packages/tools/integration/dlib-facelandmark-detector-64314?aid=1011l4ehR)
|
||||
|
||||
Demo Video
|
||||
-----
|
||||
|
|
Загрузка…
Ссылка в новой задаче